#include #include #include #include #include #include "ParseNode.h" #include "TypeData.h" #include "utility.h" #include "SynTree/Declaration.h" #include "SynTree/Expression.h" #include "SynTree/Initializer.h" #include "SemanticError.h" #include "UniqueName.h" #include "LinkageSpec.h" using namespace std; /* these must remain in the same order as the corresponding DeclarationNode enumerations */ const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue" }; const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "bool", "complex", "imaginary" }; const char *DeclarationNode::modifierName[] = { "signed", "unsigned", "short", "long" }; const char *DeclarationNode::tyConName[] = { "struct", "union", "context" }; const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" }; UniqueName DeclarationNode::anonymous( "__anonymous" ); extern LinkageSpec::Type linkage; /* defined in cfa.y */ DeclarationNode* DeclarationNode::clone() const { DeclarationNode *newnode = new DeclarationNode; newnode->type = maybeClone( type ); newnode->name = name; newnode->storageClasses = storageClasses; newnode->bitfieldWidth = maybeClone( bitfieldWidth ); newnode->hasEllipsis = hasEllipsis; newnode->initializer = initializer; newnode->next = maybeClone( next ); newnode->linkage = linkage; return newnode; } DeclarationNode::DeclarationNode() : type( 0 ), bitfieldWidth( 0 ), initializer( 0 ), hasEllipsis( false ), linkage( ::linkage ) { } DeclarationNode::~DeclarationNode() { delete type; delete bitfieldWidth; delete initializer; } bool DeclarationNode::get_hasEllipsis() const { return hasEllipsis; } const char *storageClassName[] = { // order must correspond with DeclarationNode::StorageClass "static", "auto", "extern", "register", "inline", "fortran", }; void DeclarationNode::print( std::ostream &os, int indent ) const { os << string(indent, ' '); if( name == "" ) { /// os << "An unnamed "; } else { os << name << ": a "; } if( linkage != LinkageSpec::Cforall ) { os << LinkageSpec::toString( linkage ) << " "; } printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os ); if( type ) { type->print( os, indent ); } else { os << "untyped entity "; } if( bitfieldWidth ) { os << endl << string(indent+2, ' ') << "with bitfield width "; bitfieldWidth->printOneLine( os ); } if( initializer != 0 ) { os << endl << string(indent+2, ' ') << "with initializer "; initializer->printOneLine( os ); } os << endl; } void DeclarationNode::printList( std::ostream &os, int indent ) const { ParseNode::printList( os, indent ); if( hasEllipsis ) { os << string( indent, ' ' ) << "and a variable number of other arguments" << endl; } } /* static class method */ DeclarationNode * DeclarationNode::newFunction( std::string* name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); newnode->type = new TypeData( TypeData::Function ); newnode->type->function->params = param; newnode->type->function->newStyle = newStyle; newnode->type->function->body = body; if( body ) { newnode->type->function->hasBody = true; } if( ret ) { newnode->type->base = ret->type; ret->type = 0; delete ret; } return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newQualifier( Qualifier q ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData(); newnode->type->qualifiers.push_back( q ); return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newStorageClass( StorageClass sc ) { DeclarationNode *newnode = new DeclarationNode; newnode->storageClasses.push_back( sc ); return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Basic ); newnode->type->basic->typeSpec.push_back( bt ); return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newModifier( Modifier mod ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Basic ); newnode->type->basic->modifiers.push_back( mod ); return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newForall( DeclarationNode* forall ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Unknown ); newnode->type->forall = forall; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newFromTypedef( std::string* name ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::SymbolicInst ); newnode->type->symbolic->name = assign_strptr( name ); newnode->type->symbolic->isTypedef = true; newnode->type->symbolic->params = 0; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newAggregate( TyCon kind, std::string* name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Aggregate ); newnode->type->aggregate->kind = kind; newnode->type->aggregate->name = assign_strptr( name ); if( newnode->type->aggregate->name == "" ) { newnode->type->aggregate->name = DeclarationNode::anonymous.newName(); } newnode->type->aggregate->params = formals; newnode->type->aggregate->actuals = actuals; newnode->type->aggregate->members = fields; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); newnode->type = new TypeData( TypeData::Enum ); newnode->type->enumeration->name = newnode->name; if( newnode->type->enumeration->name == "" ) { newnode->type->enumeration->name = DeclarationNode::anonymous.newName(); } newnode->type->enumeration->constants = constants; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newEnumConstant( std::string* name, ExpressionNode *constant ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); // do something with the constant return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newName( std::string* name ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newFromTypeGen( std::string* name, ExpressionNode *params ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::SymbolicInst ); newnode->type->symbolic->name = assign_strptr( name ); newnode->type->symbolic->isTypedef = false; newnode->type->symbolic->actuals = params; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, std::string* name ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); newnode->type = new TypeData( TypeData::Variable ); newnode->type->variable->tyClass = tc; newnode->type->variable->name = newnode->name; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Aggregate ); newnode->type->aggregate->kind = Context; newnode->type->aggregate->params = params; newnode->type->aggregate->members = asserts; newnode->type->aggregate->name = assign_strptr( name ); return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newContextUse( std::string *name, ExpressionNode *params ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::AggregateInst ); newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate ); newnode->type->aggInst->aggregate->aggregate->kind = Context; newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name ); newnode->type->aggInst->params = params; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); newnode->type = new TypeData( TypeData::Symbolic ); newnode->type->symbolic->isTypedef = false; newnode->type->symbolic->params = typeParams; newnode->type->symbolic->name = newnode->name; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newPointer( DeclarationNode *qualifiers ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Pointer ); return newnode->addQualifiers( qualifiers ); } /* static class method */ DeclarationNode * DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Array ); newnode->type->array->dimension = size; newnode->type->array->isStatic = isStatic; newnode->type->array->isVarLen = false; return newnode->addQualifiers( qualifiers ); } /* static class method */ DeclarationNode * DeclarationNode::newVarArray( DeclarationNode *qualifiers ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Array ); newnode->type->array->dimension = 0; newnode->type->array->isStatic = false; newnode->type->array->isVarLen = true; return newnode->addQualifiers( qualifiers ); } /* static class method */ DeclarationNode * DeclarationNode::newBitfield( ExpressionNode *size ) { DeclarationNode *newnode = new DeclarationNode; newnode->bitfieldWidth = size; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newTuple( DeclarationNode *members ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Tuple ); newnode->type->tuple->members = members; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newTypeof( ExpressionNode *expr ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Typeof ); newnode->type->typeexpr->expr = expr; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Attr ); newnode->type->attr->name = assign_strptr( name ); newnode->type->attr->expr = expr; return newnode; } /* static class method */ DeclarationNode * DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Attr ); newnode->type->attr->name = assign_strptr( name ); newnode->type->attr->type = type; return newnode; } static void addQualifiersToType( TypeData *&src, TypeData *dst ) { if( src && dst ) { if( src->forall && dst->kind == TypeData::Function ) { if( dst->forall ) { dst->forall->appendList( src->forall ); } else { dst->forall = src->forall; } src->forall = 0; } if( dst->base ) { addQualifiersToType( src, dst->base ); } else if( dst->kind == TypeData::Function ) { dst->base = src; src = 0; } else { dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers ); } } } DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode *q ) { if( q ) { storageClasses.splice( storageClasses.end(), q->storageClasses ); if( q->type ) { if( !type ) { type = new TypeData; } addQualifiersToType( q->type, type ); if( q->type && q->type->forall ) { if( type->forall ) { type->forall->appendList( q->type->forall ); } else { type->forall = q->type->forall; } q->type->forall = 0; } } } delete q; return this; } DeclarationNode * DeclarationNode::copyStorageClasses( DeclarationNode *q ) { storageClasses = q->storageClasses; return this; } static void addTypeToType( TypeData *&src, TypeData *&dst ) { if( src && dst ) { if( src->forall && dst->kind == TypeData::Function ) { if( dst->forall ) { dst->forall->appendList( src->forall ); } else { dst->forall = src->forall; } src->forall = 0; } if( dst->base ) { addTypeToType( src, dst->base ); } else { switch( dst->kind ) { case TypeData::Unknown: src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers ); dst = src; src = 0; break; case TypeData::Basic: dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers ); if( src->kind != TypeData::Unknown ) { assert( src->kind == TypeData::Basic ); dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers ); dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec ); } break; default: switch( src->kind ) { case TypeData::Aggregate: case TypeData::Enum: dst->base = new TypeData( TypeData::AggregateInst ); dst->base->aggInst->aggregate = src; if( src->kind == TypeData::Aggregate ) { dst->base->aggInst->params = maybeClone( src->aggregate->actuals ); } dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers ); src = 0; break; default: if( dst->forall ) { dst->forall->appendList( src->forall ); } else { dst->forall = src->forall; } src->forall = 0; dst->base = src; src = 0; } } } } } DeclarationNode * DeclarationNode::addType( DeclarationNode *o ) { if( o ) { storageClasses.splice( storageClasses.end(), o->storageClasses ); if ( o->type ) { if( !type ) { if( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) { type = new TypeData( TypeData::AggregateInst ); type->aggInst->aggregate = o->type; if( o->type->kind == TypeData::Aggregate ) { type->aggInst->params = maybeClone( o->type->aggregate->actuals ); } type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers ); } else { type = o->type; } o->type = 0; } else { addTypeToType( o->type, type ); } } if( o->bitfieldWidth ) { bitfieldWidth = o->bitfieldWidth; } } delete o; return this; } DeclarationNode * DeclarationNode::addTypedef() { TypeData *newtype = new TypeData( TypeData::Symbolic ); newtype->symbolic->params = 0; newtype->symbolic->isTypedef = true; newtype->symbolic->name = name; newtype->base = type; type = newtype; return this; } DeclarationNode * DeclarationNode::addAssertions( DeclarationNode* assertions ) { assert( type ); switch( type->kind ) { case TypeData::Symbolic: if( type->symbolic->assertions ) { type->symbolic->assertions->appendList( assertions ); } else { type->symbolic->assertions = assertions; } break; case TypeData::Variable: if( type->variable->assertions ) { type->variable->assertions->appendList( assertions ); } else { type->variable->assertions = assertions; } break; default: assert( false ); } return this; } DeclarationNode * DeclarationNode::addName( std::string* newname ) { name = assign_strptr( newname ); return this; } DeclarationNode * DeclarationNode::addBitfield( ExpressionNode *size ) { bitfieldWidth = size; return this; } DeclarationNode * DeclarationNode::addVarArgs() { assert( type ); hasEllipsis = true; return this; } DeclarationNode * DeclarationNode::addFunctionBody( StatementNode *body ) { assert( type ); assert( type->kind == TypeData::Function ); assert( type->function->body == 0 ); type->function->body = body; type->function->hasBody = true; return this; } DeclarationNode * DeclarationNode::addOldDeclList( DeclarationNode *list ) { assert( type ); assert( type->kind == TypeData::Function ); assert( type->function->oldDeclList == 0 ); type->function->oldDeclList = list; return this; } static void setBase( TypeData *&type, TypeData *newType ) { if( type ) { TypeData *prevBase = type; TypeData *curBase = type->base; while( curBase != 0 ) { prevBase = curBase; curBase = curBase->base; } prevBase->base = newType; } else { type = newType; } } DeclarationNode * DeclarationNode::addPointer( DeclarationNode *p ) { if( p ) { assert( p->type->kind == TypeData::Pointer ); setBase( type, p->type ); p->type = 0; delete p; } return this; } DeclarationNode * DeclarationNode::addArray( DeclarationNode *a ) { if( a ) { assert( a->type->kind == TypeData::Array ); setBase( type, a->type ); a->type = 0; delete a; } return this; } DeclarationNode * DeclarationNode::addNewPointer( DeclarationNode *p ) { if( p ) { assert( p->type->kind == TypeData::Pointer ); if( type ) { switch( type->kind ) { case TypeData::Aggregate: case TypeData::Enum: p->type->base = new TypeData( TypeData::AggregateInst ); p->type->base->aggInst->aggregate = type; if( type->kind == TypeData::Aggregate ) { p->type->base->aggInst->params = maybeClone( type->aggregate->actuals ); } p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers ); break; default: p->type->base = type; } type = 0; } delete this; return p; } else { return this; } } static TypeData * findLast( TypeData *a ) { assert( a ); TypeData *cur = a; while( cur->base ) { cur = cur->base; } return cur; } DeclarationNode * DeclarationNode::addNewArray( DeclarationNode *a ) { if( a ) { assert( a->type->kind == TypeData::Array ); TypeData *lastArray = findLast( a->type ); if( type ) { switch( type->kind ) { case TypeData::Aggregate: case TypeData::Enum: lastArray->base = new TypeData( TypeData::AggregateInst ); lastArray->base->aggInst->aggregate = type; if( type->kind == TypeData::Aggregate ) { lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals ); } lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers ); break; default: lastArray->base = type; } type = 0; } delete this; return a; } else { return this; } } DeclarationNode * DeclarationNode::addParamList( DeclarationNode *params ) { TypeData *ftype = new TypeData( TypeData::Function ); ftype->function->params = params; setBase( type, ftype ); return this; } static TypeData* addIdListToType( TypeData *type, DeclarationNode *ids ) { if( type ) { if( type->kind != TypeData::Function ) { type->base = addIdListToType( type->base, ids ); } else { type->function->idList = ids; } return type; } else { TypeData *newtype = new TypeData( TypeData::Function ); newtype->function->idList = ids; return newtype; } } DeclarationNode * DeclarationNode::addIdList( DeclarationNode *ids ) { type = addIdListToType( type, ids ); return this; } DeclarationNode * DeclarationNode::addInitializer( InitializerNode *init ) { //assert initializer = init; return this; } DeclarationNode * DeclarationNode::cloneBaseType( string *newName ) { DeclarationNode *newnode = new DeclarationNode; TypeData *srcType = type; while( srcType->base ) { srcType = srcType->base; } newnode->type = maybeClone( srcType ); if( newnode->type->kind == TypeData::AggregateInst ) { // don't duplicate members if( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) { delete newnode->type->aggInst->aggregate->enumeration->constants; newnode->type->aggInst->aggregate->enumeration->constants = 0; } else { assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate ); delete newnode->type->aggInst->aggregate->aggregate->members; newnode->type->aggInst->aggregate->aggregate->members = 0; } } newnode->type->forall = maybeClone( type->forall ); newnode->storageClasses = storageClasses; newnode->name = assign_strptr( newName ); return newnode; } DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode *o ) { if( o ) { o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() ); if ( type ) { TypeData *srcType = type; while( srcType->base ) { srcType = srcType->base; } TypeData *newType = srcType->clone(); if( newType->kind == TypeData::AggregateInst ) { // don't duplicate members if( newType->aggInst->aggregate->kind == TypeData::Enum ) { delete newType->aggInst->aggregate->enumeration->constants; newType->aggInst->aggregate->enumeration->constants = 0; } else { assert( newType->aggInst->aggregate->kind == TypeData::Aggregate ); delete newType->aggInst->aggregate->aggregate->members; newType->aggInst->aggregate->aggregate->members = 0; } } newType->forall = maybeClone( type->forall ); if( !o->type ) { o->type = newType; } else { addTypeToType( newType, o->type ); delete newType; } } } return o; } DeclarationNode * DeclarationNode::cloneType( string *newName ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = maybeClone( type ); newnode->storageClasses = storageClasses; newnode->name = assign_strptr( newName ); return newnode; } DeclarationNode * DeclarationNode::cloneType( DeclarationNode *o ) { if( o ) { o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() ); if ( type ) { TypeData *newType = type->clone(); if( !o->type ) { o->type = newType; } else { addTypeToType( newType, o->type ); delete newType; } } } return o; } DeclarationNode * DeclarationNode::appendList( DeclarationNode *node ) { if( node != 0 ) { set_link( node ); } return this; } DeclarationNode* DeclarationNode::extractAggregate() const { if( type ) { TypeData *ret = type->extractAggregate(); if( ret ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = ret; return newnode; } else { return 0; } } else { return 0; } } void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList ) { SemanticError errors; std::back_insert_iterator< std::list< Declaration* > > out( outputList ); const DeclarationNode *cur = firstNode; while( cur ) { try { if( DeclarationNode *extr = cur->extractAggregate() ) { // handle the case where a structure declaration is contained within an object or type // declaration Declaration *decl = extr->build(); if( decl ) { *out++ = decl; } } Declaration *decl = cur->build(); if( decl ) { *out++ = decl; } } catch( SemanticError &e ) { errors.append( e ); } cur = dynamic_cast< DeclarationNode* >( cur->get_link() ); } if( !errors.isEmpty() ) { throw errors; } } void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList ) { SemanticError errors; std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList ); const DeclarationNode *cur = firstNode; while( cur ) { try { /// if( DeclarationNode *extr = cur->extractAggregate() ) { /// // handle the case where a structure declaration is contained within an object or type /// // declaration /// Declaration *decl = extr->build(); /// if( decl ) { /// *out++ = decl; /// } /// } Declaration *decl = cur->build(); if( decl ) { if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { *out++ = dwt; } else if( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) { StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() ); *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 ); delete agg; } else if( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) { UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() ); *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 ); } } } catch( SemanticError &e ) { errors.append( e ); } cur = dynamic_cast< DeclarationNode* >( cur->get_link() ); } if( !errors.isEmpty() ) { throw errors; } } void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList ) { SemanticError errors; std::back_insert_iterator< std::list< Type* > > out( outputList ); const DeclarationNode *cur = firstNode; while( cur ) { try { *out++ = cur->buildType(); } catch( SemanticError &e ) { errors.append( e ); } cur = dynamic_cast< DeclarationNode* >( cur->get_link() ); } if( !errors.isEmpty() ) { throw errors; } } Declaration * DeclarationNode::build() const { if( !type ) { if( buildInline() ) { throw SemanticError( "invalid inline specification in declaration of ", this ); } else { return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ); } } else { Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) ); return newDecl; } // we should never get here assert( false ); return 0; } Type * DeclarationNode::buildType() const { assert( type ); switch( type->kind ) { case TypeData::Enum: return new EnumInstType( type->buildQualifiers(), type->enumeration->name ); case TypeData::Aggregate: { ReferenceToType *ret; switch( type->aggregate->kind ) { case DeclarationNode::Struct: ret = new StructInstType( type->buildQualifiers(), type->aggregate->name ); break; case DeclarationNode::Union: ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name ); break; case DeclarationNode::Context: ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name ); break; default: assert( false ); } buildList( type->aggregate->actuals, ret->get_parameters() ); return ret; } case TypeData::Symbolic: { TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false ); buildList( type->symbolic->actuals, ret->get_parameters() ); return ret; } default: return type->build(); } } Declaration::StorageClass DeclarationNode::buildStorageClass() const { static const Declaration::StorageClass scMap[] = { Declaration::Static, Declaration::Auto, Declaration::Extern, Declaration::Register, Declaration::NoStorageClass, // inline Declaration::Fortran }; Declaration::StorageClass ret = Declaration::NoStorageClass; for( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) { assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) ); if( *i == Inline ) continue; if( ret == Declaration::NoStorageClass ) { ret = scMap[ *i ]; } else { throw SemanticError( "invalid combination of storage classes in declaration of ", this ); } } return ret; } bool DeclarationNode::buildInline() const { std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline ); if( first == storageClasses.end() ) { return false; } else { std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline ); if( next == storageClasses.end() ) { return true; } else { throw SemanticError( "duplicate inline specification in declaration of ", this ); } } // we should never get here return false; }