[PATCH] D82796: [flang] Defer stmt function body analysis until specification part complete

Peter Klausler via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 13:02:16 PDT 2020


This revision was automatically updated to reflect the committed changes.
Closed by commit rGf45b41348ba4: [flang] Defer stmt function body analysis until specification part complete (authored by klausler).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82796/new/

https://reviews.llvm.org/D82796

Files:
  flang/lib/Semantics/resolve-names.cpp


Index: flang/lib/Semantics/resolve-names.cpp
===================================================================
--- flang/lib/Semantics/resolve-names.cpp
+++ flang/lib/Semantics/resolve-names.cpp
@@ -1436,7 +1436,7 @@
 
   void PreSpecificationConstruct(const parser::SpecificationConstruct &);
   void CreateGeneric(const parser::GenericSpec &);
-  void FinishSpecificationPart();
+  void FinishSpecificationPart(const std::list<parser::DeclarationConstruct> &);
   void CheckImports();
   void CheckImport(const SourceName &, const SourceName &);
   void HandleCall(Symbol::Flag, const parser::Call &);
@@ -2714,11 +2714,9 @@
   details.set_result(result);
   const auto &parsedExpr{std::get<parser::Scalar<parser::Expr>>(x.t)};
   Walk(parsedExpr);
-  if (auto expr{AnalyzeExpr(context(), parsedExpr)}) {
-    details.set_stmtFunction(std::move(*expr));
-  } else {
-    context().SetError(symbol);
-  }
+  // The analysis of the expression that constitutes the body of the
+  // statement function is deferred to FinishSpecificationPart() so that
+  // all declarations and implicit typing are complete.
   PopScope();
   return true;
 }
@@ -6011,7 +6009,7 @@
     }
   }
   Walk(decls);
-  FinishSpecificationPart();
+  FinishSpecificationPart(decls);
   return false;
 }
 
@@ -6068,7 +6066,8 @@
   info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
 }
 
-void ResolveNamesVisitor::FinishSpecificationPart() {
+void ResolveNamesVisitor::FinishSpecificationPart(
+    const std::list<parser::DeclarationConstruct> &decls) {
   badStmtFuncFound_ = false;
   CheckImports();
   bool inModule{currScope().kind() == Scope::Kind::Module};
@@ -6089,6 +6088,25 @@
     }
   }
   currScope().InstantiateDerivedTypes(context());
+  // Analyze the bodies of statement functions now that the symbol in this
+  // specification part have been fully declared and implicitly typed.
+  for (const auto &decl : decls) {
+    if (const auto *statement{std::get_if<
+            parser::Statement<common::Indirection<parser::StmtFunctionStmt>>>(
+            &decl.u)}) {
+      const parser::StmtFunctionStmt &stmtFunc{statement->statement.value()};
+      if (Symbol * symbol{std::get<parser::Name>(stmtFunc.t).symbol}) {
+        if (auto *details{symbol->detailsIf<SubprogramDetails>()}) {
+          if (auto expr{AnalyzeExpr(context(),
+                  std::get<parser::Scalar<parser::Expr>>(stmtFunc.t))}) {
+            details->set_stmtFunction(std::move(*expr));
+          } else {
+            context().SetError(*symbol);
+          }
+        }
+      }
+    }
+  }
   // TODO: what about instantiations in BLOCK?
   CheckSaveStmts();
   CheckCommonBlocks();
@@ -6278,8 +6296,8 @@
       node.stmt());
   Walk(node.spec());
   // If this is a function, convert result to an object. This is to prevent the
-  // result to be converted later to a function symbol if it is called inside
-  // the function.
+  // result from being converted later to a function symbol if it is called
+  // inside the function.
   // If the result is function pointer, then ConvertToObjectEntity will not
   // convert the result to an object, and calling the symbol inside the function
   // will result in calls to the result pointer.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82796.274214.patch
Type: text/x-patch
Size: 3244 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200629/c8abf960/attachment.bin>


More information about the llvm-commits mailing list