// // 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. // // TypeData.cc -- // // Author : Rodolfo G. Esteves // Created On : Sat May 16 15:12:51 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Wed Aug 24 13:46:55 2016 // Update Count : 69 // #include #include #include #include "Common/utility.h" #include "TypeData.h" #include "SynTree/Type.h" #include "SynTree/Declaration.h" #include "SynTree/Expression.h" #include "SynTree/Statement.h" #include "SynTree/Initializer.h" TypeData::TypeData( Kind k ) : kind( k ), base( 0 ), forall( 0 ) { switch ( kind ) { case Unknown: case Pointer: case EnumConstant: // nothing else to initialize break; case Basic: basic = new Basic_t; break; case Array: array = new Array_t; array->dimension = 0; array->isVarLen = false; array->isStatic = false; break; case Function: function = new Function_t; function->params = 0; function->idList = 0; function->oldDeclList = 0; function->body = 0; function->hasBody = false; function->newStyle = false; break; case Aggregate: aggregate = new Aggregate_t; aggregate->params = 0; aggregate->actuals = 0; aggregate->fields = 0; break; case AggregateInst: aggInst = new AggInst_t; aggInst->aggregate = 0; aggInst->params = 0; break; case Enum: enumeration = new Enumeration_t; enumeration->constants = 0; break; case Symbolic: case SymbolicInst: symbolic = new Symbolic_t; symbolic->params = 0; symbolic->actuals = 0; symbolic->assertions = 0; break; case Variable: variable = new Variable_t; variable->tyClass = DeclarationNode::Type; variable->assertions = 0; break; case Tuple: tuple = new Tuple_t; tuple->members = 0; break; case Typeof: typeexpr = new Typeof_t; typeexpr->expr = 0; break; case Builtin: builtin = new Builtin_t; break; case Attr: attr = new Attr_t; attr->expr = 0; attr->type = 0; break; } // switch } TypeData::~TypeData() { delete base; delete forall; switch ( kind ) { case Unknown: case Pointer: case EnumConstant: // nothing to destroy break; case Basic: delete basic; break; case Array: delete array->dimension; delete array; break; case Function: delete function->params; delete function->idList; delete function->oldDeclList; delete function->body; delete function; break; case Aggregate: delete aggregate->params; delete aggregate->actuals; delete aggregate->fields; delete aggregate; break; case AggregateInst: delete aggInst->aggregate; delete aggInst->params; delete aggInst; break; case Enum: delete enumeration->constants; delete enumeration; break; case Symbolic: case SymbolicInst: delete symbolic->params; delete symbolic->actuals; delete symbolic->assertions; delete symbolic; break; case Variable: delete variable->assertions; delete variable; break; case Tuple: delete tuple->members; delete tuple; break; case Typeof: delete typeexpr->expr; delete typeexpr; break; case Builtin: delete builtin; break; case Attr: delete attr->expr; delete attr->type; delete attr; break; } // switch } TypeData *TypeData::clone() const { TypeData *newtype = new TypeData( kind ); newtype->qualifiers = qualifiers; newtype->base = maybeClone( base ); newtype->forall = maybeClone( forall ); switch ( kind ) { case Unknown: case EnumConstant: case Pointer: // nothing else to copy break; case Basic: newtype->basic->typeSpec = basic->typeSpec; newtype->basic->modifiers = basic->modifiers; break; case Array: newtype->array->dimension = maybeClone( array->dimension ); newtype->array->isVarLen = array->isVarLen; newtype->array->isStatic = array->isStatic; break; case Function: newtype->function->params = maybeClone( function->params ); newtype->function->idList = maybeClone( function->idList ); newtype->function->oldDeclList = maybeClone( function->oldDeclList ); newtype->function->body = maybeClone( function->body ); newtype->function->hasBody = function->hasBody; newtype->function->newStyle = function->newStyle; break; case Aggregate: newtype->aggregate->params = maybeClone( aggregate->params ); newtype->aggregate->actuals = maybeClone( aggregate->actuals ); newtype->aggregate->fields = maybeClone( aggregate->fields ); newtype->aggregate->name = aggregate->name; newtype->aggregate->kind = aggregate->kind; newtype->aggregate->body = aggregate->body; break; case AggregateInst: newtype->aggInst->aggregate = maybeClone( aggInst->aggregate ); newtype->aggInst->params = maybeClone( aggInst->params ); break; case Enum: newtype->enumeration->name = enumeration->name; newtype->enumeration->constants = maybeClone( enumeration->constants ); break; case Symbolic: case SymbolicInst: newtype->symbolic->params = maybeClone( symbolic->params ); newtype->symbolic->actuals = maybeClone( symbolic->actuals ); newtype->symbolic->assertions = maybeClone( symbolic->assertions ); newtype->symbolic->isTypedef = symbolic->isTypedef; newtype->symbolic->name = symbolic->name; break; case Variable: newtype->variable->assertions = maybeClone( variable->assertions ); newtype->variable->name = variable->name; newtype->variable->tyClass = variable->tyClass; break; case Tuple: newtype->tuple->members = maybeClone( tuple->members ); break; case Typeof: newtype->typeexpr->expr = maybeClone( typeexpr->expr ); break; case Builtin: newtype->builtin->type = builtin->type; break; case Attr: newtype->attr->expr = maybeClone( attr->expr ); newtype->attr->type = maybeClone( attr->type ); break; } // switch return newtype; } void TypeData::print( std::ostream &os, int indent ) const { using std::endl; using std::string; for ( int i = 0; i < DeclarationNode::NoOfQualifier; i += 1 ) { if ( qualifiers[i] ) os << DeclarationNode::qualifierName[ i ] << ' '; } // for if ( forall ) { os << "forall " << endl; forall->printList( os, indent + 4 ); } // if switch ( kind ) { case Unknown: os << "entity of unknown type "; break; case Pointer: os << "pointer "; if ( base ) { os << "to "; base->print( os, indent ); } // if break; case EnumConstant: os << "enumeration constant "; break; case Basic: printEnums( basic->modifiers.begin(), basic->modifiers.end(), DeclarationNode::modifierName, os ); printEnums( basic->typeSpec.begin(), basic->typeSpec.end(), DeclarationNode::basicTypeName, os ); break; case Array: if ( array->isStatic ) { os << "static "; } // if if ( array->dimension ) { os << "array of "; array->dimension->printOneLine( os, indent ); } else if ( array->isVarLen ) { os << "variable-length array of "; } else { os << "open array of "; } // if if ( base ) { base->print( os, indent ); } // if break; case Function: os << "function" << endl; if ( function->params ) { os << string( indent + 2, ' ' ) << "with parameters " << endl; function->params->printList( os, indent + 4 ); } else { os << string( indent + 2, ' ' ) << "with no parameters " << endl; } // if if ( function->idList ) { os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl; function->idList->printList( os, indent + 4 ); } // if if ( function->oldDeclList ) { os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl; function->oldDeclList->printList( os, indent + 4 ); } // if os << string( indent + 2, ' ' ) << "returning "; if ( base ) { base->print( os, indent + 4 ); } else { os << "nothing "; } // if os << endl; if ( function->hasBody ) { os << string( indent + 2, ' ' ) << "with body " << endl; } // if if ( function->body ) { function->body->printList( os, indent + 2 ); } // if break; case Aggregate: os << DeclarationNode::aggregateName[ aggregate->kind ] << ' ' << aggregate->name << endl; if ( aggregate->params ) { os << string( indent + 2, ' ' ) << "with type parameters " << endl; aggregate->params->printList( os, indent + 4 ); } // if if ( aggregate->actuals ) { os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl; aggregate->actuals->printList( os, indent + 4 ); } // if if ( aggregate->fields ) { os << string( indent + 2, ' ' ) << "with members " << endl; aggregate->fields->printList( os, indent + 4 ); } // if if ( aggregate->body ) { os << string( indent + 2, ' ' ) << " with body " << endl; } // if break; case AggregateInst: if ( aggInst->aggregate ) { os << "instance of " ; aggInst->aggregate->print( os, indent ); } else { os << "instance of an unspecified aggregate "; } // if if ( aggInst->params ) { os << string( indent + 2, ' ' ) << "with parameters " << endl; aggInst->params->printList( os, indent + 2 ); } // if break; case Enum: os << "enumeration "; if ( enumeration->constants ) { os << "with constants" << endl; enumeration->constants->printList( os, indent + 2 ); } // if break; case SymbolicInst: os << "instance of type " << symbolic->name; if ( symbolic->actuals ) { os << " with parameters" << endl; symbolic->actuals->printList( os, indent + 2 ); } // if break; case Symbolic: if ( symbolic->isTypedef ) { os << "typedef definition "; } else { os << "type definition "; } // if if ( symbolic->params ) { os << endl << string( indent + 2, ' ' ) << "with parameters" << endl; symbolic->params->printList( os, indent + 2 ); } // if if ( symbolic->assertions ) { os << endl << string( indent + 2, ' ' ) << "with assertions" << endl; symbolic->assertions->printList( os, indent + 4 ); os << string( indent + 2, ' ' ); } // if if ( base ) { os << "for "; base->print( os, indent + 2 ); } // if break; case Variable: os << DeclarationNode::typeClassName[ variable->tyClass ] << " variable "; if ( variable->assertions ) { os << endl << string( indent + 2, ' ' ) << "with assertions" << endl; variable->assertions->printList( os, indent + 4 ); os << string( indent + 2, ' ' ); } // if break; case Tuple: os << "tuple "; if ( tuple->members ) { os << "with members " << endl; tuple->members->printList( os, indent + 2 ); } // if break; case Typeof: os << "type-of expression "; if ( typeexpr->expr ) { typeexpr->expr->print( os, indent + 2 ); } // if break; case Attr: os << "attribute type decl " << attr->name << " applied to "; if ( attr->expr ) { attr->expr->print( os, indent + 2 ); } // if if ( attr->type ) { attr->type->print( os, indent + 2 ); } // if break; case Builtin: os << "gcc builtin type"; break; default: os << "internal error: TypeData::print " << kind << endl; assert( false ); } // switch } TypeData *TypeData::extractAggregate( bool toplevel ) const { TypeData *ret = 0; switch ( kind ) { case Aggregate: if ( ! toplevel && aggregate->fields ) { ret = clone(); // ret->qualifiers.reset(); } // if break; case Enum: if ( ! toplevel && enumeration->constants ) { ret = clone(); // ret->qualifiers.reset(); } // if break; case AggregateInst: if ( aggInst->aggregate ) { ret = aggInst->aggregate->extractAggregate( false ); } // if break; default: if ( base ) { ret = base->extractAggregate( false ); } // if } // switch return ret; } void buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList ) { buildList( firstNode, outputList ); for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) { if ( (*i)->get_kind() == TypeDecl::Any ) { // add assertion parameters to `type' tyvars in reverse order // add dtor: void ^?{}(T *) FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false ); dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) ); (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) ); // add copy ctor: void ?{}(T *, T) FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false ); copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) ); copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) ); (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) ); // add default ctor: void ?{}(T *) FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false ); ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) ); (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) ); // add assignment operator: T * ?=?(T *, T) FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) ); assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) ); assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) ); (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) ); } // if } // for } Declaration *TypeData::buildDecl( std::string name, DeclarationNode::StorageClass sc, Expression *bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Spec linkage, Initializer *init ) const { if ( kind == TypeData::Function ) { FunctionDecl *decl; if ( function->hasBody ) { if ( function->body ) { Statement *stmt = function->body->build(); CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt ); assert( body ); decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline, isNoreturn ); } else { // std::list< Label > ls; decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list< Label >() ), isInline, isNoreturn ); } // if } else { decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline, isNoreturn ); } // if for ( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_next() ) ) { if ( cur->get_name() != "" ) { decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() ); } // if } // for buildList( function->oldDeclList, decl->get_oldDecls() ); return decl; } else if ( kind == TypeData::Aggregate ) { return buildAggregate(); } else if ( kind == TypeData::Enum ) { return buildEnum(); } else if ( kind == TypeData::Symbolic ) { return buildSymbolic( name, sc ); } else if ( kind == TypeData::Variable ) { return buildVariable(); } else { return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init, std::list< Attribute * >(), isInline, isNoreturn ); } // if return 0; } Type *TypeData::build() const { switch ( kind ) { case Unknown: // fill in implicit int return new BasicType( buildQualifiers(), BasicType::SignedInt ); case Basic: return buildBasicType(); case Pointer: return buildPointer(); case Array: return buildArray(); case Function: return buildFunction(); case AggregateInst: return buildAggInst(); case EnumConstant: // the name gets filled in later -- by SymTab::Validate return new EnumInstType( buildQualifiers(), "" ); case SymbolicInst: return buildSymbolicInst();; case Tuple: return buildTuple(); case Typeof: return buildTypeof(); case Builtin: return new VarArgsType( buildQualifiers() ); case Attr: return buildAttr(); case Symbolic: case Enum: case Aggregate: case Variable: assert( false ); } // switch return 0; } Type::Qualifiers TypeData::buildQualifiers() const { Type::Qualifiers q; q.isConst = qualifiers[ DeclarationNode::Const ]; q.isVolatile = qualifiers[ DeclarationNode::Volatile ]; q.isRestrict = qualifiers[ DeclarationNode::Restrict ]; q.isLvalue = qualifiers[ DeclarationNode::Lvalue ]; q.isAtomic = qualifiers[ DeclarationNode::Atomic ];; return q; } Type *TypeData::buildBasicType() const { static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double, BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex, BasicType::DoubleImaginary }; bool init = false; bool sawDouble = false; bool sawSigned = false; BasicType::Kind ret; for ( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) { if ( ! init ) { init = true; if ( *i == DeclarationNode::Void ) { if ( basic->typeSpec.size() != 1 || ! basic->modifiers.empty() ) { throw SemanticError( "invalid type specifier \"void\" in type: ", this ); } else { return new VoidType( buildQualifiers() ); } // if } else { ret = kindMap[ *i ]; } // if } else { switch ( *i ) { case DeclarationNode::Float: if ( sawDouble ) { throw SemanticError( "invalid type specifier \"float\" in type: ", this ); } else { switch ( ret ) { case BasicType::DoubleComplex: ret = BasicType::FloatComplex; break; case BasicType::DoubleImaginary: ret = BasicType::FloatImaginary; break; default: throw SemanticError( "invalid type specifier \"float\" in type: ", this ); } // switch } // if break; case DeclarationNode::Double: if ( sawDouble ) { throw SemanticError( "duplicate type specifier \"double\" in type: ", this ); } else { switch ( ret ) { case BasicType::DoubleComplex: case BasicType::DoubleImaginary: break; default: throw SemanticError( "invalid type specifier \"double\" in type: ", this ); } // switch } // if break; case DeclarationNode::Complex: switch ( ret ) { case BasicType::Float: ret = BasicType::FloatComplex; break; case BasicType::Double: ret = BasicType::DoubleComplex; break; default: throw SemanticError( "invalid type specifier \"_Complex\" in type: ", this ); } // switch break; case DeclarationNode::Imaginary: switch ( ret ) { case BasicType::Float: ret = BasicType::FloatImaginary; break; case BasicType::Double: ret = BasicType::DoubleImaginary; break; default: throw SemanticError( "invalid type specifier \"_Imaginary\" in type: ", this ); } // switch break; default: throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type: ", this ); } // switch } // if if ( *i == DeclarationNode::Double ) { sawDouble = true; } // if } // for for ( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) { switch ( *i ) { case DeclarationNode::Long: if ( ! init ) { init = true; ret = BasicType::LongSignedInt; } else { switch ( ret ) { case BasicType::SignedInt: ret = BasicType::LongSignedInt; break; case BasicType::UnsignedInt: ret = BasicType::LongUnsignedInt; break; case BasicType::LongSignedInt: ret = BasicType::LongLongSignedInt; break; case BasicType::LongUnsignedInt: ret = BasicType::LongLongUnsignedInt; break; case BasicType::Double: ret = BasicType::LongDouble; break; case BasicType::DoubleComplex: ret = BasicType::LongDoubleComplex; break; case BasicType::DoubleImaginary: ret = BasicType::LongDoubleImaginary; break; default: throw SemanticError( "invalid type modifier \"long\" in type: ", this ); } // switch } // if break; case DeclarationNode::Short: if ( ! init ) { init = true; ret = BasicType::ShortSignedInt; } else { switch ( ret ) { case BasicType::SignedInt: ret = BasicType::ShortSignedInt; break; case BasicType::UnsignedInt: ret = BasicType::ShortUnsignedInt; break; default: throw SemanticError( "invalid type modifier \"short\" in type: ", this ); } // switch } // if break; case DeclarationNode::Signed: if ( ! init ) { init = true; ret = BasicType::SignedInt; } else if ( sawSigned ) { throw SemanticError( "duplicate type modifer \"signed\" in type: ", this ); } else { switch ( ret ) { case BasicType::LongLongSignedInt: ret = BasicType::LongLongUnsignedInt; break; case BasicType::LongSignedInt: ret = BasicType::LongUnsignedInt; break; case BasicType::SignedInt: case BasicType::ShortSignedInt: break; case BasicType::Char: ret = BasicType::SignedChar; break; default: throw SemanticError( "invalid type modifer \"signed\" in type: ", this ); } // switch } // if break; case DeclarationNode::Unsigned: if ( ! init ) { init = true; ret = BasicType::UnsignedInt; } else if ( sawSigned ) { throw SemanticError( "invalid type modifer \"unsigned\" in type: ", this ); } else { switch ( ret ) { case BasicType::LongLongSignedInt: ret = BasicType::LongLongUnsignedInt; break; case BasicType::LongSignedInt: ret = BasicType::LongUnsignedInt; break; case BasicType::SignedInt: ret = BasicType::UnsignedInt; break; case BasicType::ShortSignedInt: ret = BasicType::ShortUnsignedInt; break; case BasicType::Char: ret = BasicType::UnsignedChar; break; default: throw SemanticError( "invalid type modifer \"unsigned\" in type: ", this ); } // switch } // if break; } // switch if ( *i == DeclarationNode::Signed ) { sawSigned = true; } // if } // for BasicType *bt; if ( ! init ) { bt = new BasicType( buildQualifiers(), BasicType::SignedInt ); } else { bt = new BasicType( buildQualifiers(), ret ); } // if buildForall( forall, bt->get_forall() ); return bt; } PointerType *TypeData::buildPointer() const { PointerType *pt; if ( base ) { pt = new PointerType( buildQualifiers(), base->build() ); } else { pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); } // if buildForall( forall, pt->get_forall() ); return pt; } ArrayType *TypeData::buildArray() const { ArrayType *at; if ( base ) { at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic ); } else { at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ), maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic ); } // if buildForall( forall, at->get_forall() ); return at; } FunctionType *TypeData::buildFunction() const { assert( kind == Function ); bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true; if ( ! function->params ) hasEllipsis = ! function->newStyle; FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis ); buildList( function->params, ft->get_parameters() ); buildForall( forall, ft->get_forall() ); if ( base ) { switch ( base->kind ) { case Tuple: buildList( base->tuple->members, ft->get_returnVals() ); break; default: ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", DeclarationNode::NoStorageClass, 0, false, false, LinkageSpec::Cforall ) ) ); } // switch } else { ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) ); } // if return ft; } AggregateDecl *TypeData::buildAggregate() const { assert( kind == Aggregate ); AggregateDecl *at; switch ( aggregate->kind ) { case DeclarationNode::Struct: at = new StructDecl( aggregate->name ); buildForall( aggregate->params, at->get_parameters() ); break; case DeclarationNode::Union: at = new UnionDecl( aggregate->name ); buildForall( aggregate->params, at->get_parameters() ); break; case DeclarationNode::Trait: at = new TraitDecl( aggregate->name ); buildList( aggregate->params, at->get_parameters() ); break; default: assert( false ); } // switch buildList( aggregate->fields, at->get_members() ); at->set_body( aggregate->body ); return at; } ReferenceToType *TypeData::buildAggInst() const { assert( kind == AggregateInst ); ReferenceToType *ret; if ( aggInst->aggregate->kind == Enum ) { ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name ); } else { assert( aggInst->aggregate->kind == Aggregate ); switch ( aggInst->aggregate->aggregate->kind ) { case DeclarationNode::Struct: ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name ); break; case DeclarationNode::Union: ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name ); break; case DeclarationNode::Trait: ret = new TraitInstType( buildQualifiers(), aggInst->aggregate->aggregate->name ); break; default: assert( false ); } // switch } // if buildList( aggInst->params, ret->get_parameters() ); buildForall( forall, ret->get_forall() ); return ret; } NamedTypeDecl *TypeData::buildSymbolic( const std::string &name, DeclarationNode::StorageClass sc ) const { assert( kind == Symbolic ); NamedTypeDecl *ret; if ( symbolic->isTypedef ) { ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) ); } else { ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any ); } // if buildList( symbolic->params, ret->get_parameters() ); buildList( symbolic->assertions, ret->get_assertions() ); return ret; } TypeDecl *TypeData::buildVariable() const { assert( kind == Variable ); static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype }; TypeDecl *ret = new TypeDecl( variable->name, DeclarationNode::NoStorageClass, 0, kindMap[ variable->tyClass ] ); buildList( variable->assertions, ret->get_assertions() ); return ret; } EnumDecl *TypeData::buildEnum() const { assert( kind == Enum ); EnumDecl *ret = new EnumDecl( enumeration->name ); buildList( enumeration->constants, ret->get_members() ); std::list< Declaration * >::iterator members = ret->get_members().begin(); for ( const DeclarationNode *cur = enumeration->constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { if ( cur->has_enumeratorValue() ) { ObjectDecl *member = dynamic_cast< ObjectDecl * >(*members); member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), std::list< Expression * >() ) ); } // if } // for return ret; } TypeInstType *TypeData::buildSymbolicInst() const { assert( kind == SymbolicInst ); TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name, false ); buildList( symbolic->actuals, ret->get_parameters() ); buildForall( forall, ret->get_forall() ); return ret; } TupleType *TypeData::buildTuple() const { assert( kind == Tuple ); TupleType *ret = new TupleType( buildQualifiers() ); buildTypeList( tuple->members, ret->get_types() ); buildForall( forall, ret->get_forall() ); return ret; } TypeofType *TypeData::buildTypeof() const { assert( kind == Typeof ); assert( typeexpr ); assert( typeexpr->expr ); TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() ); return ret; } AttrType *TypeData::buildAttr() const { assert( kind == Attr ); assert( attr ); AttrType *ret; if ( attr->expr ) { ret = new AttrType( buildQualifiers(), attr->name, attr->expr->build() ); } else { assert( attr->type ); ret = new AttrType( buildQualifiers(), attr->name, attr->type->buildType() ); } // if return ret; } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //