forked from OSchip/llvm-project
[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:
parent
a9ed8e7eee
commit
209afdcea2
|
@ -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
|
|
@ -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_
|
|
@ -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_
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue