[flang] Rearrange references to AllSources singleton, fix FindScope for module files

Original-commit: flang-compiler/f18@50ccc1c819
Reviewed-on: https://github.com/flang-compiler/f18/pull/477
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-05-31 16:37:00 -07:00
parent 9d5490a561
commit 0ddea8ae24
14 changed files with 59 additions and 41 deletions

View 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) {

View 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_; }

View 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;

View 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_;

View 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"

View 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();
}

View 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) {

View 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_;

View 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);
}

View 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};

View 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:

View 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_;
};

View 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);

View 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)