// // 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 : Thu Jul 30 15:11:39 2015 // Update Count : 141 // #ifndef PARSENODE_H #define PARSENODE_H #include #include #include #include "utility.h" #include "Parser/LinkageSpec.h" #include "SynTree/Type.h" //#include "SynTree/Declaration.h" #include "UniqueName.h" class ExpressionNode; class CompositeExprNode; class CommaExprNode; class StatementNode; class CompoundStmtNode; class DeclarationNode; class InitializerNode; // Builder class ParseNode { public: ParseNode(); ParseNode( const std::string * ); virtual ~ParseNode(); ParseNode *get_link() const; 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; } virtual void print( std::ostream &, int indent = 0 ) const; virtual void printList( std::ostream &, int indent = 0 ) const; ParseNode &operator,( ParseNode &); protected: const std::string *name; ParseNode *next; static int indent_by; }; 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 ); 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; }; // 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( Type, std::string * ); ~ConstantNode() { delete &value; } virtual ConstantNode *clone() const { return new ConstantNode( *this ); } Type get_type( void ) const { return type; } virtual void print( std::ostream &, int indent = 0) const; virtual void printOneLine( std::ostream &, int indent = 0) const; const std::string &get_value() const { return value; } ConstantNode *appendstr( const std::string *newValue ); Expression *build() const; private: Type type; BasicType::Kind btype; std::string &value; }; 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 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, Cond, NCond, SizeOf, AlignOf, Attr, CompLit, 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, UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress }; 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; static const char *OpName[]; }; 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< std::string > &get_labels() const { return labels; }; void append_label( std::string *label ) { labels.push_back( *label ); delete label; } private: std::list< std::string > 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, Context }; enum TypeClass { Type, Dtype, Ftype }; 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 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 ); 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 *newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts ); static DeclarationNode *newContextUse( 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 ); 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; 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; InitializerNode *initializer; bool hasEllipsis; LinkageSpec::Type linkage; 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 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 *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; }; 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 *>( cur->build() ); 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: //