forked from OSchip/llvm-project
[flang] Move Details rather than copying
We don't need to copy the various Details classes. We will be adding expressions to some of them (e.g. for bounds or initial values) and they should generally be moved as well. In check-do-concurrent.cc, put pointers to Symbols in the symbol collections rather than copies. Original-commit: flang-compiler/f18@cdedfc9b3e Reviewed-on: https://github.com/flang-compiler/f18/pull/223 Tree-same-pre-rewrite: false
This commit is contained in:
parent
7a9a18227e
commit
b917390549
|
@ -215,13 +215,13 @@ private:
|
|||
parser::CharBlock currentStatementSourcePosition_{nullptr};
|
||||
};
|
||||
|
||||
using CS = std::vector<Symbol>;
|
||||
using CS = std::vector<const Symbol *>;
|
||||
|
||||
struct GatherSymbols {
|
||||
CS symbols;
|
||||
template<typename T> constexpr bool Pre(const T &) { return true; }
|
||||
template<typename T> constexpr void Post(const T &) {}
|
||||
void Post(const parser::Name &name) { symbols.push_back(*name.symbol); }
|
||||
void Post(const parser::Name &name) { symbols.push_back(name.symbol); }
|
||||
};
|
||||
|
||||
static bool IntegerVariable(const Symbol &variable) {
|
||||
|
@ -237,19 +237,19 @@ static CS GatherAllVariableNames(
|
|||
[&](const parser::LocalitySpec::Local &local) {
|
||||
for (auto &v : local.v) {
|
||||
CHECK(v.symbol);
|
||||
names.emplace_back(*v.symbol);
|
||||
names.push_back(v.symbol);
|
||||
}
|
||||
},
|
||||
[&](const parser::LocalitySpec::LocalInit &localInit) {
|
||||
for (auto &v : localInit.v) {
|
||||
CHECK(v.symbol);
|
||||
names.emplace_back(*v.symbol);
|
||||
names.push_back(v.symbol);
|
||||
}
|
||||
},
|
||||
[&](const parser::LocalitySpec::Shared &shared) {
|
||||
for (auto &v : shared.v) {
|
||||
CHECK(v.symbol);
|
||||
names.emplace_back(*v.symbol);
|
||||
names.push_back(v.symbol);
|
||||
}
|
||||
}},
|
||||
ls.u);
|
||||
|
@ -264,13 +264,13 @@ static CS GatherNotSharedVariableNames(
|
|||
[&](const parser::LocalitySpec::Local &local) {
|
||||
for (auto &v : local.v) {
|
||||
CHECK(v.symbol);
|
||||
names.emplace_back(*v.symbol);
|
||||
names.push_back(v.symbol);
|
||||
}
|
||||
},
|
||||
[&](const parser::LocalitySpec::LocalInit &localInit) {
|
||||
for (auto &v : localInit.v) {
|
||||
CHECK(v.symbol);
|
||||
names.emplace_back(*v.symbol);
|
||||
names.push_back(v.symbol);
|
||||
}
|
||||
}},
|
||||
ls.u);
|
||||
|
@ -285,7 +285,7 @@ static CS GatherLocalVariableNames(
|
|||
[&](const parser::LocalitySpec::Local &local) {
|
||||
for (auto &v : local.v) {
|
||||
CHECK(v.symbol);
|
||||
names.emplace_back(*v.symbol);
|
||||
names.push_back(v.symbol);
|
||||
}
|
||||
}},
|
||||
ls.u);
|
||||
|
@ -374,8 +374,8 @@ private:
|
|||
}
|
||||
void CheckScopingConstraints(const CS &symbols) const {
|
||||
// C1124
|
||||
for (auto &symbol : symbols) {
|
||||
if (!InnermostEnclosingScope(symbol)) {
|
||||
for (auto *symbol : symbols) {
|
||||
if (!InnermostEnclosingScope(*symbol)) {
|
||||
messages_.Say(currentStatementSourcePosition_,
|
||||
"variable in locality-spec must be in innermost"
|
||||
" scoping unit"_err_en_US);
|
||||
|
@ -386,8 +386,8 @@ private:
|
|||
void CheckMaskIsPure(const parser::ScalarLogicalExpr &mask) const {
|
||||
// C1121 - procedures in mask must be pure
|
||||
CS references{GatherReferencesFromExpression(*mask.thing.thing)};
|
||||
for (auto &r : references) {
|
||||
if (isProcedure(r.flags()) && !isPure(r.attrs())) {
|
||||
for (auto *r : references) {
|
||||
if (isProcedure(r->flags()) && !isPure(r->attrs())) {
|
||||
messages_.Say(currentStatementSourcePosition_,
|
||||
"concurrent-header mask expression cannot reference impure"
|
||||
" procedure"_err_en_US);
|
||||
|
@ -397,8 +397,8 @@ private:
|
|||
}
|
||||
void CheckNoCollisions(const CS &containerA, const CS &containerB,
|
||||
const parser::MessageFormattedText &errorMessage) const {
|
||||
for (auto &a : containerA) {
|
||||
for (auto &b : containerB) {
|
||||
for (auto *a : containerA) {
|
||||
for (auto *b : containerB) {
|
||||
if (a == b) {
|
||||
messages_.Say(currentStatementSourcePosition_, errorMessage);
|
||||
return;
|
||||
|
@ -459,7 +459,7 @@ private:
|
|||
continue; // XXX - this shouldn't be needed
|
||||
}
|
||||
CHECK(indexName.symbol);
|
||||
indexNames.push_back(*indexName.symbol);
|
||||
indexNames.push_back(indexName.symbol);
|
||||
if (!IntegerVariable(*indexName.symbol)) {
|
||||
messages_.Say(
|
||||
indexName.source, "index-name must have INTEGER type"_err_en_US);
|
||||
|
|
|
@ -339,13 +339,12 @@ public:
|
|||
|
||||
// Helpers to make a Symbol in the current scope
|
||||
template<typename D>
|
||||
Symbol &MakeSymbol(
|
||||
const SourceName &name, const Attrs &attrs, const D &details) {
|
||||
Symbol &MakeSymbol(const SourceName &name, const Attrs &attrs, D &&details) {
|
||||
// Note: don't use FindSymbol here. If this is a derived type scope,
|
||||
// we want to detect if the name is already declared as a component.
|
||||
const auto &it{currScope().find(name)};
|
||||
if (it == currScope().end()) {
|
||||
const auto pair{currScope().try_emplace(name, attrs, details)};
|
||||
const auto pair{currScope().try_emplace(name, attrs, std::move(details))};
|
||||
CHECK(pair.second); // name was not found, so must be able to add
|
||||
auto &symbol{*pair.first->second};
|
||||
symbol.add_occurrence(name);
|
||||
|
@ -358,7 +357,8 @@ public:
|
|||
// derived type with same name as a generic
|
||||
auto *derivedType{d->derivedType()};
|
||||
if (!derivedType) {
|
||||
derivedType = &currScope().MakeSymbol(name, attrs, details);
|
||||
derivedType =
|
||||
&currScope().MakeSymbol(name, attrs, std::move(details));
|
||||
d->set_derivedType(*derivedType);
|
||||
} else {
|
||||
SayAlreadyDeclared(name, *derivedType);
|
||||
|
@ -369,7 +369,7 @@ public:
|
|||
if (symbol.CanReplaceDetails(details)) {
|
||||
// update the existing symbol
|
||||
symbol.attrs() |= attrs;
|
||||
symbol.set_details(details);
|
||||
symbol.set_details(std::move(details));
|
||||
return symbol;
|
||||
} else if constexpr (std::is_same_v<UnknownDetails, D>) {
|
||||
symbol.attrs() |= attrs;
|
||||
|
@ -383,16 +383,15 @@ public:
|
|||
}
|
||||
template<typename D>
|
||||
Symbol &MakeSymbol(
|
||||
const parser::Name &name, const Attrs &attrs, const D &details) {
|
||||
return MakeSymbol(name.source, attrs, details);
|
||||
const parser::Name &name, const Attrs &attrs, D &&details) {
|
||||
return MakeSymbol(name.source, attrs, std::move(details));
|
||||
}
|
||||
template<typename D>
|
||||
Symbol &MakeSymbol(const parser::Name &name, const D &details) {
|
||||
return MakeSymbol(name, Attrs(), details);
|
||||
Symbol &MakeSymbol(const parser::Name &name, D &&details) {
|
||||
return MakeSymbol(name, Attrs{}, std::move(details));
|
||||
}
|
||||
template<typename D>
|
||||
Symbol &MakeSymbol(const SourceName &name, const D &details) {
|
||||
return MakeSymbol(name, Attrs(), details);
|
||||
template<typename D> Symbol &MakeSymbol(const SourceName &name, D &&details) {
|
||||
return MakeSymbol(name, Attrs{}, std::move(details));
|
||||
}
|
||||
Symbol &MakeSymbol(const SourceName &name, Attrs attrs = Attrs{}) {
|
||||
return MakeSymbol(name, attrs, UnknownDetails{});
|
||||
|
@ -631,7 +630,7 @@ private:
|
|||
const Symbol *ResolveDerivedType(const SourceName &);
|
||||
bool CanBeTypeBoundProc(const Symbol &);
|
||||
Symbol *FindExplicitInterface(const SourceName &);
|
||||
Symbol &MakeTypeSymbol(const SourceName &, const Details &);
|
||||
Symbol &MakeTypeSymbol(const SourceName &, Details &&);
|
||||
bool OkToAddComponent(const SourceName &, bool isParentComp = false);
|
||||
|
||||
// Declare an object or procedure entity.
|
||||
|
@ -1547,8 +1546,8 @@ bool ModuleVisitor::Pre(const parser::Module &x) {
|
|||
const auto &name{
|
||||
std::get<parser::Statement<parser::ModuleStmt>>(x.t).statement.v.source};
|
||||
auto &subpPart{std::get<std::optional<parser::ModuleSubprogramPart>>(x.t)};
|
||||
auto &symbol{BeginModule(name, false, subpPart)};
|
||||
MakeSymbol(name, symbol.details());
|
||||
BeginModule(name, false, subpPart);
|
||||
MakeSymbol(name, ModuleDetails{});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2620,7 +2619,7 @@ Symbol *DeclarationVisitor::FindExplicitInterface(const SourceName &name) {
|
|||
// Create a symbol for a type parameter, component, or procedure binding in
|
||||
// the current derived type scope.
|
||||
Symbol &DeclarationVisitor::MakeTypeSymbol(
|
||||
const SourceName &name, const Details &details) {
|
||||
const SourceName &name, Details &&details) {
|
||||
Scope &derivedType{currScope()};
|
||||
CHECK(derivedType.kind() == Scope::Kind::DerivedType);
|
||||
if (auto it{derivedType.find(name)}; it != derivedType.end()) {
|
||||
|
|
|
@ -142,9 +142,9 @@ const std::string Symbol::GetDetailsName() const {
|
|||
return DetailsToString(details_);
|
||||
}
|
||||
|
||||
void Symbol::set_details(const Details &details) {
|
||||
void Symbol::set_details(Details &&details) {
|
||||
CHECK(CanReplaceDetails(details));
|
||||
details_ = details;
|
||||
details_ = std::move(details);
|
||||
}
|
||||
|
||||
bool Symbol::CanReplaceDetails(const Details &details) const {
|
||||
|
|
|
@ -346,7 +346,7 @@ public:
|
|||
const Details &details() const { return details_; }
|
||||
// Assign the details of the symbol from one of the variants.
|
||||
// Only allowed in certain cases.
|
||||
void set_details(const Details &);
|
||||
void set_details(Details &&);
|
||||
|
||||
// Can the details of this symbol be replaced with the given details?
|
||||
bool CanReplaceDetails(const Details &details) const;
|
||||
|
@ -395,12 +395,12 @@ std::ostream &operator<<(std::ostream &, Symbol::Flag);
|
|||
template<std::size_t BLOCK_SIZE> class Symbols {
|
||||
public:
|
||||
Symbol &Make(const Scope &owner, const SourceName &name, const Attrs &attrs,
|
||||
const Details &details) {
|
||||
Details &&details) {
|
||||
Symbol &symbol = Get();
|
||||
symbol.owner_ = &owner;
|
||||
symbol.occurrences_.push_back(name);
|
||||
symbol.attrs_ = attrs;
|
||||
symbol.details_ = details;
|
||||
symbol.details_ = std::move(details);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue