From 0ddea8ae24e962f3934cafc96c8eac2e4dd2d4d1 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Fri, 31 May 2019 16:37:00 -0700 Subject: [PATCH] [flang] Rearrange references to AllSources singleton, fix FindScope for module files Original-commit: flang-compiler/f18@50ccc1c819d274c0f40358bf15b5f7ac4c7a199a Reviewed-on: https://github.com/flang-compiler/f18/pull/477 Tree-same-pre-rewrite: false --- flang/lib/parser/parsing.cc | 2 -- flang/lib/parser/parsing.h | 4 +--- flang/lib/parser/provenance.cc | 10 ++++------ flang/lib/parser/provenance.h | 18 ++++++++---------- flang/lib/semantics/expression.cc | 2 +- flang/lib/semantics/mod-file.cc | 6 ++---- flang/lib/semantics/scope.cc | 14 ++++++++++++-- flang/lib/semantics/scope.h | 16 +++++++++++----- flang/lib/semantics/semantics.cc | 6 +++++- flang/lib/semantics/semantics.h | 5 ++++- flang/lib/semantics/tools.cc | 3 +-- flang/test/evaluate/intrinsics.cc | 3 ++- flang/tools/f18/f18-parse-demo.cc | 3 ++- flang/tools/f18/f18.cc | 8 ++++++-- 14 files changed, 59 insertions(+), 41 deletions(-) diff --git a/flang/lib/parser/parsing.cc b/flang/lib/parser/parsing.cc index 8414294d646c..38efb7d56b7f 100644 --- a/flang/lib/parser/parsing.cc +++ b/flang/lib/parser/parsing.cc @@ -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) { diff --git a/flang/lib/parser/parsing.h b/flang/lib/parser/parsing.h index a252096a1964..3bb77aca6307 100644 --- a/flang/lib/parser/parsing.h +++ b/flang/lib/parser/parsing.h @@ -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_; } diff --git a/flang/lib/parser/provenance.cc b/flang/lib/parser/provenance.cc index f9415bda3266..166104d6a5e0 100644 --- a/flang/lib/parser/provenance.cc +++ b/flang/lib/parser/provenance.cc @@ -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 CookedSource::GetProvenanceRange( @@ -331,8 +330,7 @@ std::optional 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; diff --git a/flang/lib/parser/provenance.h b/flang/lib/parser/provenance.h index f81e165ed45f..4efcf352b48f 100644 --- a/flang/lib/parser/provenance.h +++ b/flang/lib/parser/provenance.h @@ -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 #include #include @@ -109,9 +108,9 @@ private: std::vector provenanceMap_; }; -// AllSources is reference-counted so that multiple instances of CookedSource -// can share an AllSources instance. -class AllSources : public common::ReferenceCounted { +// 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 GetProvenanceRange(CharBlock) const; @@ -227,7 +225,7 @@ public: std::ostream &Dump(std::ostream &) const; private: - common::CountedReference allSources_; + AllSources &allSources_; CharBuffer buffer_; // before Marshal() std::string data_; // all of it, prescanned and preprocessed OffsetToProvenanceMappings provenanceMap_; diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index 08ffcacddf4b..b316181bddcb 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -30,7 +30,7 @@ #include #include -// #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" diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index dbe9d9d82472..851bcff49eb6 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -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(); } diff --git a/flang/lib/semantics/scope.cc b/flang/lib/semantics/scope.cc index 82d679b9840d..33aac1ba33a5 100644 --- a/flang/lib/semantics/scope.cc +++ b/flang/lib/semantics/scope.cc @@ -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) { diff --git a/flang/lib/semantics/scope.h b/flang/lib/semantics/scope.h index e96ef2857507..639ec7eb6f30 100644 --- a/flang/lib/semantics/scope.h +++ b/flang/lib/semantics/scope.h @@ -20,6 +20,7 @@ #include "../common/Fortran.h" #include "../common/idioms.h" #include "../parser/message.h" +#include "../parser/provenance.h" #include #include #include @@ -34,8 +35,8 @@ class Scope { using mapType = std::map; 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_; diff --git a/flang/lib/semantics/semantics.cc b/flang/lib/semantics/semantics.cc index 933e81469cbc..37e5260c4cc8 100644 --- a/flang/lib/semantics/semantics.cc +++ b/flang/lib/semantics/semantics.cc @@ -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); } diff --git a/flang/lib/semantics/semantics.h b/flang/lib/semantics/semantics.h index fe2232ec652e..3ef85d5f55c5 100644 --- a/flang/lib/semantics/semantics.h +++ b/flang/lib/semantics/semantics.h @@ -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 searchDirectories_; std::string moduleDirectory_{"."s}; diff --git a/flang/lib/semantics/tools.cc b/flang/lib/semantics/tools.cc index 7f38da2909a7..2b21aeb51fc2 100644 --- a/flang/lib/semantics/tools.cc +++ b/flang/lib/semantics/tools.cc @@ -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: diff --git a/flang/test/evaluate/intrinsics.cc b/flang/test/evaluate/intrinsics.cc index 0a88672b9a11..27503fdab949 100644 --- a/flang/test/evaluate/intrinsics.cc +++ b/flang/test/evaluate/intrinsics.cc @@ -50,7 +50,8 @@ public: } private: - parser::CookedSource cooked_; + parser::AllSources allSources_; + parser::CookedSource cooked_{allSources_}; std::map offsets_; }; diff --git a/flang/tools/f18/f18-parse-demo.cc b/flang/tools/f18/f18-parse-demo.cc index f1b3f9a7b1c6..47b6cf8395f1 100644 --- a/flang/tools/f18/f18-parse-demo.cc +++ b/flang/tools/f18/f18-parse-demo.cc @@ -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); diff --git a/flang/tools/f18/f18.cc b/flang/tools/f18/f18.cc index d419bc19724d..23e111fe63b9 100644 --- a/flang/tools/f18/f18.cc +++ b/flang/tools/f18/f18.cc @@ -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)