// // 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 : Mon Aug 29 22:30:56 2016 // Update Count : 327 // #include #include #include #include #include #include "TypeData.h" #include "SynTree/Declaration.h" #include "SynTree/Expression.h" #include "TypedefTable.h" extern TypedefTable typedefTable; using namespace std; // These must remain in the same order as the corresponding DeclarationNode enumerations. const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "" }; 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::aggregateName[] = { "struct", "union", "context" }; const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" }; const char *DeclarationNode::builtinTypeName[] = { "__builtin_va_list" }; UniqueName DeclarationNode::anonymous( "__anonymous" ); extern LinkageSpec::Spec linkage; // defined in parser.yy DeclarationNode::DeclarationNode() : type( 0 ) , storageClass( NoStorageClass ) , isInline( false ) , isNoreturn( false ) , bitfieldWidth( 0 ) , initializer( 0 ) , hasEllipsis( false ) , linkage( ::linkage ) , extension( false ) , error() { attr.expr = nullptr; attr.type = nullptr; variable.tyClass = DeclarationNode::Type; variable.assertions = nullptr; } DeclarationNode::~DeclarationNode() { delete attr.expr; delete attr.type; delete type; delete bitfieldWidth; delete initializer; } DeclarationNode *DeclarationNode::clone() const { DeclarationNode *newnode = new DeclarationNode; newnode->type = maybeClone( type ); newnode->name = name; newnode->storageClass = storageClass; newnode->isInline = isInline; newnode->isNoreturn = isNoreturn; newnode->bitfieldWidth = maybeClone( bitfieldWidth ); newnode->hasEllipsis = hasEllipsis; newnode->initializer = maybeClone( initializer ); newnode->set_next( maybeClone( get_next() ) ); newnode->linkage = linkage; newnode->variable.assertions = maybeClone( variable.assertions ); newnode->variable.name = variable.name; newnode->variable.tyClass = variable.tyClass; newnode->attr.expr = maybeClone( attr.expr ); newnode->attr.type = maybeClone( attr.type ); return newnode; } // DeclarationNode::clone bool DeclarationNode::get_hasEllipsis() const { return hasEllipsis; } void DeclarationNode::print( std::ostream &os, int indent ) const { os << string( indent, ' ' ); if ( name == "" ) { os << "unnamed: "; } else { os << name << ": "; } // if if ( linkage != LinkageSpec::Cforall ) { os << LinkageSpec::toString( linkage ) << " "; } // if if ( storageClass != NoStorageClass ) os << DeclarationNode::storageName[storageClass] << ' '; if ( isInline ) os << DeclarationNode::storageName[Inline] << ' '; if ( isNoreturn ) os << DeclarationNode::storageName[Noreturn] << ' '; if ( type ) { type->print( os, indent ); } else { os << "untyped entity "; } // if if ( bitfieldWidth ) { os << endl << string( indent + 2, ' ' ) << "with bitfield width "; bitfieldWidth->printOneLine( os ); } // if if ( initializer != 0 ) { os << endl << string( indent + 2, ' ' ) << "with initializer "; initializer->printOneLine( os ); os << " maybe constructed? " << initializer->get_maybeConstructed(); } // if 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; } // if } 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; typedefTable.addToEnclosingScope( newnode->name, TypedefTable::ID ); if ( body ) { newnode->type->function.hasBody = true; } // if if ( ret ) { newnode->type->base = ret->type; ret->type = 0; delete ret; } // if return newnode; } // DeclarationNode::newFunction DeclarationNode * DeclarationNode::newQualifier( Qualifier q ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData(); newnode->type->qualifiers[ q ] = 1; return newnode; } // DeclarationNode::newQualifier DeclarationNode * DeclarationNode::newForall( DeclarationNode *forall ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Unknown ); newnode->type->forall = forall; return newnode; } // DeclarationNode::newForall DeclarationNode * DeclarationNode::newStorageClass( DeclarationNode::StorageClass sc ) { DeclarationNode *newnode = new DeclarationNode; //switch (sc) { // case Inline: newnode->isInline = true; break; // case Noreturn: newnode->isNoreturn = true; break; // default: newnode->storageClass = sc; break; //} newnode->storageClass = sc; return newnode; } // DeclarationNode::newStorageClass 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::newBasicType 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::newModifier 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::newFromTypedef DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const std::string *name, ExpressionNode *actuals, DeclarationNode *fields, bool body ) { 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 == "" ) { // anonymous aggregate ? newnode->type->aggregate.name = anonymous.newName(); } // if newnode->type->aggregate.actuals = actuals; newnode->type->aggregate.fields = fields; newnode->type->aggregate.body = body; return newnode; } // DeclarationNode::newAggregate 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 == "" ) { // anonymous enumeration ? newnode->type->enumeration.name = DeclarationNode::anonymous.newName(); } // if newnode->type->enumeration.constants = constants; return newnode; } // DeclarationNode::newEnum DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); newnode->enumeratorValue.reset( constant ); typedefTable.addToEnclosingScope( newnode->name, TypedefTable::ID ); return newnode; } // DeclarationNode::newEnumConstant DeclarationNode *DeclarationNode::newName( std::string *name ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); return newnode; } // DeclarationNode::newName 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::newFromTypeGen DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string *name ) { DeclarationNode *newnode = new DeclarationNode; newnode->name = assign_strptr( name ); newnode->type = new TypeData( TypeData::Variable ); newnode->variable.tyClass = tc; newnode->variable.name = newnode->name; return newnode; } // DeclarationNode::newTypeParam DeclarationNode *DeclarationNode::newTrait( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Aggregate ); newnode->type->aggregate.kind = Trait; newnode->type->aggregate.params = params; newnode->type->aggregate.fields = asserts; newnode->type->aggregate.name = assign_strptr( name ); return newnode; } // DeclarationNode::newTrait DeclarationNode *DeclarationNode::newTraitUse( 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 = Trait; newnode->type->aggInst.aggregate->aggregate.name = assign_strptr( name ); newnode->type->aggInst.params = params; return newnode; } // DeclarationNode::newTraitUse 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::newTypeDecl DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Pointer ); return newnode->addQualifiers( qualifiers ); } // DeclarationNode::newPointer 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; if ( newnode->type->array.dimension == 0 || newnode->type->array.dimension->isExpressionType() ) { newnode->type->array.isVarLen = false; } else { newnode->type->array.isVarLen = true; } // if return newnode->addQualifiers( qualifiers ); } // DeclarationNode::newArray 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; return newnode; } DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Typeof ); newnode->type->typeexpr = expr; return newnode; } DeclarationNode * DeclarationNode::newBuiltinType( BuiltinType bt ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Builtin ); newnode->builtin = bt; return newnode; } // DeclarationNode::newBuiltinType DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Attr ); newnode->attr.name = assign_strptr( name ); newnode->attr.expr = expr; return newnode; } DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = new TypeData( TypeData::Attr ); newnode->attr.name = assign_strptr( name ); newnode->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; } // if src->forall = 0; } // if if ( dst->base ) { addQualifiersToType( src, dst->base ); } else if ( dst->kind == TypeData::Function ) { dst->base = src; src = 0; } else { dst->qualifiers |= src->qualifiers; } // if } // if } void DeclarationNode::checkQualifiers( const TypeData *src, const TypeData *dst ) { TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; if ( (qsrc & qdst).any() ) { // common bits between qualifier masks ? error = "duplicate qualifier "; int j = 0; // separator detector for ( int i = 0; i < DeclarationNode::NoOfQualifier; i += 1 ) { if ( qsrc[i] & qdst[i] ) { // find specific qualifiers in common if ( j > 0 ) error += ", "; error += DeclarationNode::qualifierName[i]; j += 1; } // if } // for error += " in declaration of "; } // if } // DeclarationNode::checkQualifiers DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) { if ( q ) { copyStorageClasses(q); if ( q->type ) { if ( ! type ) { type = new TypeData; } else { checkQualifiers( q->type, type ); } // if addQualifiersToType( q->type, type ); if ( q->type && q->type->forall ) { if ( type->forall ) { type->forall->appendList( q->type->forall ); } else { if ( type->kind == TypeData::Aggregate ) { type->aggregate.params = q->type->forall; // change implicit typedef from TYPEDEFname to TYPEGENname typedefTable.changeKind( type->aggregate.name, TypedefTable::TG ); } else { type->forall = q->type->forall; } // if } // if q->type->forall = 0; } // if } // if } // if delete q; return this; } DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) { isInline = isInline || q->isInline; isNoreturn = isNoreturn || q->isNoreturn; if ( storageClass == NoStorageClass ) { storageClass = q->storageClass; } else if ( q->storageClass != NoStorageClass ) { q->error = "invalid combination of storage classes in declaration of "; } // if if ( error.empty() ) error = q->error; 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; } // if src->forall = 0; } // if if ( dst->base ) { addTypeToType( src, dst->base ); } else { switch ( dst->kind ) { case TypeData::Unknown: src->qualifiers |= dst->qualifiers; dst = src; src = 0; break; case TypeData::Basic: dst->qualifiers |= 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 ); } // if 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 ); } // if dst->base->qualifiers |= src->qualifiers; src = 0; break; default: if ( dst->forall ) { dst->forall->appendList( src->forall ); } else { dst->forall = src->forall; } // if src->forall = 0; dst->base = src; src = 0; } // switch } // switch } // if } // if } DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) { if ( o ) { copyStorageClasses( o ); 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 ); } // if type->qualifiers |= o->type->qualifiers; } else { type = o->type; } // if o->type = 0; } else { addTypeToType( o->type, type ); } // if } // if if ( o->bitfieldWidth ) { bitfieldWidth = o->bitfieldWidth; } // if // there may be typedefs chained onto the type if ( o->get_next() ) { set_last( o->get_next()->clone() ); } // if } // if 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; } // if break; case TypeData::Variable: if ( variable.assertions ) { variable.assertions->appendList( assertions ); } else { variable.assertions = assertions; } // if break; default: assert( false ); } // switch 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; } // while prevBase->base = newType; } else { type = newType; } // if } DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) { if ( p ) { assert( p->type->kind == TypeData::Pointer ); setBase( type, p->type ); p->type = 0; delete p; } // if return this; } DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) { if ( a ) { assert( a->type->kind == TypeData::Array ); setBase( type, a->type ); a->type = 0; delete a; } // if 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 ); } // if p->type->base->qualifiers |= type->qualifiers; break; default: p->type->base = type; } // switch type = 0; } // if delete this; return p; } else { return this; } // if } static TypeData *findLast( TypeData *a ) { assert( a ); TypeData *cur = a; while ( cur->base ) { cur = cur->base; } // while 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 ); } // if lastArray->base->qualifiers |= type->qualifiers; break; default: lastArray->base = type; } // switch type = 0; } // if delete this; return a; } else { return this; } // if } 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; } // if return type; } else { TypeData *newtype = new TypeData( TypeData::Function ); newtype->function.idList = ids; return newtype; } // if } 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; } // while 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.fields; newnode->type->aggInst.aggregate->aggregate.fields = 0; } // if } // if newnode->type->forall = maybeClone( type->forall ); newnode->copyStorageClasses( this ); newnode->name = assign_strptr( newName ); return newnode; } DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) { if ( o ) { o->copyStorageClasses( this ); if ( type ) { TypeData *srcType = type; while ( srcType->base ) { srcType = srcType->base; } // while 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.fields; newType->aggInst.aggregate->aggregate.fields = 0; } // if } // if newType->forall = maybeClone( type->forall ); if ( ! o->type ) { o->type = newType; } else { addTypeToType( newType, o->type ); delete newType; } // if } // if } // if return o; } DeclarationNode *DeclarationNode::cloneType( string *newName ) { DeclarationNode *newnode = new DeclarationNode; newnode->type = maybeClone( type ); newnode->copyStorageClasses( this ); newnode->name = assign_strptr( newName ); return newnode; } DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) { if ( o ) { o->copyStorageClasses( this ); if ( type ) { TypeData *newType = type->clone(); if ( ! o->type ) { o->type = newType; } else { addTypeToType( newType, o->type ); delete newType; } // if } // if } // if delete o; return o; } DeclarationNode *DeclarationNode::extractAggregate() const { if ( type ) { TypeData *ret = typeextractAggregate( type ); 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 delete extr; } // if Declaration *decl = cur->build(); if ( decl ) { *out++ = decl; } // if } catch( SemanticError &e ) { errors.append( e ); } // try cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); } // 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( "", DeclarationNode::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( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 ); } // if } // if } catch( SemanticError &e ) { errors.append( e ); } // try cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); } // 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_next() ); } // while if ( ! errors.isEmpty() ) { throw errors; } // if } Declaration *DeclarationNode::build() const { if ( ! error.empty() ) throw SemanticError( error, this ); if ( type ) { if ( type->kind == TypeData::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; } else { return buildDecl( type, name, storageClass, maybeBuild< Expression >( bitfieldWidth ), isInline, isNoreturn, linkage, maybeBuild< Initializer >(initializer) )->set_extension( extension ); } // if } // if if ( ! isInline && ! isNoreturn ) { return (new ObjectDecl( name, storageClass, linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ))->set_extension( extension ); } // if throw SemanticError( "invalid function specifier in declaration of ", this ); } Type *DeclarationNode::buildType() const { assert( type ); switch ( type->kind ) { case TypeData::Enum: return new EnumInstType( buildQualifiers( type ), type->enumeration.name ); case TypeData::Aggregate: { ReferenceToType *ret; switch ( type->aggregate.kind ) { case DeclarationNode::Struct: ret = new StructInstType( buildQualifiers( type ), type->aggregate.name ); break; case DeclarationNode::Union: ret = new UnionInstType( buildQualifiers( type ), type->aggregate.name ); break; case DeclarationNode::Trait: ret = new TraitInstType( buildQualifiers( type ), type->aggregate.name ); break; default: assert( false ); } // switch buildList( type->aggregate.actuals, ret->get_parameters() ); return ret; } case TypeData::Symbolic: { TypeInstType *ret = new TypeInstType( buildQualifiers( type ), type->symbolic.name, false ); buildList( type->symbolic.actuals, ret->get_parameters() ); return ret; } case TypeData::Attr: { assert( type->kind == TypeData::Attr ); // assert( type->attr ); AttrType * ret; if ( attr.expr ) { ret = new AttrType( buildQualifiers( type ), attr.name, attr.expr->build() ); } else { assert( attr.type ); ret = new AttrType( buildQualifiers( type ), attr.name, attr.type->buildType() ); } // if return ret; } default: return typebuild( type ); } // switch } // DeclarationNode::StorageClass DeclarationNode::buildStorageClass() const { // DeclarationNode::StorageClass ret = DeclarationNode::NoStorageClass; // for ( std::list< DeclarationNode::StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) { // if ( *i == DeclarationNode::Inline || *i == DeclarationNode::Noreturn ) continue; // ignore function specifiers // if ( ret != DeclarationNode::NoStorageClass ) { // already have a valid storage class ? // throw SemanticError( "invalid combination of storage classes in declaration of ", this ); // } // if // ret = *i; // } // for // return ret; // } // bool DeclarationNode::buildFuncSpecifier( DeclarationNode::StorageClass key ) const { // std::list< DeclarationNode::StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), key ); // if ( first == storageClasses.end() ) return false; // not found // first = std::find( ++first, storageClasses.end(), key ); // found // if ( first == storageClasses.end() ) return true; // not found again // throw SemanticError( "duplicate function specifier in declaration of ", this ); // } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //