[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:
Tim Keith 2018-11-05 14:36:11 -08:00
parent 7a9a18227e
commit b917390549
4 changed files with 35 additions and 36 deletions

View File

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

View File

@ -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()) {

View File

@ -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 {

View File

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