[flang] Capture source locations for Designators and Calls
authorpeter klausler <pklausler@nvidia.com>
Mon, 15 Apr 2019 22:18:07 +0000 (15:18 -0700)
committerpeter klausler <pklausler@nvidia.com>
Mon, 15 Apr 2019 22:18:07 +0000 (15:18 -0700)
Original-commit: flang-compiler/f18@970333fff79c0ba1574290ffe965febcd6371125
Reviewed-on: https://github.com/flang-compiler/f18/pull/415
Tree-same-pre-rewrite: false

flang/lib/parser/grammar.h
flang/lib/parser/parse-tree.h
flang/lib/semantics/expression.cc
flang/lib/semantics/expression.h

index e6efaaa..f344375 100644 (file)
@@ -1415,7 +1415,7 @@ TYPE_PARSER(construct<CommonBlockObject>(name, maybe(arraySpec)))
 //  maybe an [image-selector].
 //  If it's a substring, it ends with (substring-range).
 TYPE_CONTEXT_PARSER("designator"_en_US,
-    construct<Designator>(substring) || construct<Designator>(dataRef))
+    sourced(construct<Designator>(substring) || construct<Designator>(dataRef)))
 
 constexpr auto percentOrDot{"%"_tok ||
     // legacy VAX extension for RECORD field access
@@ -1517,8 +1517,7 @@ constexpr auto teamValue{scalar(indirect(expr))};
 //        TEAM_NUMBER = scalar-int-expr
 TYPE_PARSER(construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Stat>(
                 "STAT =" >> scalar(integer(indirect(variable))))) ||
-    construct<ImageSelectorSpec>(
-        construct<TeamValue>("TEAM =" >> teamValue)) ||
+    construct<ImageSelectorSpec>(construct<TeamValue>("TEAM =" >> teamValue)) ||
     construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Team_Number>(
         "TEAM_NUMBER =" >> scalarIntExpr)))
 
@@ -3284,14 +3283,15 @@ TYPE_PARSER(
 
 // R1520 function-reference -> procedure-designator ( [actual-arg-spec-list] )
 TYPE_CONTEXT_PARSER("function reference"_en_US,
-    construct<FunctionReference>(construct<Call>(Parser<ProcedureDesignator>{},
-        parenthesized(optionalList(actualArgSpec)))) /
+    construct<FunctionReference>(
+        sourced(construct<Call>(Parser<ProcedureDesignator>{},
+            parenthesized(optionalList(actualArgSpec))))) /
         !"["_tok)
 
 // R1521 call-stmt -> CALL procedure-designator [( [actual-arg-spec-list] )]
-TYPE_PARSER(
-    construct<CallStmt>(construct<Call>("CALL" >> Parser<ProcedureDesignator>{},
-        defaulted(parenthesized(optionalList(actualArgSpec))))))
+TYPE_PARSER(construct<CallStmt>(
+    sourced(construct<Call>("CALL" >> Parser<ProcedureDesignator>{},
+        defaulted(parenthesized(optionalList(actualArgSpec)))))))
 
 // R1522 procedure-designator ->
 //         procedure-name | proc-component-ref | data-ref % binding-name
index 9152f26..406883e 100644 (file)
@@ -1756,6 +1756,7 @@ struct CharLiteralConstantSubstring {
 struct Designator {
   UNION_CLASS_BOILERPLATE(Designator);
   bool EndsInBareName() const;
+  CharBlock source;
   std::variant<DataRef, Substring> u;
 };
 
@@ -3101,6 +3102,7 @@ struct ActualArgSpec {
 // R1520 function-reference -> procedure-designator ( [actual-arg-spec-list] )
 struct Call {
   TUPLE_CLASS_BOILERPLATE(Call);
+  CharBlock source;
   std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
 };
 
index a2aa4db..5dccd71 100644 (file)
 using MaybeExpr =
     std::optional<Fortran::evaluate::Expr<Fortran::evaluate::SomeType>>;
 
-namespace Fortran::parser {
-bool SourceLocationFindingVisitor::Pre(const Expr &x) {
-  source = x.source;
-  return false;
-}
-void SourceLocationFindingVisitor::Post(const CharBlock &at) { source = at; }
-}
-
 // Much of the code that implements semantic analysis of expressions is
 // tightly coupled with their typed representations in lib/evaluate,
 // and appears here in namespace Fortran::evaluate for convenience.
@@ -342,6 +334,7 @@ static void FixMisparsedSubstring(const parser::Designator &d) {
 }
 
 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Designator &d) {
+  auto save{GetContextualMessages().SetLocation(d.source)};
   FixMisparsedSubstring(d);
   // These checks have to be deferred to these "top level" data-refs where
   // we can be sure that there are no following subscripts (yet).
@@ -1504,6 +1497,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
   // TODO: Actual arguments that are procedures and procedure pointers need to
   // be detected and represented (they're not expressions).
   // TODO: C1534: Don't allow a "restricted" specific intrinsic to be passed.
+  auto save{GetContextualMessages().SetLocation(funcRef.v.source)};
   ActualArguments arguments;
   for (const auto &arg :
       std::get<std::list<parser::ActualArgSpec>>(funcRef.v.t)) {
index 047a819..ba44ce4 100644 (file)
@@ -35,12 +35,31 @@ namespace Fortran::parser {
 struct SourceLocationFindingVisitor {
   template<typename A> bool Pre(const A &) { return true; }
   template<typename A> void Post(const A &) {}
-  bool Pre(const Expr &);
-  template<typename A> bool Pre(const Statement<A> &stmt) {
+  bool Pre(const Expr &x) {
+    source = x.source;
+    return false;
+  }
+  bool Pre(const Designator &x) {
+    source = x.source;
+    return false;
+  }
+  bool Pre(const Call &x) {
+    source = x.source;
+    return false;
+  }
+  bool Pre(const CompilerDirective &x) {
+    source = x.source;
+    return false;
+  }
+  bool Pre(const GenericSpec &x) {
+    source = x.source;
+    return false;
+  }
+  template<typename A> bool Pre(const UnlabeledStatement<A> &stmt) {
     source = stmt.source;
     return false;
   }
-  void Post(const CharBlock &);
+  void Post(const CharBlock &at) { source = at; }
 
   CharBlock source;
 };