[flang] Begin work on missing space warnings in free form. Reformat C++.
authorpeter klausler <pklausler@nvidia.com>
Thu, 29 Mar 2018 19:16:10 +0000 (12:16 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 29 Mar 2018 19:16:10 +0000 (12:16 -0700)
Original-commit: flang-compiler/f18@1bcbf0eb7bb216e14076cc1b83f1f7a2c3f75340
Reviewed-on: https://github.com/flang-compiler/f18/pull/34

flang/lib/parser/grammar.h
flang/lib/parser/parse-state.h
flang/lib/parser/parse-tree.h
flang/lib/parser/parsing.h
flang/lib/parser/token-parsers.h

index 919b4f7..5e194d0 100644 (file)
@@ -165,7 +165,7 @@ constexpr auto digitString = DigitString{};
 // end-of-statement markers.
 
 // R611 label -> digit [digit]...
-constexpr auto label = spaces >> digitString;
+constexpr auto label = spaces >> digitString / spaceCheck;
 
 template<typename PA>
 using statementConstructor = construct<Statement<typename PA::resultType>>;
index 68e2b3b..c5e6625 100644 (file)
@@ -29,19 +29,18 @@ public:
   ParseState(const CookedSource &cooked)
     : p_{&cooked[0]}, limit_{p_ + cooked.size()}, messages_{cooked} {}
   ParseState(const ParseState &that)
-    : p_{that.p_}, limit_{that.limit_},
-      messages_{that.messages_.cooked()}, userState_{that.userState_},
-      inFixedForm_{that.inFixedForm_}, encoding_{that.encoding_},
-      strictConformance_{that.strictConformance_},
+    : p_{that.p_}, limit_{that.limit_}, messages_{that.messages_.cooked()},
+      userState_{that.userState_}, inFixedForm_{that.inFixedForm_},
+      encoding_{that.encoding_}, strictConformance_{that.strictConformance_},
       warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
       warnOnDeprecatedUsage_{that.warnOnDeprecatedUsage_},
       anyErrorRecovery_{that.anyErrorRecovery_},
       anyConformanceViolation_{that.anyConformanceViolation_} {}
   ParseState(ParseState &&that)
-    : p_{that.p_}, limit_{that.limit_},
-      messages_{std::move(that.messages_)}, context_{std::move(that.context_)},
-      userState_{that.userState_}, inFixedForm_{that.inFixedForm_},
-      encoding_{that.encoding_}, strictConformance_{that.strictConformance_},
+    : p_{that.p_}, limit_{that.limit_}, messages_{std::move(that.messages_)},
+      context_{std::move(that.context_)}, userState_{that.userState_},
+      inFixedForm_{that.inFixedForm_}, encoding_{that.encoding_},
+      strictConformance_{that.strictConformance_},
       warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
       warnOnDeprecatedUsage_{that.warnOnDeprecatedUsage_},
       anyErrorRecovery_{that.anyErrorRecovery_},
index 9b5e0e4..f9a6e8b 100644 (file)
 // although a C++ compiler wouldn't default them anyway due to the presence
 // of move constructors and move assignments.
 
-
 CLASS_TRAIT(EmptyTrait);
 CLASS_TRAIT(WrapperTrait);
 CLASS_TRAIT(UnionTrait);
 CLASS_TRAIT(TupleTrait);
 
 //
-// An empty class to attach semantic information to each class in 
-// the parse-tree. In practice, each parser-tree 'classname' shall 
+// An empty class to attach semantic information to each class in
+// the parse-tree. In practice, each parser-tree 'classname' shall
 // implement a member:
 //
-//    Semantic<classname> * s = nullptr; 
-// 
-// The actual implementation of each Sema<classname> will be provided 
-// later thus allowing the parser to be build without an dependency 
+//    Semantic<classname> * s = nullptr;
+//
+// The actual implementation of each Sema<classname> will be provided
+// later thus allowing the parser to be build without an dependency
 // with the Sema library
-//  
+//
 
 namespace Fortran {
 namespace semantics {
-  template <typename T> struct Semantic {
-   Semantic(T*) {}
+template<typename T> struct Semantic {
+  Semantic(T *) {}
 };
-}
-}
+}  // namespace semantics
+}  // namespace Fortran
 
 // Most non-template classes in this file use these default definitions
 // for their move constructor and move assignment operator=, and disable
@@ -69,7 +68,7 @@ namespace semantics {
   classname &operator=(classname &&) = default; \
   classname(const classname &) = delete; \
   classname &operator=(const classname &) = delete; \
-  Fortran::semantics::Semantic<classname> * s = nullptr \
+  Fortran::semantics::Semantic<classname> *s = nullptr
 
 // Almost all classes in this file have no default constructor.
 #define BOILERPLATE(classname) \
@@ -86,7 +85,7 @@ namespace semantics {
     classname &operator=(const classname &) { return *this; }; \
     classname &operator=(classname &&) { return *this; }; \
     using EmptyTrait = std::true_type; \
-    Fortran::semantics::Semantic<classname> * s = nullptr ; \
+    Fortran::semantics::Semantic<classname> *s = nullptr; \
   }
 
 // Many classes below simply wrap a std::variant<> discriminated union,
@@ -322,7 +321,6 @@ template<typename A> struct Statement {
   A statement;
 };
 
-
 // Error recovery marker
 EMPTY_CLASS(ErrorRecovery);
 
@@ -2151,21 +2149,21 @@ struct LoopControl {
     TUPLE_CLASS_BOILERPLATE(Concurrent);
     std::tuple<ConcurrentHeader, std::list<LocalitySpec>> t;
   };
-  std::variant<LoopBounds<ScalarIntExpr>, ScalarLogicalExpr, Concurrent> u;  
+  std::variant<LoopBounds<ScalarIntExpr>, ScalarLogicalExpr, Concurrent> u;
 };
 
 // R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control]
 struct LabelDoStmt {
   TUPLE_CLASS_BOILERPLATE(LabelDoStmt);
   std::tuple<std::optional<Name>, Label, std::optional<LoopControl>> t;
-  enum {NAME,LABEL,CONTROL} ;
+  enum { NAME, LABEL, CONTROL };
 };
 
 // R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control]
 struct NonLabelDoStmt {
   TUPLE_CLASS_BOILERPLATE(NonLabelDoStmt);
   std::tuple<std::optional<Name>, std::optional<LoopControl>> t;
-  enum {NAME,CONTROL} ;
+  enum { NAME, CONTROL };
 };
 
 // R1132 end-do-stmt -> END DO [do-construct-name]
@@ -2750,7 +2748,7 @@ struct MainProgram {
       ExecutionPart, std::optional<InternalSubprogramPart>,
       Statement<EndProgramStmt>>
       t;
-  enum { PROG, SPEC, EXEC, INTERNAL, END } ; 
+  enum { PROG, SPEC, EXEC, INTERNAL, END };
 };
 
 // R1405 module-stmt -> MODULE module-name
@@ -2782,8 +2780,8 @@ struct Module {
   TUPLE_CLASS_BOILERPLATE(Module);
   std::tuple<Statement<ModuleStmt>, SpecificationPart,
       std::optional<ModuleSubprogramPart>, Statement<EndModuleStmt>>
-      t;  
-  enum { MOD, SPEC, INTERNAL, END } ; 
+      t;
+  enum { MOD, SPEC, INTERNAL, END };
 };
 
 // R1411 rename ->
@@ -3076,7 +3074,7 @@ struct FunctionSubprogram {
   std::tuple<Statement<FunctionStmt>, SpecificationPart, ExecutionPart,
       std::optional<InternalSubprogramPart>, Statement<EndFunctionStmt>>
       t;
-  enum { FUNC, SPEC, EXEC, INTERNAL, END } ; 
+  enum { FUNC, SPEC, EXEC, INTERNAL, END };
 };
 
 // R1534 subroutine-subprogram ->
@@ -3087,7 +3085,7 @@ struct SubroutineSubprogram {
   std::tuple<Statement<SubroutineStmt>, SpecificationPart, ExecutionPart,
       std::optional<InternalSubprogramPart>, Statement<EndSubroutineStmt>>
       t;
-  enum { SUBR, SPEC, EXEC, INTERNAL, END } ; 
+  enum { SUBR, SPEC, EXEC, INTERNAL, END };
 };
 
 // R1539 mp-subprogram-stmt -> MODULE PROCEDURE procedure-name
index 8029e16..a3fbf6a 100644 (file)
@@ -45,8 +45,8 @@ public:
 
   void Identify(std::ostream &o, const char *at, const std::string &prefix,
       bool echoSourceLine = false) const {
-    allSources_.Identify(o, cooked_.GetProvenance(at).start(),
-                         prefix, echoSourceLine);
+    allSources_.Identify(
+        o, cooked_.GetProvenance(at).start(), prefix, echoSourceLine);
   }
 
 private:
index 88ab79c..2e3e154 100644 (file)
@@ -85,7 +85,7 @@ constexpr struct Spaces {
   constexpr Spaces() {}
   static std::optional<Success> Parse(ParseState *state) {
     while (std::optional<char> ch{state->PeekAtNextChar()}) {
-      if (ch != ' ') {
+      if (*ch != ' ') {
         break;
       }
       state->UncheckedAdvance();
@@ -94,6 +94,23 @@ constexpr struct Spaces {
   }
 } spaces;
 
+// Warn about a missing space that must be present in free form.
+// Always succeeds.
+constexpr struct SpaceCheck {
+  using resultType = Success;
+  constexpr SpaceCheck() {}
+  static std::optional<Success> Parse(ParseState *state) {
+    if (!state->inFixedForm()) {
+      if (std::optional<char> ch{state->PeekAtNextChar()}) {
+        if (IsLegalInIdentifier(*ch)) {
+          state->PutMessage("expected space"_en_US);
+        }
+      }
+    }
+    return {Success{}};
+  }
+} spaceCheck;
+
 class TokenStringMatch {
 public:
   using resultType = Success;