forked from OSchip/llvm-project
[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:
parent
9d5490a561
commit
0ddea8ae24
|
@ -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) {
|
||||
|
|
|
@ -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_; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -50,7 +50,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
parser::CookedSource cooked_;
|
||||
parser::AllSources allSources_;
|
||||
parser::CookedSource cooked_{allSources_};
|
||||
std::map<std::string, std::size_t> offsets_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue