// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // ParseNode.h -- // // Author : Rodolfo G. Esteves // Created On : Sat May 16 13:28:16 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Wed Aug 10 21:51:49 2016 // Update Count : 437 // #ifndef PARSENODE_H #define PARSENODE_H #include #include #include #include #include "Common/utility.h" #include "Parser/LinkageSpec.h" #include "SynTree/Type.h" #include "SynTree/Expression.h" #include "SynTree/Statement.h" //#include "SynTree/Declaration.h" #include "Common/UniqueName.h" #include "SynTree/Label.h" class StatementNode; class CompoundStmtNode; class DeclarationNode; class ExpressionNode; class InitializerNode; // Builder class ParseNode { public: ParseNode(); ParseNode( const std::string * ); ParseNode( const std::string & ); // for copy constructing subclasses virtual ~ParseNode(); ParseNode *get_link() const { return next; } ParseNode *get_last(); ParseNode *set_link( ParseNode * ); void set_next( ParseNode *newlink ) { next = newlink; } virtual ParseNode *clone() const { return 0; }; const std::string &get_name() const { return name; } void set_name( const std::string &newValue ) { name = newValue; } virtual void print( std::ostream &os, int indent = 0 ) const; virtual void printList( std::ostream &os, int indent = 0 ) const; ParseNode &operator,( ParseNode & ); protected: std::string name; static int indent_by; ParseNode *next; }; ParseNode *mkList( ParseNode & ); //############################################################################## class InitializerNode : public ParseNode { public: InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode *des = 0 ); InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode *des = 0 ); ~InitializerNode(); ExpressionNode *get_expression() const { return expr; } InitializerNode *set_designators( ExpressionNode *des ) { designator = des; return this; } ExpressionNode *get_designators() const { return designator; } InitializerNode *set_maybeConstructed( bool value ) { maybeConstructed = value; return this; } bool get_maybeConstructed() const { return maybeConstructed; } InitializerNode *next_init() const { return kids; } void print( std::ostream &os, int indent = 0 ) const; void printOneLine( std::ostream & ) const; virtual Initializer *build() const; private: ExpressionNode *expr; bool aggregate; ExpressionNode *designator; // may be list InitializerNode *kids; bool maybeConstructed; }; //############################################################################## class ExpressionNode : public ParseNode { public: ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {} ExpressionNode( Expression * expr, const std::string *name ) : ParseNode( name ), expr( expr ) {} ExpressionNode( const ExpressionNode &other ); virtual ~ExpressionNode() {} virtual ExpressionNode *clone() const { return 0; } bool get_extension() const { return extension; } ExpressionNode *set_extension( bool exten ) { extension = exten; return this; } virtual void print( std::ostream &os, int indent = 0 ) const {} virtual void printOneLine( std::ostream &os, int indent = 0 ) const {} virtual Expression *build() const { return expr; } private: bool extension = false; Expression *expr; }; template< typename T > struct maybeBuild_t { static inline Expression * doit( const T *orig ) { if ( orig ) { Expression *p = orig->build(); p->set_extension( orig->get_extension() ); return p; } else { return 0; } // if } }; //############################################################################## Expression *build_constantInteger( std::string &str ); Expression *build_constantFloat( std::string &str ); Expression *build_constantChar( std::string &str ); ConstantExpr *build_constantStr( std::string &str ); //############################################################################## NameExpr *build_varref( const std::string *name, bool labelp = false ); //############################################################################## Expression *build_typevalue( DeclarationNode *decl ); //############################################################################## enum class OperKinds { // diadic SizeOf, AlignOf, OffsetOf, Plus, Minus, Mul, Div, Mod, Or, And, BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn, Index, Range, // monadic UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress, Ctor, Dtor, }; Expression *build_cast( DeclarationNode * decl_node, ExpressionNode *expr_node ); Expression *build_fieldSel( ExpressionNode *expr_node, NameExpr *member ); Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ); Expression *build_addressOf( ExpressionNode *expr_node ); Expression *build_sizeOfexpr( ExpressionNode *expr_node ); Expression *build_sizeOftype( DeclarationNode *decl_node ); Expression *build_alignOfexpr( ExpressionNode *expr_node ); Expression *build_alignOftype( DeclarationNode *decl_node ); Expression *build_offsetOf( DeclarationNode *decl_node, NameExpr *member ); Expression *build_and( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ); Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ); Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ); Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ); Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ); Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ); Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ); Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ); Expression *build_attrexpr( NameExpr *var, ExpressionNode * expr_node ); Expression *build_attrtype( NameExpr *var, DeclarationNode * decl_node ); Expression *build_tuple( ExpressionNode * expr_node = 0 ); Expression *build_func( ExpressionNode * function, ExpressionNode * expr_node ); Expression *build_range( ExpressionNode * low, ExpressionNode *high ); //############################################################################## Expression *build_asm( ExpressionNode *inout, ConstantExpr *constraint, ExpressionNode *operand ); //############################################################################## class LabelNode : public ExpressionNode { public: virtual Expression *build() const { return NULL; } virtual LabelNode *clone() const { assert( false ); return new LabelNode( *this ); } virtual void print( std::ostream &os, int indent = 0) const; virtual void printOneLine( std::ostream &os, int indent = 0) const; const std::list< Label > &get_labels() const { return labels; }; void append_label( std::string * label ) { labels.push_back( *label ); delete label; } private: std::list< Label > labels; }; //############################################################################## Expression *build_valexpr( StatementNode *s ); //############################################################################## Expression *build_compoundLiteral( DeclarationNode *decl_node, InitializerNode *kids ); //############################################################################## class TypeData; class DeclarationNode : public ParseNode { public: enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic }; enum StorageClass { Extern, Static, Auto, Register, Inline, Fortran, Noreturn, Threadlocal, NoStorageClass, }; enum BasicType { Char, Int, Float, Double, Void, Bool, Complex, Imaginary }; enum Modifier { Signed, Unsigned, Short, Long }; enum Aggregate { Struct, Union, Trait }; enum TypeClass { Type, Dtype, Ftype }; enum BuiltinType { Valist }; static const char *storageName[]; static const char *qualifierName[]; static const char *basicTypeName[]; static const char *modifierName[]; static const char *aggregateName[]; static const char *typeClassName[]; static const char *builtinTypeName[]; static DeclarationNode *newFunction( std::string *name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle = false ); static DeclarationNode *newQualifier( Qualifier ); static DeclarationNode *newStorageClass( StorageClass ); static DeclarationNode *newBasicType( BasicType ); static DeclarationNode *newModifier( Modifier ); static DeclarationNode *newForall( DeclarationNode *); static DeclarationNode *newFromTypedef( std::string *); static DeclarationNode *newAggregate( Aggregate kind, const std::string *name, ExpressionNode *actuals, DeclarationNode *fields, bool body ); static DeclarationNode *newEnum( std::string *name, DeclarationNode *constants ); static DeclarationNode *newEnumConstant( std::string *name, ExpressionNode *constant ); static DeclarationNode *newName( std::string *); static DeclarationNode *newFromTypeGen( std::string *, ExpressionNode *params ); static DeclarationNode *newTypeParam( TypeClass, std::string *); static DeclarationNode *newTrait( std::string *name, DeclarationNode *params, DeclarationNode *asserts ); static DeclarationNode *newTraitUse( std::string *name, ExpressionNode *params ); static DeclarationNode *newTypeDecl( std::string *name, DeclarationNode *typeParams ); static DeclarationNode *newPointer( DeclarationNode *qualifiers ); static DeclarationNode *newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ); static DeclarationNode *newVarArray( DeclarationNode *qualifiers ); static DeclarationNode *newBitfield( ExpressionNode *size ); static DeclarationNode *newTuple( DeclarationNode *members ); static DeclarationNode *newTypeof( ExpressionNode *expr ); static DeclarationNode *newAttr( std::string *, ExpressionNode *expr ); static DeclarationNode *newAttr( std::string *, DeclarationNode *type ); static DeclarationNode *newBuiltinType( BuiltinType ); DeclarationNode *addQualifiers( DeclarationNode *); DeclarationNode *copyStorageClasses( DeclarationNode *); DeclarationNode *addType( DeclarationNode *); DeclarationNode *addTypedef(); DeclarationNode *addAssertions( DeclarationNode *); DeclarationNode *addName( std::string *); DeclarationNode *addBitfield( ExpressionNode *size ); DeclarationNode *addVarArgs(); DeclarationNode *addFunctionBody( StatementNode *body ); DeclarationNode *addOldDeclList( DeclarationNode *list ); DeclarationNode *addPointer( DeclarationNode *qualifiers ); DeclarationNode *addArray( DeclarationNode *array ); DeclarationNode *addNewPointer( DeclarationNode *pointer ); DeclarationNode *addNewArray( DeclarationNode *array ); DeclarationNode *addParamList( DeclarationNode *list ); DeclarationNode *addIdList( DeclarationNode *list ); // old-style functions DeclarationNode *addInitializer( InitializerNode *init ); DeclarationNode *cloneType( std::string *newName ); DeclarationNode *cloneType( DeclarationNode *existing ); DeclarationNode *cloneType( int ) { return cloneType( ( std::string *)0 ); } DeclarationNode *cloneBaseType( std::string *newName ); DeclarationNode *cloneBaseType( DeclarationNode *newdecl ); DeclarationNode *appendList( DeclarationNode * ); DeclarationNode *clone() const; void print( std::ostream &os, int indent = 0 ) const; void printList( std::ostream &os, int indent = 0 ) const; Declaration *build() const; ::Type *buildType() const; bool get_hasEllipsis() const; const std::string &get_name() const { return name; } LinkageSpec::Type get_linkage() const { return linkage; } DeclarationNode *extractAggregate() const; ExpressionNode *get_enumeratorValue() const { return enumeratorValue; } bool get_extension() const { return extension; } DeclarationNode *set_extension( bool exten ) { extension = exten; return this; } DeclarationNode(); ~DeclarationNode(); private: StorageClass buildStorageClass() const; bool buildFuncSpecifier( StorageClass key ) const; TypeData *type; std::string name; std::list< StorageClass > storageClasses; std::list< std::string > attributes; ExpressionNode *bitfieldWidth; ExpressionNode *enumeratorValue; InitializerNode *initializer; bool hasEllipsis; LinkageSpec::Type linkage; bool extension = false; static UniqueName anonymous; }; // DeclarationNode Type *buildType( TypeData *type ); //############################################################################## class StatementNode : public ParseNode { public: enum Type { Exp, If, Switch, Case, Default, Choose, Fallthru, While, Do, For, Goto, Continue, Break, Return, Throw, Try, Catch, Finally, Asm, Decl }; StatementNode(); StatementNode( const std::string *name ); StatementNode( Type t, ExpressionNode *control = 0, StatementNode *block = 0 ); StatementNode( Type t, std::string *target ); StatementNode( DeclarationNode *decl ); ~StatementNode(); static StatementNode *newCatchStmt( DeclarationNode *d = 0, StatementNode *s = 0, bool catchRestP = false ); StatementNode *set_block( StatementNode *b ) { block = b; return this; } StatementNode *get_block() const { return block; } void set_control( ExpressionNode *c ) { control = c; } ExpressionNode *get_control() const { return control; } StatementNode::Type get_type() const { return type; } virtual StatementNode *add_label( const std::string * ); virtual std::list get_labels() const { return labels; } void addDeclaration( DeclarationNode *newDecl ) { decl = newDecl; } void setCatchRest( bool newVal ) { isCatchRest = newVal; } std::string get_target() const; // StatementNode *add_controlexp( ExpressionNode * ); StatementNode *append_block( StatementNode * ); StatementNode *append_last_case( StatementNode * ); void print( std::ostream &os, int indent = 0) const; virtual StatementNode *clone() const; virtual Statement *build() const; private: static const char *StType[]; Type type; ExpressionNode *control; StatementNode *block; std::list labels; std::string *target; // target label for jump statements DeclarationNode *decl; bool isCatchRest; }; // StatementNode class StatementNode2 : public StatementNode { public: StatementNode2() {} StatementNode2( Statement *stmt ) : stmt( stmt ) {} virtual ~StatementNode2() {} virtual StatementNode2 *clone() const { assert( false ); return nullptr; } virtual Statement *build() const { return stmt; } virtual StatementNode2 *add_label( const std::string * name ) { stmt->get_labels().emplace_back( *name ); return this; } virtual std::list get_labels() const { assert( false ); return StatementNode::get_labels(); } virtual void print( std::ostream &os, int indent = 0 ) {} virtual void printList( std::ostream &os, int indent = 0 ) {} private: Statement *stmt; }; // StatementNode struct ForCtl { ForCtl( ExpressionNode *expr, ExpressionNode *condition, ExpressionNode *change ) : init( new StatementNode( StatementNode::Exp, expr ) ), condition( condition ), change( change ) {} ForCtl( DeclarationNode *decl, ExpressionNode *condition, ExpressionNode *change ) : init( new StatementNode( decl ) ), condition( condition ), change( change ) {} StatementNode *init; ExpressionNode *condition; ExpressionNode *change; }; Statement *build_if( ExpressionNode *ctl, StatementNode *then_stmt, StatementNode *else_stmt ); Statement *build_switch( ExpressionNode *ctl, StatementNode *stmt ); Statement *build_while( ExpressionNode *ctl, StatementNode *stmt, bool kind = false ); Statement *build_for( ForCtl *forctl, StatementNode *stmt ); Statement *build_branch( std::string identifier, BranchStmt::Type kind ); Statement *build_case( ExpressionNode *ctl ); Statement *build_default(); //############################################################################## class CompoundStmtNode : public StatementNode { public: CompoundStmtNode(); CompoundStmtNode( const std::string * ); CompoundStmtNode( StatementNode * ); ~CompoundStmtNode(); void add_statement( StatementNode * ); void print( std::ostream &os, int indent = 0 ) const; virtual Statement *build() const; private: StatementNode *first, *last; }; //############################################################################## class AsmStmtNode : public StatementNode { public: AsmStmtNode( Type, bool voltile, ConstantExpr *instruction, ExpressionNode *output = 0, ExpressionNode *input = 0, ExpressionNode *clobber = 0, LabelNode *gotolabels = 0 ); ~AsmStmtNode(); void print( std::ostream &os, int indent = 0 ) const; Statement *build() const; private: bool voltile; ConstantExpr *instruction; ExpressionNode *output, *input; ExpressionNode *clobber; std::list< Label > gotolabels; }; //############################################################################## template< typename SynTreeType, typename NodeType > void buildList( const NodeType *firstNode, std::list< SynTreeType * > &outputList ) { SemanticError errors; std::back_insert_iterator< std::list< SynTreeType *> > out( outputList ); const NodeType *cur = firstNode; while ( cur ) { try { // SynTreeType *result = dynamic_cast< SynTreeType *>( maybeBuild::type>( cur ) ); SynTreeType *result = dynamic_cast< SynTreeType *>( maybeBuildbuild())>::element_type>( cur ) ); if ( result ) { *out++ = result; } else { } // if } catch( SemanticError &e ) { errors.append( e ); } // try cur = dynamic_cast< NodeType *>( cur->get_link() ); } // while if ( ! errors.isEmpty() ) { throw errors; } // if } // in DeclarationNode.cc void buildList( const DeclarationNode *firstNode, std::list< Declaration * > &outputList ); void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType *> &outputList ); void buildTypeList( const DeclarationNode *firstNode, std::list< Type * > &outputList ); #endif // PARSENODE_H // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //