// // 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. // // DeclarationNode.cc -- // // Author : Rodolfo G. Esteves // Created On : Sat May 16 12:34:05 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Sat Jun 6 23:29:13 2015 // Update Count : 23 // #include #include #include #include #include #include "TypeData.h" #include "SynTree/Expression.h" using namespace std; // These must remain in the same order as the corresponding DeclarationNode enumerations. const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic" }; 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 "extern", "static", "auto", "register", "inline", "fortran", }; void DeclarationNode::print( std::ostream &os, int indent ) const { os << string( indent, ' ' ); if ( name == "" ) { os << "unnamed: "; } else { os << name << ": "; } 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; } } 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; } DeclarationNode *DeclarationNode::newQualifier( Qualifier q ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData(); newnode->type->qualifiers.push_back( q ); return newnode; } DeclarationNode *DeclarationNode::newStorageClass( StorageClass sc ) { DeclarationNode *newnode = new DeclarationNode; newnode->storageClasses.push_back( sc ); return newnode; } DeclarationNode *DeclarationNode::newBasicType( BasicType bt ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Basic ); newnode->type->basic->typeSpec.push_back( bt ); return newnode; } DeclarationNode *DeclarationNode::newModifier( Modifier mod ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Basic ); newnode->type->basic->modifiers.push_back( mod ); return newnode; } DeclarationNode *DeclarationNode::newForall( DeclarationNode *forall ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Unknown ); newnode->type->forall = forall; return newnode; } 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; } 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; } 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; } DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); // do something with the constant return newnode; } DeclarationNode *DeclarationNode::newName( std::string *name ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); return newnode; } 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; } 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; } 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; } 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; } 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; } DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Pointer ); return newnode->addQualifiers( qualifiers ); } 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 ); } 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 ); } DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) { DeclarationNode *newnode = new DeclarationNode; newnode->bitfieldWidth = size; return newnode; } DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Tuple ); newnode->type->tuple->members = members; return newnode; } DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Typeof ); newnode->type->typeexpr->expr = expr; return newnode; } 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; } 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; } // if } // if 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; } // if } // if Declaration *decl = cur->build(); if ( decl ) { *out++ = decl; } // if } catch( SemanticError &e ) { errors.append( e ); } // try cur = dynamic_cast< DeclarationNode *>( cur->get_link() ); } // while if ( ! errors.isEmpty() ) { throw errors; } // if } 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 ); } // if } // if } catch( SemanticError &e ) { errors.append( e ); } // try cur = dynamic_cast< DeclarationNode *>( cur->get_link() ); } // while if ( ! errors.isEmpty() ) { throw errors; } // if } 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 ); } // try cur = dynamic_cast< DeclarationNode *>( cur->get_link() ); } // while if ( ! errors.isEmpty() ) { throw errors; } // if } Declaration *DeclarationNode::build() const { if ( type ) { Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) ); return newDecl; } // if if ( ! buildInline() ) { return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ); } // if throw SemanticError( "invalid inline specification in declaration of ", this ); } 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 ); } // switch 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(); } // switch } Declaration::StorageClass DeclarationNode::buildStorageClass() const { static const Declaration::StorageClass scMap[] = { Declaration::Extern, Declaration::Static, Declaration::Auto, Declaration::Register, Declaration::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 ) { throw SemanticError( "invalid combination of storage classes in declaration of ", this ); } ret = scMap[ *i ]; } 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; std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline ); if ( next == storageClasses.end() ) return true; throw SemanticError( "duplicate inline specification in declaration of ", this ); } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //