diff --git a/flang/lib/Parser/basic-parsers.h b/flang/lib/Parser/basic-parsers.h --- a/flang/lib/Parser/basic-parsers.h +++ b/flang/lib/Parser/basic-parsers.h @@ -800,13 +800,14 @@ // must discard its result in order to be compatible in type with other // parsers in an alternative, e.g. "x >> ok || y >> ok" is type-safe even // when x and y have distinct result types. -constexpr struct OkParser { +struct OkParser { using resultType = Success; constexpr OkParser() {} static constexpr std::optional Parse(ParseState &) { return Success{}; } -} ok; +}; +constexpr OkParser ok; // A variant of recovery() above for convenience. template diff --git a/flang/lib/Parser/expr-parsers.cpp b/flang/lib/Parser/expr-parsers.cpp --- a/flang/lib/Parser/expr-parsers.cpp +++ b/flang/lib/Parser/expr-parsers.cpp @@ -119,7 +119,7 @@ // R1005 add-operand -> [add-operand mult-op] mult-operand // R1008 mult-op -> * | / // The left recursion in the grammar is implemented iteratively. -constexpr struct AddOperand { +struct AddOperand { using resultType = Expr; constexpr AddOperand() {} static inline std::optional Parse(ParseState &state) { @@ -142,7 +142,8 @@ } return result; } -} addOperand; +}; +constexpr AddOperand addOperand; // R1006 level-2-expr -> [[level-2-expr] add-op] add-operand // R1009 add-op -> + | - @@ -151,7 +152,7 @@ // by means of a missing first operand; e.g., 2*-3 is valid in C but not // standard Fortran. We accept unary + and - to appear before any primary // as an extension. -constexpr struct Level2Expr { +struct Level2Expr { using resultType = Expr; constexpr Level2Expr() {} static inline std::optional Parse(ParseState &state) { @@ -179,13 +180,14 @@ } return result; } -} level2Expr; +}; +constexpr Level2Expr level2Expr; // R1010 level-3-expr -> [level-3-expr concat-op] level-2-expr // R1011 concat-op -> // // Concatenation (//) is left-associative for parsing performance, although // one would never notice if it were right-associated. -constexpr struct Level3Expr { +struct Level3Expr { using resultType = Expr; constexpr Level3Expr() {} static inline std::optional Parse(ParseState &state) { @@ -203,14 +205,15 @@ } return result; } -} level3Expr; +}; +constexpr Level3Expr level3Expr; // R1012 level-4-expr -> [level-3-expr rel-op] level-3-expr // R1013 rel-op -> // .EQ. | .NE. | .LT. | .LE. | .GT. | .GE. | // == | /= | < | <= | > | >= @ | <> // N.B. relations are not recursive (i.e., LOGICAL is not ordered) -constexpr struct Level4Expr { +struct Level4Expr { using resultType = Expr; constexpr Level4Expr() {} static inline std::optional Parse(ParseState &state) { @@ -252,17 +255,19 @@ } return result; } -} level4Expr; +}; +constexpr Level4Expr level4Expr; // R1014 and-operand -> [not-op] level-4-expr // R1018 not-op -> .NOT. // N.B. Fortran's .NOT. binds less tightly than its comparison operators do. // PGI/Intel extension: accept multiple .NOT. operators -constexpr struct AndOperand { +struct AndOperand { using resultType = Expr; constexpr AndOperand() {} static inline std::optional Parse(ParseState &); -} andOperand; +}; +constexpr AndOperand andOperand; // Match a logical operator or, optionally, its abbreviation. inline constexpr auto logicalOp(const char *op, const char *abbrev) { @@ -283,7 +288,7 @@ // R1015 or-operand -> [or-operand and-op] and-operand // R1019 and-op -> .AND. // .AND. is left-associative -constexpr struct OrOperand { +struct OrOperand { using resultType = Expr; constexpr OrOperand() {} static inline std::optional Parse(ParseState &state) { @@ -303,12 +308,13 @@ } return result; } -} orOperand; +}; +constexpr OrOperand orOperand; // R1016 equiv-operand -> [equiv-operand or-op] or-operand // R1020 or-op -> .OR. // .OR. is left-associative -constexpr struct EquivOperand { +struct EquivOperand { using resultType = Expr; constexpr EquivOperand() {} static inline std::optional Parse(ParseState &state) { @@ -327,13 +333,14 @@ } return result; } -} equivOperand; +}; +constexpr EquivOperand equivOperand; // R1017 level-5-expr -> [level-5-expr equiv-op] equiv-operand // R1021 equiv-op -> .EQV. | .NEQV. // Logical equivalence is left-associative. // Extension: .XOR. as synonym for .NEQV. -constexpr struct Level5Expr { +struct Level5Expr { using resultType = Expr; constexpr Level5Expr() {} static inline std::optional Parse(ParseState &state) { @@ -358,7 +365,8 @@ } return result; } -} level5Expr; +}; +constexpr Level5Expr level5Expr; // R1022 expr -> [expr defined-binary-op] level-5-expr // Defined binary operators associate leftwards. diff --git a/flang/lib/Parser/token-parsers.h b/flang/lib/Parser/token-parsers.h --- a/flang/lib/Parser/token-parsers.h +++ b/flang/lib/Parser/token-parsers.h @@ -62,7 +62,7 @@ constexpr auto digit{"0123456789"_ch}; // Skips over optional spaces. Always succeeds. -constexpr struct Space { +struct Space { using resultType = Success; constexpr Space() {} static std::optional Parse(ParseState &state) { @@ -74,7 +74,8 @@ } return {Success{}}; } -} space; +}; +constexpr Space space; // Skips a space that in free form requires a warning if it precedes a // character that could begin an identifier or keyword. Always succeeds. @@ -85,7 +86,7 @@ } } -constexpr struct SpaceCheck { +struct SpaceCheck { using resultType = Success; constexpr SpaceCheck() {} static std::optional Parse(ParseState &state) { @@ -101,7 +102,8 @@ } return {Success{}}; } -} spaceCheck; +}; +constexpr SpaceCheck spaceCheck; // Matches a token string. Spaces in the token string denote where // spaces may appear in the source; they can be made mandatory for @@ -346,7 +348,7 @@ // R711 digit-string -> digit [digit]... // N.B. not a token -- no space is skipped -constexpr struct DigitString { +struct DigitString { using resultType = CharBlock; static std::optional Parse(ParseState &state) { if (std::optional ch1{state.PeekAtNextChar()}) { @@ -363,7 +365,8 @@ } return std::nullopt; } -} digitString; +}; +constexpr DigitString digitString; struct SignedIntLiteralConstantWithoutKind { using resultType = CharBlock; @@ -380,7 +383,7 @@ } }; -constexpr struct DigitString64 { +struct DigitString64 { using resultType = std::uint64_t; static std::optional Parse(ParseState &state) { std::optional firstDigit{digit.Parse(state)}; @@ -406,7 +409,8 @@ } return {value}; } -} digitString64; +}; +constexpr DigitString64 digitString64; // R707 signed-int-literal-constant -> [sign] int-literal-constant // N.B. Spaces are consumed before and after the sign, since the sign @@ -537,7 +541,7 @@ } }; -constexpr struct ConsumedAllInputParser { +struct ConsumedAllInputParser { using resultType = Success; constexpr ConsumedAllInputParser() {} static inline std::optional Parse(ParseState &state) { @@ -546,7 +550,8 @@ } return std::nullopt; } -} consumedAllInput; +}; +constexpr ConsumedAllInputParser consumedAllInput; template struct SkipPast { using resultType = Success; @@ -599,7 +604,7 @@ // the ones that specify the source form) that might appear before the // next statement. Skip over empty statements (bare semicolons) when // not in strict standard conformance mode. Always succeeds. -constexpr struct SkipStuffBeforeStatement { +struct SkipStuffBeforeStatement { using resultType = Success; static std::optional Parse(ParseState &state) { if (UserState * ustate{state.userState()}) { @@ -637,7 +642,8 @@ } return {Success{}}; } -} skipStuffBeforeStatement; +}; +constexpr SkipStuffBeforeStatement skipStuffBeforeStatement; // R602 underscore -> _ constexpr auto underscore{"_"_ch};