[flang] Use std::optional<>::value() where appropriate.

Original-commit: flang-compiler/f18@4278b79b3d
Reviewed-on: https://github.com/flang-compiler/f18/pull/237
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2018-12-05 13:03:39 -08:00
parent bf9d7ba483
commit 1b1f60ff50
10 changed files with 29 additions and 36 deletions

View file

@ -124,6 +124,8 @@ with lists of types.
This simple little type is used wherever a value might or might not be
present.
It is especially useful for function results and
rvalue reference arguments.
It corresponds directly to the optional elements in the productions
of the Fortran grammar.
It is also used as a wrapper around a parse tree node type to define the

View file

@ -147,6 +147,13 @@ We have an `ENUM_CLASS` macro that helps capture the names of constants.
explicitly, it should contains either a `default:;` at its end or a
`default:` label that obviously crashes; we have a `CRASH_NO_CASE` macro
for such situations.
1. When using `std::optional` values, avoid unprotected access to their content.
This is usually by means of `x.has_value()` guarding execution of `*x`.
This is implicit when they are function results assigned to local variables
in `if`/`while` predicates.
When no presence test is obviously protecting a `*x` reference to the
contents, and it is assumed that the contents are present, validate that
assumption by using `x.value()` instead.
#### Classes
1. Define POD structures with `struct`.
1. Don't use `this->` in (non-static) member functions, unless forced to

View file

@ -908,7 +908,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
if (sameArg == nullptr) {
sameArg = arg;
}
argOk = *type == sameArg->GetType();
argOk = type.value() == sameArg->GetType();
break;
case KindCode::effectiveKind:
common::die("INTERNAL: KindCode::effectiveKind appears on argument '%s' "
@ -1017,7 +1017,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
if (call.isSubroutineCall) {
return std::nullopt;
}
resultType = DynamicType{*result.categorySet.LeastElement(), 0};
resultType = DynamicType{result.categorySet.LeastElement().value(), 0};
switch (result.kindCode) {
case KindCode::defaultIntegerKind:
CHECK(result.categorySet == IntType);
@ -1124,11 +1124,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
break;
case Rank::shaped:
CHECK(shapeArg != nullptr);
{
std::optional<int> shapeLen{shapeArg->VectorSize()};
CHECK(shapeLen.has_value());
resultRank = *shapeLen;
}
resultRank = shapeArg->VectorSize().value();
break;
case Rank::elementalOrBOZ:
case Rank::shape:

View file

@ -51,13 +51,6 @@ public:
static constexpr int maxExponent{(1 << exponentBits) - 1};
static constexpr int exponentBias{maxExponent / 2};
// Decimal precision of a binary floating-point representation is
// actually the same as the base-5 precision, as factors of two
// can be accommodated by the binary exponent.
// log(2)/log(5) = 0.430+ in any base.
// Calculate "precision*0.43" with integer arithmetic so as to be constexpr.
static constexpr int decimalDigits{(precision * 43) / 100};
template<typename W, int P, bool I> friend class Real;
constexpr Real() {} // +0.0

View file

@ -295,8 +295,9 @@ template<TypeCategory TOCAT, typename VALUE> struct ConvertToKindHelper {
template<TypeCategory TOCAT, typename VALUE>
Expr<SomeKind<TOCAT>> ConvertToKind(int kind, VALUE &&x) {
return *common::SearchDynamicTypes(
ConvertToKindHelper<TOCAT, VALUE>{kind, std::move(x)});
return common::SearchDynamicTypes(
ConvertToKindHelper<TOCAT, VALUE>{kind, std::move(x)})
.value();
}
// Given a type category CAT, SameKindExprs<CAT, N> is a variant that

View file

@ -488,7 +488,7 @@ public:
resultType result;
result.emplace_back(std::move(*first));
if (state.GetLocation() > start) {
result.splice(result.end(), *many(parser_).Parse(state));
result.splice(result.end(), many(parser_).Parse(state).value());
}
return {std::move(result)};
}
@ -581,8 +581,7 @@ public:
constexpr DefaultedParser(const PA &p) : parser_{p} {}
std::optional<resultType> Parse(ParseState &state) const {
std::optional<std::optional<resultType>> ax{maybe(parser_).Parse(state)};
CHECK(ax.has_value()); // maybe() always succeeds
if (ax.value().has_value()) {
if (ax.value().has_value()) { // maybe() always succeeds
return std::move(*ax);
}
return {resultType{}};

View file

@ -148,7 +148,7 @@ void EmitQuotedChar(char32_t ch, const NORMAL &emit, const INSERTED &insert,
emit('\\');
} else if (ch < ' ' || (ch >= 0x80 && ch <= 0xff)) {
insert('\\');
if (std::optional escape{BackslashEscapeChar(ch)}) {
if (std::optional<char> escape{BackslashEscapeChar(ch)}) {
emit(*escape);
} else {
// octal escape sequence

View file

@ -66,12 +66,12 @@ template<typename M> void Walk(format::IntrinsicTypeDataEditDesc &, M &);
// Traversal of needed STL template classes (optional, list, tuple, variant)
template<typename T, typename V>
void Walk(const std::optional<T> &x, V &visitor) {
if (x) {
if (x.has_value()) {
Walk(*x, visitor);
}
}
template<typename T, typename M> void Walk(std::optional<T> &x, M &mutator) {
if (x) {
if (x.has_value()) {
Walk(*x, mutator);
}
}

View file

@ -430,9 +430,8 @@ constexpr struct SkipDigitString {
static std::optional<std::int64_t> SignedInteger(
const std::optional<std::uint64_t> &x, Location at, bool negate,
ParseState &state) {
std::optional<std::int64_t> result;
if (!x.has_value()) {
return result;
return std::nullopt;
}
std::uint64_t limit{std::numeric_limits<std::int64_t>::max()};
if (negate) {
@ -442,8 +441,7 @@ static std::optional<std::int64_t> SignedInteger(
state.Say(at, "overflow in signed decimal literal"_err_en_US);
}
std::int64_t value = *x;
result = negate ? -value : value;
return result;
return std::make_optional<std::int64_t>(negate ? -value : value);
}
struct SignedIntLiteralConstantWithoutKind {
@ -580,9 +578,7 @@ struct HollerithLiteral {
} else {
// Multi-byte character
while (bytes-- > 0) {
std::optional<const char *> byte{nextCh.Parse(state)};
CHECK(byte.has_value());
content += **byte;
content += *nextCh.Parse(state).value();
}
}
}

View file

@ -818,8 +818,8 @@ MaybeExpr AnalyzeExpr(
if (dynamicType->category == TypeCategory::Character) {
return WrapperHelper<TypeCategory::Character, Designator,
Substring>(dynamicType->kind,
Substring{
std::move(*checked), std::move(first), std::move(last)});
Substring{std::move(checked.value()), std::move(first),
std::move(last)});
}
}
context.Say("substring may apply only to CHARACTER"_err_en_US);
@ -848,9 +848,8 @@ MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context,
lower = Expr<SubscriptInteger>{1};
}
if (!upper.has_value()) {
std::optional<std::int64_t> size{ToInt64(length)};
CHECK(size.has_value());
upper = Expr<SubscriptInteger>{static_cast<std::int64_t>(*size)};
upper = Expr<SubscriptInteger>{
static_cast<std::int64_t>(ToInt64(length).value())};
}
return std::visit(
[&](auto &&ckExpr) -> MaybeExpr {
@ -861,8 +860,8 @@ MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context,
staticData->set_alignment(Result::kind)
.set_itemBytes(Result::kind)
.Push(cp->value);
Substring substring{
std::move(staticData), std::move(*lower), std::move(*upper)};
Substring substring{std::move(staticData), std::move(lower.value()),
std::move(upper.value())};
return AsGenericExpr(Expr<SomeCharacter>{
Expr<Result>{Designator<Result>{std::move(substring)}}});
},