[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