[flang] Removed unused files and declarations.

Renamed ParseTreeDump to dump-parse-tree.

Original-commit: flang-compiler/f18@9de97328f1
Reviewed-on: https://github.com/flang-compiler/f18/pull/76
Tree-same-pre-rewrite: false
This commit is contained in:
Steve Scalpone 2018-05-02 09:15:33 -07:00
parent a9ed8e7eee
commit 209afdcea2
12 changed files with 0 additions and 5127 deletions

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 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

@ -1,134 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_SEMANTICS_GETVALUE_H_
#define FORTRAN_SEMANTICS_GETVALUE_H_
#undef IGNORE_optional
#undef IGNORE_Statement
#undef IGNORE_Scalar
#undef IGNORE_Constant
#undef IGNORE_Indirection
#undef IGNORE_Logical
#undef IGNORE_DefaultChar
// Each include of "GetValue.def" provides a set of helper functions
// whose names are specified by the macros GET_VALUE, HAS_VALUE and
// GET_OPT_VALUE.
//
// The purpose of those function is to provide easier access to the
// parse-tree by ignoring some wrapper classes/
//
//
// GET_VALUE(x) provides a reference to the value that x is holding.
//
// The following wrapper classes are ignored unless the corresponding
// IGNORES_xxx macro is defined.
//
// Scalar<T>
// Constant<T>
// Integer<T>
// Logical<T>
// DefaultChar<T>
// Indirection<T>
// Statement<T>
// std::optional<T>
//
//
// HAS_VALUE(x) return true if it is legal to call GET_VALUE(x) in case x
// contains some std::optional<T>
//
// Example:
// Constant<std::optional<Indirection<std::optional<int>>>> &x = ... ;
// if ( HasValue(x) ) {
// const int &v = getValue(x) ;
// ...
// }
//
// GET_OPT_VALUE(T &x) is equivalent to
//
// HAS_VALUE(x) ? &GET_VALUE(x) : (Type*) nullptr
//
// here Type is the type of GET_VALUE(x)
//
// Example:
//
// const Scalar<optional<Integer<Expr>>> & z = ...
// const Expr *ptr_z = GET_OPT_VALUE(z) ;
// if ( ptr_z ) {
// ... do something with *ptr_z %
// }
//
// This is the default version that handles all wrapper
#define GET_VALUE GetValue
#define HAS_VALUE HasValue
#define GET_OPT_VALUE GetOptValue
#include "GetValue.def"
// HAS_VALUE and GET_OPT_VALUE are only interesting when
// std::optional is not ignored.
// We need to give a name to the function but they are pretty much useless
#define IGNORE_optional
#define GET_VALUE GetOptionalValue
#define HAS_VALUE HasOptionalValue__
#define GET_OPT_VALUE GetOptValue__
#include "GetValue.def"
#undef IGNORE_optional
#define IGNORE_Statement
#define GET_VALUE GetStatementValue
#define HAS_VALUE HasStatementValue
#define GET_OPT_VALUE GetOptStatementValue
#include "GetValue.def"
#undef IGNORE_Statement
#define IGNORE_Scalar
#define GET_VALUE GetScalarValue
#define HAS_VALUE HasScalarValue
#define GET_OPT_VALUE GetOptScalarValue
#include "GetValue.def"
#undef IGNORE_Scalar
#define IGNORE_Constant
#define GET_VALUE GetConstantValue
#define HAS_VALUE HasConstantValue
#define GET_OPT_VALUE GetOptConstantValue
#include "GetValue.def"
#undef IGNORE_Constant
#define IGNORE_Indirection
#define GET_VALUE GetIndirectionValue
#define HAS_VALUE HasIndirectionValue
#define GET_OPT_VALUE GetOptIndirectionValue
#include "GetValue.def"
#undef IGNORE_Indirection
#define IGNORE_Logical
#define GET_VALUE GetLogicalValue
#define HAS_VALUE HasLogicalValue
#define GET_OPT_VALUE GetOptLogicalValue
#include "GetValue.def"
#undef IGNORE_Logical
#define IGNORE_DefaultChar
#define GET_VALUE GetDefaultCharValue
#define HAS_VALUE HasDefaultCharValue
#define GET_OPT_VALUE GetOptDefaultCharValue
#include "GetValue.def"
#undef IGNORE_DefaultChar
#endif // FORTRAN_SEMANTICS_GETVALUE_H_

View File

@ -1,106 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_SEMANTICS_LABELTABLE_H_
#define FORTRAN_SEMANTICS_LABELTABLE_H_
#include <cassert>
#include <stack>
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_SEMANTICS_LABELTABLE_H_

View File

@ -1,608 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_SEMANTICS_SEMANTICDATA_H_
#define FORTRAN_SEMANTICS_SEMANTICDATA_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_SEMANTICS_SEMANTICDATA_H_

View File

@ -1,622 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "StatementMap.h"
#include <cassert>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#define FAIL(msg) \
do { \
std::cerr << "FATAL " << __FILE__ << ":" << __LINE__ << ":\n " << msg \
<< "\n"; \
exit(1); \
} while (0)
#define INTERNAL_ERROR FAIL("Internal Error")
namespace Fortran::semantics {
StatementMap::Entry &StatementMap::at(Index index) {
if (!(( First() <= index) && (index <= Last()))) {
FAIL("Illegal Stmt index " << index << " (expect "
<< First() << " .." << Last() << ")");
exit(1);
}
return entries_[index - 1];
}
const StatementMap::Entry &StatementMap::at(Index index) const {
if (!((First() <= index) && (index <= Last()))) {
FAIL("Illegal Stmt index " << index << " (expect "
<< First() << ".." << Last() << ")");
exit(1);
}
return entries_[index - 1];
}
StatementMap::Index StatementMap::Add(StmtClass sclass, int label) {
Entry self;
self.sclass = sclass;
self.group = StmtClassToGroup(sclass);
self.label = label;
self.parent = None;
self.prev_in_body = None;
self.next_in_body = None;
self.prev_in_construct = None;
self.next_in_construct = None;
Index self_index = Last() + 1;
if (Size() == 0) {
// Special case of the first entry.
entries_.push_back(self);
return self_index;
}
Index prev_index = self_index - 1;
auto prev_group = at(prev_index).group;
if (prev_group == StmtGroup::End) {
// When inserting after a closed construct, do as if
// that was after a single statement
prev_index = StartOfConstruct(prev_index);
prev_group = StmtGroup::Single;
}
Entry &prev = at(prev_index);
if (self.group == StmtGroup::Single || self.group == StmtGroup::Start) {
if (prev_group == StmtGroup::Start || prev_group == StmtGroup::Part) {
// Insert 'self' as first statement in body of 'prev;
self.parent = prev_index;
} else if (prev_group == StmtGroup::Single) {
// Insert 'self' after 'prev' (in the same body)
prev.next_in_body = self_index;
self.prev_in_body = prev_index;
self.parent = prev.parent;
} else {
INTERNAL_ERROR;
}
} else if (self.group == StmtGroup::Part || self.group == StmtGroup::End) {
if (prev_group == StmtGroup::Start || prev_group == StmtGroup::Part) {
// Close the empty body of 'prev'
assert(prev.next_in_construct == None);
prev.next_in_construct = self_index;
self.prev_in_construct = prev_index;
} else if (prev_group == StmtGroup::Single) {
// Close a non-empty body ending with 'prev'
assert(prev.next_in_body == None);
if (prev.parent == None) {
DumpFlat(std::cerr);
}
assert(prev.parent != None);
at(prev.parent).next_in_construct = self_index;
self.prev_in_construct = prev.parent;
} else {
INTERNAL_ERROR;
}
}
// TODO: Beware of the reallocation cost of calling push_back() for each
// statement.
// const int chunksize = 128;
// entries_.reserve( (entries_.size()/chunksize+1)*chunksize );
entries_.push_back(self);
if ( self.group == StmtGroup::Part || self.group == StmtGroup::End ) {
assert( self.prev_in_construct != None) ;
assert( NextInConstruct(self.prev_in_construct) == self_index) ;
assert( PrevInConstruct(self_index) == self.prev_in_construct) ;
AssertNextInConstruct(self.prev_in_construct);
}
return self_index;
}
//
// 'prev_index' shall be a Start or Part statement.
//
// Assert that the next statement in the construct is of an expected class.
//
//
void StatementMap::AssertNextInConstruct(Index prev_index) const {
if (prev_index == None) return;
auto &prev = at(prev_index);
if (prev.next_in_construct == None) return;
auto &next = at(prev.next_in_construct);
#define ORDER(A, B) (prev.sclass == StmtClass::A && next.sclass == StmtClass::B)
if ( // If THEN ... [ELSEIF]* ... [ELSE] ... Endif
ORDER(IfThen, ElseIf) || ORDER(IfThen, Else) || ORDER(IfThen, EndIf) ||
ORDER(ElseIf, ElseIf) || ORDER(ElseIf, Else) || ORDER(ElseIf, EndIf) ||
ORDER(Else, EndIf) ||
// PROGRAM ... [CONTAINS] ... END
ORDER(Program, Contains) || ORDER(Program, EndProgram) ||
ORDER(Contains, EndProgram) ||
// MODULE
ORDER(Module, Contains) || ORDER(Module, EndModule) ||
ORDER(Contains, EndModule) ||
// SUBROUTINE
ORDER(Subroutine, Contains) || ORDER(Subroutine, EndSubroutine) ||
ORDER(Contains, EndSubroutine) ||
// FUNCTION
ORDER(Function, Contains) || ORDER(Function, EndFunction) ||
ORDER(Contains, EndFunction) ||
// IF ..
ORDER(If, DummyEndIf) ||
// FORALL ..
ORDER(Forall, DummyEndForall) || ORDER(ForallConstruct, EndForall) ||
// WHERE ..
ORDER(Where, DummyEndWhere) || ORDER(WhereConstruct, MaskedElsewhere) ||
ORDER(WhereConstruct, EndWhere) || ORDER(ElseWhere, EndWhere) ||
ORDER(MaskedElsewhere, EndWhere) ||
ORDER(MaskedElsewhere, MaskedElsewhere) ||
// ASSOCIATE
ORDER(Associate, EndAssociate) ||
// BLOCK
ORDER(Block, EndBlock) ||
// CHANGE TEAM
ORDER(ChangeTeam, EndChangeTeam) ||
// CRITICAL
ORDER(Critical, EndCritical) ||
// TYPE
ORDER(DerivedType, EndType) ||
// ENUM
ORDER(EnumDef, EndEnum) ||
// INTERFACE
ORDER(Interface, EndInterface) ||
// DO var=...
ORDER(NonLabelDo, EndDo) ||
// DO WHILE ...
ORDER(NonLabelDoWhile, EndDo) ||
// DO CONCURRENT
ORDER(NonLabelDoConcurrent, EndDo) ||
// DO <label> var=....
ORDER(LabelDo, EndDo) ||
ORDER(LabelDo, DummyEndDo) ||
// DO <label> WHILE ...
ORDER(LabelDoWhile, EndDo) ||
ORDER(LabelDoWhile, DummyEndDo) ||
// DO <label> CONCURRENT ...
ORDER(LabelDoConcurrent, EndDo) ||
ORDER(LabelDoConcurrent, DummyEndDo) ||
// SELECT CASE
ORDER(SelectCase, EndSelect) || ORDER(SelectCase, Case) ||
ORDER(Case, Case) || ORDER(Case, EndSelect) ||
ORDER(SelectCase, CaseDefault) || ORDER(CaseDefault, Case) ||
ORDER(Case, CaseDefault) || ORDER(CaseDefault, CaseDefault) ||
ORDER(CaseDefault, EndSelect) ||
// SELECT RANK
ORDER(SelectRank, EndSelect) || ORDER(SelectRank, SelectRankCase) ||
ORDER(SelectRank, SelectRankStar) || ORDER(SelectRank, SelectRankDefault) ||
ORDER(SelectRankCase, SelectRankCase) || ORDER(SelectRankCase, SelectRankStar) ||
ORDER(SelectRankCase, SelectRankDefault) || ORDER(SelectRankCase, EndSelect) ||
ORDER(SelectRankStar, SelectRankCase) || ORDER(SelectRankStar, SelectRankStar) ||
ORDER(SelectRankStar, SelectRankDefault) || ORDER(SelectRankStar, EndSelect) ||
ORDER(SelectRankDefault, SelectRankCase) || ORDER(SelectRankDefault, SelectRankStar) ||
ORDER(SelectRankDefault, SelectRankDefault) ||ORDER(SelectRankDefault, EndSelect) ||
// SELECT TYPE
ORDER(SelectType, EndSelect) || ORDER(SelectType, TypeGuard) ||
ORDER(SelectType, ClassGuard) || ORDER(SelectType, ClassDefault) ||
ORDER(TypeGuard, EndSelect) || ORDER(TypeGuard, TypeGuard) ||
ORDER(TypeGuard, ClassGuard) || ORDER(TypeGuard, ClassDefault) ||
ORDER(ClassGuard, EndSelect) || ORDER(ClassGuard, TypeGuard) ||
ORDER(ClassGuard, ClassGuard) || ORDER(ClassGuard, ClassDefault) ||
ORDER(ClassDefault, EndSelect) || ORDER(ClassDefault, TypeGuard) ||
ORDER(ClassDefault, ClassGuard) || ORDER(ClassDefault, ClassDefault) ||
// STRUCTURE (PGI)
ORDER(Structure, EndStructure)) {
// That looks good
} else {
// Todo: print location of both statement
FAIL("Found " << StmtClassName(next.sclass) << " after "
<< StmtClassName(prev.sclass));
}
#undef ORDER
}
// Provide the number of statements in the map.
// Reminder: the proper indices are 1..Size()
int StatementMap::Size() const { return entries_.size(); }
//
// Specialize the StmtClass of an existing statement.
//
//
void StatementMap::Specialize( Index index, StmtClass oldc, StmtClass newc) {
Entry &self = at(index);
if (self.sclass != oldc) {
INTERNAL_ERROR;
}
if (self.group != StmtClassToGroup(oldc)) {
INTERNAL_ERROR;
}
if (self.group != StmtClassToGroup(newc)) {
INTERNAL_ERROR;
}
// Only a few specializations are allowed
if ((oldc == StmtClass::Case && newc == StmtClass::CaseDefault) ||
(oldc == StmtClass::TypeGuard && newc == StmtClass::ClassDefault) ||
(oldc == StmtClass::TypeGuard && newc == StmtClass::ClassGuard) ||
(oldc == StmtClass::SelectRankCase && newc == StmtClass::SelectRankStar) ||
(oldc == StmtClass::SelectRankCase && newc == StmtClass::SelectRankDefault) ||
(oldc == StmtClass::Access && newc == StmtClass::PublicAccess) ||
(oldc == StmtClass::Access && newc == StmtClass::PrivateAccess) ||
(oldc == StmtClass::LabelDo && newc == StmtClass::LabelDoWhile)||
(oldc == StmtClass::LabelDo && newc == StmtClass::LabelDoConcurrent) ||
(oldc == StmtClass::NonLabelDo && newc == StmtClass::NonLabelDoWhile) ||
(oldc == StmtClass::NonLabelDo && newc == StmtClass::NonLabelDoConcurrent)) {
self.sclass = newc;
// Paranoid mode! More consistency checks
AssertNextInConstruct(self.prev_in_construct);
AssertNextInConstruct(index);
} else {
INTERNAL_ERROR;
}
}
void StatementMap::DumpFlat(std::ostream &out, bool verbose) const {
for (Index i = First() ; i <= Last(); i++) {
out << std::setw(4) << std::right << i << ": ";
DumpStmt(out, i, verbose);
}
}
void StatementMap::DumpBody(
std::ostream &out, Index index, bool rec, int level, bool verbose) const {
for (Index i = FirstInBody(index); i != None; i = Next(i)) {
Dump(out, i, rec, level, verbose);
}
}
void StatementMap::DumpStmt(
std::ostream &out, Index index, bool verbose) const {
const auto &stmt = at(index);
switch (stmt.group) {
case StmtGroup::Single: out << "| "; break;
case StmtGroup::Start: out << "> "; break;
case StmtGroup::Part: out << "+ "; break;
case StmtGroup::End: out << "< "; break;
}
out << StmtClassName(stmt.sclass);
if (verbose) {
// Enable this while debugging the Map
if (stmt.parent) out << " parent=" << stmt.parent;
if (stmt.prev_in_body) out << " prev_in_body=" << stmt.prev_in_body;
if (stmt.next_in_body) out << " next_in_body=" << stmt.next_in_body;
if (stmt.prev_in_construct)
out << " prev_in_construct=" << stmt.prev_in_construct;
if (stmt.next_in_construct)
out << " next_in_construct=" << stmt.next_in_construct;
}
out << "\n";
}
void StatementMap::Dump(
std::ostream &out, Index index, bool rec, int level, bool verbose) const {
while (index != None) {
const auto &stmt = at(index);
out << std::setw(4) << std::right << index << ": ";
for (int i = 0; i < level; i++)
out << "| ";
DumpStmt(out, index, verbose);
if (rec &&
(stmt.group == StmtGroup::Start || stmt.group == StmtGroup::Part)) {
DumpBody(out, index, rec, level + 1, verbose);
index = NextInConstruct(index);
} else {
index = None;
}
}
}
void StatementMap::CheckIndex(Index index) const {
assert(index > 0 && index < int(entries_.size()));
}
StatementMap::Index StatementMap::Next(Index index) const {
auto &e = at(index);
if (e.group == StmtGroup::Single) {
return e.next_in_body;
} else if (e.group == StmtGroup::Start) {
return e.next_in_body;
} else {
INTERNAL_ERROR;
return None;
}
}
StatementMap::Index StatementMap::Prev(Index index) const {
auto &e = at(index);
if (e.group == StmtGroup::Single) {
return e.prev_in_body;
} else if (e.group == StmtGroup::Start) {
return e.prev_in_body;
} else {
INTERNAL_ERROR;
return None;
}
}
bool StatementMap::EmptyBody(Index index) const {
auto &e = at(index);
if (e.group == StmtGroup::Start) {
if (e.next_in_construct == None) {
// The body construction is not finished yet
INTERNAL_ERROR;
return None;
} else {
return (e.next_in_construct == index + 1);
}
} else if (e.group == StmtGroup::Part) {
if (e.next_in_construct == None) {
// The body construction is not finished yet
INTERNAL_ERROR;
return None;
}
return (e.next_in_construct == index + 1);
} else {
INTERNAL_ERROR;
return None;
}
}
StatementMap::Index StatementMap::FirstInBody(StatementMap::Index index) const {
auto &e = at(index);
if (e.group == StmtGroup::Start) {
if (e.next_in_construct == index + 1)
return None; // an empty body
else
return index + 1;
} else if (e.group == StmtGroup::Part) {
if (e.next_in_construct == index + 1)
return None; // an empty body
else
return index + 1;
} else {
INTERNAL_ERROR;
return None;
}
}
StatementMap::Index StatementMap::LastInBody(StatementMap::Index index) const {
CheckIndex(index);
auto &stmt = at(index);
if (stmt.group == StmtGroup::Start) {
if (stmt.next_in_construct == index + 1) {
return None; // empty body
} else if (stmt.next_in_construct == None) {
// We are probably querying an incomplete construct
INTERNAL_ERROR;
return None;
} else {
return LastInPreviousBody(stmt.next_in_construct);
}
} else if (stmt.group == StmtGroup::Part) {
if (stmt.next_in_construct == index + 1) {
return None; // empty body
} else if (stmt.next_in_construct == None) {
// We are probably querying an incomplete construct
INTERNAL_ERROR;
return None;
} else {
return LastInPreviousBody(stmt.next_in_construct);
}
} else {
INTERNAL_ERROR;
return None;
}
}
// Functionnally equivalent to LastInBody(PreviousPartOfConstruct(index))
StatementMap::Index StatementMap::LastInPreviousBody(
StatementMap::Index index) const {
auto &stmt = at(index);
if (stmt.group == StmtGroup::Part || stmt.group == StmtGroup::End) {
auto &prev = at(index - 1);
if (prev.group == StmtGroup::Single) {
return index - 1;
} else if (prev.group == StmtGroup::End) {
return StartOfConstruct(index - 1);
} else if (prev.group == StmtGroup::Start) {
return None;
} else if (prev.group == StmtGroup::Part) {
return None;
} else {
INTERNAL_ERROR;
return None;
}
} else {
INTERNAL_ERROR;
return None;
}
}
StatementMap::Index StatementMap::FindPrevInConstruct(
StatementMap::Index index, StmtClass sclass) const {
while (true) {
index = PrevInConstruct(index);
if (index == None) return None;
if (at(index).sclass == sclass) return index;
}
}
StatementMap::Index StatementMap::FindNextInConstruct(
StatementMap::Index index, StmtClass sclass) const {
while (true) {
index = NextInConstruct(index);
if (index == None) return None;
if (at(index).sclass == sclass) return index;
}
}
StatementMap::Index StatementMap::PrevInConstruct(
StatementMap::Index index) const {
auto &stmt = at(index);
if (stmt.group == StmtGroup::Start) {
return None;
} else if (stmt.group == StmtGroup::Part) {
return stmt.prev_in_construct;
} else if (stmt.group == StmtGroup::End) {
return stmt.prev_in_construct;
} else {
INTERNAL_ERROR;
return None;
}
}
StatementMap::Index StatementMap::NextInConstruct(
StatementMap::Index index) const {
auto &stmt = at(index);
if (stmt.group == StmtGroup::Start) {
return stmt.next_in_construct;
} else if (stmt.group == StmtGroup::Part) {
return stmt.next_in_construct;
} else if (stmt.group == StmtGroup::End) {
return None;
} else {
INTERNAL_ERROR;
return None;
}
}
// Find the Start component of a construct specified by
// any of its component.
StatementMap::Index StatementMap::StartOfConstruct(
StatementMap::Index index) const {
auto &stmt = at(index);
if (stmt.group == StmtGroup::Start) {
return index;
} else if (stmt.group == StmtGroup::Part || stmt.group == StmtGroup::End) {
return StartOfConstruct(stmt.prev_in_construct);
} else {
INTERNAL_ERROR;
return None;
}
}
// Find the End component of a construct specified by
// any of its component.
StatementMap::Index StatementMap::EndOfConstruct(
StatementMap::Index index) const {
while (true) {
auto &stmt = at(index);
if (stmt.group == StmtGroup::Start || stmt.group == StmtGroup::Part) {
index = stmt.next_in_construct;
} else if (stmt.group == StmtGroup::End) {
return index;
} else {
INTERNAL_ERROR;
return None;
}
}
}
// Find the last component of a construct.
//
// Unlike EndOfConstruct(), this visitor does not require the presence of
// any End construct and so can be safely used during the creation of
// the statement map
//
StatementMap::Index StatementMap::LastOfConstruct(
StatementMap::Index index) const {
while (true) {
auto &stmt = at(index);
if (stmt.group == StmtGroup::Start || stmt.group == StmtGroup::Part) {
if (stmt.next_in_construct == None)
return index; // end of an incomplete construct
index = stmt.next_in_construct;
} else if (stmt.group == StmtGroup::End) {
return index; // end of an complete construct
} else {
INTERNAL_ERROR;
return None;
}
}
}
// Visit all the statements that compose a construct.
//
// 'stmt' shall be a construct component (so in group Start, Part or End)
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)) {
if (!action(at)) break;
}
}
// 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 StatementMap::VisitConstructRev(
Index stmt, std::function<bool(Index)> action) const {
// Reminder: Using LastOfConstruct instead of EndOfConstruct
// because the visitor shall usable while constructing
// the statement map.
std::cerr << "#" << stmt;
Index start = LastOfConstruct(stmt);
std::cerr << "%" << start;
for (Index at = start; at != None; at = PrevInConstruct(at)) {
std::cerr << "@" << at;
if (!action(at)) break;
}
}
// // Set the label required to close a LabelDo
// void StatementMap::SetLabelDoLabel(Index do_stmt, int label) {
// assert(at(do_stmt).sclass == StmtClass::LabelDo);
// assert(label != 0);
// label_do_map_[do_stmt] = label;
// }
// int StatementMap::GetLabelDoLabel(Index do_stmt) const {
// auto it = label_do_map_.find(do_stmt);
// if (it != label_do_map_.end()) {
// return it->second;
// }
// // In theory that should never happen
// INTERNAL_ERROR;
// return 0;
// }
} // namespace Fortran::semantics

View File

@ -1,242 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_SEMANTICS_STATEMENTMAP_H_
#define FORTRAN_SEMANTICS_STATEMENTMAP_H_
#include "Stmt.h"
#include <functional>
#include <map>
#include <vector>
namespace Fortran::semantics {
//
// A StatementMap describes the relations between statements in a program unit
// and also hold information that are common to each statement (label, provenance,
// ...)
//
// In the parse-tree each struct representing a statement (see Stmt.def)
// is associated with an index in the statement map.
//
// Valid indices are 1 to Size().
//
// The index None=0 represents no statement.
//
// In the map, each statement belong to one of 4 groups Single,
// Start, Part, and End (see Stmt.def)
//
// Also, the statements are stored in 2 dimensions:
// - the body dimension for Single and Start statements.
// - the construct dimension for Start, Part and End statements
//
// In the construct dimension, a sequence of statement is always
// composed of one Start, any number of Part and one End.
//
// Only Start and Part statements can have a body and they are
// the 'parent' of each statement in that body.
//
// The mapping of Fortran statements to the 4 groups Single, Start,
// Part, and End should be obvious.
//
// For instance, consider the following piece of code
//
// DO i=1,n
// PRINT *, "in DO body"
// IF (i==1) THEN
// PRINT *, "in IF body"
// CYCLE
// ELSE IF (i==2)
// PRINT *, "in ELSE IF body"
// ELSE
// PRINT *, "in ELSE body"
// ENDIF
// PRINT *, "also in DO body"
// ENDDO
//
// The statement map Dump() for that piece of code shall look like that
//
// 10: > NonLabelDo
// 11: | | Print
// 12: | > IfThen
// 13: | | | Print
// 14: | | | Cycle
// 15: | + ElseIf
// 16: | | | Print
// 17: | + Else
// 18: | | | Print
// 19: | < EndIf
// 20: | | Print
// 21: < EndDo
//
// The '>', '+' and '>' are used to mark the Start, Part and End statements.
//
// In that dump, we see that:
// - 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,
// the construct
//
// IF (cond) CYCLE
//
// could dump as follow:
//
// 30: > If
// 31: | | Cycle
// 32: < DummyEndIf
//
//
class StatementMap {
public:
typedef int Index; // should become an opaque type.
static constexpr Index None = 0;
private:
struct Entry {
StmtClass sclass;
StmtGroup group;
int label; // The label associated to the statement (1..99999) or 0
// Relations to other statements.
Index parent;
Index prev_in_body;
Index next_in_body;
Index prev_in_construct;
Index next_in_construct;
};
std::vector<Entry> entries_;
std::map<Index, int> label_do_map_;
Entry &at(Index index);
const Entry &at(Index index) const;
public:
// Add a statement to the map.
Index Add(StmtClass sclass, int label);
// Set the label required to close a LabelDo
// void SetLabelDoLabel(Index do_stmt, int label);
// int GetLabelDoLabel(Index do_stmt) const;
//
// 'prev_index' shall be a Start or Part statement.
//
// Assert that the next statement in the construct is of an expected class.
//
//
void AssertNextInConstruct(Index prev_index) const;
// Provide the number of statements in the map.
// Reminder: the proper indices are 1..Size()
int Size() const;
// The index of the first statement added to the map
Index First() const { return 1; }
// The index of the last statement added to the map
Index Last() const { return Size(); }
//
// Specialize the StmtClass of an existing statement.
//
//
void Specialize(Index index, StmtClass oldclass, StmtClass newclass);
StmtClass GetClass(Index index) const { return at(index).sclass; }
StmtGroup GetGroup(Index index) const { return at(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.
int GetLabel(Index index) const { return at(index).label; }
Index GetParent(Index index) const { return at(index).parent; }
// Dump all the statements in the map in sequence so without
// relying on the statement 'hierarchy'. This is only useful
// to debug the statement map 'hierarchy'.
void DumpFlat(std::ostream &out, bool verbose = true) const;
void DumpBody(std::ostream &out, Index index, bool rec = true, int level = 0,
bool verbose = false) const;
void DumpStmt(std::ostream &out, Index index, bool verbose = false) const;
void Dump(std::ostream &out, Index index, bool rec = true, int level = 0,
bool verbose = false) const;
void CheckIndex(Index index) const;
Index Next(Index index) const;
Index Prev(Index index) const;
bool EmptyBody(Index index) const;
Index FirstInBody(Index index) const;
Index LastInBody(Index index) const;
// Functionally equivalent to LastInBody(PreviousPartOfConstruct(index))
Index LastInPreviousBody(Index index) const;
Index FindPrevInConstruct(Index index, StmtClass sclass) const;
Index FindNextInConstruct(Index index, StmtClass sclass) const;
Index PrevInConstruct(Index index) const;
Index NextInConstruct(Index index) const;
// Find the Start component of a construct specified by
// any of its component.
Index StartOfConstruct(Index index) const;
// Find the End component of a construct specified by
// any of its component.
Index EndOfConstruct(Index index) const;
// Find the last component of a construct.
//
// Unlike EndOfConstruct(), this visitor does not require the presence of
// any End construct and so can be safely used during the creation of
// the statement map
//
Index LastOfConstruct(Index index) const;
// Visit all the statements that compose a construct.
//
// 'stmt' shall be a construct component (so in group Start, Part or End)
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 VisitConstructRev(Index stmt, std::function<bool(Index)> action) const;
};
} // namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_STATEMENTMAP_H_

View File

@ -1,191 +0,0 @@
//
// DECLARE_PARSER_STMT(Name,Class,Group,Text)
// - Name is the name in StmtClass enum (typically, that is 'Class' without the 'Stmt' suffix.
// - Class is a parser-tree class name.
// - Group is any StmtGroup value so one of Single, Start, Part, End.
// - Text is a human readable text describing the statement and usable in
// a formated error message such as "error in %s statement"
//
// For a given Class, there should be exactly one DECLARE_PARSER_STMT
//
// DECLARE_PARSER_STMT_ALT(Name,Class,Group,Text)
// Provide an alternative Name for a given Class.
//
// DECLARE_DUMMY_STMT(Name,Group,Text)
// Provide a Name in StmtClass enum that does not correspond to any existing Class.
//
//
// The default implementation for those macros is to call DECLARE_STMT(Name,Class,Group,Text)
//
//
#ifndef DECLARE_PARSER_STMT
#define DECLARE_PARSER_STMT(Name,Class,Group,Text) DECLARE_STMT(Name,Class,Group,Text)
#endif
#ifndef DECLARE_PARSER_STMT_ALT
#define DECLARE_PARSER_STMT_ALT(Name,Class,Group,Text) DECLARE_STMT(Name,Class,Group,Text)
#endif
#ifndef DECLARE_DUMMY_STMT
#define DECLARE_DUMMY_STMT(Name,Group,Text) DECLARE_STMT(Name,void,Group,Text)
#endif
// DECLARE_FIRST_STMT is a special alias for the first occurence of DECLARE_PARSER_STMT.
#ifndef DECLARE_FIRST_STMT
#define DECLARE_FIRST_STMT(Name,Class,Group,Text) DECLARE_PARSER_STMT(Name,Class,Group,Text)
#endif
DECLARE_FIRST_STMT( Access , AccessStmt , Single , "PUBLIC or PRIVATE" )
DECLARE_PARSER_STMT(Allocatable , AllocatableStmt , Single , "ALLOCATABLE" )
DECLARE_PARSER_STMT(Allocate , AllocateStmt , Single , "ALLOCATE" )
DECLARE_PARSER_STMT(ArithmeticIf , ArithmeticIfStmt , Single , "arithmetic IF" )
DECLARE_PARSER_STMT(Assign , AssignStmt , Single , "ASSIGN TO" )
DECLARE_PARSER_STMT(AssignedGoto , AssignedGotoStmt , Single , "assigned GOTO" )
DECLARE_PARSER_STMT(Assignment , AssignmentStmt , Single , "assignment" )
DECLARE_PARSER_STMT(Associate , AssociateStmt , Start , "ASSOCIATE" )
DECLARE_PARSER_STMT(Asynchronous , AsynchronousStmt , Single , "ASYNCHRONOUS" )
DECLARE_PARSER_STMT(Backspace , BackspaceStmt , Single , "BACKSPACE" )
DECLARE_PARSER_STMT(BasedPointer , BasedPointerStmt , Single , "Based Pointer" )
DECLARE_PARSER_STMT(Bind , BindStmt , Single , "BIND" )
DECLARE_PARSER_STMT(Block , BlockStmt , Start , "BLOCK" )
DECLARE_PARSER_STMT(Call , CallStmt , Single , "CALL" )
DECLARE_PARSER_STMT(Case , CaseStmt , Part , "CASE" )
DECLARE_PARSER_STMT(ChangeTeam , ChangeTeamStmt , Start , "CHANGE TEAM" )
DECLARE_PARSER_STMT(Close , CloseStmt , Single , "CLOSE" )
DECLARE_PARSER_STMT(Codimension , CodimensionStmt , Single , "CODIMENSION" )
DECLARE_PARSER_STMT(Common , CommonStmt , Single , "COMMON" )
DECLARE_PARSER_STMT(ComputedGoto , ComputedGotoStmt , Single , "computed GOTO" )
DECLARE_PARSER_STMT(ComponentDef , ComponentDefStmt , Single , "component declaration" )
DECLARE_PARSER_STMT(Contains , ContainsStmt , Part , "CONTAINS" )
DECLARE_PARSER_STMT(Contiguous , ContiguousStmt , Single , "CONTIGUOUS" )
DECLARE_PARSER_STMT(Continue , ContinueStmt , Single , "CONTINUE" )
DECLARE_PARSER_STMT(Critical , CriticalStmt , Start , "CRITICAL" )
DECLARE_PARSER_STMT(Cycle , CycleStmt , Single , "CYCLE" )
DECLARE_PARSER_STMT(Data , DataStmt , Single , "DATA" )
DECLARE_PARSER_STMT(Deallocate , DeallocateStmt , Single , "DEALLOCATE" )
DECLARE_PARSER_STMT(DerivedType , DerivedTypeStmt , Start , "TYPE declaration" )
DECLARE_PARSER_STMT(Dimension , DimensionStmt , Single , "DIMENSION" )
DECLARE_PARSER_STMT(Else , ElseStmt , Part , "ELSE" )
DECLARE_PARSER_STMT(ElseIf , ElseIfStmt , Part , "ELSE IF" )
DECLARE_PARSER_STMT(ElseWhere , ElseWhereStmt , Part , "ELSE WHERE" )
DECLARE_PARSER_STMT(EndAssociate , EndAssociateStmt , End , "END ASSOCIATE" )
DECLARE_PARSER_STMT(EndBlock , EndBlockStmt , End , "END BLOCK" )
DECLARE_PARSER_STMT(EndChangeTeam , EndChangeTeamStmt , End , "END TEAM" )
DECLARE_PARSER_STMT(EndCritical , EndCriticalStmt , End , "END CRITICAL" )
DECLARE_PARSER_STMT(EndDo , EndDoStmt , End , "END DO" )
DECLARE_PARSER_STMT(EndEnum , EndEnumStmt , End , "END ENUM" )
DECLARE_PARSER_STMT(EndForall , EndForallStmt , End , "END FORALL" )
DECLARE_PARSER_STMT(EndFunction , EndFunctionStmt , End , "END FUNCTION" )
DECLARE_PARSER_STMT(EndIf , EndIfStmt , End , "END IF" )
DECLARE_PARSER_STMT(EndInterface , EndInterfaceStmt , End , "END INTERFACE" )
DECLARE_PARSER_STMT(EndModule , EndModuleStmt , End , "END MODULE" )
DECLARE_PARSER_STMT(EndProgram , EndProgramStmt , End , "END PROGRAM" )
DECLARE_PARSER_STMT(EndSelect , EndSelectStmt , End , "END SELECT" )
DECLARE_PARSER_STMT(EndStructure , EndStructureStmt , End , "END STRUCTURE?" )
DECLARE_PARSER_STMT(EndSubroutine , EndSubroutineStmt , End , "END SUBROUTINE" )
DECLARE_PARSER_STMT(EndType , EndTypeStmt , End , "END TYPE" )
DECLARE_PARSER_STMT(EndWhere , EndWhereStmt , End , "END WHERE" )
DECLARE_PARSER_STMT(Endfile , EndfileStmt , Single , "ENDFILE" )
DECLARE_PARSER_STMT(Entry , EntryStmt , Single , "ENTRY" )
DECLARE_PARSER_STMT(EnumDef , EnumDefStmt , Start , "ENUM" )
DECLARE_PARSER_STMT(EnumeratorDef , EnumeratorDefStmt , Single , "ENUMERATOR" )
DECLARE_PARSER_STMT(Equivalence , EquivalenceStmt , Single , "EQUIVALENCE" )
DECLARE_PARSER_STMT(EventPost , EventPostStmt , Single , "EVENT POST" )
DECLARE_PARSER_STMT(EventWait , EventWaitStmt , Single , "EVENT WAIT" )
DECLARE_PARSER_STMT(Exit , ExitStmt , Single , "EXIT" )
DECLARE_PARSER_STMT(External , ExternalStmt , Single , "EXTERNAL" )
DECLARE_PARSER_STMT(FailImage , FailImageStmt , Single , "FAIL IMAGE" )
DECLARE_PARSER_STMT(FinalProcedure , FinalProcedureStmt , Single , "FINAL PROCEDURE" )
DECLARE_PARSER_STMT(Flush , FlushStmt , Single , "FLUSH" )
DECLARE_PARSER_STMT(Forall , ForallStmt , Start , "FORALL" )
DECLARE_PARSER_STMT(ForallAssignment , ForallAssignmentStmt , Single , "FORALL Assignment" )
DECLARE_PARSER_STMT(ForallConstruct , ForallConstructStmt , Start , "FORALL Construct" )
DECLARE_PARSER_STMT(FormTeam , FormTeamStmt , Single , "FORM TEAM" )
DECLARE_PARSER_STMT(Format , FormatStmt , Single , "FORMAT" )
DECLARE_PARSER_STMT(Function , FunctionStmt , Start , "FUNCTION" )
DECLARE_PARSER_STMT(Generic , GenericStmt , Single , "GENERIC" )
DECLARE_PARSER_STMT(Goto , GotoStmt , Single , "GOTO" )
DECLARE_PARSER_STMT(If , IfStmt , Start , "IF" )
DECLARE_PARSER_STMT(IfThen , IfThenStmt , Start , "IF THEN" )
DECLARE_PARSER_STMT(Implicit , ImplicitStmt , Single , "IMPLICIT" )
DECLARE_PARSER_STMT(Import , ImportStmt , Single , "IMPORT" )
DECLARE_PARSER_STMT(Inquire , InquireStmt , Single , "INQUIRE" )
DECLARE_PARSER_STMT(Intent , IntentStmt , Single , "INTENT" )
DECLARE_PARSER_STMT(Interface , InterfaceStmt , Start , "INTERFACE" )
DECLARE_PARSER_STMT(Intrinsic , IntrinsicStmt , Single , "INTRINSIC" )
DECLARE_PARSER_STMT(LabelDo , LabelDoStmtStmt , Start , "label-DO " )
DECLARE_PARSER_STMT(Lock , LockStmt , Single , "LOCK" )
DECLARE_PARSER_STMT(MaskedElsewhere , MaskedElsewhereStmt , Part , "masked ELSE WHERE" )
DECLARE_PARSER_STMT(Module , ModuleStmt , Start , "MODULE" )
DECLARE_PARSER_STMT(Namelist , NamelistStmt , Single , "NAMELIST" )
DECLARE_PARSER_STMT(NonLabelDo , NonLabelDoStmtStmt , Start , "DO" )
DECLARE_PARSER_STMT(Nullify , NullifyStmt , Single , "NULLIFY" )
DECLARE_PARSER_STMT(Open , OpenStmt , Single , "OPEN" )
DECLARE_PARSER_STMT(Optional , OptionalStmt , Single , "OPTIONAL" )
DECLARE_PARSER_STMT(Parameter , ParameterStmt , Single , "PARAMETER" )
DECLARE_PARSER_STMT(Pause , PauseStmt , Single , "PAUSE" )
DECLARE_PARSER_STMT(Pointer , PointerStmt , Single , "POINTER" )
DECLARE_PARSER_STMT(PointerAssignment , PointerAssignmentStmt , Single , "pointer assignment" )
DECLARE_PARSER_STMT(Print , PrintStmt , Single , "PRINT" )
// PrivateStmt is only used in TYPE definitions
DECLARE_PARSER_STMT(Private , PrivateStmt , Single , "PRIVATE" )
DECLARE_PARSER_STMT(ProcedureDeclaration , ProcedureDeclarationStmt , Single , "PROCEDURE" )
DECLARE_PARSER_STMT(Program , ProgramStmt , Start , "PROGRAM" )
DECLARE_PARSER_STMT(Protected , ProtectedStmt , Single , "PROTECTED" )
DECLARE_PARSER_STMT(Read , ReadStmt , Single , "READ" )
DECLARE_PARSER_STMT(Redimension , RedimensionStmt , Single , "REDIMENSION" )
DECLARE_PARSER_STMT(Return , ReturnStmt , Single , "RETURN" )
DECLARE_PARSER_STMT(Rewind , RewindStmt , Single , "REWIND" )
DECLARE_PARSER_STMT(Save , SaveStmt , Single , "SAVE" )
DECLARE_PARSER_STMT(SelectCase , SelectCaseStmt , Start , "SELECT CASE" )
DECLARE_PARSER_STMT(SelectRank , SelectRankStmt , Start , "SELECT RANK" )
DECLARE_PARSER_STMT(SelectRankCase , SelectRankCaseStmt , Part , "RANK" )
DECLARE_PARSER_STMT(SelectType , SelectTypeStmt , Start , "SELECT TYPE" )
DECLARE_PARSER_STMT(Subroutine , SubroutineStmt , Start , "SUBROUTINE" )
DECLARE_PARSER_STMT(StmtFunction , StmtFunctionStmt , Single , "statement-function" )
DECLARE_PARSER_STMT(Stop , StopStmt , Single , "STOP" )
DECLARE_PARSER_STMT(Structure , StructureStmt , Start , "STRUCTURE" )
DECLARE_PARSER_STMT(SyncAll , SyncAllStmt , Single , "SYNC ALL" )
DECLARE_PARSER_STMT(SyncImages , SyncImagesStmt , Single , "SYNC IMAGES" )
DECLARE_PARSER_STMT(SyncMemory , SyncMemoryStmt , Single , "SYNC MEMORY" )
DECLARE_PARSER_STMT(SyncTeam , SyncTeamStmt , Single , "SYNC TEAM" )
DECLARE_PARSER_STMT(Target , TargetStmt , Single , "TARGET" )
DECLARE_PARSER_STMT(TypeBoundGeneric , TypeBoundGenericStmt , Single , "type bound GENERIC" )
DECLARE_PARSER_STMT(TypeBoundProcedure , TypeBoundProcedureStmt , Single , "type bound PROCEDURE" )
DECLARE_PARSER_STMT(TypeDeclaration , TypeDeclarationStmt , Single , "declaration" )
DECLARE_PARSER_STMT(TypeGuard , TypeGuardStmt , Part , "TYPE IS" ) // See
DECLARE_PARSER_STMT(Unlock , UnlockStmt , Single , "UNLOCK" )
DECLARE_PARSER_STMT(Use , UseStmt , Single , "USE" )
DECLARE_PARSER_STMT(Value , ValueStmt , Single , "VALUE" )
DECLARE_PARSER_STMT(Volatile , VolatileStmt , Single , "VOLATILE" )
DECLARE_PARSER_STMT(Wait , WaitStmt , Single , "WAIT" )
DECLARE_PARSER_STMT(Where , WhereStmt , Start , "WHERE" )
DECLARE_PARSER_STMT(WhereConstruct , WhereConstructStmt , Start , "WHERE construct" )
DECLARE_PARSER_STMT(Write , WriteStmt , Single , "WRITE" )
DECLARE_PARSER_STMT_ALT(CaseDefault , CaseStmt , Part , "CASE" )
DECLARE_PARSER_STMT_ALT(ClassDefault , TypeGuardStmt , Part , "CLASS DEFAULT" )
DECLARE_PARSER_STMT_ALT(ClassGuard , TypeGuardStmt , Part , "CLASS IS" )
DECLARE_PARSER_STMT_ALT(SelectRankStar , SelectRankCaseStmt , Part , "RANK(*)" )
DECLARE_PARSER_STMT_ALT(SelectRankDefault, SelectRankCaseStmt , Part , "RANK DEFAULT" )
DECLARE_PARSER_STMT_ALT(PublicAccess , AccessStmt , Single , "default PUBLIC" )
DECLARE_PARSER_STMT_ALT(PrivateAccess , AccessStmt , Single , "default PRIVATE" )
DECLARE_PARSER_STMT_ALT(LabelDoWhile , LabelDoStmt , Start , "label-DO WHILE" )
DECLARE_PARSER_STMT_ALT(LabelDoConcurrent, LabelDoStmt , Start , "label-DO CONCURRENT" )
DECLARE_PARSER_STMT_ALT(NonLabelDoWhile , NonLabelDoStmt , Start , "DO " )
DECLARE_PARSER_STMT_ALT(NonLabelDoConcurrent, NonLabelDoConcurrent , Start , "DO CONCURRENT" )
// DummyEnd is used to provide an end to constructs that lack an explicit end statement after their body.
DECLARE_DUMMY_STMT(DummyEndIf , End , "<DummyEndIf>" )
DECLARE_DUMMY_STMT(DummyEndForall , End , "<DummyEndForall>" )
DECLARE_DUMMY_STMT(DummyEndWhere , End , "<DummyEndWhere>" )
DECLARE_DUMMY_STMT(DummyEndDo , End , "<DummyEndDo>" )
#undef DECLARE_PARSER_STMT
#undef DECLARE_PARSER_STMT_ALT
#undef DECLARE_DUMMY_STMT
#undef DECLARE_FIRST_STMT
#undef DECLARE_STMT

View File

@ -1,69 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_SEMANTICS_STMT_H_
#define FORTRAN_SEMANTICS_STMT_H_
#include "../parser/parse-tree.h"
#include <variant>
namespace Fortran::semantics {
enum class StmtClass {
#define DECLARE_STMT(Name, Class, Group, Text) Name,
#include "Stmt.def"
};
enum class StmtGroup {
Single, // A standalone statement
Start, // A statement that starts a construct
Part, // A statement that marks a part of a construct
End // A statement that ends a construct
};
constexpr StmtGroup StmtClassToGroup(StmtClass sc) {
switch (sc) {
#define DECLARE_STMT(Name, Class, Group, Text) \
case StmtClass::Name: return StmtGroup::Group;
#include "Stmt.def"
}
// Hummm... should not happen but cannot add error or assert
// in constexpr expression.
return StmtGroup::Single;
}
constexpr const char *StmtClassName(StmtClass sc) {
switch (sc) {
#define DECLARE_STMT(Name, Class, Group, Text) \
case StmtClass::Name: return #Name;
#include "Stmt.def"
}
return "????";
}
constexpr const char *StmtClassText(StmtClass sc) {
switch (sc) {
#define DECLARE_STMT(Name, Class, Group, Text) \
case StmtClass::Name: return Text;
#include "Stmt.def"
}
return "????";
}
} // end of namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_STMT_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "../../lib/parser/parsing.h"
#include "../../lib/semantics/attr.h"
#include "../../lib/semantics/type.h"
#include <cstdlib>
#include <iostream>
#include <list>
#include <optional>
#include <sstream>
#include <stddef.h>
#include <string>
using namespace Fortran;
using namespace parser;
extern void DoSemanticAnalysis(const CookedSource &, const Program &);
//static void visitProgramUnit(const ProgramUnit &unit);
int main(int argc, char *const argv[]) {
if (argc != 2) {
std::cerr << "Expected 1 source file, got " << (argc - 1) << "\n";
return EXIT_FAILURE;
}
std::string path{argv[1]};
Parsing parsing;
if (parsing.ForTesting(path, std::cerr)) {
DoSemanticAnalysis(parsing.cooked(), *parsing.parseTree());
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}