[flang] Debugging after testing. Take care of a TODO in the prescanner.
authorpeter klausler <pklausler@nvidia.com>
Fri, 30 Mar 2018 23:21:12 +0000 (16:21 -0700)
committerpeter klausler <pklausler@nvidia.com>
Fri, 30 Mar 2018 23:21:12 +0000 (16:21 -0700)
Original-commit: flang-compiler/f18@4c8181e106fd73b145208ce987abb702a72fee87
Reviewed-on: https://github.com/flang-compiler/f18/pull/37
Tree-same-pre-rewrite: false

flang/lib/parser/grammar.h
flang/lib/parser/parse-tree.cc
flang/lib/parser/parse-tree.h
flang/lib/parser/parsing.cc
flang/lib/parser/prescan.cc
flang/lib/parser/prescan.h
flang/lib/parser/user-state.h

index c053848..61b43cf 100644 (file)
@@ -1638,7 +1638,7 @@ constexpr struct StructureComponentName {
   static std::optional<Name> Parse(ParseState *state) {
     if (std::optional<Name> n{name.Parse(state)}) {
       if (const auto *user = state->userState()) {
-        if (user->IsStructureComponent(n->source)) {
+        if (user->IsOldStructureComponent(n->source)) {
           return n;
         }
       }
@@ -3453,7 +3453,7 @@ std::optional<FunctionReference> Parser<FunctionReference>::Parse(
       return {std::move(**funcref)};
     }
     Designator *desig{&*std::get<Indirection<Designator>>(var->u)};
-    if (std::optional<Call> call{desig->ConvertToCall()}) {
+    if (std::optional<Call> call{desig->ConvertToCall(state->userState())}) {
       if (!std::get<std::list<ActualArgSpec>>(call.value().t).empty()) {
         // Parsed a designator that ended with a nonempty list of subscripts
         // that have all been converted to actual arguments.
@@ -3478,7 +3478,7 @@ template<> std::optional<CallStmt> Parser<CallStmt>::Parse(ParseState *state) {
       return {CallStmt{std::move((*funcref)->v)}};
     }
     Designator *desig{&*std::get<Indirection<Designator>>(var->u)};
-    if (std::optional<Call> call{desig->ConvertToCall()}) {
+    if (std::optional<Call> call{desig->ConvertToCall(state->userState())}) {
       return {CallStmt{std::move(call.value())}};
     }
   }
@@ -3647,7 +3647,7 @@ constexpr struct StructureComponents {
     if (defs.has_value()) {
       if (auto ustate = state->userState()) {
         for (const auto &decl : std::get<std::list<ComponentDecl>>(defs->t)) {
-          ustate->NoteStructureComponent(std::get<Name>(decl.t).source);
+          ustate->NoteOldStructureComponent(std::get<Name>(decl.t).source);
         }
       }
     }
index 315edef..ebd9425 100644 (file)
@@ -1,6 +1,7 @@
 #include "parse-tree.h"
 #include "idioms.h"
 #include "indirection.h"
+#include "user-state.h"
 #include <algorithm>
 
 namespace Fortran {
@@ -29,7 +30,7 @@ ProcedureDesignator Designator::ConvertToProcedureDesignator() {
       visitors{
           [](ObjectName &n) -> ProcedureDesignator { return {std::move(n)}; },
           [](DataReference &dr) -> ProcedureDesignator {
-            if (Name *n = std::get_if<Name>(&dr.u)) {
+            if (Name * n{std::get_if<Name>(&dr.u)}) {
               return {std::move(*n)};
             }
             StructureComponent &sc{
@@ -45,24 +46,28 @@ ProcedureDesignator Designator::ConvertToProcedureDesignator() {
       u);
 }
 
-std::optional<Call> Designator::ConvertToCall() {
+std::optional<Call> Designator::ConvertToCall(const UserState *ustate) {
   return std::visit(
       visitors{[](ObjectName &n) -> std::optional<Call> {
                  return {Call{ProcedureDesignator{std::move(n)},
                      std::list<ActualArgSpec>{}}};
                },
-          [this](DataReference &dr) -> std::optional<Call> {
+          [=](DataReference &dr) -> std::optional<Call> {
             if (std::holds_alternative<Indirection<CoindexedNamedObject>>(
                     dr.u)) {
               return {};
             }
-            if (Name *n = std::get_if<Name>(&dr.u)) {
+            if (Name * n{std::get_if<Name>(&dr.u)}) {
               return {Call{ProcedureDesignator{std::move(*n)},
                   std::list<ActualArgSpec>{}}};
             }
             if (auto *isc =
                     std::get_if<Indirection<StructureComponent>>(&dr.u)) {
               StructureComponent &sc{**isc};
+              if (ustate &&
+                  ustate->IsOldStructureComponent(sc.component.source)) {
+                return {};
+              }
               Variable var{Indirection<Designator>{std::move(sc.base)}};
               ProcComponentRef pcr{
                   Scalar<Variable>{std::move(var)}, std::move(sc.component)};
@@ -87,6 +92,10 @@ std::optional<Call> Designator::ConvertToCall() {
             }
             StructureComponent &bsc{
                 *std::get<Indirection<StructureComponent>>(ae.base.u)};
+            if (ustate &&
+                ustate->IsOldStructureComponent(bsc.component.source)) {
+              return {};
+            }
             Variable var{Indirection<Designator>{std::move(bsc.base)}};
             ProcComponentRef pcr{
                 Scalar<Variable>{std::move(var)}, std::move(bsc.component)};
index f9a6e8b..568fac5 100644 (file)
@@ -16,6 +16,7 @@
 #include "indirection.h"
 #include "message.h"
 #include "provenance.h"
+#include "user-state.h"
 #include <cinttypes>
 #include <list>
 #include <optional>
@@ -1716,7 +1717,7 @@ struct Designator {
   UNION_CLASS_BOILERPLATE(Designator);
   bool EndsInBareName() const;
   ProcedureDesignator ConvertToProcedureDesignator();
-  std::optional<Call> ConvertToCall();
+  std::optional<Call> ConvertToCall(const UserState *ustate = nullptr);
   std::variant<ObjectName, DataReference, Substring> u;
 };
 
index 78e3ede..8e8a859 100644 (file)
@@ -47,6 +47,7 @@ bool Parsing::Prescan(const std::string &path, Options options) {
       .set_encoding(options.encoding)
       .set_enableBackslashEscapesInCharLiterals(options.enableBackslashEscapes)
       .set_enableOldDebugLines(options.enableOldDebugLines)
+      .set_warnOnNonstandardUsage(options_.isStrictlyStandard)
       .AddCompilerDirectiveSentinel("dir$");
   ProvenanceRange range{
       allSources_.AddIncludedFile(*sourceFile, ProvenanceRange{})};
index 8cd94fb..d16cd36 100644 (file)
@@ -25,6 +25,7 @@ Prescanner::Prescanner(const Prescanner &that)
     enableOldDebugLines_{that.enableOldDebugLines_},
     enableBackslashEscapesInCharLiterals_{
         that.enableBackslashEscapesInCharLiterals_},
+    warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
     compilerDirectiveBloomFilter_{that.compilerDirectiveBloomFilter_},
     compilerDirectiveSentinels_{that.compilerDirectiveSentinels_} {}
 
@@ -670,7 +671,11 @@ const char *Prescanner::FixedFormContinuationLine() {
   }
   // Normal case: not in a compiler directive.
   if (*p == '&') {
-    return p + 1;  // extension; TODO: emit warning with -Mstandard
+    // Extension: '&' as continuation marker
+    if (warnOnNonstandardUsage_) {
+      Complain("nonstandard usage"_en_US, GetProvenance(p));
+    }
+    return p + 1;
   }
   if (*p == '\t' && p[1] >= '1' && p[1] <= '9') {
     tabInCurrentLine_ = true;
index ee978b1..9630e85 100644 (file)
@@ -52,6 +52,10 @@ public:
     fixedFormColumnLimit_ = limit;
     return *this;
   }
+  Prescanner &set_warnOnNonstandardUsage(bool yes) {
+    warnOnNonstandardUsage_ = yes;
+    return *this;
+  }
 
   Prescanner &AddCompilerDirectiveSentinel(const std::string &);
 
@@ -155,6 +159,7 @@ private:
   Encoding encoding_{Encoding::UTF8};
   bool enableOldDebugLines_{false};
   bool enableBackslashEscapesInCharLiterals_{true};
+  bool warnOnNonstandardUsage_{false};
   int delimiterNesting_{0};
 
   Provenance startProvenance_;
index e6565f3..a919242 100644 (file)
@@ -19,7 +19,7 @@ public:
   void NewSubprogram() {
     doLabels_.clear();
     nonlabelDoConstructNestingDepth_ = 0;
-    structureComponents_.clear();
+    oldStructureComponents_.clear();
   }
 
   using Label = std::uint64_t;
@@ -37,17 +37,17 @@ public:
     }
   }
 
-  void NoteStructureComponent(const CharBlock &name) {
-    structureComponents_.insert(name);
+  void NoteOldStructureComponent(const CharBlock &name) {
+    oldStructureComponents_.insert(name);
   }
-  bool IsStructureComponent(const CharBlock &name) const {
-    return structureComponents_.find(name) != structureComponents_.end();
+  bool IsOldStructureComponent(const CharBlock &name) const {
+    return oldStructureComponents_.find(name) != oldStructureComponents_.end();
   }
 
 private:
   std::unordered_set<Label> doLabels_;
   int nonlabelDoConstructNestingDepth_{0};
-  std::set<CharBlock> structureComponents_;
+  std::set<CharBlock> oldStructureComponents_;
 };
 }  // namespace parser
 }  // namespace Fortran