// // 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 : Tue Jul 12 20:50:21 2016 // Update Count : 261 // #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/Declaration.h" #include "Common/UniqueName.h" #include "SynTree/Label.h" class ExpressionNode; class CompositeExprNode; class CommaExprNode; class StatementNode; class CompoundStmtNode; class DeclarationNode; 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 &, int indent = 0 ) const; virtual void printList( std::ostream &, int indent = 0 ) const; ParseNode &operator,( ParseNode &); protected: std::string name; static int indent_by; ParseNode *next; }; ParseNode *mkList( ParseNode & ); class ExpressionNode : public ParseNode { public: ExpressionNode(); ExpressionNode( const std::string * ); ExpressionNode( const ExpressionNode &other ); virtual ~ExpressionNode() { delete argName; } // cannot delete argName because it might be referenced elsewhere virtual ExpressionNode *clone() const = 0; virtual CommaExprNode *add_to_list( ExpressionNode * ); ExpressionNode *get_argName() const { return argName; } ExpressionNode *set_argName( const std::string *aName ); ExpressionNode *set_argName( ExpressionNode *aDesignator ); bool get_extension() const { return extension; } ExpressionNode *set_extension( bool exten ) { extension = exten; return this; } virtual void print( std::ostream &, int indent = 0) const = 0; virtual void printOneLine( std::ostream &, int indent = 0) const = 0; virtual Expression *build() const = 0; protected: void printDesignation ( std::ostream &, int indent = 0) const; private: ExpressionNode *argName = 0; bool extension = false; }; 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 } }; // NullExprNode is used in tuples as a place-holder where a tuple component is omitted e.g., [ 2, , 3 ] class NullExprNode : public ExpressionNode { public: NullExprNode(); virtual NullExprNode *clone() const; virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; virtual Expression *build() const; }; class ConstantNode : public ExpressionNode { public: enum Type { Integer, Float, Character, String }; ConstantNode( ConstantExpr * ); ConstantNode( const ConstantNode &other ) : expr( other.expr->clone() ) {}; ~ConstantNode() { delete expr; } virtual ConstantNode *clone() const { return new ConstantNode( *this ); } virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; ConstantNode *appendstr( const std::string *newValue ); Expression *build() const; private: ConstantExpr *expr; }; ConstantNode *makeConstant( ConstantNode::Type, std::string * ); ConstantNode *makeConstantStr( ConstantNode::Type type, std::string *str ); class VarRefNode : public ExpressionNode { public: VarRefNode(); VarRefNode( const std::string *, bool isLabel = false ); VarRefNode( const VarRefNode &other ); virtual Expression *build() const ; virtual VarRefNode *clone() const { return new VarRefNode( *this ); } virtual void print( std::ostream &, int indent = 0 ) const; virtual void printOneLine( std::ostream &, int indent = 0 ) const; private: bool isLabel; }; class DesignatorNode : public ExpressionNode { public: DesignatorNode( ExpressionNode *expr, bool isArrayIndex = false ); DesignatorNode( const DesignatorNode &other ); virtual Expression *build() const ; virtual DesignatorNode *clone() const { return new DesignatorNode( *this ); } virtual void print( std::ostream &, int indent = 0 ) const; virtual void printOneLine( std::ostream &, int indent = 0 ) const; private: bool isArrayIndex; }; class TypeValueNode : public ExpressionNode { public: TypeValueNode( DeclarationNode * ); TypeValueNode( const TypeValueNode &other ); DeclarationNode *get_decl() const { return decl; } virtual Expression *build() const ; virtual TypeValueNode *clone() const { return new TypeValueNode( *this ); } virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; private: DeclarationNode *decl; }; class OperatorNode : public ExpressionNode { public: enum Type { TupleC, Comma, TupleFieldSel, // n-adic // triadic Cond, NCond, // diadic SizeOf, AlignOf, OffsetOf, Attr, 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, FieldSel, PFieldSel, Range, // monadic UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress, Ctor, Dtor, }; OperatorNode( Type t ); OperatorNode( const OperatorNode &other ); virtual ~OperatorNode(); virtual OperatorNode *clone() const { return new OperatorNode( *this ); } Type get_type() const; const char *get_typename() const; virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; virtual Expression *build() const { return 0; } private: Type type; }; class CompositeExprNode : public ExpressionNode { public: CompositeExprNode(); CompositeExprNode( const std::string * ); CompositeExprNode( ExpressionNode *f, ExpressionNode *args = 0 ); CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2 ); CompositeExprNode( const CompositeExprNode &other ); virtual ~CompositeExprNode(); virtual CompositeExprNode *clone() const { return new CompositeExprNode( *this ); } virtual Expression *build() const; virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; void set_function( ExpressionNode * ); void set_args( ExpressionNode * ); void add_arg( ExpressionNode * ); ExpressionNode *get_function() const; ExpressionNode *get_args() const; private: ExpressionNode *function; ExpressionNode *arguments; }; class AsmExprNode : public ExpressionNode { public: AsmExprNode(); AsmExprNode( ExpressionNode *inout, ConstantNode *constraint, ExpressionNode *operand ) : inout( inout ), constraint( constraint ), operand( operand ) {} virtual ~AsmExprNode() { delete inout; delete constraint; delete operand; } virtual AsmExprNode *clone() const { return new AsmExprNode( *this ); } virtual Expression *build() const; virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; ExpressionNode *get_inout() const { return inout; }; void set_inout( ExpressionNode *newValue ) { inout = newValue; } ConstantNode *get_constraint() const { return constraint; }; void set_constraint( ConstantNode *newValue ) { constraint = newValue; } ExpressionNode *get_operand() const { return operand; }; void set_operand( ExpressionNode *newValue ) { operand = newValue; } private: ExpressionNode *inout; ConstantNode *constraint; ExpressionNode *operand; }; class LabelNode : public ExpressionNode { public: virtual Expression *build() const { return NULL; } virtual LabelNode *clone() const { return new LabelNode( *this ); } virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, 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; }; class CommaExprNode : public CompositeExprNode { public: CommaExprNode(); CommaExprNode( ExpressionNode * ); CommaExprNode( ExpressionNode *, ExpressionNode * ); CommaExprNode( const CommaExprNode &other ); virtual CommaExprNode *add_to_list( ExpressionNode * ); virtual CommaExprNode *clone() const { return new CommaExprNode( *this ); } }; class ForCtlExprNode : public ExpressionNode { public: ForCtlExprNode( ParseNode *, ExpressionNode *, ExpressionNode * ) throw ( SemanticError ); ForCtlExprNode( const ForCtlExprNode &other ); ~ForCtlExprNode(); StatementNode *get_init() const { return init; } ExpressionNode *get_condition() const { return condition; } ExpressionNode *get_change() const { return change; } virtual ForCtlExprNode *clone() const { return new ForCtlExprNode( *this ); } virtual Expression *build() const; virtual void print( std::ostream &, int indent = 0 ) const; virtual void printOneLine( std::ostream &, int indent = 0 ) const; private: StatementNode *init; ExpressionNode *condition; ExpressionNode *change; }; class ValofExprNode : public ExpressionNode { public: ValofExprNode(); ValofExprNode( StatementNode *s = 0 ); ValofExprNode( const ValofExprNode &other ); ~ValofExprNode(); virtual ValofExprNode *clone() const { return new ValofExprNode( *this ); } StatementNode *get_body() const { return body; } void print( std::ostream &, int indent = 0 ) const; void printOneLine( std::ostream &, int indent = 0 ) const; Expression *build() const; private: StatementNode *body; }; 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 &, int indent = 0 ) const; void printList( std::ostream &, 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 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; } StatementNode *add_label( const std::string * ); const 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 &, 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 CompoundStmtNode : public StatementNode { public: CompoundStmtNode(); CompoundStmtNode( const std::string * ); CompoundStmtNode( StatementNode * ); ~CompoundStmtNode(); void add_statement( StatementNode * ); void print( std::ostream &, int indent = 0 ) const; virtual Statement *build() const; private: StatementNode *first, *last; }; class AsmStmtNode : public StatementNode { public: AsmStmtNode( Type, bool voltile, ConstantNode *instruction, ExpressionNode *output = 0, ExpressionNode *input = 0, ConstantNode *clobber = 0, LabelNode *gotolabels = 0 ); ~AsmStmtNode(); void print( std::ostream &, int indent = 0 ) const; Statement *build() const; private: bool voltile; ConstantNode *instruction; ExpressionNode *output, *input; ConstantNode *clobber; std::list< Label > gotolabels; }; class NullStmtNode : public CompoundStmtNode { public: Statement *build() const; void print( std::ostream &, int indent = 0 ) const; }; 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 &, 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 CompoundLiteralNode : public ExpressionNode { public: CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ); CompoundLiteralNode( const CompoundLiteralNode &type ); ~CompoundLiteralNode(); virtual CompoundLiteralNode *clone() const; DeclarationNode *get_type() const { return type; } CompoundLiteralNode *set_type( DeclarationNode *t ) { type = t; return this; } InitializerNode *get_initializer() const { return kids; } CompoundLiteralNode *set_initializer( InitializerNode *k ) { kids = k; return this; } void print( std::ostream &, int indent = 0 ) const; void printOneLine( std::ostream &, int indent = 0 ) const; virtual Expression *build() const; private: DeclarationNode *type; InitializerNode *kids; }; 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 ); // in ExpressionNode.cc ExpressionNode *flattenCommas( ExpressionNode *list ); ExpressionNode *tupleContents( ExpressionNode *tuple ); #endif // PARSENODE_H // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //