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());
}
};
// 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());
/// 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;
- /// Make a Symbol with unknown details.
- Symbol &MakeSymbol(
- const Name &name, Attrs attrs = Attrs{});
+ 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.
+ 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 &);
};