[flang] Change API of Scope to match std::map

The Scope can be thought of as (among other things) a mapping of Name to
Symbol. This change reflects that by changing the API to match std::map.

Original-commit: flang-compiler/f18@37f6ad73cc
Reviewed-on: https://github.com/flang-compiler/f18/pull/46
Tree-same-pre-rewrite: false
This commit is contained in:
Tim Keith 2018-04-09 10:07:36 -07:00
parent 46602719fc
commit 75e4108d55
3 changed files with 34 additions and 37 deletions

View File

@ -228,12 +228,17 @@ private:
void PostSubprogram(const Name &name, const std::list<Name> &dummyNames);
// Helpers to make a Symbol in the current scope
template<typename D> Symbol &MakeSymbol(const Name &name, D &&details) {
return CurrScope().MakeSymbol(name, details);
template<typename D>
std::pair<Scope::iterator, bool> MakeSymbol(
const Name &name, const Attrs &attrs, D &&details) {
return CurrScope().try_emplace(name, attrs, details);
}
template<typename D>
Symbol &MakeSymbol(const Name &name, const Attrs &attrs, D &&details) {
return CurrScope().MakeSymbol(name, attrs, details);
std::pair<Scope::iterator, bool> MakeSymbol(const Name &name, D &&details) {
return MakeSymbol(name, Attrs(), details);
}
std::pair<Scope::iterator, bool> MakeSymbol(const Name &name) {
return CurrScope().try_emplace(name, UnknownDetails());
}
};
@ -581,7 +586,8 @@ void ResolveNamesVisitor::Post(const parser::EntityDecl &x) {
// TODO: may be under StructureStmt
const auto &name{std::get<parser::ObjectName>(x.t)};
// TODO: optional ArraySpec, CoarraySpec, CharLength, Initialization
Symbol &symbol{CurrScope().GetOrMakeSymbol(name.ToString())};
Symbol &symbol{MakeSymbol(name.ToString()).first->second};
symbol.attrs() |= *attrs_; // TODO: check attribute consistency
if (symbol.has<UnknownDetails>()) {
symbol.set_details(EntityDetails());

View File

@ -12,19 +12,6 @@ Scope &Scope::MakeScope(Kind kind) {
return children_.back();
}
Symbol &Scope::GetOrMakeSymbol(const Name &name) {
const auto it = symbols_.find(name);
if (it != symbols_.end()) {
return it->second;
} else {
return MakeSymbol(name);
}
}
Symbol &Scope::MakeSymbol(const Name &name, Attrs attrs) {
return MakeSymbol(name, attrs, UnknownDetails());
}
static const char *ToString(Scope::Kind kind) {
switch (kind) {
case Scope::Kind::System: return "System";

View File

@ -36,38 +36,42 @@ public:
/// Make a scope nested in this one
Scope &MakeScope(Kind kind);
/// If there is a symbol with this name already in the scope, return it.
/// Otherwise make a new one and return that.
Symbol &GetOrMakeSymbol(const Name &name);
using map_type = std::map<Name, Symbol>;
using size_type = map_type::size_type;
using iterator = map_type::iterator;
using const_iterator = map_type::const_iterator;
iterator begin() { return symbols_.begin(); }
iterator end() { return symbols_.end(); }
const_iterator begin() const { return symbols_.begin(); }
const_iterator end() const { return symbols_.end(); }
iterator find(const Name &name) { return symbols_.find(name); }
const_iterator find(const Name &name) const { return symbols_.find(name); }
size_type erase(const Name &name) { return symbols_.erase(name); }
/// Make a Symbol with unknown details.
Symbol &MakeSymbol(
const Name &name, Attrs attrs = Attrs{});
std::pair<iterator, bool> try_emplace(
const Name &name, Attrs attrs = Attrs()) {
return try_emplace(name, attrs, UnknownDetails());
}
/// Make a Symbol with provided details.
template<typename D>
Symbol &MakeSymbol(const Name &name, D &&details) {
const auto &result =
symbols_.try_emplace(name, *this, name, Attrs{}, details);
return result.first->second;
std::pair<iterator, bool> try_emplace(const Name &name, D &&details) {
return try_emplace(name, Attrs(), details);
}
/// Make a Symbol with attrs and details
template<typename D>
Symbol &MakeSymbol(
std::pair<iterator, bool> try_emplace(
const Name &name, Attrs attrs, D &&details) {
const auto &result =
symbols_.try_emplace(name, *this, name, attrs, details);
return result.first->second;
}
void EraseSymbol(const Name &name) {
symbols_.erase(name);
return symbols_.try_emplace(name, *this, name, attrs, details);
}
private:
const Scope &parent_;
const Kind kind_;
std::list<Scope> children_;
std::map<Name, Symbol> symbols_;
map_type symbols_;
friend std::ostream &operator<<(std::ostream &, const Scope &);
};