[flang] several changes following pull comments

Original-commit: flang-compiler/f18@ba1275a7cb
Reviewed-on: https://github.com/flang-compiler/f18/pull/24
Tree-same-pre-rewrite: false
This commit is contained in:
Stephane Chauveau 2018-03-09 16:48:12 +01:00 committed by GitHub
parent b65824fb32
commit 99dd6d03de
10 changed files with 330 additions and 229 deletions

View file

@ -7,6 +7,89 @@
namespace Fortran {
namespace semantics {
// A class describing an identifier.
//
// All Identifiers associated to the same name are sharing the same
// storage for that name. That makes comparison of 'Identifier'
// very fast since the strings do not have to be compared.
//
class Identifier;
typedef std::optional<Identifier> OptIdentifier ;
class Identifier
{
private:
const std::string *text_ ;
public:
Identifier() = delete ;
Identifier(const Identifier &in) : text_(in.text_) {}
Identifier(const std::string &);
// Construct an Identifier from a constant C-string.
//
// That constructor is not entirely redundant with the std::string
// constructor because it serves a secundary purpose: catch the illegal
// use of 0 to initialize an Identifier.
//
// Without it, the std::string constructor would be called (since 0
// is somehow a legal std::string initializer). The result would be an
// 'std::logic_error' exception.
//
Identifier(const char *);
// Helper to create
static Identifier make(const std::string &text) { return Identifier(text); }
// Helper to create OptIdentifier
static std::optional<Identifier> make(const std::optional<std::string> &text) {
if (text) {
return Identifier(*text);
} else {
return std::nullopt;
}
}
bool operator==(const Identifier &a) const {
return text_ == a.text_ ;
}
bool operator!=(const Identifier &a) const {
return text_ != a.text_ ;
}
bool operator<(const Identifier &a) const {
return name() < a.name() ;
}
bool operator<=(const Identifier &a) const {
return name() <= a.name() ;
}
bool operator>(const Identifier &a) const {
return name() > a.name() ;
}
bool operator>=(const Identifier &a) const {
return name() >= a.name() ;
}
const std::string & name() const {
return *text_ ;
}
};
#if 0
// A class describing an identifier.
//
// For each name, there is one and only one identifier.
@ -34,6 +117,7 @@ public:
return n ? Identifier::get(n.value()) : nullptr ;
}
};
#endif
} // namespace semantics
} // namespace Fortran

View file

@ -30,7 +30,7 @@ class Scope;
//
class Scope {
public:
enum Kind {
enum class Kind {
SK_SYSTEM, // the unique scope associated to the system (and providing
// intrinsic procedures)
SK_GLOBAL, // the unique global scope containing all units
@ -56,7 +56,7 @@ private:
Kind kind_;
//
// For most ranks, id contains a unique identifier that is increased
// For most ranks, id contains a district identifier that is increased
// each time a new Scope is created.
//
// The System and Global scope respectively have 0 and 1
@ -100,7 +100,7 @@ private:
Scope *module;
// All identifiers to exclude when doing a lookup
// in that module
std::vector<Identifier *> exclude;
std::vector<Identifier> exclude;
};
//
@ -111,11 +111,8 @@ private:
Scope *parent_scope_;
// The host scope is the scope that is searched last. 9
//
//
//
Scope *host_scope_; // The host scope
// The host scope is the scope that is searched last.
Scope *host_scope_;
std::list<Scope *> use_; // Scopes for the modules that are entirely used
std::list<Scope *>
@ -174,7 +171,7 @@ private:
std::vector<Symbol *> owned_;
public:
Kind getKind() const { return kind_; }
Kind kind() const { return kind_; }
const Scope *getParentScope() const { return parent_scope_; }
Scope *getParentScope() { return parent_scope_; }
@ -187,8 +184,8 @@ public:
//
// The Global scope is the scope that is immediately below the System scope.
//
// It contains the symbols for the Program unit (PROGRAM, MODULE, FUNCTION,
// SUBROUTINE and BLOCKDATA)
// It contains the symbols for the Program unit (PROGRAM, MODULE, SUBMODULE,
// FUNCTION, SUBROUTINE and BLOCKDATA)
//
// However, that scope is not standard in the sense that it requires a
// dedicated lookup to find its symbols.
@ -201,32 +198,32 @@ public:
const Scope *getGlobalScope() const;
// Look for a symbol locally and in the host scope (if any)
Symbol *Lookup(const Identifier *name);
const Symbol *Lookup(const Identifier *name) const;
Symbol *Lookup(Identifier name);
const Symbol *Lookup(Identifier name) const;
// Look for a symbol locally (do not explore the host scope).
//
Symbol *LookupLocal(const Identifier *name);
const Symbol *LookupLocal(const Identifier *name) const;
Symbol *LookupLocal(Identifier name);
const Symbol *LookupLocal(Identifier name) const;
//
// Lookup for a Program Unit by name
//
Symbol *LookupProgramUnit(const Identifier *name);
const Symbol *LookupProgramUnit(const Identifier *name) const;
Symbol *LookupProgramUnit(Identifier name);
const Symbol *LookupProgramUnit(Identifier name) const;
//
// Lookup for a known module.
//
// The result is either null or a scope of kind SK_USE_MODULE.
//
Symbol *LookupModule(const Identifier *name);
const Symbol *LookupModule(const Identifier *name) const;
Symbol *LookupModule(Identifier name);
const Symbol *LookupModule(Identifier name) const;
//
// Provide the distinct id associated to each scope
//
//
int getId() const;
int id() const;
//
// Add a symbol to the scope.
@ -243,4 +240,4 @@ public:
} // namespace Fortran::semantics
#endif
#endif // FLANG_SEMA_SCOPE_H

View file

@ -10,7 +10,7 @@ namespace Fortran::semantics {
//
// A StatementMap describes the relations between statements in a program unit
// and also hold information that are common each statement (label, provenance,
// and also hold information that are common to each statement (label, provenance,
// ...)
//
// In the parse-tree each struct representing a statement (see Stmt.def)
@ -34,7 +34,7 @@ namespace Fortran::semantics {
// the 'parent' of each statement in that body.
//
// The mapping of Fortran statements to the 4 groups Single, Start,
// Part, and End shall be obvious.
// Part, and End should be obvious.
//
// For instance, consider the following piece of code
//
@ -69,12 +69,12 @@ namespace Fortran::semantics {
// The '>', '+' and '>' are used to mark the Start, Part and End statements.
//
// In that dump, we see that:
// - The DO construct is composed of statements 10 and 21
// - The IF construct is composed of statements 12, 15, 17 and 19
// - The body of statement 10 is composed of statements 11, 12, and 20
// - The body of statement 12 is composed of statements 13 and 14
// - The body of statement 15 is composed of statement 16
// - The body of statement 17 is composed of statement 18
// - The DO construct is comprised of statements 10 and 21
// - The IF construct is comprised of statements 12, 15, 17 and 19
// - The body of statement 10 is comprised of statements 11, 12, and 20
// - The body of statement 12 is comprised of statements 13 and 14
// - The body of statement 15 is comprised of statement 16
// - The body of statement 17 is comprised of statement 18
//
// For the few Fortran constructs that do not provide an explicit 'End'
// statement, a dummy entry will be provided in the map. For instance,
@ -93,7 +93,7 @@ class StatementMap {
public:
typedef int Index; // should become an opaque type.
static const Index None = 0;
static constexpr Index None = 0;
private:
struct Entry {
@ -155,7 +155,6 @@ public:
StmtGroup GetGroup(Index index) const { return Get(index).group; }
// Provide the numerical label associated to that statement or 0.
// Be aware that labels are not necessarily unique and so cannot
// be used to identify a statement within the whole map.
@ -185,7 +184,7 @@ public:
Index FirstInBody(Index index) const;
Index LastInBody(Index index) const;
// Functionnally equivalent to LastInBody(PreviousPartOfConstruct(index))
// Functionally equivalent to LastInBody(PreviousPartOfConstruct(index))
Index LastInPreviousBody(Index index) const;
Index FindPrevInConstruct(Index index, StmtClass sclass) const;
@ -214,13 +213,13 @@ public:
// Visit all the statements that compose a construct.
//
// 'stmt' shall be a construct component (so in group Start, Part or End)
void VisistConstruct(Index stmt, std::function<bool(Index)> action) const;
void VisitConstruct(Index stmt, std::function<bool(Index)> action) const;
// Visit all the statements that compose a construct in reverse order.
//
// 'stmt' shall be a construct component (so in group Start, Part or End)
//
void VisistConstructRev(Index stmt, std::function<bool(Index)> action) const;
void VisitConstructRev(Index stmt, std::function<bool(Index)> action) const;
};
} // namespace Fortran::semantics

View file

@ -29,11 +29,11 @@ public:
private:
ClassId cid_;
Scope *owner_; // The scope that owns this symbol
const Identifier *name_; // The local name of that symbol
Identifier ident_; // The local name of that symbol
private:
TypeSpec *type_ = nullptr; // The type associated to that symbol
public:
Symbol(ClassId cid, Scope *owner, const Identifier *name);
Symbol(ClassId cid, Scope *owner, Identifier name);
public:
// For now, provide some toXXXX() member to perform the dynamic cast.
@ -53,11 +53,11 @@ public:
public:
Scope *owner() { return owner_; }
const Identifier *name() { return name_; }
Identifier name() { return ident_; }
bool Match(const Identifier *ident) { return ident == name_; }
bool Match(Identifier ident) { return ident == ident_; }
std::string toString() const { return name_->name(); }
std::string toString() const { return ident_.name(); }
};
//
@ -74,7 +74,7 @@ public:
//
class TemporarySymbol : public Symbol {
public:
TemporarySymbol(Scope *owner, const Identifier *name)
TemporarySymbol(Scope *owner, Identifier name)
: Symbol(TemporarySymbolId, owner, name) {}
private:
@ -90,7 +90,7 @@ private:
//
class ModuleSymbol : public Symbol {
public:
ModuleSymbol(Scope *owner, const Identifier *name)
ModuleSymbol(Scope *owner, Identifier name)
: Symbol(ProgramSymbolId, owner, name) {}
private:
@ -101,7 +101,7 @@ private:
//
class ProgramSymbol : public Symbol {
public:
ProgramSymbol(Scope *owner, const Identifier *name)
ProgramSymbol(Scope *owner, Identifier name)
: Symbol(ProgramSymbolId, owner, name) {}
private:
@ -112,7 +112,7 @@ private:
//
class BlockDataSymbol : public Symbol {
public:
BlockDataSymbol(Scope *owner, const Identifier *name)
BlockDataSymbol(Scope *owner, Identifier name)
: Symbol(BlockDataSymbolId, owner, name) {}
private:
@ -123,14 +123,14 @@ private:
//
class ParameterSymbol : public Symbol {
public:
ParameterSymbol(Scope *owner, const Identifier *name)
ParameterSymbol(Scope *owner, Identifier name)
: Symbol(ParameterSymbolId, owner, name) {}
};
// A symbol representing an EXTERNAL function.
class ExternalSymbol : public Symbol {
public:
ExternalSymbol(Scope *owner, const Identifier *name)
ExternalSymbol(Scope *owner, Identifier name)
: Symbol(ExternalSymbolId, owner, name) {}
};
@ -144,14 +144,14 @@ public:
//
class VariableSymbol : public Symbol {
public:
VariableSymbol(Scope *owner, const Identifier *name)
VariableSymbol(Scope *owner, Identifier name)
: Symbol(VariableSymbolId, owner, name) {}
};
// A symbol representing a dummy argument.
class DummyArgumentSymbol : public Symbol {
public:
DummyArgumentSymbol(Scope *owner, const Identifier *name)
DummyArgumentSymbol(Scope *owner, Identifier name)
: Symbol(DummyArgumentSymbolId, owner, name) {}
};
@ -164,12 +164,12 @@ public:
//
class CommonSymbol : public Symbol {
public:
CommonSymbol(Scope *owner, const Identifier *name)
CommonSymbol(Scope *owner, Identifier name)
: Symbol(CommonSymbolId, owner, name) {}
private:
// The content of the common section.
std::vector<const Identifier *> content_;
std::vector<Identifier > content_;
};
//
@ -181,7 +181,7 @@ private:
//
class SubroutineSymbol : public Symbol {
public:
SubroutineSymbol(Scope *owner, const Identifier *name)
SubroutineSymbol(Scope *owner, Identifier name)
: Symbol(SubroutineSymbolId, owner, name) {}
private:
@ -191,7 +191,7 @@ private:
class FunctionSymbol : public Symbol {
public:
FunctionSymbol(Scope *owner, const Identifier *name)
FunctionSymbol(Scope *owner, Identifier name)
: Symbol(FunctionSymbolId, owner, name) {}
private:
@ -204,7 +204,7 @@ private:
// A null name is allowed to represent an unnamed interface.
class InterfaceSymbol : public Symbol {
public:
InterfaceSymbol(Scope *owner, const Identifier *name)
InterfaceSymbol(Scope *owner, Identifier name)
: Symbol(InterfaceSymbolId, owner, name) {}
private:
@ -215,7 +215,7 @@ private:
// automatically or via an 'import' statement.
class ImportedSymbol : public Symbol {
public:
ImportedSymbol(Scope *owner, const Identifier *name)
ImportedSymbol(Scope *owner, Identifier name)
: Symbol(ImportedSymbolId, owner, name) {}
private:
@ -240,7 +240,7 @@ private:
//
class SubSymbol : public Symbol {
public:
SubSymbol(Scope *owner, const Identifier *name)
SubSymbol(Scope *owner, Identifier name)
: Symbol(SubSymbolId, owner, name) {}
private:
@ -258,7 +258,7 @@ private:
//
class UsedSymbol : public Symbol {
public:
UsedSymbol(Scope *owner, const Identifier *name)
UsedSymbol(Scope *owner, Identifier name)
: Symbol(UsedSymbolId, owner, name) {}
private:
@ -272,7 +272,7 @@ private:
//
class DerivedTypeSymbol : public Symbol {
public:
DerivedTypeSymbol(Scope *owner, const Identifier *name)
DerivedTypeSymbol(Scope *owner, Identifier name)
: Symbol(DerivedTypeSymbolId, owner, name) {}
private:
@ -284,7 +284,7 @@ private:
//
class MemberSymbol : public Symbol {
public:
MemberSymbol(Scope *owner, const Identifier *name)
MemberSymbol(Scope *owner, Identifier name)
: Symbol(MemberSymbolId, owner, name) {}
private:
@ -295,7 +295,7 @@ private:
//
class NamelistSymbol : public Symbol {
public:
NamelistSymbol(Scope *owner, const Identifier *name)
NamelistSymbol(Scope *owner, Identifier name)
: Symbol(NamelistSymbolId, owner, name) {}
private:
@ -307,7 +307,7 @@ private:
//
class ConstructSymbol : public Symbol {
public:
ConstructSymbol(Scope *owner, const Identifier *name)
ConstructSymbol(Scope *owner, Identifier name)
: Symbol(ConstructSymbolId, owner, name) {}
private:

View file

@ -4,6 +4,7 @@ add_library( FlangSemantics
Scope.cc
Symbol.cc
StatementMap.cc
ParseTreeDump.cc
Type.cc # ../semantics/type.cc
Attr.cc # ../semantics/attr.cc
)

View file

@ -1,16 +1,26 @@
#include "flang/Sema/Identifier.h"
#include <map>
#include <set>
#include <cassert>
#include <cstring>
using Fortran::semantics::Identifier;
static std::map<std::string, Identifier *> all;
static std::set<std::string> all;
const Identifier *Identifier::get(std::string n) {
Identifier *&ref = all[n];
if (!ref) {
ref = new Identifier(n);
}
return ref;
Identifier::Identifier(const std::string &text)
{
// TODO: Produce a proper 'ICE' if empty text.
assert( text.size() > 0 ) ;
text_ = &(*(all.insert(text).first)) ;
}
Identifier::Identifier(const char *text)
{
// TODO: Produce a proper 'ICE' if text is empty or null.
assert(text) ;
assert(text[0] != '\0' ); // cheaper than strlen(text)==0
text_ = &(*(all.insert( std::string(text) ).first)) ;
}

View file

@ -11,97 +11,97 @@ Scope::Scope(Kind k, Scope *p, Symbol *s)
: kind_(k), id_or_counter_(0), self_(s), parent_scope_(p), host_scope_(p) {
switch (k) {
case SK_SYSTEM:
case Kind::SK_SYSTEM:
assert(parent_scope_ == NULL);
id_or_counter_ = -1;
break;
case SK_GLOBAL:
assert(parent_scope_->kind_ == SK_SYSTEM);
case Kind::SK_GLOBAL:
assert(parent_scope_->kind_ == Kind::SK_SYSTEM);
id_or_counter_ = 2;
break;
case SK_PROGRAM:
assert(parent_scope_->kind_ == SK_GLOBAL);
case Kind::SK_PROGRAM:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL);
if (self_) {
assert(self_->owner() == parent_scope_);
}
break;
case SK_MODULE:
assert(parent_scope_->kind_ == SK_GLOBAL);
case Kind::SK_MODULE:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL);
assert(self_);
assert(self_->owner() == parent_scope_);
break;
case SK_SUBMODULE:
assert(parent_scope_->kind_ == SK_GLOBAL);
case Kind::SK_SUBMODULE:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL);
assert(self_);
assert(self_->owner() == parent_scope_);
break;
case SK_FUNCTION:
assert(parent_scope_->kind_ == SK_GLOBAL ||
parent_scope_->kind_ == SK_PROGRAM ||
parent_scope_->kind_ == SK_MODULE ||
parent_scope_->kind_ == SK_FUNCTION ||
parent_scope_->kind_ == SK_SUBROUTINE ||
parent_scope_->kind_ == SK_INTERFACE ||
parent_scope_->kind_ == SK_USE_MODULE);
case Kind::SK_FUNCTION:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL ||
parent_scope_->kind_ == Kind::SK_PROGRAM ||
parent_scope_->kind_ == Kind::SK_MODULE ||
parent_scope_->kind_ == Kind::SK_FUNCTION ||
parent_scope_->kind_ == Kind::SK_SUBROUTINE ||
parent_scope_->kind_ == Kind::SK_INTERFACE ||
parent_scope_->kind_ == Kind::SK_USE_MODULE);
assert(self_);
assert(self_->owner() == parent_scope_);
break;
case SK_SUBROUTINE:
assert(parent_scope_->kind_ == SK_GLOBAL ||
parent_scope_->kind_ == SK_PROGRAM ||
parent_scope_->kind_ == SK_MODULE ||
parent_scope_->kind_ == SK_FUNCTION ||
parent_scope_->kind_ == SK_SUBROUTINE ||
parent_scope_->kind_ == SK_INTERFACE ||
parent_scope_->kind_ == SK_USE_MODULE);
case Kind::SK_SUBROUTINE:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL ||
parent_scope_->kind_ == Kind::SK_PROGRAM ||
parent_scope_->kind_ == Kind::SK_MODULE ||
parent_scope_->kind_ == Kind::SK_FUNCTION ||
parent_scope_->kind_ == Kind::SK_SUBROUTINE ||
parent_scope_->kind_ == Kind::SK_INTERFACE ||
parent_scope_->kind_ == Kind::SK_USE_MODULE);
assert(self_);
assert(self_->owner() == parent_scope_);
break;
case SK_BLOCKDATA:
assert(parent_scope_->kind_ == SK_GLOBAL);
case Kind::SK_BLOCKDATA:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL);
assert(self_);
assert(self_->owner() == parent_scope_);
break;
case SK_USE_MODULE:
assert(parent_scope_->kind_ == SK_GLOBAL);
case Kind::SK_USE_MODULE:
assert(parent_scope_->kind_ == Kind::SK_GLOBAL);
assert(self_);
assert(self_->owner() == parent_scope_);
break;
case SK_BLOCK:
assert(parent_scope_->kind_ == SK_PROGRAM ||
parent_scope_->kind_ == SK_BLOCK ||
parent_scope_->kind_ == SK_FUNCTION ||
parent_scope_->kind_ == SK_SUBROUTINE);
case Kind::SK_BLOCK:
assert(parent_scope_->kind_ == Kind::SK_PROGRAM ||
parent_scope_->kind_ == Kind::SK_BLOCK ||
parent_scope_->kind_ == Kind::SK_FUNCTION ||
parent_scope_->kind_ == Kind::SK_SUBROUTINE);
if (self_) {
assert(self_->owner() == parent_scope_);
assert(self_->toConstructSymbol());
}
break;
case SK_DERIVED:
assert(parent_scope_->kind_ == SK_PROGRAM ||
parent_scope_->kind_ == SK_MODULE ||
parent_scope_->kind_ == SK_FUNCTION ||
parent_scope_->kind_ == SK_SUBROUTINE ||
parent_scope_->kind_ == SK_INTERFACE ||
parent_scope_->kind_ == SK_USE_MODULE);
case Kind::SK_DERIVED:
assert(parent_scope_->kind_ == Kind::SK_PROGRAM ||
parent_scope_->kind_ == Kind::SK_MODULE ||
parent_scope_->kind_ == Kind::SK_FUNCTION ||
parent_scope_->kind_ == Kind::SK_SUBROUTINE ||
parent_scope_->kind_ == Kind::SK_INTERFACE ||
parent_scope_->kind_ == Kind::SK_USE_MODULE);
break;
case SK_INTERFACE:
assert(parent_scope_->kind_ == SK_PROGRAM ||
parent_scope_->kind_ == SK_MODULE ||
parent_scope_->kind_ == SK_FUNCTION ||
parent_scope_->kind_ == SK_SUBROUTINE ||
parent_scope_->kind_ == SK_USE_MODULE);
case Kind::SK_INTERFACE:
assert(parent_scope_->kind_ == Kind::SK_PROGRAM ||
parent_scope_->kind_ == Kind::SK_MODULE ||
parent_scope_->kind_ == Kind::SK_FUNCTION ||
parent_scope_->kind_ == Kind::SK_SUBROUTINE ||
parent_scope_->kind_ == Kind::SK_USE_MODULE);
// Within an interface, the symbols must be explicitly imported
// from the parent scope so there is no default host scope.
@ -134,7 +134,7 @@ void Scope::fail(const std::string &msg) const {
const Scope *Scope::getSystemScope() const {
for (const Scope *scope = this; scope; scope = scope->parent_scope_) {
if (scope->kind_ == SK_SYSTEM) return scope;
if (scope->kind_ == Kind::SK_SYSTEM) return scope;
}
fail("System scope not found");
return nullptr;
@ -142,7 +142,7 @@ const Scope *Scope::getSystemScope() const {
Scope *Scope::getGlobalScope() {
for (auto scope = this; scope; scope = scope->parent_scope_) {
if (scope->kind_ == SK_GLOBAL) return scope;
if (scope->kind_ == Kind::SK_GLOBAL) return scope;
}
return nullptr;
}
@ -151,16 +151,16 @@ const Scope *Scope::getGlobalScope() const {
return const_cast<Scope *>(this)->getGlobalScope();
}
Symbol *Scope::Lookup(const Identifier *name) {
if (kind_ == SK_GLOBAL) return parent_scope_->Lookup(name);
Symbol *Scope::Lookup(Identifier name) {
if (kind_ == Kind::SK_GLOBAL) return parent_scope_->Lookup(name);
// TODO
return nullptr;
}
Symbol *Scope::LookupLocal(const Identifier *name) {
if (kind_ == SK_GLOBAL) return nullptr;
Symbol *Scope::LookupLocal(Identifier name) {
if (kind_ == Kind::SK_GLOBAL) return nullptr;
auto &entries{this->entries_};
for (auto it = entries.rbegin(); it != entries.rend(); ++it) {
@ -171,7 +171,7 @@ Symbol *Scope::LookupLocal(const Identifier *name) {
return nullptr;
}
Symbol *Scope::LookupProgramUnit(const Identifier *name) {
Symbol *Scope::LookupProgramUnit(Identifier name) {
Scope *scope = this->getGlobalScope();
auto &entries{scope->entries_};
@ -187,20 +187,20 @@ Symbol *Scope::LookupProgramUnit(const Identifier *name) {
return nullptr;
}
const Symbol *Scope::LookupProgramUnit(const Identifier *name) const {
const Symbol *Scope::LookupProgramUnit(Identifier name) const {
return const_cast<Scope *>(this)->LookupProgramUnit(name);
}
Symbol *Scope::LookupModule(const Identifier *name) { return nullptr; }
Symbol *Scope::LookupModule(Identifier name) { return nullptr; }
const Symbol *Scope::LookupModule(const Identifier *name) const {
const Symbol *Scope::LookupModule(Identifier name) const {
return const_cast<Scope *>(this)->LookupModule(name);
}
int Scope::getId(void) const {
if (this->kind_ == SK_SYSTEM)
int Scope::id(void) const {
if (this->kind_ == Kind::SK_SYSTEM)
return 0;
else if (this->kind_ == SK_GLOBAL)
else if (this->kind_ == Kind::SK_GLOBAL)
return 1;
else
return id_or_counter_;
@ -216,7 +216,7 @@ std::string Scope::toString(void) {
const char *info;
switch (kind_) {
#define SEMA_DEFINE_SCOPE(KIND, INFO) \
case KIND: \
case Kind::KIND: \
info = INFO; \
break;
#include "flang/Sema/Scope.def"
@ -225,10 +225,10 @@ std::string Scope::toString(void) {
}
if (self_) {
return std::string("#") + std::to_string(getId()) + " " + info + " (" +
return std::string("#") + std::to_string(id()) + " " + info + " (" +
self_->toString() + ")";
} else {
return std::string("#") + std::to_string(getId()) + " " + info +
return std::string("#") + std::to_string(id()) + " " + info +
" (***UNNAMED***)";
}
}

View file

@ -17,16 +17,18 @@
namespace Fortran::semantics {
StatementMap::Entry &StatementMap::Get(Index index) {
if (!((1 <= index) && (index <= Size()))) {
FAIL("Illegal Stmt index " << index << " (expect 1.." << Size() << ")");
if (!(( First() <= index) && (index <= Last()))) {
FAIL("Illegal Stmt index " << index << " (expect "
<< First() << " .." << Last() << ")");
exit(1);
}
return entries_[index - 1];
}
const StatementMap::Entry &StatementMap::Get(Index index) const {
if (!((1 <= index) && (index <= Size()))) {
FAIL("Illegal Stmt index " << index << " (expect 1.." << Size() << ")");
if (!((First() <= index) && (index <= Last()))) {
FAIL("Illegal Stmt index " << index << " (expect "
<< First() << ".." << Last() << ")");
exit(1);
}
return entries_[index - 1];
@ -44,7 +46,7 @@ StatementMap::Index StatementMap::Add(StmtClass sclass, int label) {
self.prev_in_construct = None;
self.next_in_construct = None;
Index self_index = Size() + 1;
Index self_index = Last() + 1;
if (Size() == 0) {
// Special case of the first entry.
@ -272,7 +274,7 @@ void StatementMap::Specialize( Index index, StmtClass oldc, StmtClass newc) {
}
void StatementMap::DumpFlat(std::ostream &out, bool verbose) const {
for (Index i = 1; i <= Size(); i++) {
for (Index i = First() ; i <= Last(); i++) {
out << std::setw(4) << std::right << i << ": ";
DumpStmt(out, i, verbose);
}
@ -560,7 +562,7 @@ StatementMap::Index StatementMap::LastOfConstruct(
// Visit all the statements that compose a construct.
//
// 'stmt' shall be a construct component (so in group Start, Part or End)
void StatementMap::VisistConstruct(
void StatementMap::VisitConstruct(
StatementMap::Index stmt, std::function<bool(Index)> action) const {
Index start = StartOfConstruct(stmt);
for (Index at = start; at != None; at = NextInConstruct(at)) {
@ -572,7 +574,7 @@ void StatementMap::VisistConstruct(
//
// 'stmt' shall be a construct component (so in group Start, Part or End)
//
void StatementMap::VisistConstructRev(
void StatementMap::VisitConstructRev(
Index stmt, std::function<bool(Index)> action) const {
// Reminder: Using LastOfConstruct instead of EndOfConstruct
// because the visitor shall usable while constructing

View file

@ -8,8 +8,8 @@
namespace Fortran::semantics {
Symbol::Symbol(ClassId cid, Scope *owner, const Identifier *name)
: cid_(cid), owner_(owner), name_(name) {
Symbol::Symbol(ClassId cid, Scope *owner, Identifier ident)
: cid_(cid), owner_(owner), ident_(ident) {
owner->add(this);
}

View file

@ -7,12 +7,14 @@
#include "flang/Sema/Scope.h"
#include "flang/Sema/StatementMap.h"
#include "flang/Sema/ParseTreeDump.h"
#include <vector>
#include <map>
#include <stack>
#include <functional>
#include <iomanip>
#include <cstring>
namespace psr = Fortran::parser ;
namespace sm = Fortran::semantics ;
@ -773,6 +775,7 @@ using SMap = sm::StatementMap;
namespace Fortran::parser {
class Pass1 : public LabelTableStack
{
@ -782,8 +785,8 @@ public:
current_label_(-1) ,
current_smap_(0)
{
system_scope_ = new Scope(Scope::SK_SYSTEM, nullptr, nullptr ) ;
unit_scope_ = new Scope(Scope::SK_GLOBAL, system_scope_, nullptr) ;
system_scope_ = new Scope(Scope::Kind::SK_SYSTEM, nullptr, nullptr ) ;
unit_scope_ = new Scope(Scope::Kind::SK_GLOBAL, system_scope_, nullptr) ;
current_scope_ = nullptr ;
}
@ -799,7 +802,7 @@ public:
Scope * current_scope_ ;
SMap * current_smap_ ;
std::map<SMap::Index, const sm::Identifier *> construct_name_ ;
std::map<SMap::Index, sm::Identifier> construct_name_ ;
// Provide all label-DO statements that are still open.
// The key is the LabelDoStmt index
@ -826,7 +829,7 @@ public:
}
void LeaveScope(Scope::Kind k) {
assert( current_scope_->getKind() == k ) ;
assert( current_scope_->kind() == k ) ;
TRACE("Leaving Scope " << current_scope_->toString() );
current_scope_ = current_scope_->getParentScope() ;
}
@ -901,25 +904,24 @@ public:
//
// Should operate with Symbol instead of Identifier
//
const sm::Identifier * GetConstructName(SMap::Index stmt) {
sm::OptIdentifier GetConstructName(SMap::Index stmt) {
auto it = construct_name_.find(stmt);
if ( it == construct_name_.end() ) {
// Hummm... not sure because in order to handle EXIT and CYCLE
// we will have to check the name of all parent constructs.
INTERNAL_ERROR;
return nullptr;
return std::nullopt ;
}
return it->second;
}
//
void
SetConstructName(SMap::Index stmt, const sm::Identifier *name) {
construct_name_[stmt] = name;
SetConstructName(SMap::Index stmt, sm::OptIdentifier name) {
if (name) {
construct_name_.insert_or_assign(stmt, *name);
}
}
void
CheckStatementName( SMap::Index part_or_end, const sm::Identifier *found, bool required) {
CheckStatementName( SMap::Index part_or_end, sm::OptIdentifier found, bool required) {
auto & smap = GetStatementMap() ;
@ -929,13 +931,13 @@ public:
SMap::Index start = smap.StartOfConstruct(part_or_end);
assert( smap.GetGroup(start) == StmtGroup::Start );
const sm::Identifier * expect = GetConstructName(start);
sm::OptIdentifier expect = GetConstructName(start);
// TODO: Get the location from part_or_end
const char * text = StmtClassText( smap.GetClass(part_or_end) ) ;
if ( expect ) {
if ( found ) {
if ( found != expect ) {
if ( *found != *expect ) {
FAIL("In statement #" << part_or_end
<< ": Unexpected name '" << found->name() << "' in " << text
<< "' (expected '" << expect->name() << "') ");
@ -1264,13 +1266,15 @@ public:
template <typename T> bool Pre(const T &x) {
if ( ENV("TRACE_FALLBACK") )
TRACE( "*** fallback " << __PRETTY_FUNCTION__ ) ;
TRACE( "*** fallback Pre(" << sm::GetTypeName(x) << ")" ) ;
// TRACE( "*** fallback " << __PRETTY_FUNCTION__ ) ;
return true ;
}
template <typename T> void Post(const T &) {
if ( ENV("TRACE_FALLBACK") )
TRACE( "*** fallback " << __PRETTY_FUNCTION__ ) ;
// if ( ENV("TRACE_FALLBACK") )
// TRACE( "*** fallback " << __PRETTY_FUNCTION__ ) ;
}
// fallback for std::variant
@ -1399,29 +1403,27 @@ public:
sm::ProgramSymbol * symbol{0};
const ProgramStmt * program_stmt = GetOptValue( std::get<x.PROG>(x.t) ) ;
const ProgramStmt * program_stmt = GetOptValue( std::get<x.PROG>(x.t) ) ;
const sm::Identifier * program_ident{0};
sm::OptIdentifier program_ident;
if ( program_stmt ) {
const std::string & name = program_stmt->v ;
TRACE("program name = " << name ) ;
program_ident = sm::Identifier::get(name) ;
symbol = new sm::ProgramSymbol( current_scope_, program_ident ) ;
program_ident = sm::Identifier::make(program_stmt->v) ;
symbol = new sm::ProgramSymbol( current_scope_, *program_ident ) ;
TraceStatementInfo( std::get<x.PROG>(x.t) ) ;
}
// TODO: Should we create a symbol when there is no PROGRAM statement?
// Install the scope
sema.scope_provider = EnterScope( new Scope(Scope::SK_PROGRAM, current_scope_, symbol) ) ;
sema.scope_provider = EnterScope( new Scope(Scope::Kind::SK_PROGRAM, current_scope_, symbol) ) ;
// Install the label table
sema.label_table = PushLabelTable( new LabelTable ) ;
// Check the name consistancy
// const std::string * end_name = GetOptValue(end_stmt.v) ;
// const sm::Identifier * end_ident = end_name ? sm::Identifier::get(*end_name) : nullptr ;
// sm::Identifier end_ident = end_name ? sm::Identifier::get(*end_name) : nullptr ;
// CheckStatementName(program_ident,end_ident,"program",false) ;
@ -1432,7 +1434,7 @@ public:
// } else if ( program_ident ) {
// FAIL("Unexpected end program name '" << end_ident->name() << "'");
// }
return true ;
}
@ -1440,7 +1442,7 @@ public:
auto &sema = getSema(x);
GetLabelTable().dump() ;
PopLabelTable(sema.label_table) ;
LeaveScope(Scope::SK_PROGRAM) ;
LeaveScope(Scope::Kind::SK_PROGRAM) ;
TRACE_CALL() ;
}
@ -1454,22 +1456,22 @@ public:
// const EndFunctionStmt & end_stmt = GetValue(std::get<x.END>(x.t)) ;
const std::string &function_name = std::get<1>(function_stmt.t) ;
const sm::Identifier *function_ident = sm::Identifier::get(function_name) ;
sm::Identifier function_ident = sm::Identifier::make(function_name) ;
// TODO: lookup for name conflict
sm::Symbol *lookup ;
if ( current_scope_->getKind() == Scope::SK_GLOBAL ) {
if ( current_scope_->kind() == Scope::Kind::SK_GLOBAL ) {
lookup = current_scope_->LookupProgramUnit(function_ident) ;
if (lookup) FAIL("A unit '" << function_ident->name() << "' is already declared") ;
if (lookup) FAIL("A unit '" << function_ident.name() << "' is already declared") ;
} else {
lookup = current_scope_->LookupLocal(function_ident) ;
// TODO: There are a few cases, a function redeclaration is not necessarily a problem.
// A typical example is a PRIVATE or PUBLIC statement in a module
if (lookup) FAIL("A unit '" << function_ident->name() << "' is already declared") ;
if (lookup) FAIL("A unit '" << function_ident.name() << "' is already declared") ;
}
auto symbol = new sm::FunctionSymbol( current_scope_, function_ident ) ;
sema.scope_provider = EnterScope( new Scope(Scope::SK_FUNCTION, current_scope_, symbol) ) ;
sema.scope_provider = EnterScope( new Scope(Scope::Kind::SK_FUNCTION, current_scope_, symbol) ) ;
// Install the label table
sema.label_table = PushLabelTable( new LabelTable ) ;
@ -1478,7 +1480,7 @@ public:
// Check the end function name
//const std::string * end_name = GetOptValue(end_stmt.v) ;
// const sm::Identifier * end_ident = end_name ? sm::Identifier::get(*end_name) : nullptr ;
// sm::Identifier end_ident = end_name ? sm::Identifier::make(*end_name) : nullptr ;
// CheckStatementName(function_ident,end_ident,"function",false) ;
@ -1490,7 +1492,7 @@ public:
auto &sema = getSema(x);
GetLabelTable().dump() ;
PopLabelTable(sema.label_table) ;
LeaveScope(Scope::SK_FUNCTION) ;
LeaveScope(Scope::Kind::SK_FUNCTION) ;
}
// ========== SubroutineSubprogram ===========
@ -1503,22 +1505,22 @@ public:
// const EndSubroutineStmt & end_stmt = GetValue(std::get<x.END>(x.t)) ;
const std::string &subroutine_name = std::get<1>(subroutine_stmt.t) ;
const sm::Identifier *subroutine_ident = sm::Identifier::get(subroutine_name) ;
sm::Identifier subroutine_ident = sm::Identifier::make(subroutine_name) ;
// TODO: lookup for name conflict
sm::Symbol *lookup ;
if ( current_scope_->getKind() == Scope::SK_GLOBAL ) {
if ( current_scope_->kind() == Scope::Kind::SK_GLOBAL ) {
lookup = current_scope_->LookupProgramUnit(subroutine_ident) ;
if (lookup) FAIL("A unit '" << subroutine_ident->name() << "' is already declared") ;
if (lookup) FAIL("A unit '" << subroutine_ident.name() << "' is already declared") ;
} else {
lookup = current_scope_->LookupLocal(subroutine_ident) ;
// TODO: There are a few cases, a subroutine redeclaration is not necessarily a problem.
// A typical example is a PRIVATE or PUBLIC statement in a module
if (lookup) FAIL("A unit '" << subroutine_ident->name() << "' is already declared") ;
if (lookup) FAIL("A unit '" << subroutine_ident.name() << "' is already declared") ;
}
auto symbol = new sm::SubroutineSymbol( current_scope_, subroutine_ident ) ;
sema.scope_provider = EnterScope( new Scope(Scope::SK_SUBROUTINE, current_scope_, symbol) ) ;
sema.scope_provider = EnterScope( new Scope(Scope::Kind::SK_SUBROUTINE, current_scope_, symbol) ) ;
// Install the label table
sema.label_table = PushLabelTable( new LabelTable ) ;
@ -1527,7 +1529,7 @@ public:
// Check the end subroutine name
// const std::string * end_name = GetOptValue(end_stmt.v) ;
// const sm::Identifier * end_ident = end_name ? sm::Identifier::get(*end_name) : nullptr ;
// sm::Identifier end_ident = end_name ? sm::Identifier::make(*end_name) : nullptr ;
// CheckStatementName(subroutine_ident,end_ident,"subroutine",false) ;
return true ;
@ -1540,7 +1542,7 @@ public:
PopLabelTable(sema.label_table) ;
if ( ! opened_label_do_.empty() )
INTERNAL_ERROR;
LeaveScope(Scope::SK_SUBROUTINE) ;
LeaveScope(Scope::Kind::SK_SUBROUTINE) ;
}
@ -1554,22 +1556,22 @@ public:
// const EndModuleStmt & end_stmt = GetValue(std::get<x.END>(x.t)) ;
const std::string &module_name = module_stmt.v ;
const sm::Identifier *module_ident = sm::Identifier::get(module_name) ;
sm::Identifier module_ident = sm::Identifier::make(module_name) ;
// TODO: lookup for name conflict
sm::Symbol *lookup ;
if ( current_scope_->getKind() == Scope::SK_GLOBAL ) {
if ( current_scope_->kind() == Scope::Kind::SK_GLOBAL ) {
lookup = current_scope_->LookupProgramUnit(module_ident) ;
if (lookup) FAIL("A unit '" << module_ident->name() << "' is already declared") ;
if (lookup) FAIL("A unit '" << module_ident.name() << "' is already declared") ;
} else {
lookup = current_scope_->LookupLocal(module_ident) ;
// TODO: There are a few cases, a module redeclaration is not necessarily a problem.
// A typical example is a PRIVATE or PUBLIC statement in a module
if (lookup) FAIL("A unit '" << module_ident->name() << "' is already declared") ;
if (lookup) FAIL("A unit '" << module_ident.name() << "' is already declared") ;
}
auto symbol = new sm::ModuleSymbol( current_scope_, module_ident ) ;
sema.scope_provider = EnterScope( new Scope(Scope::SK_MODULE, current_scope_, symbol) ) ;
sema.scope_provider = EnterScope( new Scope(Scope::Kind::SK_MODULE, current_scope_, symbol) ) ;
// Install the label table
sema.label_table = PushLabelTable( new LabelTable ) ;
@ -1578,7 +1580,7 @@ public:
// Check the end module name
// const std::string * end_name = GetOptValue(end_stmt.v) ;
// const sm::Identifier * end_ident = end_name ? sm::Identifier::get(*end_name) : nullptr ;
// sm::Identifier end_ident = end_name ? sm::Identifier::make(*end_name) : nullptr ;
// CheckStatementName(module_ident,end_ident,"module",false) ;
@ -1590,7 +1592,7 @@ public:
auto &sema = getSema(x);
GetLabelTable().dump() ;
PopLabelTable(sema.label_table) ;
LeaveScope(Scope::SK_MODULE) ;
LeaveScope(Scope::Kind::SK_MODULE) ;
}
@ -1626,7 +1628,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::DerivedType);
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -1642,7 +1644,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndType);
auto name = sm::Identifier::get(x.v) ;
auto name = sm::Identifier::make(x.v) ;
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -1658,7 +1660,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Module);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
SetConstructName(sema.stmt_index, name);
return true ;
@ -1674,7 +1676,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::EndModule);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -1690,7 +1692,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Subroutine);
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -1706,7 +1708,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::EndSubroutine);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, false);
return true ;
}
@ -1717,7 +1719,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Function);
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -1733,7 +1735,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::EndFunction);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -1797,6 +1799,8 @@ public:
bool Pre(const AssignmentStmt &x) {
TRACE_CALL() ;
InitStmt(x, StmtClass::Assignment);
return true ;
}
@ -1810,9 +1814,10 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Program);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
SetConstructName(sema.stmt_index, name);
return true ;
}
@ -1826,7 +1831,7 @@ public:
TRACE_CALL() ;
auto &sema =InitStmt(x, StmtClass::EndProgram);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -2127,7 +2132,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Block);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
SetConstructName(sema.stmt_index, name);
return true ;
@ -2144,7 +2149,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndBlock);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2161,7 +2166,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::ForallConstruct);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2178,7 +2183,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndForall);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2196,7 +2201,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Associate);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2213,7 +2218,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndAssociate);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2229,7 +2234,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::ChangeTeam);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2245,7 +2250,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndChangeTeam);
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2261,7 +2266,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::Critical);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2277,7 +2282,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndCritical);
auto name = sm::Identifier::get(x.v) ;
auto name = sm::Identifier::make(x.v) ;
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2357,7 +2362,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::IfThen);
auto name = sm::Identifier::get( std::get<0>(x.t) );
auto name = sm::Identifier::make( std::get<0>(x.t) );
SetConstructName(sema.stmt_index, name);
return true ;
@ -2373,7 +2378,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::ElseIf);
auto name = sm::Identifier::get( std::get<1>(x.t) );
auto name = sm::Identifier::make( std::get<1>(x.t) );
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -2389,7 +2394,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::Else);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -2405,7 +2410,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndIf);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2421,7 +2426,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::NonLabelDo);
auto name = sm::Identifier::get( std::get<0>(x.t) );
auto name = sm::Identifier::make( std::get<0>(x.t) );
SetConstructName(sema.stmt_index, name);
// Specialize from StmtClass::LabelDo to StmtClass::NonLabelDoWhile or
@ -2457,7 +2462,7 @@ public:
}
// And also record the construct name
auto name = sm::Identifier::get( std::get<0>(x.t) );
auto name = sm::Identifier::make( std::get<0>(x.t) );
SetConstructName(sema.stmt_index, name);
// Specialize from StmtClass::LabelDo to StmtClass::LabelDoWhile or
@ -2477,7 +2482,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::EndDo);
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2507,7 +2512,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::SelectCase);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2536,7 +2541,7 @@ public:
#if 1
// Method 1: Manually visit the construct elements
// smap.VisistConstruct( sema.stmt_index,
smap.VisistConstructRev( sema.stmt_index,
smap.VisitConstructRev( sema.stmt_index,
[&]( SMap::Index at ) -> bool
{
if ( smap.GetClass(at) == StmtClass::CaseDefault ) {
@ -2563,7 +2568,7 @@ public:
}
// Check the construct name
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
CheckStatementName(sema.stmt_index, name, false);
return true ;
@ -2581,7 +2586,7 @@ public:
auto &sema = InitStmt(x, StmtClass::EndSelect);
// Check the construct name
auto name = sm::Identifier::get(x.v);
auto name = sm::Identifier::make(x.v);
CheckStatementName(sema.stmt_index, name, true);
return true ;
@ -2597,7 +2602,7 @@ public:
TRACE_CALL() ;
auto & sema = InitStmt(x, StmtClass::SelectRank);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2670,7 +2675,7 @@ public:
// Check the construct name
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
CheckStatementName(sema.stmt_index, name, false);
@ -2687,7 +2692,7 @@ public:
TRACE_CALL() ;
auto &sema = InitStmt(x, StmtClass::SelectType);
auto name = sm::Identifier::get(std::get<0>(x.t));
auto name = sm::Identifier::make(std::get<0>(x.t));
SetConstructName(sema.stmt_index, name);
return true ;
@ -2756,7 +2761,7 @@ public:
}
// Check the construct name.
auto name = sm::Identifier::get(std::get<1>(x.t));
auto name = sm::Identifier::make(std::get<1>(x.t));
CheckStatementName(sema.stmt_index, name, false);
@ -2959,7 +2964,7 @@ public:
auto & smap = GetStatementMap() ;
// the name of the construct we are looking for (can be null)
const sm::Identifier * target_name = sm::Identifier::get(x.v) ;
sm::OptIdentifier target_name = sm::Identifier::make(x.v) ;
// Reminder: Unlike in EXIT, the target of a CYCLE statement is always
// a DO so the target resolution are similar but not identical.
@ -3082,7 +3087,7 @@ public:
auto & smap = GetStatementMap() ;
// the name of the construct we are looking for (can be null)
const sm::Identifier * target_name = sm::Identifier::get(x.v) ;
sm::OptIdentifier target_name = sm::Identifier::make(x.v) ;
// Remark: I am currently search the target construct by
// only considering its identifer but this is actually incorrect
@ -3520,6 +3525,7 @@ public:
bool Pre(const AssignStmt &x) {
TRACE_CALL() ;
InitStmt(x, StmtClass::Assign);
return true ;
}
@ -3622,7 +3628,9 @@ void DoSemanticAnalysis( const psr::Program &all)
psr::Pass1 pass1 ;
for (const psr::ProgramUnit &unit : all.v) {
TRACE("===========================================================================================================");
pass1.run(unit) ;
psr::DumpTree(unit);
TRACE("===========================================================================================================");
pass1.run(unit) ;
}
}