[flang-commits] [flang] 207d449 - [flang][msvc] Split class declaration and constexpr variable definition. NFC.

Michael Kruse via flang-commits flang-commits at lists.llvm.org
Sat Aug 22 13:05:55 PDT 2020


Author: Michael Kruse
Date: 2020-08-22T15:05:48-05:00
New Revision: 207d4499dfab050b0535c7361527d3c37cf6488a

URL: https://github.com/llvm/llvm-project/commit/207d4499dfab050b0535c7361527d3c37cf6488a
DIFF: https://github.com/llvm/llvm-project/commit/207d4499dfab050b0535c7361527d3c37cf6488a.diff

LOG: [flang][msvc] Split class declaration and constexpr variable definition. NFC.

Msvc has trouble defining a struct/class and defining a constexpr symbol in the same declarator. It reports the following error:
```
basic-parsers.h(809): error C2131: expression did not evaluate to a constant
basic-parsers.h(809): note: failure was caused by call of undefined function or one not declared 'constexpr'
basic-parsers.h(809): note: see usage of 'Fortran::parser::OkParser::OkParser'
```

Fix the msvc compilation by splitting the two definitions into two separate declarators.

This patch is part of the series to [[ http://lists.llvm.org/pipermail/flang-dev/2020-July/000448.html | make flang compilable with MS Visual Studio ]].

Reviewed By: DavidTruby, klausler

Differential Revision: https://reviews.llvm.org/D85937

Added: 
    

Modified: 
    flang/lib/Parser/basic-parsers.h
    flang/lib/Parser/expr-parsers.cpp
    flang/lib/Parser/token-parsers.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Parser/basic-parsers.h b/flang/lib/Parser/basic-parsers.h
index 300400517507..56d9ff1b0706 100644
--- a/flang/lib/Parser/basic-parsers.h
+++ b/flang/lib/Parser/basic-parsers.h
@@ -800,13 +800,14 @@ inline constexpr auto nonemptySeparated(PA p, PB sep) {
 // 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<Success> Parse(ParseState &) {
     return Success{};
   }
-} ok;
+};
+constexpr OkParser ok;
 
 // A variant of recovery() above for convenience.
 template <typename PA, typename PB>

diff  --git a/flang/lib/Parser/expr-parsers.cpp b/flang/lib/Parser/expr-parsers.cpp
index a7ae7c32f9f6..35e68e364ed5 100644
--- a/flang/lib/Parser/expr-parsers.cpp
+++ b/flang/lib/Parser/expr-parsers.cpp
@@ -119,7 +119,7 @@ inline std::optional<Expr> MultOperand::Parse(ParseState &state) {
 // 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<Expr> Parse(ParseState &state) {
@@ -142,7 +142,8 @@ constexpr struct AddOperand {
     }
     return result;
   }
-} addOperand;
+};
+constexpr AddOperand addOperand;
 
 // R1006 level-2-expr -> [[level-2-expr] add-op] add-operand
 // R1009 add-op -> + | -
@@ -151,7 +152,7 @@ constexpr struct AddOperand {
 // 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<Expr> Parse(ParseState &state) {
@@ -179,13 +180,14 @@ constexpr struct Level2Expr {
     }
     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<Expr> Parse(ParseState &state) {
@@ -203,14 +205,15 @@ constexpr struct Level3Expr {
     }
     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<Expr> Parse(ParseState &state) {
@@ -252,17 +255,19 @@ constexpr struct Level4Expr {
     }
     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<Expr> 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 @@ inline std::optional<Expr> AndOperand::Parse(ParseState &state) {
 // 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<Expr> Parse(ParseState &state) {
@@ -303,12 +308,13 @@ constexpr struct OrOperand {
     }
     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<Expr> Parse(ParseState &state) {
@@ -327,13 +333,14 @@ constexpr struct EquivOperand {
     }
     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<Expr> Parse(ParseState &state) {
@@ -358,7 +365,8 @@ constexpr struct Level5Expr {
     }
     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
index 2ad89053fc65..8d9c79e5c4e0 100644
--- a/flang/lib/Parser/token-parsers.h
+++ b/flang/lib/Parser/token-parsers.h
@@ -62,7 +62,7 @@ constexpr auto letter{"abcdefghijklmnopqrstuvwxyz"_ch};
 constexpr auto digit{"0123456789"_ch};
 
 // Skips over optional spaces.  Always succeeds.
-constexpr struct Space {
+struct Space {
   using resultType = Success;
   constexpr Space() {}
   static std::optional<Success> Parse(ParseState &state) {
@@ -74,7 +74,8 @@ constexpr struct Space {
     }
     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 @@ inline void MissingSpace(ParseState &state) {
   }
 }
 
-constexpr struct SpaceCheck {
+struct SpaceCheck {
   using resultType = Success;
   constexpr SpaceCheck() {}
   static std::optional<Success> Parse(ParseState &state) {
@@ -101,7 +102,8 @@ constexpr struct SpaceCheck {
     }
     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 @@ struct BOZLiteral {
 
 // 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<resultType> Parse(ParseState &state) {
     if (std::optional<const char *> ch1{state.PeekAtNextChar()}) {
@@ -363,7 +365,8 @@ constexpr struct DigitString {
     }
     return std::nullopt;
   }
-} digitString;
+};
+constexpr DigitString digitString;
 
 struct SignedIntLiteralConstantWithoutKind {
   using resultType = CharBlock;
@@ -380,7 +383,7 @@ struct SignedIntLiteralConstantWithoutKind {
   }
 };
 
-constexpr struct DigitString64 {
+struct DigitString64 {
   using resultType = std::uint64_t;
   static std::optional<std::uint64_t> Parse(ParseState &state) {
     std::optional<const char *> firstDigit{digit.Parse(state)};
@@ -406,7 +409,8 @@ constexpr struct DigitString64 {
     }
     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 @@ struct HollerithLiteral {
   }
 };
 
-constexpr struct ConsumedAllInputParser {
+struct ConsumedAllInputParser {
   using resultType = Success;
   constexpr ConsumedAllInputParser() {}
   static inline std::optional<Success> Parse(ParseState &state) {
@@ -546,7 +550,8 @@ constexpr struct ConsumedAllInputParser {
     }
     return std::nullopt;
   }
-} consumedAllInput;
+};
+constexpr ConsumedAllInputParser consumedAllInput;
 
 template <char goal> struct SkipPast {
   using resultType = Success;
@@ -599,7 +604,7 @@ inline constexpr auto optionalListBeforeColons(const PA &p) {
 // 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<Success> Parse(ParseState &state) {
     if (UserState * ustate{state.userState()}) {
@@ -637,7 +642,8 @@ constexpr struct SkipStuffBeforeStatement {
     }
     return {Success{}};
   }
-} skipStuffBeforeStatement;
+};
+constexpr SkipStuffBeforeStatement skipStuffBeforeStatement;
 
 // R602 underscore -> _
 constexpr auto underscore{"_"_ch};


        


More information about the flang-commits mailing list