a3de9d789c
A Symbol consists of a common part (in class Symbol) containing name, owner, attributes. Information for a specific kind of symbol is in a variant containing one of the *Details classes. So the kind of symbol is determined by the type of details class stored in the details_ variant. For scopes there is a single Scope class with an enum indicating the kind. So far there isn't a need for extra kind-specific details as with Symbols but that could change. Symbols defined in a Scope are stored there in a simple map. resolve-names.cc is a partial implementation of a parse-tree walker that resolves names to Symbols. Currently is only handles functions (which introduce a new Scope) and entity-decls. The test-type executable was reused as a driver for this to avoid the need for a new one. Sample output is below. When each "end function" is encountered the scope is dumped, which shows the symbols defined in it. $ cat a.f90 pure integer(8) function foo(arg1, arg2) result(res) integer :: arg1 real :: arg2 contains function bar(arg1) real :: bar real :: arg1 end function end function $ Debug/tools/f18/test-type a.f90 Subprogram scope: 0 children arg1: Entity type: REAL bar: Entity type: REAL Subprogram scope: 1 children arg1: Entity type: INTEGER arg2: Entity type: REAL bar: Subprogram (arg1) foo: Subprogram (arg1, arg2) result(res) res: Entity type: INTEGER(8) Original-commit: flang-compiler/f18@1cd2fbc04d Reviewed-on: https://github.com/flang-compiler/f18/pull/30 Tree-same-pre-rewrite: false
94 lines
2.5 KiB
C++
94 lines
2.5 KiB
C++
#include "../parser/idioms.h"
|
|
#include "attr.h"
|
|
#include <stddef.h>
|
|
|
|
namespace Fortran {
|
|
namespace semantics {
|
|
|
|
constexpr static size_t toInt(Attr attr) { return static_cast<size_t>(attr); }
|
|
|
|
static const char *attrToString[] = {
|
|
[toInt(Attr::ABSTRACT)] = "ABSTRACT",
|
|
[toInt(Attr::ALLOCATABLE)] = "ALLOCATABLE",
|
|
[toInt(Attr::ASYNCHRONOUS)] = "ASYNCHRONOUS",
|
|
[toInt(Attr::BIND_C)] = "BIND_C",
|
|
[toInt(Attr::CONTIGUOUS)] = "CONTIGUOUS",
|
|
[toInt(Attr::DEFERRED)] = "DEFERRED",
|
|
[toInt(Attr::ELEMENTAL)] = "ELEMENTAL",
|
|
[toInt(Attr::EXTERNAL)] = "EXTERNAL",
|
|
[toInt(Attr::IMPURE)] = "IMPURE",
|
|
[toInt(Attr::INTENT_IN)] = "INTENT_IN",
|
|
[toInt(Attr::INTENT_OUT)] = "INTENT_OUT",
|
|
[toInt(Attr::INTRINSIC)] = "INTRINSIC",
|
|
[toInt(Attr::MODULE)] = "MODULE",
|
|
[toInt(Attr::NON_OVERRIDABLE)] = "NON_OVERRIDABLE",
|
|
[toInt(Attr::NON_RECURSIVE)] = "NON_RECURSIVE",
|
|
[toInt(Attr::NOPASS)] = "NOPASS",
|
|
[toInt(Attr::OPTIONAL)] = "OPTIONAL",
|
|
[toInt(Attr::PARAMETER)] = "PARAMETER",
|
|
[toInt(Attr::PASS)] = "PASS",
|
|
[toInt(Attr::POINTER)] = "POINTER",
|
|
[toInt(Attr::PRIVATE)] = "PRIVATE",
|
|
[toInt(Attr::PROTECTED)] = "PROTECTED",
|
|
[toInt(Attr::PUBLIC)] = "PUBLIC",
|
|
[toInt(Attr::PURE)] = "PURE",
|
|
[toInt(Attr::RECURSIVE)] = "RECURSIVE",
|
|
[toInt(Attr::SAVE)] = "SAVE",
|
|
[toInt(Attr::TARGET)] = "TARGET",
|
|
[toInt(Attr::VALUE)] = "VALUE",
|
|
[toInt(Attr::VOLATILE)] = "VOLATILE",
|
|
};
|
|
|
|
const Attrs Attrs::EMPTY;
|
|
|
|
Attrs::Attrs(std::initializer_list<Attr> attrs) {
|
|
bits_ = 0;
|
|
for (auto attr : attrs) {
|
|
Set(attr);
|
|
}
|
|
}
|
|
|
|
Attrs &Attrs::Set(Attr attr) {
|
|
bits_ |= 1u << toInt(attr);
|
|
return *this;
|
|
}
|
|
Attrs &Attrs::Add(const Attrs &attrs) {
|
|
bits_ |= attrs.bits_;
|
|
return *this;
|
|
}
|
|
|
|
bool Attrs::Has(Attr attr) const { return (bits_ & (1u << toInt(attr))) != 0; }
|
|
|
|
bool Attrs::HasAny(const Attrs &attrs) const {
|
|
return (bits_ & attrs.bits_) != 0;
|
|
}
|
|
|
|
bool Attrs::HasAll(const Attrs &attrs) const {
|
|
return (bits_ & attrs.bits_) == attrs.bits_;
|
|
}
|
|
|
|
void Attrs::CheckValid(const Attrs &allowed) const {
|
|
if (!allowed.HasAll(*this)) {
|
|
parser::die("invalid attribute");
|
|
}
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &o, Attr attr) {
|
|
return o << attrToString[toInt(attr)];
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &o, const Attrs &attrs) {
|
|
int i = 0, n = 0;
|
|
for (std::uint64_t bits = attrs.bits_; bits != 0; bits >>= 1, ++i) {
|
|
if (bits & 1) {
|
|
if (n++) {
|
|
o << ", ";
|
|
}
|
|
o << attrToString[i];
|
|
}
|
|
}
|
|
return o;
|
|
}
|
|
|
|
} // namespace semantics
|
|
} // namespace Fortran
|