2018-03-23 01:08:20 +01:00
|
|
|
#ifndef FORTRAN_SEMANTICS_SCOPE_H_
|
|
|
|
#define FORTRAN_SEMANTICS_SCOPE_H_
|
|
|
|
|
|
|
|
#include "attr.h"
|
|
|
|
#include "symbol.h"
|
2018-04-12 21:23:20 +02:00
|
|
|
#include "../parser/idioms.h"
|
|
|
|
#include "../parser/parse-tree.h"
|
2018-03-23 01:08:20 +01:00
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
|
2018-03-23 20:24:29 +01:00
|
|
|
namespace Fortran::semantics {
|
2018-03-23 01:08:20 +01:00
|
|
|
|
|
|
|
class Scope {
|
2018-04-11 22:11:42 +02:00
|
|
|
using mapType = std::map<SourceName, Symbol>;
|
2018-04-09 20:53:20 +02:00
|
|
|
|
2018-03-23 01:08:20 +01:00
|
|
|
public:
|
|
|
|
// root of the scope tree; contains intrinsics:
|
|
|
|
static const Scope systemScope;
|
|
|
|
static Scope globalScope; // contains program-units
|
|
|
|
|
2018-04-11 22:26:38 +02:00
|
|
|
ENUM_CLASS(Kind, System, Global, Module, MainProgram, Subprogram)
|
2018-03-23 01:08:20 +01:00
|
|
|
|
2018-04-19 00:06:35 +02:00
|
|
|
Scope(const Scope &parent, Kind kind, const Symbol *symbol)
|
|
|
|
: parent_{parent}, kind_{kind}, symbol_{symbol} {}
|
2018-03-23 01:08:20 +01:00
|
|
|
|
|
|
|
const Scope &parent() const {
|
|
|
|
CHECK(kind_ != Kind::System);
|
|
|
|
return parent_;
|
|
|
|
}
|
|
|
|
Kind kind() const { return kind_; }
|
2018-04-19 00:06:35 +02:00
|
|
|
const Symbol *symbol() const { return symbol_; }
|
2018-03-23 01:08:20 +01:00
|
|
|
|
|
|
|
/// Make a scope nested in this one
|
2018-04-19 00:06:35 +02:00
|
|
|
Scope &MakeScope(Kind kind, const Symbol *symbol = nullptr);
|
2018-03-23 01:08:20 +01:00
|
|
|
|
2018-04-11 22:11:42 +02:00
|
|
|
using size_type = mapType::size_type;
|
|
|
|
using iterator = mapType::iterator;
|
|
|
|
using const_iterator = mapType::const_iterator;
|
2018-03-23 01:08:20 +01:00
|
|
|
|
2018-04-09 19:07:36 +02:00
|
|
|
iterator begin() { return symbols_.begin(); }
|
|
|
|
iterator end() { return symbols_.end(); }
|
|
|
|
const_iterator begin() const { return symbols_.begin(); }
|
|
|
|
const_iterator end() const { return symbols_.end(); }
|
2018-04-09 20:53:20 +02:00
|
|
|
const_iterator cbegin() const { return symbols_.cbegin(); }
|
|
|
|
const_iterator cend() const { return symbols_.cend(); }
|
2018-04-09 19:07:36 +02:00
|
|
|
|
2018-04-11 22:11:42 +02:00
|
|
|
iterator find(const SourceName &name) { return symbols_.find(name); }
|
|
|
|
const_iterator find(const SourceName &name) const {
|
|
|
|
return symbols_.find(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_type erase(const SourceName &name) { return symbols_.erase(name); }
|
2018-03-23 01:08:20 +01:00
|
|
|
|
2018-04-09 19:07:36 +02:00
|
|
|
/// Make a Symbol with unknown details.
|
|
|
|
std::pair<iterator, bool> try_emplace(
|
2018-04-11 22:11:42 +02:00
|
|
|
const SourceName &name, Attrs attrs = Attrs()) {
|
2018-04-09 19:07:36 +02:00
|
|
|
return try_emplace(name, attrs, UnknownDetails());
|
|
|
|
}
|
2018-03-23 01:08:20 +01:00
|
|
|
/// Make a Symbol with provided details.
|
2018-03-23 20:24:29 +01:00
|
|
|
template<typename D>
|
2018-04-11 22:11:42 +02:00
|
|
|
std::pair<iterator, bool> try_emplace(const SourceName &name, D &&details) {
|
2018-04-09 19:07:36 +02:00
|
|
|
return try_emplace(name, Attrs(), details);
|
2018-03-23 01:08:20 +01:00
|
|
|
}
|
2018-04-09 19:07:36 +02:00
|
|
|
/// Make a Symbol with attrs and details
|
2018-03-23 01:08:20 +01:00
|
|
|
template<typename D>
|
2018-04-09 19:07:36 +02:00
|
|
|
std::pair<iterator, bool> try_emplace(
|
2018-04-11 22:11:42 +02:00
|
|
|
const SourceName &name, Attrs attrs, D &&details) {
|
2018-04-09 19:07:36 +02:00
|
|
|
return symbols_.try_emplace(name, *this, name, attrs, details);
|
2018-03-23 20:24:29 +01:00
|
|
|
}
|
|
|
|
|
2018-04-19 00:06:35 +02:00
|
|
|
std::list<Scope> &children() { return children_; }
|
|
|
|
const std::list<Scope> &children() const { return children_; }
|
|
|
|
|
2018-03-23 01:08:20 +01:00
|
|
|
private:
|
|
|
|
const Scope &parent_;
|
|
|
|
const Kind kind_;
|
2018-04-19 00:06:35 +02:00
|
|
|
const Symbol *const symbol_;
|
2018-03-23 01:08:20 +01:00
|
|
|
std::list<Scope> children_;
|
2018-04-11 22:11:42 +02:00
|
|
|
mapType symbols_;
|
2018-03-23 01:08:20 +01:00
|
|
|
|
|
|
|
friend std::ostream &operator<<(std::ostream &, const Scope &);
|
|
|
|
};
|
|
|
|
|
2018-03-23 20:24:29 +01:00
|
|
|
} // namespace Fortran::semantics
|
2018-03-23 01:08:20 +01:00
|
|
|
#endif // FORTRAN_SEMANTICS_SCOPE_H_
|