// // 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 : Mon Aug 15 14:52:12 2016 // Update Count : 512 // #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_next() const { return next; } ParseNode *set_next( ParseNode *newlink ) { next = newlink; return this; } ParseNode *get_last(); ParseNode *set_last( ParseNode * ); 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; }; //############################################################################## 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 } }; 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, }; struct LabelNode { std::list< Label > labels; }; 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 ); 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_asmexpr( ExpressionNode *inout, ConstantExpr *constraint, ExpressionNode *operand ); 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: StatementNode() { stmt = nullptr; } StatementNode( Statement *stmt ) : stmt( stmt ) {} StatementNode( DeclarationNode *decl ); virtual ~StatementNode() {} virtual StatementNode *clone() const { assert( false ); return nullptr; } virtual Statement *build() const { return stmt; } virtual StatementNode *add_label( const std::string * name ) { stmt->get_labels().emplace_back( *name ); return this; } virtual StatementNode *append_last_case( StatementNode * ); virtual void print( std::ostream &os, int indent = 0 ) {} virtual void printList( std::ostream &os, int indent = 0 ) {} private: Statement *stmt; }; // StatementNode Statement *build_expr( ExpressionNode *ctl ); struct ForCtl { ForCtl( ExpressionNode *expr, ExpressionNode *condition, ExpressionNode *change ) : init( new StatementNode( build_expr( 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_case( ExpressionNode *ctl ); Statement *build_default(); 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_computedgoto( ExpressionNode *ctl ); Statement *build_return( ExpressionNode *ctl ); Statement *build_throw( ExpressionNode *ctl ); Statement *build_try( StatementNode *try_stmt, StatementNode *catch_stmt, StatementNode *finally_stmt ); Statement *build_catch( DeclarationNode *decl, StatementNode *stmt, bool catchAny = false ); Statement *build_finally( StatementNode *stmt ); Statement *build_compound( StatementNode *first ); Statement *build_asmstmt( bool voltile, ConstantExpr *instruction, ExpressionNode *output = 0, ExpressionNode *input = 0, ExpressionNode *clobber = 0, LabelNode *gotolabels = 0 ); //############################################################################## 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_next() ); } // 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: //