Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r45e753c re4d7c1c  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 12:34:05 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Apr 20 11:46:00 2023
    13 // Update Count     : 1393
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Aug  8 17:07:00 2022
     13// Update Count     : 1185
    1414//
    15 
    16 #include "DeclarationNode.h"
    1715
    1816#include <cassert>                 // for assert, assertf, strict_dynamic_cast
     
    2321#include <string>                  // for string, operator+, allocator, char...
    2422
    25 #include "AST/Attribute.hpp"       // for Attribute
    26 #include "AST/Copy.hpp"            // for shallowCopy
    27 #include "AST/Decl.hpp"            // for Decl
    28 #include "AST/Expr.hpp"            // for Expr
    29 #include "AST/Print.hpp"           // for print
    30 #include "AST/Stmt.hpp"            // for AsmStmt, DirectiveStmt
    31 #include "AST/StorageClasses.hpp"  // for Storage::Class
    32 #include "AST/Type.hpp"            // for Type
    33 #include "Common/CodeLocation.h"   // for CodeLocation
    34 #include "Common/Iterate.hpp"      // for reverseIterate
    3523#include "Common/SemanticError.h"  // for SemanticError
    3624#include "Common/UniqueName.h"     // for UniqueName
    37 #include "Common/utility.h"        // for maybeClone
    38 #include "Parser/ExpressionNode.h" // for ExpressionNode
    39 #include "Parser/InitializerNode.h"// for InitializerNode
    40 #include "Parser/StatementNode.h"  // for StatementNode
     25#include "Common/utility.h"        // for maybeClone, maybeBuild, CodeLocation
     26#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
     27#include "SynTree/LinkageSpec.h"   // for Spec, linkageName, Cforall
     28#include "SynTree/Attribute.h"     // for Attribute
     29#include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration
     30#include "SynTree/Expression.h"    // for Expression, ConstantExpr
     31#include "SynTree/Statement.h"     // for AsmStmt
     32#include "SynTree/Type.h"          // for Type, Type::StorageClasses, Type::...
    4133#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    4234#include "TypedefTable.h"          // for TypedefTable
     
    4941
    5042// These must harmonize with the corresponding DeclarationNode enumerations.
    51 const char * DeclarationNode::basicTypeNames[] = {
    52         "void", "_Bool", "char", "int", "int128",
    53         "float", "double", "long double", "float80", "float128",
    54         "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames"
    55 };
    56 const char * DeclarationNode::complexTypeNames[] = {
    57         "_Complex", "NoComplexTypeNames", "_Imaginary"
    58 }; // Imaginary unsupported => parse, but make invisible and print error message
    59 const char * DeclarationNode::signednessNames[] = {
    60         "signed", "unsigned", "NoSignednessNames"
    61 };
    62 const char * DeclarationNode::lengthNames[] = {
    63         "short", "long", "long long", "NoLengthNames"
    64 };
    65 const char * DeclarationNode::builtinTypeNames[] = {
    66         "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames"
    67 };
     43const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128",
     44                                                                                                   "float", "double", "long double", "float80", "float128",
     45                                                                                                   "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" };
     46const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message
     47const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
     48const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
     49const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
    6850
    6951UniqueName DeclarationNode::anonymous( "__anonymous" );
    7052
    71 extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
     53extern LinkageSpec::Spec linkage;                                               // defined in parser.yy
    7254
    7355DeclarationNode::DeclarationNode() :
     
    7557
    7658//      variable.name = nullptr;
    77         variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
     59        variable.tyClass = TypeDecl::NUMBER_OF_KINDS;
    7860        variable.assertions = nullptr;
    7961        variable.initializer = nullptr;
    8062
     63//      attr.name = nullptr;
     64        attr.expr = nullptr;
     65        attr.type = nullptr;
     66
    8167        assert.condition = nullptr;
    8268        assert.message = nullptr;
     
    8470
    8571DeclarationNode::~DeclarationNode() {
     72//      delete attr.name;
     73        delete attr.expr;
     74        delete attr.type;
     75
    8676//      delete variable.name;
    8777        delete variable.assertions;
    8878        delete variable.initializer;
    8979
    90 //      delete type;
     80//      delete type;
    9181        delete bitfieldWidth;
    9282
     
    113103        newnode->hasEllipsis = hasEllipsis;
    114104        newnode->linkage = linkage;
    115         newnode->asmName = maybeCopy( asmName );
    116         newnode->attributes = attributes;
     105        newnode->asmName = maybeClone( asmName );
     106        cloneAll( attributes, newnode->attributes );
    117107        newnode->initializer = maybeClone( initializer );
    118108        newnode->extension = extension;
     
    125115        newnode->variable.initializer = maybeClone( variable.initializer );
    126116
     117//      newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr;
     118        newnode->attr.expr = maybeClone( attr.expr );
     119        newnode->attr.type = maybeClone( attr.type );
     120
    127121        newnode->assert.condition = maybeClone( assert.condition );
    128         newnode->assert.message = maybeCopy( assert.message );
     122        newnode->assert.message = maybeClone( assert.message );
    129123        return newnode;
    130124} // DeclarationNode::clone
     
    136130        } // if
    137131
    138         if ( linkage != ast::Linkage::Cforall ) {
    139                 os << ast::Linkage::name( linkage ) << " ";
    140         } // if
    141 
    142         ast::print( os, storageClasses );
    143         ast::print( os, funcSpecs );
     132        if ( linkage != LinkageSpec::Cforall ) {
     133                os << LinkageSpec::name( linkage ) << " ";
     134        } // if
     135
     136        storageClasses.print( os );
     137        funcSpecs.print( os );
    144138
    145139        if ( type ) {
     
    160154        } // if
    161155
    162         if ( ! attributes.empty() ) {
    163                 os << string( indent + 2, ' ' ) << "with attributes " << endl;
    164                 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
    165                         os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
    166                 } // for
    167         } // if
     156        for ( Attribute * attr: reverseIterate( attributes ) ) {
     157                os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
     158        } // for
    168159
    169160        os << endl;
     
    177168}
    178169
    179 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
     170DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {
    180171        DeclarationNode * newnode = new DeclarationNode;
    181172        newnode->storageClasses = sc;
     
    183174} // DeclarationNode::newStorageClass
    184175
    185 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
     176DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {
    186177        DeclarationNode * newnode = new DeclarationNode;
    187178        newnode->funcSpecs = fs;
     
    189180} // DeclarationNode::newFuncSpecifier
    190181
    191 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
     182DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {
    192183        DeclarationNode * newnode = new DeclarationNode;
    193184        newnode->type = new TypeData();
     
    249240}
    250241
    251 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     242DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    252243        DeclarationNode * newnode = new DeclarationNode;
    253244        newnode->type = new TypeData( TypeData::Aggregate );
    254245        newnode->type->aggregate.kind = kind;
    255         newnode->type->aggregate.anon = name == nullptr;
    256         newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
     246        newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    257247        newnode->type->aggregate.actuals = actuals;
    258248        newnode->type->aggregate.fields = fields;
     
    260250        newnode->type->aggregate.tagged = false;
    261251        newnode->type->aggregate.parent = nullptr;
     252        newnode->type->aggregate.anon = name == nullptr;
    262253        return newnode;
    263254} // DeclarationNode::newAggregate
     
    266257        DeclarationNode * newnode = new DeclarationNode;
    267258        newnode->type = new TypeData( TypeData::Enum );
    268         newnode->type->enumeration.anon = name == nullptr;
    269         newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
     259        newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    270260        newnode->type->enumeration.constants = constants;
    271261        newnode->type->enumeration.body = body;
     262        newnode->type->enumeration.anon = name == nullptr;
    272263        newnode->type->enumeration.typed = typed;
    273264        newnode->type->enumeration.hiding = hiding;
    274         if ( base && base->type )  {
     265        if ( base && base->type)  {
    275266                newnode->type->base = base->type;
    276267        } // if
     
    278269        return newnode;
    279270} // DeclarationNode::newEnum
     271
     272
    280273
    281274DeclarationNode * DeclarationNode::newName( const string * name ) {
     
    330323} // DeclarationNode::newFromTypeGen
    331324
    332 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
     325DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
    333326        DeclarationNode * newnode = newName( name );
    334327        newnode->type = nullptr;
     
    342335        newnode->type = new TypeData( TypeData::Aggregate );
    343336        newnode->type->aggregate.name = name;
    344         newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
     337        newnode->type->aggregate.kind = AggregateDecl::Trait;
    345338        newnode->type->aggregate.params = params;
    346339        newnode->type->aggregate.fields = asserts;
     
    352345        newnode->type = new TypeData( TypeData::AggregateInst );
    353346        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
    354         newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
     347        newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
    355348        newnode->type->aggInst.aggregate->aggregate.name = name;
    356349        newnode->type->aggInst.params = params;
     
    387380        newnode->type->array.dimension = size;
    388381        newnode->type->array.isStatic = isStatic;
    389         if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
     382        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) {
    390383                newnode->type->array.isVarLen = false;
    391384        } else {
     
    457450        DeclarationNode * newnode = new DeclarationNode;
    458451        newnode->type = nullptr;
    459         std::vector<ast::ptr<ast::Expr>> exprs;
     452        std::list< Expression * > exprs;
    460453        buildList( expr, exprs );
    461         newnode->attributes.push_back(
    462                 new ast::Attribute( *name, std::move( exprs ) ) );
     454        newnode->attributes.push_back( new Attribute( *name, exprs ) );
    463455        delete name;
    464456        return newnode;
     
    477469}
    478470
    479 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
     471DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
    480472        DeclarationNode * newnode = new DeclarationNode;
    481473        newnode->assert.condition = condition;
     
    484476}
    485477
    486 static void appendError( string & dst, const string & src ) {
     478
     479void appendError( string & dst, const string & src ) {
    487480        if ( src.empty() ) return;
    488481        if ( dst.empty() ) { dst = src; return; }
     
    491484
    492485void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
    493         const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
    494         const ast::CV::Qualifiers duplicates = qsrc & qdst;
    495 
    496         if ( duplicates.any() ) {
    497                 std::stringstream str;
    498                 str << "duplicate ";
    499                 ast::print( str, duplicates );
    500                 str << "qualifier(s)";
    501                 appendError( error, str.str() );
     486        const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
     487
     488        if ( (qsrc & qdst).any() ) {                                            // duplicates ?
     489                for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates
     490                        if ( qsrc[i] && qdst[i] ) {
     491                                appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] );
     492                        } // if
     493                } // for
    502494        } // for
    503495} // DeclarationNode::checkQualifiers
    504496
    505497void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    506         ast::Function::Specs fsDups = funcSpecs & src->funcSpecs;
    507         if ( fsDups.any() ) {
    508                 std::stringstream str;
    509                 str << "duplicate ";
    510                 ast::print( str, fsDups );
    511                 str << "function specifier(s)";
    512                 appendError( error, str.str() );
    513         } // if
    514 
    515         // Skip if everything is unset.
    516         if ( storageClasses.any() && src->storageClasses.any() ) {
    517                 ast::Storage::Classes dups = storageClasses & src->storageClasses;
    518                 // Check for duplicates.
    519                 if ( dups.any() ) {
    520                         std::stringstream str;
    521                         str << "duplicate ";
    522                         ast::print( str, dups );
    523                         str << "storage class(es)";
    524                         appendError( error, str.str() );
    525                 // Check for conflicts.
    526                 } else if ( !src->storageClasses.is_threadlocal_any() ) {
    527                         std::stringstream str;
    528                         str << "conflicting ";
    529                         ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) );
    530                         str << "& ";
    531                         ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) );
    532                         str << "storage classes";
    533                         appendError( error, str.str() );
    534                         // FIX to preserve invariant of one basic storage specifier
    535                         src->storageClasses.reset();
    536                 }
     498        if ( (funcSpecs & src->funcSpecs).any() ) {                     // duplicates ?
     499                for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates
     500                        if ( funcSpecs[i] && src->funcSpecs[i] ) {
     501                                appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] );
     502                        } // if
     503                } // for
     504        } // if
     505
     506        if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ?
     507                if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ?
     508                        for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates
     509                                if ( storageClasses[i] && src->storageClasses[i] ) {
     510                                        appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] );
     511                                } // if
     512                        } // for
     513                        // src is the new item being added and has a single bit
     514                } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
     515                        appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] +
     516                                                 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
     517                        src->storageClasses.reset();                            // FIX to preserve invariant of one basic storage specifier
     518                } // if
    537519        } // if
    538520
     
    544526        storageClasses |= q->storageClasses;
    545527
    546         std::vector<ast::ptr<ast::Attribute>> tmp;
    547         tmp.reserve( q->attributes.size() );
    548         for ( auto const & attr : q->attributes ) {
    549                 tmp.emplace_back( ast::shallowCopy( attr.get() ) );
    550         }
    551         spliceBegin( attributes, tmp );
    552 
     528        for ( Attribute * attr: reverseIterate( q->attributes ) ) {
     529                attributes.push_front( attr->clone() );
     530        } // for
    553531        return this;
    554532} // DeclarationNode::copySpecifiers
     
    598576
    599577        checkQualifiers( type, q->type );
    600         if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
    601                 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
     578        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.val != 0 && error.length() == 0 ) {
     579                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )], builtinTypeNames[builtin] );
    602580        } // if
    603581        addQualifiersToType( q->type, type );
     
    620598        } else {
    621599                switch ( dst->kind ) {
    622                 case TypeData::Unknown:
     600                  case TypeData::Unknown:
    623601                        src->qualifiers |= dst->qualifiers;
    624602                        dst = src;
    625603                        src = nullptr;
    626604                        break;
    627                 case TypeData::Basic:
     605                  case TypeData::Basic:
    628606                        dst->qualifiers |= src->qualifiers;
    629607                        if ( src->kind != TypeData::Unknown ) {
     
    653631                        } // if
    654632                        break;
    655                 default:
     633                  default:
    656634                        switch ( src->kind ) {
    657                         case TypeData::Aggregate:
    658                         case TypeData::Enum:
     635                          case TypeData::Aggregate:
     636                          case TypeData::Enum:
    659637                                dst->base = new TypeData( TypeData::AggregateInst );
    660638                                dst->base->aggInst.aggregate = src;
     
    665643                                src = nullptr;
    666644                                break;
    667                         default:
     645                          default:
    668646                                if ( dst->forall ) {
    669647                                        dst->forall->appendList( src->forall );
     
    736714
    737715DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
    738         if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    739                 if ( variable.assertions ) {
    740                         variable.assertions->appendList( assertions );
    741                 } else {
    742                         variable.assertions = assertions;
    743                 } // if
    744                 return this;
     716        if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     717                if ( variable.assertions ) {
     718                        variable.assertions->appendList( assertions );
     719                } else {
     720                        variable.assertions = assertions;
     721                } // if
     722                return this;
    745723        } // if
    746724
    747725        assert( type );
    748726        switch ( type->kind ) {
    749         case TypeData::Symbolic:
     727          case TypeData::Symbolic:
    750728                if ( type->symbolic.assertions ) {
    751729                        type->symbolic.assertions->appendList( assertions );
     
    754732                } // if
    755733                break;
    756         default:
     734          default:
    757735                assert( false );
    758736        } // switch
     
    818796DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
    819797        if ( a ) {
    820                 spliceBegin( attributes, a->attributes );
     798                for ( Attribute *attr: reverseIterate( a->attributes ) ) {
     799                        attributes.push_front( attr );
     800                } // for
    821801                a->attributes.clear();
    822802        } // if
     
    851831                if ( type ) {
    852832                        switch ( type->kind ) {
    853                         case TypeData::Aggregate:
    854                         case TypeData::Enum:
     833                          case TypeData::Aggregate:
     834                          case TypeData::Enum:
    855835                                p->type->base = new TypeData( TypeData::AggregateInst );
    856836                                p->type->base->aggInst.aggregate = type;
     
    861841                                break;
    862842
    863                         default:
     843                          default:
    864844                                p->type->base = type;
    865845                        } // switch
     
    883863
    884864DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
    885         if ( ! a ) return this;
     865  if ( ! a ) return this;
    886866        assert( a->type->kind == TypeData::Array );
    887867        TypeData * lastArray = findLast( a->type );
    888868        if ( type ) {
    889869                switch ( type->kind ) {
    890                 case TypeData::Aggregate:
    891                 case TypeData::Enum:
     870                  case TypeData::Aggregate:
     871                  case TypeData::Enum:
    892872                        lastArray->base = new TypeData( TypeData::AggregateInst );
    893873                        lastArray->base->aggInst.aggregate = type;
     
    897877                        lastArray->base->qualifiers |= type->qualifiers;
    898878                        break;
    899                 default:
     879                  default:
    900880                        lastArray->base = type;
    901881                } // switch
     
    939919
    940920DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
    941         assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
     921        assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
    942922        variable.initializer = init;
    943923        return this;
     
    1003983}
    1004984
    1005 // If a typedef wraps an anonymous declaration, name the inner declaration
    1006 // so it has a consistent name across translation units.
    1007 static void nameTypedefedDecl(
    1008                 DeclarationNode * innerDecl,
    1009                 const DeclarationNode * outerDecl ) {
    1010         TypeData * outer = outerDecl->type;
    1011         assert( outer );
    1012         // First make sure this is a typedef:
    1013         if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) {
    1014                 return;
    1015         }
    1016         TypeData * inner = innerDecl->type;
    1017         assert( inner );
    1018         // Always clear any CVs associated with the aggregate:
    1019         inner->qualifiers.reset();
    1020         // Handle anonymous aggregates: typedef struct { int i; } foo
    1021         if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) {
    1022                 delete inner->aggregate.name;
    1023                 inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
    1024                 inner->aggregate.anon = false;
    1025                 assert( outer->base );
    1026                 delete outer->base->aggInst.aggregate->aggregate.name;
    1027                 outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
    1028                 outer->base->aggInst.aggregate->aggregate.anon = false;
    1029                 outer->base->aggInst.aggregate->qualifiers.reset();
    1030         // Handle anonymous enumeration: typedef enum { A, B, C } foo
    1031         } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) {
    1032                 delete inner->enumeration.name;
    1033                 inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
    1034                 inner->enumeration.anon = false;
    1035                 assert( outer->base );
    1036                 delete outer->base->aggInst.aggregate->enumeration.name;
    1037                 outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
    1038                 outer->base->aggInst.aggregate->enumeration.anon = false;
    1039                 // No qualifiers.reset() here.
    1040         }
    1041 }
    1042 
    1043 // This code handles a special issue with the attribute transparent_union.
    1044 //
    1045 //    typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))
    1046 //
    1047 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are
    1048 // aligned.  However, the attribute transparent_union must be moved from the typedef_name to
    1049 // alias union U.  Currently, this is the only know attribute that must be moved from typedef to
    1050 // alias.
    1051 static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) {
    1052         if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {
    1053                 // Is the typedef alias a union aggregate?
    1054                 if ( nullptr == unionDecl ) return;
    1055 
    1056                 // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
    1057                 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {
    1058                         auto instType = ast::mutate( unionInstType );
    1059                         // Remove all transparent_union attributes from typedef and move to alias union.
    1060                         for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) {
    1061                                 assert( *attr );
    1062                                 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
    1063                                         unionDecl->attributes.emplace_back( attr->release() );
    1064                                         attr = instType->attributes.erase( attr );
    1065                                 } else {
    1066                                         attr++;
    1067                                 }
    1068                         }
    1069                         typedefDecl->base = instType;
    1070                 }
    1071         }
    1072 }
    1073 
    1074 // Get the non-anonymous name of the instance type of the declaration,
    1075 // if one exists.
    1076 static const std::string * getInstTypeOfName( ast::Decl * decl ) {
    1077         if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    1078                 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) {
    1079                         if ( aggr->name.find("anonymous") == std::string::npos ) {
    1080                                 return &aggr->name;
    1081                         }
    1082                 }
    1083         }
    1084         return nullptr;
    1085 }
    1086 
    1087 void buildList( DeclarationNode * firstNode,
    1088                 std::vector<ast::ptr<ast::Decl>> & outputList ) {
     985void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {
    1089986        SemanticErrorException errors;
    1090         std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
    1091 
    1092         for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
     987        std::back_insert_iterator< std::list< Declaration * > > out( outputList );
     988
     989        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    1093990                try {
    1094                         bool extracted_named = false;
    1095                         ast::UnionDecl * unionDecl = nullptr;
    1096 
     991                        bool extracted = false;
     992                        bool anon = false;
    1097993                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    1098                                 assert( cur->type );
    1099                                 nameTypedefedDecl( extr, cur );
    1100 
    1101                                 if ( ast::Decl * decl = extr->build() ) {
    1102                                         // Remember the declaration if it is a union aggregate ?
    1103                                         unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
    1104 
    1105                                         *out++ = decl;
     994                                // handle the case where a structure declaration is contained within an object or type declaration
     995                                Declaration * decl = extr->build();
     996                                if ( decl ) {
     997                                        // hoist the structure declaration
     998                                        decl->location = cur->location;
     999                                        * out++ = decl;
    11061000
    11071001                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
     1002                                        extracted = true;
    11081003                                        assert( extr->type );
    11091004                                        if ( extr->type->kind == TypeData::Aggregate ) {
    1110                                                 // typedef struct { int A } B is the only case?
    1111                                                 extracted_named = !extr->type->aggregate.anon;
     1005                                                anon = extr->type->aggregate.anon;
    11121006                                        } else if ( extr->type->kind == TypeData::Enum ) {
    1113                                                 // typedef enum { A } B is the only case?
    1114                                                 extracted_named = !extr->type->enumeration.anon;
    1115                                         } else {
    1116                                                 extracted_named = true;
     1007                                                // xxx - is it useful to have an implicit anonymous enum member?
     1008                                                anon = extr->type->enumeration.anon;
    11171009                                        }
    11181010                                } // if
     
    11201012                        } // if
    11211013
    1122                         if ( ast::Decl * decl = cur->build() ) {
    1123                                 moveUnionAttribute( decl, unionDecl );
    1124 
    1125                                 if ( "" == decl->name && !cur->get_inLine() ) {
    1126                                         // Don't include anonymous declaration for named aggregates,
    1127                                         // but do include them for anonymous aggregates, e.g.:
    1128                                         // struct S {
    1129                                         //   struct T { int x; }; // no anonymous member
    1130                                         //   struct { int y; };   // anonymous member
    1131                                         //   struct T;            // anonymous member
    1132                                         // };
    1133                                         if ( extracted_named ) {
    1134                                                 continue;
    1135                                         }
    1136 
    1137                                         if ( auto name = getInstTypeOfName( decl ) ) {
    1138                                                 // Temporary: warn about anonymous member declarations of named types, since
    1139                                                 // this conflicts with the syntax for the forward declaration of an anonymous type.
    1140                                                 SemanticWarning( cur->location, Warning::AggrForwardDecl, name->c_str() );
    1141                                         }
     1014                        Declaration * decl = cur->build();
     1015                        if ( decl ) {
     1016                                // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
     1017                                // struct S {
     1018                                //   struct T { int x; }; // no anonymous member
     1019                                //   struct { int y; };   // anonymous member
     1020                                //   struct T;            // anonymous member
     1021                                // };
     1022                                if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) {
     1023                                        if ( decl->name == "" ) {
     1024                                                if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) {
     1025                                                        if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) {
     1026                                                                if ( aggr->name.find("anonymous") == std::string::npos ) {
     1027                                                                        if ( ! cur->get_inLine() ) {
     1028                                                                                // temporary: warn about anonymous member declarations of named types, since
     1029                                                                                // this conflicts with the syntax for the forward declaration of an anonymous type
     1030                                                                                SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() );
     1031                                                                        } // if
     1032                                                                } // if
     1033                                                        } // if
     1034                                                } // if
     1035                                        } // if
     1036                                        decl->location = cur->location;
     1037                                        *out++ = decl;
    11421038                                } // if
    1143                                 *out++ = decl;
    11441039                        } // if
    1145                 } catch ( SemanticErrorException & e ) {
     1040                } catch( SemanticErrorException & e ) {
    11461041                        errors.append( e );
    11471042                } // try
     
    11541049
    11551050// currently only builds assertions, function parameters, and return values
    1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
     1051void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) {
    11571052        SemanticErrorException errors;
    1158         std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
    1159 
    1160         for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
     1053        std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
     1054
     1055        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    11611056                try {
    1162                         ast::Decl * decl = cur->build();
    1163                         assertf( decl, "buildList: build for ast::DeclWithType." );
    1164                         if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
     1057                        Declaration * decl = cur->build();
     1058                        assert( decl );
     1059                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    11651060                                dwt->location = cur->location;
    11661061                                *out++ = dwt;
    1167                         } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
     1062                        } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
    11681063                                // e.g., int foo(struct S) {}
    1169                                 auto inst = new ast::StructInstType( agg->name );
    1170                                 auto obj = new ast::ObjectDecl( cur->location, "", inst );
    1171                                 obj->linkage = linkage;
     1064                                StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
     1065                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1066                                obj->location = cur->location;
    11721067                                *out++ = obj;
    11731068                                delete agg;
    1174                         } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
     1069                        } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
    11751070                                // e.g., int foo(union U) {}
    1176                                 auto inst = new ast::UnionInstType( agg->name );
    1177                                 auto obj = new ast::ObjectDecl( cur->location,
    1178                                         "", inst, nullptr, ast::Storage::Classes(),
    1179                                         linkage );
     1071                                UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
     1072                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1073                                obj->location = cur->location;
    11801074                                *out++ = obj;
    1181                         } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
     1075                        } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
    11821076                                // e.g., int foo(enum E) {}
    1183                                 auto inst = new ast::EnumInstType( agg->name );
    1184                                 auto obj = new ast::ObjectDecl( cur->location,
    1185                                         "",
    1186                                         inst,
    1187                                         nullptr,
    1188                                         ast::Storage::Classes(),
    1189                                         linkage
    1190                                 );
     1077                                EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
     1078                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1079                                obj->location = cur->location;
    11911080                                *out++ = obj;
    1192                         } else {
    1193                                 assertf( false, "buildList: Could not convert to ast::DeclWithType." );
    11941081                        } // if
    1195                 } catch ( SemanticErrorException & e ) {
     1082                } catch( SemanticErrorException & e ) {
    11961083                        errors.append( e );
    11971084                } // try
     
    12031090} // buildList
    12041091
    1205 void buildTypeList( const DeclarationNode * firstNode,
    1206                 std::vector<ast::ptr<ast::Type>> & outputList ) {
     1092void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {
    12071093        SemanticErrorException errors;
    1208         std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
    1209 
    1210         for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
     1094        std::back_insert_iterator< std::list< Type * > > out( outputList );
     1095        const DeclarationNode * cur = firstNode;
     1096
     1097        while ( cur ) {
    12111098                try {
    12121099                        * out++ = cur->buildType();
    1213                 } catch ( SemanticErrorException & e ) {
     1100                } catch( SemanticErrorException & e ) {
    12141101                        errors.append( e );
    12151102                } // try
    1216         } // for
     1103                cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
     1104        } // while
    12171105
    12181106        if ( ! errors.isEmpty() ) {
     
    12211109} // buildTypeList
    12221110
    1223 ast::Decl * DeclarationNode::build() const {
     1111Declaration * DeclarationNode::build() const {
    12241112        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
    12251113
    12261114        if ( asmStmt ) {
    1227                 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
    1228                 return new ast::AsmDecl( stmt->location, stmt );
     1115                return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) );
    12291116        } // if
    12301117        if ( directiveStmt ) {
    1231                 auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
    1232                 return new ast::DirectiveDecl( stmt->location, stmt );
    1233         } // if
    1234 
    1235         if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
     1118                return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) );
     1119        } // if
     1120
     1121        if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
    12361122                // otype is internally converted to dtype + otype parameters
    1237                 static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };
    1238                 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
     1123                static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension };
     1124                static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
    12391125                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1240                 ast::TypeDecl * ret = new ast::TypeDecl( location,
    1241                         *name,
    1242                         ast::Storage::Classes(),
    1243                         (ast::Type *)nullptr,
    1244                         kindMap[ variable.tyClass ],
    1245                         variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype,
    1246                         variable.initializer ? variable.initializer->buildType() : nullptr
    1247                 );
    1248                 buildList( variable.assertions, ret->assertions );
     1126                TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr );
     1127                buildList( variable.assertions, ret->get_assertions() );
    12491128                return ret;
    12501129        } // if
     
    12681147                } // if
    12691148                bool isDelete = initializer && initializer->get_isDelete();
    1270                 ast::Decl * decl = buildDecl(
    1271                         type,
    1272                         name ? *name : string( "" ),
    1273                         storageClasses,
    1274                         maybeBuild( bitfieldWidth ),
    1275                         funcSpecs,
    1276                         linkage,
    1277                         asmName,
    1278                         isDelete ? nullptr : maybeBuild( initializer ),
    1279                         copy( attributes )
    1280                 )->set_extension( extension );
     1149                Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
    12811150                if ( isDelete ) {
    1282                         auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
     1151                        DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
    12831152                        dwt->isDeleted = true;
    12841153                }
     
    12871156
    12881157        if ( assert.condition ) {
    1289                 auto cond = maybeBuild( assert.condition );
    1290                 auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) );
    1291                 return new ast::StaticAssertDecl( location, cond, msg );
     1158                return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
    12921159        }
    12931160
     
    13001167        } // if
    13011168        if ( enumInLine ) {
    1302                 return new ast::InlineMemberDecl( location,
    1303                         *name, (ast::Type*)nullptr, storageClasses, linkage );
     1169                return new InlineMemberDecl( *name, storageClasses, linkage, nullptr );
    13041170        } // if
    13051171        assertf( name, "ObjectDecl must a have name\n" );
    1306         auto ret = new ast::ObjectDecl( location,
    1307                 *name,
    1308                 (ast::Type*)nullptr,
    1309                 maybeBuild( initializer ),
    1310                 storageClasses,
    1311                 linkage,
    1312                 maybeBuild( bitfieldWidth )
    1313         );
    1314         ret->asmName = asmName;
    1315         ret->extension = extension;
    1316         return ret;
    1317 }
    1318 
    1319 ast::Type * DeclarationNode::buildType() const {
     1172        return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension );
     1173}
     1174
     1175Type * DeclarationNode::buildType() const {
    13201176        assert( type );
    13211177
     1178        if ( attr.expr ) {
     1179                return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes );
     1180        } else if ( attr.type ) {
     1181                return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes );
     1182        } // if
     1183
    13221184        switch ( type->kind ) {
    1323         case TypeData::Enum:
    1324         case TypeData::Aggregate: {
    1325                 ast::BaseInstType * ret =
    1326                         buildComAggInst( type, copy( attributes ), linkage );
    1327                 buildList( type->aggregate.actuals, ret->params );
    1328                 return ret;
    1329         }
    1330         case TypeData::Symbolic: {
    1331                 ast::TypeInstType * ret = new ast::TypeInstType(
    1332                         *type->symbolic.name,
    1333                         // This is just a default, the true value is not known yet.
    1334                         ast::TypeDecl::Dtype,
    1335                         buildQualifiers( type ),
    1336                         copy( attributes ) );
    1337                 buildList( type->symbolic.actuals, ret->params );
    1338                 return ret;
    1339         }
    1340         default:
    1341                 ast::Type * simpletypes = typebuild( type );
    1342                 // copy because member is const
    1343                 simpletypes->attributes = attributes;
     1185          case TypeData::Enum:
     1186          case TypeData::Aggregate: {
     1187                  ReferenceToType * ret = buildComAggInst( type, attributes, linkage );
     1188                  buildList( type->aggregate.actuals, ret->get_parameters() );
     1189                  return ret;
     1190          }
     1191          case TypeData::Symbolic: {
     1192                  TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes );
     1193                  buildList( type->symbolic.actuals, ret->get_parameters() );
     1194                  return ret;
     1195          }
     1196          default:
     1197                Type * simpletypes = typebuild( type );
     1198                simpletypes->get_attributes() = attributes;             // copy because member is const
    13441199                return simpletypes;
    13451200        } // switch
Note: See TracChangeset for help on using the changeset viewer.