[flang] Rearrange references to AllSources singleton, fix FindScope for module files
authorpeter klausler <pklausler@nvidia.com>
Fri, 31 May 2019 23:37:00 +0000 (16:37 -0700)
committerpeter klausler <pklausler@nvidia.com>
Tue, 4 Jun 2019 20:37:09 +0000 (13:37 -0700)
Original-commit: flang-compiler/f18@50ccc1c819d274c0f40358bf15b5f7ac4c7a199a
Reviewed-on: https://github.com/flang-compiler/f18/pull/477
Tree-same-pre-rewrite: false

14 files changed:
flang/lib/parser/parsing.cc
flang/lib/parser/parsing.h
flang/lib/parser/provenance.cc
flang/lib/parser/provenance.h
flang/lib/semantics/expression.cc
flang/lib/semantics/mod-file.cc
flang/lib/semantics/scope.cc
flang/lib/semantics/scope.h
flang/lib/semantics/semantics.cc
flang/lib/semantics/semantics.h
flang/lib/semantics/tools.cc
flang/test/evaluate/intrinsics.cc
flang/tools/f18/f18-parse-demo.cc
flang/tools/f18/f18.cc

index 8414294..38efb7d 100644 (file)
@@ -25,9 +25,7 @@
 
 namespace Fortran::parser {
 
-Parsing::Parsing() {}
 Parsing::Parsing(AllSources &s) : cooked_{s} {}
-
 Parsing::~Parsing() {}
 
 void Parsing::Prescan(const std::string &path, Options options) {
index a252096..3bb77ac 100644 (file)
@@ -46,9 +46,7 @@ struct Options {
 
 class Parsing {
 public:
-  Parsing();
-  explicit Parsing(AllSources &);  // to share an extant AllSources instance
-
+  explicit Parsing(AllSources &);
   ~Parsing();
 
   bool consumedWholeFile() const { return consumedWholeFile_; }
index f9415bd..166104d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION.  All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -312,8 +312,7 @@ const AllSources::Origin &AllSources::MapToOrigin(Provenance at) const {
   return origin_[low];
 }
 
-CookedSource::CookedSource() : allSources_{new AllSources} {}
-CookedSource::CookedSource(AllSources &s) : allSources_{&s} {}
+CookedSource::CookedSource(AllSources &s) : allSources_{s} {}
 CookedSource::~CookedSource() {}
 
 std::optional<ProvenanceRange> CookedSource::GetProvenanceRange(
@@ -331,8 +330,7 @@ std::optional<ProvenanceRange> CookedSource::GetProvenanceRange(
 
 void CookedSource::Marshal() {
   CHECK(provenanceMap_.size() == buffer_.size());
-  provenanceMap_.Put(
-      allSources_->AddCompilerInsertion("(after end of source)"));
+  provenanceMap_.Put(allSources_.AddCompilerInsertion("(after end of source)"));
   data_ = buffer_.Marshal();
   buffer_.clear();
 }
@@ -390,7 +388,7 @@ std::ostream &AllSources::Dump(std::ostream &o) const {
 
 std::ostream &CookedSource::Dump(std::ostream &o) const {
   o << "CookedSource:\n";
-  allSources_->Dump(o);
+  allSources_.Dump(o);
   o << "CookedSource::provenanceMap_:\n";
   provenanceMap_.Dump(o);
   return o;
index f81e165..4efcf35 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION.  All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
 #include "source.h"
 #include "../common/idioms.h"
 #include "../common/interval.h"
-#include "../common/reference-counted.h"
 #include <cstddef>
 #include <map>
 #include <memory>
@@ -109,9 +108,9 @@ private:
   std::vector<ContiguousProvenanceMapping> provenanceMap_;
 };
 
-// AllSources is reference-counted so that multiple instances of CookedSource
-// can share an AllSources instance.
-class AllSources : public common::ReferenceCounted<AllSources> {
+// A singleton AllSources instance for the whole compilation
+// is shared by reference.
+class AllSources {
 public:
   AllSources();
   ~AllSources();
@@ -186,12 +185,11 @@ private:
 
 class CookedSource {
 public:
-  CookedSource();
   explicit CookedSource(AllSources &);
   ~CookedSource();
 
-  AllSources &allSources() { return *allSources_; }
-  const AllSources &allSources() const { return *allSources_; }
+  AllSources &allSources() { return allSources_; }
+  const AllSources &allSources() const { return allSources_; }
   const std::string &data() const { return data_; }
 
   bool IsValid(const char *p) const {
@@ -200,7 +198,7 @@ public:
   bool IsValid(CharBlock range) const {
     return !range.empty() && IsValid(range.begin()) && IsValid(range.end() - 1);
   }
-  bool IsValid(ProvenanceRange r) const { return allSources_->IsValid(r); }
+  bool IsValid(ProvenanceRange r) const { return allSources_.IsValid(r); }
 
   std::optional<ProvenanceRange> GetProvenanceRange(CharBlock) const;
 
@@ -227,7 +225,7 @@ public:
   std::ostream &Dump(std::ostream &) const;
 
 private:
-  common::CountedReference<AllSources> allSources_;
+  AllSources &allSources_;
   CharBuffer buffer_;  // before Marshal()
   std::string data_;  // all of it, prescanned and preprocessed
   OffsetToProvenanceMappings provenanceMap_;
index 08ffcac..b316181 100644 (file)
@@ -30,7 +30,7 @@
 #include <optional>
 #include <set>
 
-// #define DUMP_ON_FAILURE 1
+#define DUMP_ON_FAILURE 1  // TODO pmk rm
 // #define CRASH_ON_FAILURE 1
 #if DUMP_ON_FAILURE
 #include "../parser/dump-parse-tree.h"
index dbe9d9d..851bcff 100644 (file)
@@ -683,8 +683,7 @@ Scope *ModFileReader::Read(const SourceName &name, Scope *ancestor) {
         "Module file for '%s' has invalid checksum: %s"_err_en_US, name, *path);
     return nullptr;
   }
-  // TODO: Construct parsing with an AllSources reference to share provenance
-  parser::Parsing parsing;
+  parser::Parsing parsing{context_.allSources()};
   parser::Options options;
   options.isModuleFile = true;
   parsing.Prescan(*path, options);
@@ -711,9 +710,8 @@ Scope *ModFileReader::Read(const SourceName &name, Scope *ancestor) {
     return nullptr;
   }
   auto &modSymbol{*it->second};
-  // TODO: Preserve the CookedSource rather than acquiring its string.
-  modSymbol.scope()->set_chars(std::string{parsing.cooked().AcquireData()});
   modSymbol.set(Symbol::Flag::ModFile);
+  modSymbol.scope()->set_chars(parsing.cooked());
   return modSymbol.scope();
 }
 
index 82d679b..33aac1b 100644 (file)
@@ -133,6 +133,15 @@ DeclTypeSpec &Scope::MakeDerivedType(
       category, DerivedTypeSpec{std::move(spec)});
 }
 
+void Scope::set_chars(parser::CookedSource &cooked) {
+  CHECK(kind_ == Kind::Module);
+  CHECK(parent_.kind_ == Kind::Global || parent_.IsModuleFile());
+  CHECK(symbol_ != nullptr);
+  CHECK(symbol_->test(Symbol::Flag::ModFile));
+  // TODO: Preserve the CookedSource rather than acquiring its string.
+  chars_ = cooked.AcquireData();
+}
+
 Scope::ImportKind Scope::GetImportKind() const {
   if (importKind_) {
     return *importKind_;
@@ -190,7 +199,8 @@ const Scope *Scope::FindScope(parser::CharBlock source) const {
 }
 
 Scope *Scope::FindScope(parser::CharBlock source) {
-  if (!sourceRange_.Contains(source)) {
+  bool isContained{sourceRange_.Contains(source)};
+  if (!isContained && kind_ != Kind::Global && !IsModuleFile()) {
     return nullptr;
   }
   for (auto &child : children_) {
@@ -198,7 +208,7 @@ Scope *Scope::FindScope(parser::CharBlock source) {
       return scope;
     }
   }
-  return this;
+  return isContained ? this : nullptr;
 }
 
 void Scope::AddSourceRange(const parser::CharBlock &source) {
index e96ef28..639ec7e 100644 (file)
@@ -20,6 +20,7 @@
 #include "../common/Fortran.h"
 #include "../common/idioms.h"
 #include "../parser/message.h"
+#include "../parser/provenance.h"
 #include <list>
 #include <map>
 #include <set>
@@ -34,8 +35,8 @@ class Scope {
   using mapType = std::map<SourceName, Symbol *>;
 
 public:
-  ENUM_CLASS(Kind, System, Global, Module, MainProgram, Subprogram, DerivedType,
-      Block, Forall, ImpliedDos)
+  ENUM_CLASS(Kind, Global, Module, MainProgram, Subprogram, DerivedType, Block,
+      Forall, ImpliedDos)
   using ImportKind = common::ImportKind;
 
   // Create the Global scope -- the root of the scope tree
@@ -52,11 +53,11 @@ public:
   bool operator!=(const Scope &that) const { return this != &that; }
 
   Scope &parent() {
-    CHECK(kind_ != Kind::System);
+    CHECK(&parent_ != this);
     return parent_;
   }
   const Scope &parent() const {
-    CHECK(kind_ != Kind::System);
+    CHECK(&parent_ != this);
     return parent_;
   }
   Kind kind() const { return kind_; }
@@ -154,7 +155,7 @@ public:
 
   // For modules read from module files, this is the stream of characters
   // that are referenced by SourceName objects.
-  void set_chars(std::string &&chars) { chars_ = std::move(chars); }
+  void set_chars(parser::CookedSource &);
 
   ImportKind GetImportKind() const;
   // Names appearing in IMPORT statements in this scope
@@ -193,6 +194,11 @@ public:
   const DeclTypeSpec &InstantiateIntrinsicType(
       const DeclTypeSpec &, SemanticsContext &);
 
+  bool IsModuleFile() const {
+    return kind_ == Kind::Module && symbol_ != nullptr &&
+        symbol_->test(Symbol::Flag::ModFile);
+  }
+
 private:
   Scope &parent_;  // this is enclosing scope, not extended derived type base
   const Kind kind_;
index 933e814..37e5260 100644 (file)
@@ -96,12 +96,16 @@ static bool PerformStatementSemantics(
 
 SemanticsContext::SemanticsContext(
     const common::IntrinsicTypeDefaultKinds &defaultKinds,
-    const parser::LanguageFeatureControl &languageFeatures)
+    const parser::LanguageFeatureControl &languageFeatures,
+    parser::AllSources &allSources)
   : defaultKinds_{defaultKinds}, languageFeatures_{languageFeatures},
+    allSources_{allSources},
     intrinsics_{evaluate::IntrinsicProcTable::Configure(defaultKinds)},
     foldingContext_{evaluate::FoldingContext{
         parser::ContextualMessages{parser::CharBlock{}, &messages_}}} {}
 
+SemanticsContext::~SemanticsContext() {}
+
 bool SemanticsContext::IsEnabled(parser::LanguageFeature feature) const {
   return languageFeatures_.IsEnabled(feature);
 }
index fe2232e..3ef85d5 100644 (file)
@@ -41,7 +41,8 @@ class Symbol;
 class SemanticsContext {
 public:
   SemanticsContext(const common::IntrinsicTypeDefaultKinds &,
-      const parser::LanguageFeatureControl &);
+      const parser::LanguageFeatureControl &, parser::AllSources &);
+  ~SemanticsContext();
 
   const common::IntrinsicTypeDefaultKinds &defaultKinds() const {
     return defaultKinds_;
@@ -60,6 +61,7 @@ public:
   Scope &globalScope() { return globalScope_; }
   parser::Messages &messages() { return messages_; }
   evaluate::FoldingContext &foldingContext() { return foldingContext_; }
+  parser::AllSources &allSources() { return allSources_; }
 
   SemanticsContext &set_location(const parser::CharBlock *location) {
     location_ = location;
@@ -115,6 +117,7 @@ public:
 private:
   const common::IntrinsicTypeDefaultKinds &defaultKinds_;
   const parser::LanguageFeatureControl &languageFeatures_;
+  parser::AllSources &allSources_;
   const parser::CharBlock *location_{nullptr};
   std::vector<std::string> searchDirectories_;
   std::string moduleDirectory_{"."s};
index 7f38da2..2b21aeb 100644 (file)
@@ -55,8 +55,7 @@ const Scope *FindProgramUnitContaining(const Scope &start) {
     case Scope::Kind::Module:
     case Scope::Kind::MainProgram:
     case Scope::Kind::Subprogram: return scope;
-    case Scope::Kind::Global:
-    case Scope::Kind::System: return nullptr;
+    case Scope::Kind::Global: return nullptr;
     case Scope::Kind::DerivedType:
     case Scope::Kind::Block:
     case Scope::Kind::Forall:
index 0a88672..27503fd 100644 (file)
@@ -50,7 +50,8 @@ public:
   }
 
 private:
-  parser::CookedSource cooked_;
+  parser::AllSources allSources_;
+  parser::CookedSource cooked_{allSources_};
   std::map<std::string, std::size_t> offsets_;
 };
 
index f1b3f9a..47b6cf8 100644 (file)
@@ -172,7 +172,8 @@ std::string CompileFortran(
     }
   }
   options.searchDirectories = driver.searchDirectories;
-  Fortran::parser::Parsing parsing;
+  Fortran::parser::AllSources allSources;
+  Fortran::parser::Parsing parsing{allSources};
 
   auto start{CPUseconds()};
   parsing.Prescan(path, options);
index d419bc1..23e111f 100644 (file)
@@ -177,7 +177,7 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options,
     }
   }
   options.searchDirectories = driver.searchDirectories;
-  Fortran::parser::Parsing parsing;
+  Fortran::parser::Parsing parsing{semanticsContext.allSources()};
   parsing.Prescan(path, options);
   if (!parsing.messages().empty() &&
       (driver.warningsAreErrors || parsing.messages().AnyFatalError())) {
@@ -338,6 +338,9 @@ int main(int argc, char *const argv[]) {
   options.predefinitions.emplace_back("__F18_MAJOR__", "1");
   options.predefinitions.emplace_back("__F18_MINOR__", "1");
   options.predefinitions.emplace_back("__F18_PATCHLEVEL__", "1");
+#if __x86_64__
+  options.predefinitions.emplace_back("__x86_64__", "1");
+#endif
 
   Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;
 
@@ -521,8 +524,9 @@ int main(int argc, char *const argv[]) {
     driver.pgf90Args.push_back("-mp");
   }
 
+  Fortran::parser::AllSources allSources;
   Fortran::semantics::SemanticsContext semanticsContext{
-      defaultKinds, options.features};
+      defaultKinds, options.features, allSources};
   semanticsContext.set_moduleDirectory(driver.moduleDirectory)
       .set_moduleFileSuffix(driver.moduleFileSuffix)
       .set_searchDirectories(driver.searchDirectories)