Ignore:
Timestamp:
Apr 21, 2023, 5:36:12 PM (2 years ago)
Author:
JiadaL <j82liang@…>
Branches:
ADT, master
Children:
28f8f15, 6e4c44d
Parents:
2ed94a9 (diff), 699a97d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r2ed94a9 rb110bcc  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 12:34:05 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug  8 17:07:00 2022
    13 // Update Count     : 1185
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Apr 20 11:46:00 2023
     13// Update Count     : 1393
    1414//
     15
     16#include "DeclarationNode.h"
    1517
    1618#include <cassert>                 // for assert, assertf, strict_dynamic_cast
     
    2123#include <string>                  // for string, operator+, allocator, char...
    2224
     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
    2335#include "Common/SemanticError.h"  // for SemanticError
    2436#include "Common/UniqueName.h"     // for UniqueName
    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::...
     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
    3341#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    3442#include "TypedefTable.h"          // for TypedefTable
     
    4149
    4250// These must harmonize with the corresponding DeclarationNode enumerations.
    43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128",
    44                                                                                                    "float", "double", "long double", "float80", "float128",
    45                                                                                                    "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" };
    46 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message
    47 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
    48 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
    49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
     51const 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};
     56const char * DeclarationNode::complexTypeNames[] = {
     57        "_Complex", "NoComplexTypeNames", "_Imaginary"
     58}; // Imaginary unsupported => parse, but make invisible and print error message
     59const char * DeclarationNode::signednessNames[] = {
     60        "signed", "unsigned", "NoSignednessNames"
     61};
     62const char * DeclarationNode::lengthNames[] = {
     63        "short", "long", "long long", "NoLengthNames"
     64};
     65const char * DeclarationNode::builtinTypeNames[] = {
     66        "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames"
     67};
    5068
    5169UniqueName DeclarationNode::anonymous( "__anonymous" );
    5270
    53 extern LinkageSpec::Spec linkage;                                               // defined in parser.yy
     71extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
    5472
    5573DeclarationNode::DeclarationNode() :
     
    5775
    5876//      variable.name = nullptr;
    59         variable.tyClass = TypeDecl::NUMBER_OF_KINDS;
     77        variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
    6078        variable.assertions = nullptr;
    6179        variable.initializer = nullptr;
    6280
    63 //      attr.name = nullptr;
    64         attr.expr = nullptr;
    65         attr.type = nullptr;
    66 
    6781        assert.condition = nullptr;
    6882        assert.message = nullptr;
     
    7084
    7185DeclarationNode::~DeclarationNode() {
    72 //      delete attr.name;
    73         delete attr.expr;
    74         delete attr.type;
    75 
    7686//      delete variable.name;
    7787        delete variable.assertions;
    7888        delete variable.initializer;
    7989
    80 //      delete type;
     90//      delete type;
    8191        delete bitfieldWidth;
    8292
     
    103113        newnode->hasEllipsis = hasEllipsis;
    104114        newnode->linkage = linkage;
    105         newnode->asmName = maybeClone( asmName );
    106         cloneAll( attributes, newnode->attributes );
     115        newnode->asmName = maybeCopy( asmName );
     116        newnode->attributes = attributes;
    107117        newnode->initializer = maybeClone( initializer );
    108118        newnode->extension = extension;
     
    115125        newnode->variable.initializer = maybeClone( variable.initializer );
    116126
    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 
    121127        newnode->assert.condition = maybeClone( assert.condition );
    122         newnode->assert.message = maybeClone( assert.message );
     128        newnode->assert.message = maybeCopy( assert.message );
    123129        return newnode;
    124130} // DeclarationNode::clone
     
    130136        } // if
    131137
    132         if ( linkage != LinkageSpec::Cforall ) {
    133                 os << LinkageSpec::name( linkage ) << " ";
    134         } // if
    135 
    136         storageClasses.print( os );
    137         funcSpecs.print( os );
     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 );
    138144
    139145        if ( type ) {
     
    154160        } // if
    155161
    156         for ( Attribute * attr: reverseIterate( attributes ) ) {
    157                 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
    158         } // for
     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
    159168
    160169        os << endl;
     
    168177}
    169178
    170 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {
     179DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
    171180        DeclarationNode * newnode = new DeclarationNode;
    172181        newnode->storageClasses = sc;
     
    174183} // DeclarationNode::newStorageClass
    175184
    176 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {
     185DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
    177186        DeclarationNode * newnode = new DeclarationNode;
    178187        newnode->funcSpecs = fs;
     
    180189} // DeclarationNode::newFuncSpecifier
    181190
    182 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {
     191DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
    183192        DeclarationNode * newnode = new DeclarationNode;
    184193        newnode->type = new TypeData();
     
    240249}
    241250
    242 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     251DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    243252        DeclarationNode * newnode = new DeclarationNode;
    244253        newnode->type = new TypeData( TypeData::Aggregate );
    245254        newnode->type->aggregate.kind = kind;
    246         newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     255        newnode->type->aggregate.anon = name == nullptr;
     256        newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    247257        newnode->type->aggregate.actuals = actuals;
    248258        newnode->type->aggregate.fields = fields;
     
    250260        newnode->type->aggregate.tagged = false;
    251261        newnode->type->aggregate.parent = nullptr;
    252         newnode->type->aggregate.anon = name == nullptr;
    253262        return newnode;
    254263} // DeclarationNode::newAggregate
     
    257266        DeclarationNode * newnode = new DeclarationNode;
    258267        newnode->type = new TypeData( TypeData::Enum );
    259         newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     268        newnode->type->enumeration.anon = name == nullptr;
     269        newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    260270        newnode->type->enumeration.constants = constants;
    261271        newnode->type->enumeration.body = body;
    262         newnode->type->enumeration.anon = name == nullptr;
    263272        newnode->type->enumeration.typed = typed;
    264273        newnode->type->enumeration.hiding = hiding;
    265         if ( base && base->type)  {
     274        if ( base && base->type )  {
    266275                newnode->type->base = base->type;
    267276        } // if
     
    269278        return newnode;
    270279} // DeclarationNode::newEnum
    271 
    272 
    273280
    274281DeclarationNode * DeclarationNode::newName( const string * name ) {
     
    323330} // DeclarationNode::newFromTypeGen
    324331
    325 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
     332DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
    326333        DeclarationNode * newnode = newName( name );
    327334        newnode->type = nullptr;
     
    335342        newnode->type = new TypeData( TypeData::Aggregate );
    336343        newnode->type->aggregate.name = name;
    337         newnode->type->aggregate.kind = AggregateDecl::Trait;
     344        newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
    338345        newnode->type->aggregate.params = params;
    339346        newnode->type->aggregate.fields = asserts;
     
    345352        newnode->type = new TypeData( TypeData::AggregateInst );
    346353        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
    347         newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
     354        newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
    348355        newnode->type->aggInst.aggregate->aggregate.name = name;
    349356        newnode->type->aggInst.params = params;
     
    380387        newnode->type->array.dimension = size;
    381388        newnode->type->array.isStatic = isStatic;
    382         if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) {
     389        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
    383390                newnode->type->array.isVarLen = false;
    384391        } else {
     
    450457        DeclarationNode * newnode = new DeclarationNode;
    451458        newnode->type = nullptr;
    452         std::list< Expression * > exprs;
     459        std::vector<ast::ptr<ast::Expr>> exprs;
    453460        buildList( expr, exprs );
    454         newnode->attributes.push_back( new Attribute( *name, exprs ) );
     461        newnode->attributes.push_back(
     462                new ast::Attribute( *name, std::move( exprs ) ) );
    455463        delete name;
    456464        return newnode;
     
    469477}
    470478
    471 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
     479DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
    472480        DeclarationNode * newnode = new DeclarationNode;
    473481        newnode->assert.condition = condition;
     
    476484}
    477485
    478 
    479 void appendError( string & dst, const string & src ) {
     486static void appendError( string & dst, const string & src ) {
    480487        if ( src.empty() ) return;
    481488        if ( dst.empty() ) { dst = src; return; }
     
    484491
    485492void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
    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
     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() );
    494502        } // for
    495503} // DeclarationNode::checkQualifiers
    496504
    497505void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    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
     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                }
    519537        } // if
    520538
     
    526544        storageClasses |= q->storageClasses;
    527545
    528         for ( Attribute * attr: reverseIterate( q->attributes ) ) {
    529                 attributes.push_front( attr->clone() );
    530         } // for
     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
    531553        return this;
    532554} // DeclarationNode::copySpecifiers
     
    576598
    577599        checkQualifiers( type, q->type );
    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] );
     600        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
     601                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
    580602        } // if
    581603        addQualifiersToType( q->type, type );
     
    598620        } else {
    599621                switch ( dst->kind ) {
    600                   case TypeData::Unknown:
     622                case TypeData::Unknown:
    601623                        src->qualifiers |= dst->qualifiers;
    602624                        dst = src;
    603625                        src = nullptr;
    604626                        break;
    605                   case TypeData::Basic:
     627                case TypeData::Basic:
    606628                        dst->qualifiers |= src->qualifiers;
    607629                        if ( src->kind != TypeData::Unknown ) {
     
    631653                        } // if
    632654                        break;
    633                   default:
     655                default:
    634656                        switch ( src->kind ) {
    635                           case TypeData::Aggregate:
    636                           case TypeData::Enum:
     657                        case TypeData::Aggregate:
     658                        case TypeData::Enum:
    637659                                dst->base = new TypeData( TypeData::AggregateInst );
    638660                                dst->base->aggInst.aggregate = src;
     
    643665                                src = nullptr;
    644666                                break;
    645                           default:
     667                        default:
    646668                                if ( dst->forall ) {
    647669                                        dst->forall->appendList( src->forall );
     
    714736
    715737DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
    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;
     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;
    723745        } // if
    724746
    725747        assert( type );
    726748        switch ( type->kind ) {
    727           case TypeData::Symbolic:
     749        case TypeData::Symbolic:
    728750                if ( type->symbolic.assertions ) {
    729751                        type->symbolic.assertions->appendList( assertions );
     
    732754                } // if
    733755                break;
    734           default:
     756        default:
    735757                assert( false );
    736758        } // switch
     
    796818DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
    797819        if ( a ) {
    798                 for ( Attribute *attr: reverseIterate( a->attributes ) ) {
    799                         attributes.push_front( attr );
    800                 } // for
     820                spliceBegin( attributes, a->attributes );
    801821                a->attributes.clear();
    802822        } // if
     
    831851                if ( type ) {
    832852                        switch ( type->kind ) {
    833                           case TypeData::Aggregate:
    834                           case TypeData::Enum:
     853                        case TypeData::Aggregate:
     854                        case TypeData::Enum:
    835855                                p->type->base = new TypeData( TypeData::AggregateInst );
    836856                                p->type->base->aggInst.aggregate = type;
     
    841861                                break;
    842862
    843                           default:
     863                        default:
    844864                                p->type->base = type;
    845865                        } // switch
     
    863883
    864884DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
    865   if ( ! a ) return this;
     885        if ( ! a ) return this;
    866886        assert( a->type->kind == TypeData::Array );
    867887        TypeData * lastArray = findLast( a->type );
    868888        if ( type ) {
    869889                switch ( type->kind ) {
    870                   case TypeData::Aggregate:
    871                   case TypeData::Enum:
     890                case TypeData::Aggregate:
     891                case TypeData::Enum:
    872892                        lastArray->base = new TypeData( TypeData::AggregateInst );
    873893                        lastArray->base->aggInst.aggregate = type;
     
    877897                        lastArray->base->qualifiers |= type->qualifiers;
    878898                        break;
    879                   default:
     899                default:
    880900                        lastArray->base = type;
    881901                } // switch
     
    919939
    920940DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
    921         assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
     941        assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
    922942        variable.initializer = init;
    923943        return this;
     
    9831003}
    9841004
    985 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {
     1005// If a typedef wraps an anonymous declaration, name the inner declaration
     1006// so it has a consistent name across translation units.
     1007static 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.
     1051static 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.
     1076static 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
     1087void buildList( DeclarationNode * firstNode,
     1088                std::vector<ast::ptr<ast::Decl>> & outputList ) {
    9861089        SemanticErrorException errors;
    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() ) ) {
     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 ) ) {
    9901093                try {
    991                         bool extracted = false;
    992                         bool anon = false;
     1094                        bool extracted_named = false;
     1095                        ast::UnionDecl * unionDecl = nullptr;
     1096
    9931097                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    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;
     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;
    10001106
    10011107                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
    1002                                         extracted = true;
    10031108                                        assert( extr->type );
    10041109                                        if ( extr->type->kind == TypeData::Aggregate ) {
    1005                                                 anon = extr->type->aggregate.anon;
     1110                                                // typedef struct { int A } B is the only case?
     1111                                                extracted_named = !extr->type->aggregate.anon;
    10061112                                        } else if ( extr->type->kind == TypeData::Enum ) {
    1007                                                 // xxx - is it useful to have an implicit anonymous enum member?
    1008                                                 anon = extr->type->enumeration.anon;
     1113                                                // typedef enum { A } B is the only case?
     1114                                                extracted_named = !extr->type->enumeration.anon;
     1115                                        } else {
     1116                                                extracted_named = true;
    10091117                                        }
    10101118                                } // if
     
    10121120                        } // if
    10131121
    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;
     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                                        }
    10381142                                } // if
     1143                                *out++ = decl;
    10391144                        } // if
    1040                 } catch( SemanticErrorException & e ) {
     1145                } catch ( SemanticErrorException & e ) {
    10411146                        errors.append( e );
    10421147                } // try
     
    10491154
    10501155// currently only builds assertions, function parameters, and return values
    1051 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) {
     1156void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
    10521157        SemanticErrorException errors;
    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() ) ) {
     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 ) ) {
    10561161                try {
    1057                         Declaration * decl = cur->build();
    1058                         assert( decl );
    1059                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     1162                        ast::Decl * decl = cur->build();
     1163                        assertf( decl, "buildList: build for ast::DeclWithType." );
     1164                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    10601165                                dwt->location = cur->location;
    10611166                                *out++ = dwt;
    1062                         } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
     1167                        } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
    10631168                                // e.g., int foo(struct S) {}
    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;
     1169                                auto inst = new ast::StructInstType( agg->name );
     1170                                auto obj = new ast::ObjectDecl( cur->location, "", inst );
     1171                                obj->linkage = linkage;
    10671172                                *out++ = obj;
    10681173                                delete agg;
    1069                         } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1174                        } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
    10701175                                // e.g., int foo(union U) {}
    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;
     1176                                auto inst = new ast::UnionInstType( agg->name );
     1177                                auto obj = new ast::ObjectDecl( cur->location,
     1178                                        "", inst, nullptr, ast::Storage::Classes(),
     1179                                        linkage );
    10741180                                *out++ = obj;
    1075                         } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
     1181                        } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
    10761182                                // e.g., int foo(enum E) {}
    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;
     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                                );
    10801191                                *out++ = obj;
     1192                        } else {
     1193                                assertf( false, "buildList: Could not convert to ast::DeclWithType." );
    10811194                        } // if
    1082                 } catch( SemanticErrorException & e ) {
     1195                } catch ( SemanticErrorException & e ) {
    10831196                        errors.append( e );
    10841197                } // try
     
    10901203} // buildList
    10911204
    1092 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {
     1205void buildTypeList( const DeclarationNode * firstNode,
     1206                std::vector<ast::ptr<ast::Type>> & outputList ) {
    10931207        SemanticErrorException errors;
    1094         std::back_insert_iterator< std::list< Type * > > out( outputList );
    1095         const DeclarationNode * cur = firstNode;
    1096 
    1097         while ( cur ) {
     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 ) ) {
    10981211                try {
    10991212                        * out++ = cur->buildType();
    1100                 } catch( SemanticErrorException & e ) {
     1213                } catch ( SemanticErrorException & e ) {
    11011214                        errors.append( e );
    11021215                } // try
    1103                 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
    1104         } // while
     1216        } // for
    11051217
    11061218        if ( ! errors.isEmpty() ) {
     
    11091221} // buildTypeList
    11101222
    1111 Declaration * DeclarationNode::build() const {
     1223ast::Decl * DeclarationNode::build() const {
    11121224        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
    11131225
    11141226        if ( asmStmt ) {
    1115                 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) );
     1227                auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
     1228                return new ast::AsmDecl( stmt->location, stmt );
    11161229        } // if
    11171230        if ( directiveStmt ) {
    1118                 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) );
    1119         } // if
    1120 
    1121         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     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 ) {
    11221236                // otype is internally converted to dtype + otype parameters
    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." );
     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." );
    11251239                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    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() );
     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 );
    11281249                return ret;
    11291250        } // if
     
    11471268                } // if
    11481269                bool isDelete = initializer && initializer->get_isDelete();
    1149                 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     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 );
    11501281                if ( isDelete ) {
    1151                         DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
     1282                        auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
    11521283                        dwt->isDeleted = true;
    11531284                }
     
    11561287
    11571288        if ( assert.condition ) {
    1158                 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
     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 );
    11591292        }
    11601293
     
    11671300        } // if
    11681301        if ( enumInLine ) {
    1169                 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr );
     1302                return new ast::InlineMemberDecl( location,
     1303                        *name, (ast::Type*)nullptr, storageClasses, linkage );
    11701304        } // if
    11711305        assertf( name, "ObjectDecl must a have name\n" );
    1172         return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension );
    1173 }
    1174 
    1175 Type * DeclarationNode::buildType() const {
     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
     1319ast::Type * DeclarationNode::buildType() const {
    11761320        assert( type );
    11771321
    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 
    11841322        switch ( type->kind ) {
    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
     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;
    11991344                return simpletypes;
    12001345        } // switch
Note: See TracChangeset for help on using the changeset viewer.