// // 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 : Mon Sep 12 21:11:22 2016 // Update Count : 377 // #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 = nullptr; break; case Typeof: // typeexpr = new Typeof_t; typeexpr = nullptr; break; case Attr: // attr = new Attr_t; // attr.expr = nullptr; // attr.type = nullptr; break; case Builtin: // builtin = new Builtin_t; break; } // switch } // TypeData::TypeData 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 Attr: // delete attr.expr; // delete attr.type; // delete attr; break; case Builtin: // delete builtin; break; } // switch } // TypeData::~TypeData 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->basictype = basictype; newtype->complextype = complextype; newtype->signedness = signedness; newtype->length = length; 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: assert( false ); // newtype->variable.assertions = maybeClone( variable.assertions ); // newtype->variable.name = variable.name; // newtype->variable.tyClass = variable.tyClass; break; case Tuple: newtype->tuple = maybeClone( tuple ); break; case Typeof: newtype->typeexpr = maybeClone( typeexpr ); break; case Attr: assert( false ); // newtype->attr.expr = maybeClone( attr.expr ); // newtype->attr.type = maybeClone( attr.type ); break; case Builtin: assert( false ); // newtype->builtin = builtin; break; } // switch return newtype; } // TypeData::clone void TypeData::print( std::ostream &os, int indent ) const { using std::endl; using std::string; for ( int i = 0; i < DeclarationNode::NoQualifier; 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: if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessName[ signedness ] << " "; if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthName[ length ] << " "; assert( basictype != DeclarationNode::NoBasicType ); os << DeclarationNode::basicTypeName[ basictype ] << " "; if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeName[ complextype ] << " "; 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 ) { os << "with members " << endl; tuple->printList( os, indent + 2 ); } // if break; case Typeof: os << "type-of expression "; if ( typeexpr ) { typeexpr->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::print template< typename ForallList > void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { buildList( firstNode, outputList ); for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i ) { TypeDecl * td = static_cast(*i); if ( td->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(), td->get_name(), td ) ), 0 ) ); td->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(), td->get_name(), td ) ), 0 ) ); copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), td->get_name(), td ), 0 ) ); td->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(), td->get_name(), td ) ), 0 ) ); td->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(), td->get_name(), td ) ), 0 ) ); assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), td->get_name(), td ), 0 ) ); assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), td->get_name(), td ), 0 ) ); td->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) ); } // if } // for } Type * typebuild( const TypeData * td ) { assert( td ); switch ( td->kind ) { case TypeData::Unknown: // fill in implicit int return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); case TypeData::Basic: return buildBasicType( td ); case TypeData::Pointer: return buildPointer( td ); case TypeData::Array: return buildArray( td ); case TypeData::Function: return buildFunction( td ); case TypeData::AggregateInst: return buildAggInst( td ); case TypeData::EnumConstant: // the name gets filled in later -- by SymTab::Validate return new EnumInstType( buildQualifiers( td ), "" ); case TypeData::SymbolicInst: return buildSymbolicInst( td );; case TypeData::Tuple: return buildTuple( td ); case TypeData::Typeof: return buildTypeof( td ); case TypeData::Builtin: return new VarArgsType( buildQualifiers( td ) ); case TypeData::Attr: assert( false ); return buildAttr( td ); case TypeData::Symbolic: case TypeData::Enum: case TypeData::Aggregate: case TypeData::Variable: assert( false ); } // switch return 0; } // typebuild TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) { TypeData * ret = 0; switch ( td->kind ) { case TypeData::Aggregate: if ( ! toplevel && td->aggregate.fields ) { ret = td->clone(); } // if break; case TypeData::Enum: if ( ! toplevel && td->enumeration.constants ) { ret = td->clone(); } // if break; case TypeData::AggregateInst: if ( td->aggInst.aggregate ) { ret = typeextractAggregate( td->aggInst.aggregate, false ); } // if break; default: if ( td->base ) { ret = typeextractAggregate( td->base, false ); } // if } // switch return ret; } // typeextractAggregate Type::Qualifiers buildQualifiers( const TypeData * td ) { Type::Qualifiers q; q.isConst = td->qualifiers[ DeclarationNode::Const ]; q.isVolatile = td->qualifiers[ DeclarationNode::Volatile ]; q.isRestrict = td->qualifiers[ DeclarationNode::Restrict ]; q.isLvalue = td->qualifiers[ DeclarationNode::Lvalue ]; q.isAtomic = td->qualifiers[ DeclarationNode::Atomic ];; return q; } // buildQualifiers Type * buildBasicType( const TypeData * td ) { BasicType::Kind ret; switch ( td->basictype ) { case DeclarationNode::Void: if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) { throw SemanticError( "invalid type specifier \"void\" in type: ", td ); } // if return new VoidType( buildQualifiers( td ) ); break; case DeclarationNode::Bool: if ( td->signedness != DeclarationNode::NoSignedness ) { throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td ); } // if if ( td->length != DeclarationNode::NoLength ) { throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td ); } // if ret = BasicType::Bool; break; case DeclarationNode::Char: // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the // character types. The implementation shall define char to have the same range, representation, and behavior as // either signed char or unsigned char. static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char }; if ( td->length != DeclarationNode::NoLength ) { throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td ); } // if ret = chartype[ td->signedness ]; break; case DeclarationNode::Int: static BasicType::Kind inttype[2][4] = { { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt }, { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt }, }; Integral: ; if ( td->signedness == DeclarationNode::NoSignedness ) { const_cast(td)->signedness = DeclarationNode::Signed; } // if ret = inttype[ td->signedness ][ td->length ]; break; case DeclarationNode::Float: case DeclarationNode::Double: case DeclarationNode::LongDouble: // not set until below static BasicType::Kind floattype[3][3] = { { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary }, { BasicType::Float, BasicType::Double, BasicType::LongDouble }, }; FloatingPoint: ; if ( td->signedness != DeclarationNode::NoSignedness ) { throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td ); } // if if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) { throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td ); } // if if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) { throw SemanticError( "invalid type specifier \"long\" in type: ", td ); } // if if ( td->length == DeclarationNode::Long ) { const_cast(td)->basictype = DeclarationNode::LongDouble; } // if ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ]; break; case DeclarationNode::NoBasicType: // No basic type in declaration => default double for Complex/Imaginary and int type for integral types if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) { const_cast(td)->basictype = DeclarationNode::Double; goto FloatingPoint; } // if const_cast(td)->basictype = DeclarationNode::Int; goto Integral; } // switch BasicType * bt = new BasicType( buildQualifiers( td ), ret ); buildForall( td->forall, bt->get_forall() ); return bt; } // buildBasicType PointerType * buildPointer( const TypeData * td ) { PointerType * pt; if ( td->base ) { pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) ); } else { pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); } // if buildForall( td->forall, pt->get_forall() ); return pt; } // buildPointer ArrayType * buildArray( const TypeData * td ) { ArrayType * at; if ( td->base ) { at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic ); } else { at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ), maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic ); } // if buildForall( td->forall, at->get_forall() ); return at; } // buildPointer AggregateDecl * buildAggregate( const TypeData * td ) { assert( td->kind == TypeData::Aggregate ); AggregateDecl * at; switch ( td->aggregate.kind ) { case DeclarationNode::Struct: at = new StructDecl( td->aggregate.name ); buildForall( td->aggregate.params, at->get_parameters() ); break; case DeclarationNode::Union: at = new UnionDecl( td->aggregate.name ); buildForall( td->aggregate.params, at->get_parameters() ); break; case DeclarationNode::Trait: at = new TraitDecl( td->aggregate.name ); buildList( td->aggregate.params, at->get_parameters() ); break; default: assert( false ); } // switch buildList( td->aggregate.fields, at->get_members() ); at->set_body( td->aggregate.body ); return at; } // buildAggregate ReferenceToType * buildAggInst( const TypeData * td ) { assert( td->kind == TypeData::AggregateInst ); ReferenceToType * ret; if ( td->aggInst.aggregate->kind == TypeData::Enum ) { ret = new EnumInstType( buildQualifiers( td ), td->aggInst.aggregate->enumeration.name ); } else { assert( td->aggInst.aggregate->kind == TypeData::Aggregate ); switch ( td->aggInst.aggregate->aggregate.kind ) { case DeclarationNode::Struct: ret = new StructInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name ); break; case DeclarationNode::Union: ret = new UnionInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name ); break; case DeclarationNode::Trait: ret = new TraitInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name ); break; default: assert( false ); } // switch } // if buildList( td->aggInst.params, ret->get_parameters() ); buildForall( td->forall, ret->get_forall() ); return ret; } // buildAggInst NamedTypeDecl * buildSymbolic( const TypeData * td, const std::string & name, DeclarationNode::StorageClass sc ) { assert( td->kind == TypeData::Symbolic ); NamedTypeDecl * ret; assert( td->base ); if ( td->symbolic.isTypedef ) { ret = new TypedefDecl( name, sc, typebuild( td->base ) ); } else { ret = new TypeDecl( name, sc, typebuild( td->base ), TypeDecl::Any ); } // if buildList( td->symbolic.params, ret->get_parameters() ); buildList( td->symbolic.assertions, ret->get_assertions() ); return ret; } // buildSymbolic TypeDecl * buildVariable( const TypeData * td ) { assert( false ); return nullptr; // assert( td->kind == TypeData::Variable ); // static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype }; // TypeDecl * ret = new TypeDecl( td->variable.name, DeclarationNode::NoStorageClass, 0, kindMap[ td->variable.tyClass ] ); // buildList( td->variable.assertions, ret->get_assertions() ); // return ret; } // buildSymbolic EnumDecl * buildEnum( const TypeData * td ) { assert( td->kind == TypeData::Enum ); EnumDecl * ret = new EnumDecl( td->enumeration.name ); buildList( td->enumeration.constants, ret->get_members() ); std::list< Declaration * >::iterator members = ret->get_members().begin(); for ( const DeclarationNode * cur = td->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; } // buildEnum TypeInstType * buildSymbolicInst( const TypeData * td ) { assert( td->kind == TypeData::SymbolicInst ); TypeInstType * ret = new TypeInstType( buildQualifiers( td ), td->symbolic.name, false ); buildList( td->symbolic.actuals, ret->get_parameters() ); buildForall( td->forall, ret->get_forall() ); return ret; } // buildSymbolicInst TupleType * buildTuple( const TypeData * td ) { assert( td->kind == TypeData::Tuple ); TupleType * ret = new TupleType( buildQualifiers( td ) ); buildTypeList( td->tuple, ret->get_types() ); buildForall( td->forall, ret->get_forall() ); return ret; } // buildTuple TypeofType * buildTypeof( const TypeData * td ) { assert( td->kind == TypeData::Typeof ); assert( td->typeexpr ); // assert( td->typeexpr->expr ); return new TypeofType( buildQualifiers( td ), td->typeexpr->build() ); } // buildTypeof AttrType * buildAttr( const TypeData * td ) { assert( false ); return nullptr; // assert( td->kind == TypeData::Attr ); // // assert( td->attr ); // AttrType * ret; // if ( td->attr.expr ) { // ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.expr->build() ); // } else { // assert( td->attr.type ); // ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.type->buildType() ); // } // if // return ret; } // buildAttr Declaration * buildDecl( const TypeData * td, std::string name, DeclarationNode::StorageClass sc, Expression * bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Spec linkage, Initializer * init ) { if ( td->kind == TypeData::Function ) { FunctionDecl * decl; if ( td->function.hasBody ) { if ( td->function.body ) { Statement * stmt = td->function.body->build(); CompoundStmt * body = dynamic_cast< CompoundStmt* >( stmt ); assert( body ); decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), body, isInline, isNoreturn ); } else { // std::list< Label > ls; decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), new CompoundStmt( std::list< Label >() ), isInline, isNoreturn ); } // if } else { decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), 0, isInline, isNoreturn ); } // if for ( DeclarationNode * cur = td->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( td->function.oldDeclList, decl->get_oldDecls() ); return decl; } else if ( td->kind == TypeData::Aggregate ) { return buildAggregate( td ); } else if ( td->kind == TypeData::Enum ) { return buildEnum( td ); } else if ( td->kind == TypeData::Symbolic ) { return buildSymbolic( td, name, sc ); } else if ( td->kind == TypeData::Variable ) { assert( false ); return buildVariable( td ); } else { return new ObjectDecl( name, sc, linkage, bitfieldWidth, typebuild( td ), init, std::list< Attribute * >(), isInline, isNoreturn ); } // if return 0; } // buildDecl FunctionType * buildFunction( const TypeData * td ) { assert( td->kind == TypeData::Function ); bool hasEllipsis = td->function.params ? td->function.params->get_hasEllipsis() : true; if ( ! td->function.params ) hasEllipsis = ! td->function.newStyle; FunctionType * ft = new FunctionType( buildQualifiers( td ), hasEllipsis ); buildList( td->function.params, ft->get_parameters() ); buildForall( td->forall, ft->get_forall() ); if ( td->base ) { switch ( td->base->kind ) { case TypeData::Tuple: buildList( td->base->tuple, ft->get_returnVals() ); break; default: ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( buildDecl( td->base, "", 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; } // buildFunction // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //