[flang] Merge with current master and move code to lib/semantics/

Original-commit: flang-compiler/f18@8b31a01102
Reviewed-on: https://github.com/flang-compiler/f18/pull/24
Tree-same-pre-rewrite: false
This commit is contained in:
Stephane Chauveau 2018-03-26 15:49:04 +02:00 committed by GitHub
parent 934b518443
commit f49e2dfa2a
21 changed files with 1017 additions and 1251 deletions

View File

@ -1,91 +0,0 @@
#ifndef FLANG_SEMA_IDENTIFIER_H
#define FLANG_SEMA_IDENTIFIER_H
#include <string>
#include <optional>
namespace Fortran::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_ ;
}
};
} // namespace Fortran::semantics
#endif // of FLANG_SEMA_IDENTIFIER_H

View File

@ -1,3 +1,3 @@
add_subdirectory(parser)
add_subdirectory(Sema)
add_subdirectory(semantics)

View File

@ -1,2 +0,0 @@
#include "../semantics/attr.cc"

View File

@ -1,9 +0,0 @@
add_library( FlangSemantics
Identifier.cc
StatementMap.cc
ParseTreeDump.cc
Type.cc # ../semantics/type.cc
Attr.cc # ../semantics/attr.cc
)

View File

@ -1,26 +0,0 @@
#include "flang/Sema/Identifier.h"
#include <set>
#include <cassert>
#include <cstring>
using Fortran::semantics::Identifier;
static std::set<std::string> all;
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

@ -1,2 +0,0 @@
#include "../semantics/type.cc"

View File

@ -6,4 +6,7 @@ add_library(FlangSemantics
scope.cc
symbol.cc
type.cc
ParseTreeDump.cc
StatementMap.cc
pass1.cc
)

View File

@ -0,0 +1,148 @@
// ============ Forward declarations ==============
template <typename T> inline const auto & GET_VALUE( const T &x) ;
template <typename T> inline auto & GET_VALUE( T &x) ;
template <typename T> inline bool HAS_VALUE( const T &x) ;
template <typename T> inline bool HAS_VALUE( T &x) ;
#ifndef IGNORE_Scalar
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Scalar<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::Scalar<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Scalar<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::Scalar<T> &x) ;
#endif
#ifndef IGNORE_Constant
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Constant<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::Constant<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Constant<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::Constant<T> &x) ;
#endif
#ifndef IGNORE_Integer
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Integer<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::Integer<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Integer<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::Integer<T> &x) ;
#endif
#ifndef IGNORE_Logical
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Logical<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::Logical<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Logical<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::Logical<T> &x) ;
#endif
#ifndef IGNORE_DefaultChar
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::DefaultChar<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::DefaultChar<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::DefaultChar<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::DefaultChar<T> &x) ;
#endif
#ifndef IGNORE_Indirection
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Indirection<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::Indirection<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Indirection<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::Indirection<T> &x) ;
#endif
#ifndef IGNORE_Statement
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Statement<T> &x) ;
template <typename T> inline auto & GET_VALUE( Fortran::parser::Statement<T> &x) ;
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Statement<T> &x) ;
template <typename T> inline bool HAS_VALUE( Fortran::parser::Statement<T> &x) ;
#endif
#ifndef IGNORE_optional
template <typename T> inline const auto & GET_VALUE( const std::optional<T> &x) ;
template <typename T> inline auto & GET_VALUE( std::optional<T> &x) ;
template <typename T> inline bool HAS_VALUE( const std::optional<T> &x) ;
template <typename T> inline bool HAS_VALUE( std::optional<T> &x) ;
#endif
// =========== Actual implementation of GET_VALUE() and HAS_VALUE() ==============================
template <typename T> inline const auto & GET_VALUE( const T &x) { return x ;}
template <typename T> inline auto & GET_VALUE( T &x) { return x ;}
template <typename T> inline bool HAS_VALUE( const T &x) { return true; }
template <typename T> inline bool HAS_VALUE( T &x) { return true; }
#ifndef IGNORE_Scalar
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Scalar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::Scalar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Scalar<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::Scalar<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Constant
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Constant<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::Constant<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Constant<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::Constant<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Integer
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Integer<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::Integer<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Integer<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::Integer<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Logical
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Logical<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::Logical<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Logical<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::Logical<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_DefaultChar
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::DefaultChar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::DefaultChar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::DefaultChar<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::DefaultChar<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Indirection
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Indirection<T> &x) { return GET_VALUE(*x) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::Indirection<T> &x) { return GET_VALUE(*x) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Indirection<T> &x) { return GET_VALUE(*x) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::Indirection<T> &x) { return GET_VALUE(*x) ;}
#endif
#ifndef IGNORE_Statement
template <typename T> inline const auto & GET_VALUE( const Fortran::parser::Statement<T> &x) { return GET_VALUE(x.statement) ;}
template <typename T> inline auto & GET_VALUE( Fortran::parser::Statement<T> &x) { return GET_VALUE(x.statement) ;}
template <typename T> inline bool HAS_VALUE( const Fortran::parser::Statement<T> &x) { return HAS_VALUE(x.statement) ;}
template <typename T> inline bool HAS_VALUE( Fortran::parser::Statement<T> &x) { return HAS_VALUE(x.statement) ;}
#endif
#ifndef IGNORE_optional
template <typename T> inline const auto & GET_VALUE( const std::optional<T> &x) { return GET_VALUE(x.value()) ; }
template <typename T> inline auto & GET_VALUE( std::optional<T> &x) { return GET_VALUE(x.value()) ; }
template <typename T> inline bool HAS_VALUE( const std::optional<T> &x) { return x.has_value() && HAS_VALUE(*x); }
template <typename T> inline bool HAS_VALUE( std::optional<T> &x) { return x.has_value() && HAS_VALUE(*x); }
#endif
template <typename T> inline auto GET_OPT_VALUE(const T &x) {
if ( HAS_VALUE(x) ) {
return & GET_VALUE(x) ;
} else {
return decltype(&GET_VALUE(x)){0} ;
}
}
template <typename T> inline auto GET_OPT_VALUE(T &x) {
if ( HAS_VALUE(x) ) {
return & GET_VALUE(x) ;
} else {
return decltype(&GET_VALUE(x)){0} ;
}
}
#undef GET_VALUE
#undef HAS_VALUE
#undef GET_OPT_VALUE

View File

@ -0,0 +1,92 @@
#ifndef FORTRAN_LABEL_TABLE_H_
#define FORTRAN_LABEL_TABLE_H_
#include <stack>
#include <cassert>
namespace Fortran::semantics {
// Each statement label is in one of those groups
enum class LabelGroup
{
BranchTarget, ///< A label a possible branch target
Format, ///< A label on a FORMAT statement
Other ///< A label on another statement
};
//
// Hold all the labels of a Program Unit
//
// This is going to a integrated into the Scope/SymbolTable
// once we have it implemented. For now, I am just simulating
// scopes with LabelTable and LabelTableStack
//
class LabelTable
{
private:
struct Entry {
// TODO: what to put here
Fortran::parser::Provenance loc;
};
std::map<int,Entry> entries_ ;
public:
void add( int label , Fortran::parser::Provenance loc )
{
if (label<1 || label>99999) return ; // Hoops!
auto &entry = entries_[label] ;
entry.loc = loc ;
}
bool find(int label, Fortran::parser::Provenance &loc)
{
auto it = entries_.find(label);
if( it != entries_.end()) {
Entry & entry{it->second};
loc = entry.loc;
return true;
}
return false;
}
}; // of class LabelTable
class LabelTableStack {
private:
std::stack<LabelTable*> stack ;
public:
LabelTable *PushLabelTable( LabelTable *table )
{
assert(table!=NULL);
stack.push(table);
return table;
}
void PopLabelTable( LabelTable *table )
{
assert( !stack.empty() ) ;
assert( stack.top() == table ) ;
stack.pop();
}
LabelTable & GetLabelTable() {
assert( !stack.empty() ) ;
return *stack.top() ;
}
bool NoLabelTable() {
return stack.empty() ;
}
}; // of class LabelTableStack
} // of namespace Fortran::semantics
#endif // FORTRAN_LABEL_TABLE_H_

View File

@ -1,4 +1,4 @@
#include "flang/Sema/ParseTreeDump.h"
#include "ParseTreeDump.h"
#include <string>
#include <cstring>

View File

@ -1,11 +1,11 @@
#ifndef FLANG_SEMA_PARSE_TREE_DUMP_H
#define FLANG_SEMA_PARSE_TREE_DUMP_H
#include "../../../lib/parser/format-specification.h"
#include "../../../lib/parser/idioms.h"
#include "../../../lib/parser/indirection.h"
#include "../../../lib/parser/parse-tree-visitor.h"
#include "../../../lib/parser/parse-tree.h"
#include "../parser/format-specification.h"
#include "../parser/idioms.h"
#include "../parser/indirection.h"
#include "../parser/parse-tree-visitor.h"
#include "../parser/parse-tree.h"
#include <string>

View File

@ -0,0 +1,594 @@
#ifndef FORTRAN_SEMA_DATA_H_
#define FORTRAN_SEMA_DATA_H_
#include <cassert>
//
//
// Declare here the members of the Semantic<T> that will
// be attached to each parse-tree class T. The default is
// an empty struct. All members added here shall be
// copiable and should be provided with a default value.
//
// Here are a few common fields
//
// Scope *scope_provider = the scope provided by a construct or statement
// int stmt_index = the index used in the StatementMap
//
// Remark: Weither we want to annotate parse-tree nodes with
// semantic information is still debatable.
//
namespace Fortran::semantics {
// Initialize the semantic information attached to a parser-tree node
//
// Ideally, the function should be called once at the begining of the corresponding Pre()
// member in Pass1. However, for the few cases where the semantic data need to be
// initialize earlier the strict argument can be set to false.
//
template <typename T> Semantic<T> & InitSema(const T &node, bool strict=true) {
// Do not use the default implementation!
// If the following assert fails, then a DECLARE_SEMANTIC_DATA is
// missing below
assert(Semantic<T>::IS_DECLARED);
if (node.s) {
if (strict) {
// TODO: emit proper message
std::cerr << "Duplicate call of " << __PRETTY_FUNCTION__ << "\n" ;
exit(1);
} else {
return *(node.s);
}
}
auto s = new Semantic<T>( const_cast<T*>(&node) ) ;
const_cast<T&>(node).s = s;
return *s ;
}
// Retreive the semantic information attached to a parser-tree node
template <typename T> Semantic<T> & GetSema(const T &node) {
// Do not use the default implementation!
// If the following assert fails, then a DECLARE_SEMANTIC is missing above
assert(Semantic<T>::IS_DECLARED);
assert(node.s) ;
return *(node.s) ;
}
#define DEFINE_SEMANTIC_DATA(Class) \
template <> struct Semantic<Fortran::parser::Class> { \
Semantic<Fortran::parser::Class>(Fortran::parser::Class *node) {} \
enum {IS_DECLARED=1};
#define END_SEMANTIC_DATA \
}
// Some fields that need to be defined for all statements
#define SEMANTIC_STMT_FIELDS \
int stmt_index=0
DEFINE_SEMANTIC_DATA(ProgramUnit)
StatementMap *statement_map=0 ;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(MainProgram)
Scope *scope_provider=0 ;
LabelTable *label_table=0 ;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SubroutineSubprogram)
Scope *scope_provider=0 ;
LabelTable *label_table=0 ;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FunctionSubprogram)
Scope *scope_provider=0 ;
LabelTable *label_table=0 ;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(Module)
Scope *scope_provider=0 ;
LabelTable *label_table=0 ;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(DerivedTypeDef)
// WARNING: there is also a sm::DerivedTypeDef defined in types.h
Scope *scope_provider=0 ;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AssignmentStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(DataStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FunctionStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SubroutineStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ModuleStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndModuleStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(StmtFunctionStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndFunctionStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndSubroutineStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(TypeDeclarationStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(DerivedTypeStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndTypeStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(PrintStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(UseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ProgramStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndProgramStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ImplicitStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AccessStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AllocatableStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AsynchronousStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(BindStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CodimensionStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ContiguousStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ContainsStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(DimensionStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ExternalStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(IntentStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(IntrinsicStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(NamelistStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(OptionalStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(PointerStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ProtectedStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SaveStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(TargetStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ValueStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(VolatileStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CommonStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EquivalenceStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(BasedPointerStmt) // extension
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(GenericStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ParameterStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EnumDef)
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EnumDefStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndEnumStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(InterfaceStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndInterfaceStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(IfThenStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ElseIfStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ElseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndIfStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(IfStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SelectCaseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CaseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndSelectStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SelectRankStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SelectRankCaseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SelectTypeStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ProcedureDeclarationStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(StructureStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(StructureDef::EndStructureStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FormatStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EntryStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ImportStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AllocateStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(BackspaceStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CallStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CloseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ContinueStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(DeallocateStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndfileStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EventPostStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EventWaitStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CycleStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ExitStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FailImageStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FlushStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FormTeamStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(GotoStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(InquireStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(LockStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(NullifyStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(OpenStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(PointerAssignmentStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ReadStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ReturnStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(RewindStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(StopStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SyncAllStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SyncImagesStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SyncMemoryStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(SyncTeamStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(UnlockStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(WaitStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(WhereStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(WriteStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ComputedGotoStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ForallStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ForallConstructStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndForallStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ArithmeticIfStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AssignStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AssignedGotoStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(PauseStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(PrivateStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(TypeBoundProcedureStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(TypeBoundGenericStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(FinalProcedureStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ComponentDefStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EnumeratorDefStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(TypeGuardStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(NonLabelDoStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(LabelDoStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndDoStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(BlockStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndBlockStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(AssociateStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndAssociateStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(ChangeTeamStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndChangeTeamStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(CriticalStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
DEFINE_SEMANTIC_DATA(EndCriticalStmt)
SEMANTIC_STMT_FIELDS;
END_SEMANTIC_DATA;
#undef DEFINE_SEMANTIC_DATA
#undef END_SEMANTIC_DATA_SEMANTIC
#undef SEMANTIC_STMT_FIELDS
} // of namespace Fortran::semantics
#endif // FORTRAN_SEMA_DATA_H_

View File

@ -1,5 +1,5 @@
#include "flang/Sema/StatementMap.h"
#include "StatementMap.h"
#include <cassert>
#include <cstdlib>

View File

@ -1,7 +1,7 @@
#ifndef FLANG_SEMA_STATEMENT_MAP_H
#define FLANG_SEMA_STATEMENT_MAP_H
#include "flang/Sema/Stmt.h"
#include "Stmt.h"
#include <functional>
#include <map>
#include <vector>

View File

@ -1,7 +1,7 @@
#ifndef FLANG_SEMA_STMT_H
#define FLANG_SEMA_STMT_H
#ifndef FLANG_SEMA_STMT_H_
#define FLANG_SEMA_STMT_H_
#include "../../../lib/parser/parse-tree.h"
#include "../parser/parse-tree.h"
#include <variant>
namespace Fortran::semantics {
@ -23,7 +23,7 @@ constexpr StmtGroup StmtClassToGroup(StmtClass sc) {
#define DECLARE_STMT(Name, Class, Group, Text) \
case StmtClass::Name: return StmtGroup::Group;
#include "flang/Sema/Stmt.def"
#include "Stmt.def"
}
// Hummm... should not happen but cannot add error or assert
// in constexpr expression.
@ -35,7 +35,7 @@ constexpr const char *StmtClassName(StmtClass sc) {
#define DECLARE_STMT(Name, Class, Group, Text) \
case StmtClass::Name: return #Name;
#include "flang/Sema/Stmt.def"
#include "Stmt.def"
}
return "????";
}
@ -45,21 +45,11 @@ constexpr const char *StmtClassText(StmtClass sc) {
#define DECLARE_STMT(Name, Class, Group, Text) \
case StmtClass::Name: return Text;
#include "flang/Sema/Stmt.def"
#include "Stmt.def"
}
return "????";
}
// AnyStmt is a std::variant<> of const pointers to all possible statement
// classes.
// typedef std::variant<
//#define DECLARE_DUMMY_STMT(Name,Group,Text)
//#define DECLARE_PARSER_STMT_ALT(Name,Class,Group,Text)
//#define DECLARE_PARSER_STMT(Name,Class,Group,Text) , const
//Fortran::parser::Class * #define DECLARE_FIRST_STMT(Name,Class,Group,Text)
//const Fortran::parser::Class * #include "flang/Sema/Stmt.def"
// > AnyStmt ;
} // end of namespace Fortran::semantics
#endif // of FLANG_SEMA_STMT_H
#endif // of FLANG_SEMA_STMT_H_

File diff suppressed because it is too large Load Diff

View File

@ -23,11 +23,10 @@ target_link_libraries( test-type
add_executable( test-sema
test-sema.cc
sema-impl.cc
)
target_link_libraries( test-sema
FlangParser
FortranParser
FlangSemantics
)

View File

@ -1,148 +0,0 @@
// ============ Forward declarations ==============
template <typename T> inline const auto & GET_VALUE( const T &x) ;
template <typename T> inline auto & GET_VALUE( T &x) ;
template <typename T> inline bool HAS_VALUE( const T &x) ;
template <typename T> inline bool HAS_VALUE( T &x) ;
#ifndef IGNORE_Scalar
template <typename T> inline const auto & GET_VALUE( const psr::Scalar<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::Scalar<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::Scalar<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::Scalar<T> &x) ;
#endif
#ifndef IGNORE_Constant
template <typename T> inline const auto & GET_VALUE( const psr::Constant<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::Constant<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::Constant<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::Constant<T> &x) ;
#endif
#ifndef IGNORE_Integer
template <typename T> inline const auto & GET_VALUE( const psr::Integer<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::Integer<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::Integer<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::Integer<T> &x) ;
#endif
#ifndef IGNORE_Logical
template <typename T> inline const auto & GET_VALUE( const psr::Logical<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::Logical<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::Logical<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::Logical<T> &x) ;
#endif
#ifndef IGNORE_DefaultChar
template <typename T> inline const auto & GET_VALUE( const psr::DefaultChar<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::DefaultChar<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::DefaultChar<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::DefaultChar<T> &x) ;
#endif
#ifndef IGNORE_Indirection
template <typename T> inline const auto & GET_VALUE( const psr::Indirection<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::Indirection<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::Indirection<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::Indirection<T> &x) ;
#endif
#ifndef IGNORE_Statement
template <typename T> inline const auto & GET_VALUE( const psr::Statement<T> &x) ;
template <typename T> inline auto & GET_VALUE( psr::Statement<T> &x) ;
template <typename T> inline bool HAS_VALUE( const psr::Statement<T> &x) ;
template <typename T> inline bool HAS_VALUE( psr::Statement<T> &x) ;
#endif
#ifndef IGNORE_optional
template <typename T> inline const auto & GET_VALUE( const std::optional<T> &x) ;
template <typename T> inline auto & GET_VALUE( std::optional<T> &x) ;
template <typename T> inline bool HAS_VALUE( const std::optional<T> &x) ;
template <typename T> inline bool HAS_VALUE( std::optional<T> &x) ;
#endif
// =========== Actual implementation of GET_VALUE() and HAS_VALUE() ==============================
template <typename T> inline const auto & GET_VALUE( const T &x) { return x ;}
template <typename T> inline auto & GET_VALUE( T &x) { return x ;}
template <typename T> inline bool HAS_VALUE( const T &x) { return true; }
template <typename T> inline bool HAS_VALUE( T &x) { return true; }
#ifndef IGNORE_Scalar
template <typename T> inline const auto & GET_VALUE( const psr::Scalar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( psr::Scalar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const psr::Scalar<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( psr::Scalar<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Constant
template <typename T> inline const auto & GET_VALUE( const psr::Constant<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( psr::Constant<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const psr::Constant<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( psr::Constant<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Integer
template <typename T> inline const auto & GET_VALUE( const psr::Integer<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( psr::Integer<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const psr::Integer<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( psr::Integer<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Logical
template <typename T> inline const auto & GET_VALUE( const psr::Logical<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( psr::Logical<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const psr::Logical<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( psr::Logical<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_DefaultChar
template <typename T> inline const auto & GET_VALUE( const psr::DefaultChar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline auto & GET_VALUE( psr::DefaultChar<T> &x) { return GET_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( const psr::DefaultChar<T> &x) { return HAS_VALUE(x.thing) ;}
template <typename T> inline bool HAS_VALUE( psr::DefaultChar<T> &x) { return HAS_VALUE(x.thing) ;}
#endif
#ifndef IGNORE_Indirection
template <typename T> inline const auto & GET_VALUE( const psr::Indirection<T> &x) { return GET_VALUE(*x) ;}
template <typename T> inline auto & GET_VALUE( psr::Indirection<T> &x) { return GET_VALUE(*x) ;}
template <typename T> inline bool HAS_VALUE( const psr::Indirection<T> &x) { return GET_VALUE(*x) ;}
template <typename T> inline bool HAS_VALUE( psr::Indirection<T> &x) { return GET_VALUE(*x) ;}
#endif
#ifndef IGNORE_Statement
template <typename T> inline const auto & GET_VALUE( const psr::Statement<T> &x) { return GET_VALUE(x.statement) ;}
template <typename T> inline auto & GET_VALUE( psr::Statement<T> &x) { return GET_VALUE(x.statement) ;}
template <typename T> inline bool HAS_VALUE( const psr::Statement<T> &x) { return HAS_VALUE(x.statement) ;}
template <typename T> inline bool HAS_VALUE( psr::Statement<T> &x) { return HAS_VALUE(x.statement) ;}
#endif
#ifndef IGNORE_optional
template <typename T> inline const auto & GET_VALUE( const std::optional<T> &x) { return GET_VALUE(x.value()) ; }
template <typename T> inline auto & GET_VALUE( std::optional<T> &x) { return GET_VALUE(x.value()) ; }
template <typename T> inline bool HAS_VALUE( const std::optional<T> &x) { return x.has_value() && HAS_VALUE(*x); }
template <typename T> inline bool HAS_VALUE( std::optional<T> &x) { return x.has_value() && HAS_VALUE(*x); }
#endif
template <typename T> inline auto GET_OPT_VALUE(const T &x) {
if ( HAS_VALUE(x) ) {
return & GET_VALUE(x) ;
} else {
return decltype(&GET_VALUE(x)){0} ;
}
}
template <typename T> inline auto GET_OPT_VALUE(T &x) {
if ( HAS_VALUE(x) ) {
return & GET_VALUE(x) ;
} else {
return decltype(&GET_VALUE(x)){0} ;
}
}
#undef GET_VALUE
#undef HAS_VALUE
#undef GET_OPT_VALUE

View File

@ -22,7 +22,7 @@
using namespace Fortran;
using namespace parser;
extern void DoSemanticAnalysis(const Program &);
extern void DoSemanticAnalysis(ParseState &, const Program &);
//static void visitProgramUnit(const ProgramUnit &unit);
@ -67,6 +67,6 @@ int main(int argc, char *const argv[]) {
state.messages()->Emit(std::cerr);
return EXIT_FAILURE;
}
DoSemanticAnalysis(*result) ;
DoSemanticAnalysis(state,*result) ;
return EXIT_SUCCESS;
}