source: src/Parser/DeclarationNode.cc @ 36e120a

Last change on this file since 36e120a was 5bf685f, checked in by Andrew Beach <ajbeach@…>, 6 months ago

Replayed maybeClone with maybeCopy, removed unused helppers in utility.h and pushed some includes out of headers.

  • Property mode set to 100644
File size: 44.4 KB
RevLine 
[b87a5ed]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[974906e2]7// DeclarationNode.cc --
[b87a5ed]8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 12:34:05 2015
[b38f6da]11// Last Modified By : Peter A. Buhr
[ca9d65e]12// Last Modified On : Thu Dec 14 19:05:17 2023
13// Update Count     : 1407
[b87a5ed]14//
15
[c468150]16#include "DeclarationNode.h"
17
[e3e16bc]18#include <cassert>                 // for assert, assertf, strict_dynamic_cast
[d180746]19#include <iterator>                // for back_insert_iterator
20#include <list>                    // for list
21#include <memory>                  // for unique_ptr
22#include <ostream>                 // for operator<<, ostream, basic_ostream
23#include <string>                  // for string, operator+, allocator, char...
[51b7345]24
[bb7422a]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
[d180746]35#include "Common/SemanticError.h"  // for SemanticError
36#include "Common/UniqueName.h"     // for UniqueName
[5bf685f]37#include "Common/utility.h"        // for copy, spliceBegin
[c468150]38#include "Parser/ExpressionNode.h" // for ExpressionNode
39#include "Parser/InitializerNode.h"// for InitializerNode
40#include "Parser/StatementNode.h"  // for StatementNode
[d180746]41#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
[2f0a0678]42#include "TypedefTable.h"          // for TypedefTable
[bdd516a]43
[de62360d]44extern TypedefTable typedefTable;
45
[51b7345]46using namespace std;
47
[201aeb9]48// These must harmonize with the corresponding DeclarationNode enumerations.
[702e826]49const char * DeclarationNode::basicTypeNames[] = {
50        "void", "_Bool", "char", "int", "int128",
51        "float", "double", "long double", "float80", "float128",
52        "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames"
53};
54const char * DeclarationNode::complexTypeNames[] = {
55        "_Complex", "NoComplexTypeNames", "_Imaginary"
56}; // Imaginary unsupported => parse, but make invisible and print error message
57const char * DeclarationNode::signednessNames[] = {
58        "signed", "unsigned", "NoSignednessNames"
59};
60const char * DeclarationNode::lengthNames[] = {
61        "short", "long", "long long", "NoLengthNames"
62};
63const char * DeclarationNode::builtinTypeNames[] = {
64        "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames"
65};
[51b7345]66
67UniqueName DeclarationNode::anonymous( "__anonymous" );
68
[bb7422a]69extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
[51b7345]70
[7d05e7e]71DeclarationNode::DeclarationNode() :
[e07caa2]72        linkage( ::linkage ) {
[2298f728]73
[faddbd8]74//      variable.name = nullptr;
[bb7422a]75        variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
[28307be]76        variable.assertions = nullptr;
[67cf18c]77        variable.initializer = nullptr;
[7d05e7e]78
[f6e3e34]79        assert.condition = nullptr;
80        assert.message = nullptr;
[28307be]81}
82
83DeclarationNode::~DeclarationNode() {
[faddbd8]84//      delete variable.name;
[2298f728]85        delete variable.assertions;
[67cf18c]86        delete variable.initializer;
[2298f728]87
[702e826]88//      delete type;
[28307be]89        delete bitfieldWidth;
[e994912]90
91        delete asmStmt;
[58dd019]92        // asmName, no delete, passed to next stage
[28307be]93        delete initializer;
[f6e3e34]94
95        delete assert.condition;
96        delete assert.message;
[28307be]97}
98
[ba7aa2d]99DeclarationNode * DeclarationNode::clone() const {
100        DeclarationNode * newnode = new DeclarationNode;
[5bf685f]101        newnode->set_next( maybeCopy( get_next() ) );
[2298f728]102        newnode->name = name ? new string( *name ) : nullptr;
[c0aa336]103
[2e5fa345]104        newnode->builtin = NoBuiltinType;
[5bf685f]105        newnode->type = maybeCopy( type );
[679e644]106        newnode->inLine = inLine;
[a7c90d4]107        newnode->storageClasses = storageClasses;
108        newnode->funcSpecs = funcSpecs;
[5bf685f]109        newnode->bitfieldWidth = maybeCopy( bitfieldWidth );
110        newnode->enumeratorValue.reset( maybeCopy( enumeratorValue.get() ) );
[b87a5ed]111        newnode->hasEllipsis = hasEllipsis;
112        newnode->linkage = linkage;
[bb7422a]113        newnode->asmName = maybeCopy( asmName );
114        newnode->attributes = attributes;
[5bf685f]115        newnode->initializer = maybeCopy( initializer );
[c0aa336]116        newnode->extension = extension;
[5bf685f]117        newnode->asmStmt = maybeCopy( asmStmt );
[c0aa336]118        newnode->error = error;
[3848e0e]119
[faddbd8]120//      newnode->variable.name = variable.name ? new string( *variable.name ) : nullptr;
[28307be]121        newnode->variable.tyClass = variable.tyClass;
[5bf685f]122        newnode->variable.assertions = maybeCopy( variable.assertions );
123        newnode->variable.initializer = maybeCopy( variable.initializer );
[3848e0e]124
[5bf685f]125        newnode->assert.condition = maybeCopy( assert.condition );
[bb7422a]126        newnode->assert.message = maybeCopy( assert.message );
[28307be]127        return newnode;
128} // DeclarationNode::clone
[3848e0e]129
[f2f512ba]130void DeclarationNode::print( std::ostream & os, int indent ) const {
[59db689]131        os << string( indent, ' ' );
[2298f728]132        if ( name ) {
133                os << *name << ": ";
[68cd1ce]134        } // if
[51b7345]135
[bb7422a]136        if ( linkage != ast::Linkage::Cforall ) {
137                os << ast::Linkage::name( linkage ) << " ";
[68cd1ce]138        } // if
[3848e0e]139
[bb7422a]140        ast::print( os, storageClasses );
141        ast::print( os, funcSpecs );
[dd020c0]142
[b87a5ed]143        if ( type ) {
144                type->print( os, indent );
145        } else {
146                os << "untyped entity ";
[68cd1ce]147        } // if
[3848e0e]148
[b87a5ed]149        if ( bitfieldWidth ) {
[59db689]150                os << endl << string( indent + 2, ' ' ) << "with bitfield width ";
[b87a5ed]151                bitfieldWidth->printOneLine( os );
[68cd1ce]152        } // if
[3848e0e]153
[2298f728]154        if ( initializer ) {
[59db689]155                os << endl << string( indent + 2, ' ' ) << "with initializer ";
[b87a5ed]156                initializer->printOneLine( os );
[974906e2]157                os << " maybe constructed? " << initializer->get_maybeConstructed();
[68cd1ce]158        } // if
[3848e0e]159
[692c1cc]160        if ( ! attributes.empty() ) {
161                os << string( indent + 2, ' ' ) << "with attributes " << endl;
[bb7422a]162                for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
[692c1cc]163                        os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
164                } // for
165        } // if
[66406f3]166
[b87a5ed]167        os << endl;
[51b7345]168}
169
[f2f512ba]170void DeclarationNode::printList( std::ostream & os, int indent ) const {
[b87a5ed]171        ParseNode::printList( os, indent );
172        if ( hasEllipsis ) {
173                os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
[68cd1ce]174        } // if
[51b7345]175}
176
[bb7422a]177DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
[ba7aa2d]178        DeclarationNode * newnode = new DeclarationNode;
[08d5507b]179        newnode->storageClasses = sc;
[b87a5ed]180        return newnode;
[dd020c0]181} // DeclarationNode::newStorageClass
[3848e0e]182
[bb7422a]183DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
[ba7aa2d]184        DeclarationNode * newnode = new DeclarationNode;
[08d5507b]185        newnode->funcSpecs = fs;
[c1c1112]186        return newnode;
[dd020c0]187} // DeclarationNode::newFuncSpecifier
[c1c1112]188
[bb7422a]189DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
[ba7aa2d]190        DeclarationNode * newnode = new DeclarationNode;
[dd020c0]191        newnode->type = new TypeData();
[738e304]192        newnode->type->qualifiers = tq;
[b87a5ed]193        return newnode;
[dd020c0]194} // DeclarationNode::newQualifier
[3848e0e]195
[c1c1112]196DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) {
[ba7aa2d]197        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]198        newnode->type = new TypeData( TypeData::Basic );
[5b639ee]199        newnode->type->basictype = bt;
[b87a5ed]200        return newnode;
[984dce6]201} // DeclarationNode::newBasicType
[3848e0e]202
[5b639ee]203DeclarationNode * DeclarationNode::newComplexType( ComplexType ct ) {
[ba7aa2d]204        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]205        newnode->type = new TypeData( TypeData::Basic );
[5b639ee]206        newnode->type->complextype = ct;
[b87a5ed]207        return newnode;
[5b639ee]208} // DeclarationNode::newComplexType
209
210DeclarationNode * DeclarationNode::newSignedNess( Signedness sn ) {
[ba7aa2d]211        DeclarationNode * newnode = new DeclarationNode;
[5b639ee]212        newnode->type = new TypeData( TypeData::Basic );
213        newnode->type->signedness = sn;
214        return newnode;
215} // DeclarationNode::newSignedNess
216
217DeclarationNode * DeclarationNode::newLength( Length lnth ) {
[ba7aa2d]218        DeclarationNode * newnode = new DeclarationNode;
[5b639ee]219        newnode->type = new TypeData( TypeData::Basic );
220        newnode->type->length = lnth;
221        return newnode;
222} // DeclarationNode::newLength
[3848e0e]223
[dd020c0]224DeclarationNode * DeclarationNode::newForall( DeclarationNode * forall ) {
225        DeclarationNode * newnode = new DeclarationNode;
226        newnode->type = new TypeData( TypeData::Unknown );
227        newnode->type->forall = forall;
228        return newnode;
229} // DeclarationNode::newForall
230
[47498bd]231DeclarationNode * DeclarationNode::newFromGlobalScope() {
232        DeclarationNode * newnode = new DeclarationNode;
233        newnode->type = new TypeData( TypeData::GlobalScope );
234        return newnode;
235}
236
[c5d7701]237DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {
[c194661]238        DeclarationNode * newnode = new DeclarationNode;
239        newnode->type = new TypeData( TypeData::Qualified );
240        newnode->type->qualified.parent = parent->type;
241        newnode->type->qualified.child = child->type;
242        parent->type = nullptr;
243        child->type = nullptr;
244        delete parent;
245        delete child;
246        return newnode;
[c5d7701]247}
248
[bb7422a]249DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
[ba7aa2d]250        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]251        newnode->type = new TypeData( TypeData::Aggregate );
[8f6f47d7]252        newnode->type->aggregate.kind = kind;
[692c1cc]253        newnode->type->aggregate.anon = name == nullptr;
254        newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
[8f6f47d7]255        newnode->type->aggregate.actuals = actuals;
256        newnode->type->aggregate.fields = fields;
257        newnode->type->aggregate.body = body;
[6ea87486]258        newnode->type->aggregate.tagged = false;
259        newnode->type->aggregate.parent = nullptr;
[b87a5ed]260        return newnode;
[984dce6]261} // DeclarationNode::newAggregate
[3848e0e]262
[e4d7c1c]263DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
[ba7aa2d]264        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]265        newnode->type = new TypeData( TypeData::Enum );
[692c1cc]266        newnode->type->enumeration.anon = name == nullptr;
267        newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
[8f6f47d7]268        newnode->type->enumeration.constants = constants;
[ca1a547]269        newnode->type->enumeration.body = body;
[b0d9ff7]270        newnode->type->enumeration.typed = typed;
[e4d7c1c]271        newnode->type->enumeration.hiding = hiding;
[78e2fca]272        if ( base && base->type )  {
[ed9a1ae]273                newnode->type->base = base->type;
[9e7236f4]274        } // if
275
[b87a5ed]276        return newnode;
[984dce6]277} // DeclarationNode::newEnum
[3848e0e]278
[a46b69c]279DeclarationNode * DeclarationNode::newName( const string * name ) {
[ba7aa2d]280        DeclarationNode * newnode = new DeclarationNode;
[a46b69c]281        assert( ! newnode->name );
[2298f728]282        newnode->name = name;
[a46b69c]283        return newnode;
284} // DeclarationNode::newName
285
[374cb117]286DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) {
[a46b69c]287        DeclarationNode * newnode = newName( name );
[4f147cc]288        newnode->enumeratorValue.reset( constant );
[b87a5ed]289        return newnode;
[984dce6]290} // DeclarationNode::newEnumConstant
[3848e0e]291
[374cb117]292DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) {
[b0d9ff7]293        if ( init ) {
294                if ( init->get_expression() ) {
[374cb117]295                        return newEnumConstant( name, init->get_expression() );
[b0d9ff7]296                } else {
[374cb117]297                        DeclarationNode * newnode = newName( name );
298                        newnode->initializer = init;
299                        return newnode;
300                } // if
301        } else {
[b0d9ff7]302                return newName( name );
[374cb117]303        } // if
[9e7236f4]304} // DeclarationNode::newEnumValueGeneric
[374cb117]305
[1e30df7]306DeclarationNode * DeclarationNode::newEnumInLine( const string name ) {
307        DeclarationNode * newnode = newName( new std::string(name) );
308        newnode->enumInLine = true;
309        return newnode;
310}
311
[a46b69c]312DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
[ba7aa2d]313        DeclarationNode * newnode = new DeclarationNode;
[a46b69c]314        newnode->type = new TypeData( TypeData::SymbolicInst );
315        newnode->type->symbolic.name = name;
316        newnode->type->symbolic.isTypedef = true;
317        newnode->type->symbolic.params = nullptr;
[b87a5ed]318        return newnode;
[a46b69c]319} // DeclarationNode::newFromTypedef
[3848e0e]320
[25bca42]321DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) {
[ba7aa2d]322        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]323        newnode->type = new TypeData( TypeData::SymbolicInst );
[fb114fa1]324        newnode->type->symbolic.name = name;
[8f6f47d7]325        newnode->type->symbolic.isTypedef = false;
326        newnode->type->symbolic.actuals = params;
[b87a5ed]327        return newnode;
[984dce6]328} // DeclarationNode::newFromTypeGen
[3848e0e]329
[bb7422a]330DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
[a46b69c]331        DeclarationNode * newnode = newName( name );
[2298f728]332        newnode->type = nullptr;
[28307be]333        newnode->variable.tyClass = tc;
[faddbd8]334        newnode->variable.assertions = nullptr;
[b87a5ed]335        return newnode;
[984dce6]336} // DeclarationNode::newTypeParam
[3848e0e]337
[fb114fa1]338DeclarationNode * DeclarationNode::newTrait( const string * name, DeclarationNode * params, DeclarationNode * asserts ) {
[ba7aa2d]339        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]340        newnode->type = new TypeData( TypeData::Aggregate );
[2298f728]341        newnode->type->aggregate.name = name;
[bb7422a]342        newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
[8f6f47d7]343        newnode->type->aggregate.params = params;
344        newnode->type->aggregate.fields = asserts;
[b87a5ed]345        return newnode;
[984dce6]346} // DeclarationNode::newTrait
[3848e0e]347
[fb114fa1]348DeclarationNode * DeclarationNode::newTraitUse( const string * name, ExpressionNode * params ) {
[ba7aa2d]349        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]350        newnode->type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]351        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
[bb7422a]352        newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
[2298f728]353        newnode->type->aggInst.aggregate->aggregate.name = name;
[8f6f47d7]354        newnode->type->aggInst.params = params;
[b87a5ed]355        return newnode;
[984dce6]356} // DeclarationNode::newTraitUse
[3848e0e]357
[25bca42]358DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) {
[a46b69c]359        DeclarationNode * newnode = newName( name );
[b87a5ed]360        newnode->type = new TypeData( TypeData::Symbolic );
[8f6f47d7]361        newnode->type->symbolic.isTypedef = false;
362        newnode->type->symbolic.params = typeParams;
[b87a5ed]363        return newnode;
[984dce6]364} // DeclarationNode::newTypeDecl
[3848e0e]365
[ce8c12f]366DeclarationNode * DeclarationNode::newPointer( DeclarationNode * qualifiers, OperKinds kind ) {
[ba7aa2d]367        DeclarationNode * newnode = new DeclarationNode;
[ce8c12f]368        newnode->type = new TypeData( kind == OperKinds::PointTo ? TypeData::Pointer : TypeData::Reference );
[71d0eab]369        if ( kind == OperKinds::And ) {
370                // T && is parsed as 'And' operator rather than two references => add a second reference type
371                TypeData * td = new TypeData( TypeData::Reference );
372                td->base = newnode->type;
373                newnode->type = td;
374        }
[c3396e0]375        if ( qualifiers ) {
376                return newnode->addQualifiers( qualifiers );
377        } else {
378                return newnode;
379        } // if
[984dce6]380} // DeclarationNode::newPointer
[3848e0e]381
[ba7aa2d]382DeclarationNode * DeclarationNode::newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic ) {
383        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]384        newnode->type = new TypeData( TypeData::Array );
[8f6f47d7]385        newnode->type->array.dimension = size;
386        newnode->type->array.isStatic = isStatic;
[bb7422a]387        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
[8f6f47d7]388                newnode->type->array.isVarLen = false;
[71bd8c6]389        } else {
[8f6f47d7]390                newnode->type->array.isVarLen = true;
[71bd8c6]391        } // if
[b87a5ed]392        return newnode->addQualifiers( qualifiers );
[984dce6]393} // DeclarationNode::newArray
[3848e0e]394
[ba7aa2d]395DeclarationNode * DeclarationNode::newVarArray( DeclarationNode * qualifiers ) {
396        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]397        newnode->type = new TypeData( TypeData::Array );
[2298f728]398        newnode->type->array.dimension = nullptr;
[8f6f47d7]399        newnode->type->array.isStatic = false;
400        newnode->type->array.isVarLen = true;
[b87a5ed]401        return newnode->addQualifiers( qualifiers );
[3848e0e]402}
403
[ba7aa2d]404DeclarationNode * DeclarationNode::newBitfield( ExpressionNode * size ) {
405        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]406        newnode->bitfieldWidth = size;
407        return newnode;
[3848e0e]408}
409
[ba7aa2d]410DeclarationNode * DeclarationNode::newTuple( DeclarationNode * members ) {
411        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]412        newnode->type = new TypeData( TypeData::Tuple );
[8f6f47d7]413        newnode->type->tuple = members;
[b87a5ed]414        return newnode;
[3848e0e]415}
416
[f855545]417DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) {
[ba7aa2d]418        DeclarationNode * newnode = new DeclarationNode;
[f855545]419        newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof );
[8f6f47d7]420        newnode->type->typeexpr = expr;
[b87a5ed]421        return newnode;
[3848e0e]422}
423
[93bbbc4]424DeclarationNode * DeclarationNode::newVtableType( DeclarationNode * decl ) {
425        DeclarationNode * newnode = new DeclarationNode;
426        newnode->type = new TypeData( TypeData::Vtable );
427        newnode->setBase( decl->type );
428        return newnode;
429}
430
[8f6f47d7]431DeclarationNode * DeclarationNode::newBuiltinType( BuiltinType bt ) {
[ba7aa2d]432        DeclarationNode * newnode = new DeclarationNode;
[8f6f47d7]433        newnode->type = new TypeData( TypeData::Builtin );
434        newnode->builtin = bt;
[148f7290]435        newnode->type->builtintype = newnode->builtin;
[8f6f47d7]436        return newnode;
437} // DeclarationNode::newBuiltinType
438
[a46b69c]439DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {
440        DeclarationNode * newnode = newName( name );
441        newnode->type = new TypeData( TypeData::Function );
442        newnode->type->function.params = param;
443        newnode->type->function.body = body;
444
445        if ( ret ) {
446                newnode->type->base = ret->type;
447                ret->type = nullptr;
448                delete ret;
449        } // if
450
451        return newnode;
452} // DeclarationNode::newFunction
453
[25bca42]454DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
[44a81853]455        DeclarationNode * newnode = new DeclarationNode;
456        newnode->type = nullptr;
[bb7422a]457        std::vector<ast::ptr<ast::Expr>> exprs;
[44a81853]458        buildList( expr, exprs );
[b38f6da]459        newnode->attributes.push_back( new ast::Attribute( *name, std::move( exprs ) ) );
[44a81853]460        delete name;
461        return newnode;
462}
463
[2d019af]464DeclarationNode * DeclarationNode::newDirectiveStmt( StatementNode * stmt ) {
465        DeclarationNode * newnode = new DeclarationNode;
466        newnode->directiveStmt = stmt;
467        return newnode;
468}
469
[e994912]470DeclarationNode * DeclarationNode::newAsmStmt( StatementNode * stmt ) {
471        DeclarationNode * newnode = new DeclarationNode;
472        newnode->asmStmt = stmt;
473        return newnode;
474}
475
[bb7422a]476DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
[f6e3e34]477        DeclarationNode * newnode = new DeclarationNode;
478        newnode->assert.condition = condition;
479        newnode->assert.message = message;
480        return newnode;
481}
482
[bb7422a]483static void appendError( string & dst, const string & src ) {
[5b639ee]484        if ( src.empty() ) return;
485        if ( dst.empty() ) { dst = src; return; }
486        dst += ", " + src;
487} // appendError
488
[ba7aa2d]489void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
[bb7422a]490        const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
491        const ast::CV::Qualifiers duplicates = qsrc & qdst;
492
493        if ( duplicates.any() ) {
494                std::stringstream str;
495                str << "duplicate ";
496                ast::print( str, duplicates );
497                str << "qualifier(s)";
498                appendError( error, str.str() );
[a7c90d4]499        } // for
[c1c1112]500} // DeclarationNode::checkQualifiers
501
[a7c90d4]502void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
[bb7422a]503        ast::Function::Specs fsDups = funcSpecs & src->funcSpecs;
504        if ( fsDups.any() ) {
505                std::stringstream str;
506                str << "duplicate ";
507                ast::print( str, fsDups );
508                str << "function specifier(s)";
509                appendError( error, str.str() );
[dd020c0]510        } // if
511
[bb7422a]512        // Skip if everything is unset.
513        if ( storageClasses.any() && src->storageClasses.any() ) {
514                ast::Storage::Classes dups = storageClasses & src->storageClasses;
515                // Check for duplicates.
516                if ( dups.any() ) {
517                        std::stringstream str;
518                        str << "duplicate ";
519                        ast::print( str, dups );
520                        str << "storage class(es)";
521                        appendError( error, str.str() );
522                // Check for conflicts.
523                } else if ( !src->storageClasses.is_threadlocal_any() ) {
524                        std::stringstream str;
525                        str << "conflicting ";
526                        ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) );
527                        str << "& ";
528                        ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) );
529                        str << "storage classes";
530                        appendError( error, str.str() );
531                        // FIX to preserve invariant of one basic storage specifier
532                        src->storageClasses.reset();
533                }
[b6424d9]534        } // if
[dd020c0]535
[a7c90d4]536        appendError( error, src->error );
537} // DeclarationNode::checkSpecifiers
[b6424d9]538
[a7c90d4]539DeclarationNode * DeclarationNode::copySpecifiers( DeclarationNode * q ) {
[6f95000]540        funcSpecs |= q->funcSpecs;
541        storageClasses |= q->storageClasses;
[c0aa336]542
[bb7422a]543        std::vector<ast::ptr<ast::Attribute>> tmp;
544        tmp.reserve( q->attributes.size() );
545        for ( auto const & attr : q->attributes ) {
546                tmp.emplace_back( ast::shallowCopy( attr.get() ) );
547        }
548        spliceBegin( attributes, tmp );
549
[b6424d9]550        return this;
[a7c90d4]551} // DeclarationNode::copySpecifiers
[b6424d9]552
[f2f512ba]553static void addQualifiersToType( TypeData *& src, TypeData * dst ) {
[101e0bd]554        if ( dst->base ) {
555                addQualifiersToType( src, dst->base );
556        } else if ( dst->kind == TypeData::Function ) {
557                dst->base = src;
[2298f728]558                src = nullptr;
[101e0bd]559        } else {
[6f95000]560                dst->qualifiers |= src->qualifiers;
[101e0bd]561        } // if
562} // addQualifiersToType
563
[ba7aa2d]564DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) {
[af9da5f]565        if ( ! q ) { return this; }                                                     // empty qualifier
[101e0bd]566
[a7c90d4]567        checkSpecifiers( q );
568        copySpecifiers( q );
[101e0bd]569
[c38ae92]570        if ( ! q->type ) { delete q; return this; }
[101e0bd]571
572        if ( ! type ) {
[c38ae92]573                type = q->type;                                                                 // reuse structure
[1b77274]574                q->type = nullptr;
575                delete q;
[101e0bd]576                return this;
577        } // if
578
[c38ae92]579        if ( q->type->forall ) {                                                        // forall qualifier ?
580                if ( type->forall ) {                                                   // polymorphic routine ?
581                        type->forall->appendList( q->type->forall ); // augment forall qualifier
[101e0bd]582                } else {
[c38ae92]583                        if ( type->kind == TypeData::Aggregate ) {      // struct/union ?
584                                if ( type->aggregate.params ) {                 // polymorphic ?
585                                        type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier
586                                } else {                                                                // not polymorphic
[a1c9ddd]587                                        type->aggregate.params = q->type->forall; // set forall qualifier
[c38ae92]588                                } // if
589                        } else {                                                                        // not polymorphic
590                                type->forall = q->type->forall;                 // make polymorphic routine
[68cd1ce]591                        } // if
592                } // if
[c38ae92]593                q->type->forall = nullptr;                                              // forall qualifier moved
[68cd1ce]594        } // if
[6ef2d81]595
[a7c90d4]596        checkQualifiers( type, q->type );
[78e2fca]597        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
[be00a2d]598                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
[9dc31c10]599        } // if
[6ef2d81]600        addQualifiersToType( q->type, type );
601
[b87a5ed]602        delete q;
603        return this;
[101e0bd]604} // addQualifiers
[3848e0e]605
[f2f512ba]606static void addTypeToType( TypeData *& src, TypeData *& dst ) {
[101e0bd]607        if ( src->forall && dst->kind == TypeData::Function ) {
608                if ( dst->forall ) {
609                        dst->forall->appendList( src->forall );
[b87a5ed]610                } else {
[101e0bd]611                        dst->forall = src->forall;
612                } // if
[2298f728]613                src->forall = nullptr;
[101e0bd]614        } // if
615        if ( dst->base ) {
616                addTypeToType( src, dst->base );
617        } else {
618                switch ( dst->kind ) {
[0d0931d]619                case TypeData::Unknown:
[6f95000]620                        src->qualifiers |= dst->qualifiers;
[101e0bd]621                        dst = src;
[2298f728]622                        src = nullptr;
[101e0bd]623                        break;
[0d0931d]624                case TypeData::Basic:
[6f95000]625                        dst->qualifiers |= src->qualifiers;
[101e0bd]626                        if ( src->kind != TypeData::Unknown ) {
627                                assert( src->kind == TypeData::Basic );
628
629                                if ( dst->basictype == DeclarationNode::NoBasicType ) {
630                                        dst->basictype = src->basictype;
631                                } else if ( src->basictype != DeclarationNode::NoBasicType )
[ca9d65e]632                                        SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
633                                                                   DeclarationNode::basicTypeNames[ dst->basictype ],
634                                                                   DeclarationNode::basicTypeNames[ src->basictype ] );
[101e0bd]635                                if ( dst->complextype == DeclarationNode::NoComplexType ) {
636                                        dst->complextype = src->complextype;
637                                } else if ( src->complextype != DeclarationNode::NoComplexType )
[ca9d65e]638                                        SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
639                                                                   DeclarationNode::complexTypeNames[ src->complextype ],
640                                                                   DeclarationNode::complexTypeNames[ src->complextype ] );
[101e0bd]641                                if ( dst->signedness == DeclarationNode::NoSignedness ) {
642                                        dst->signedness = src->signedness;
643                                } else if ( src->signedness != DeclarationNode::NoSignedness )
[ca9d65e]644                                        SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
645                                                                   DeclarationNode::signednessNames[ dst->signedness ],
646                                                                   DeclarationNode::signednessNames[ src->signedness ] );
[101e0bd]647                                if ( dst->length == DeclarationNode::NoLength ) {
648                                        dst->length = src->length;
649                                } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) {
650                                        dst->length = DeclarationNode::LongLong;
651                                } else if ( src->length != DeclarationNode::NoLength )
[ca9d65e]652                                        SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
653                                                                   DeclarationNode::lengthNames[ dst->length ],
654                                                                   DeclarationNode::lengthNames[ src->length ] );
[101e0bd]655                        } // if
656                        break;
[0d0931d]657                default:
[101e0bd]658                        switch ( src->kind ) {
[0d0931d]659                        case TypeData::Aggregate:
660                        case TypeData::Enum:
[101e0bd]661                                dst->base = new TypeData( TypeData::AggregateInst );
662                                dst->base->aggInst.aggregate = src;
663                                if ( src->kind == TypeData::Aggregate ) {
[5bf685f]664                                        dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
[68cd1ce]665                                } // if
[6f95000]666                                dst->base->qualifiers |= src->qualifiers;
[2298f728]667                                src = nullptr;
[b87a5ed]668                                break;
[0d0931d]669                        default:
[101e0bd]670                                if ( dst->forall ) {
671                                        dst->forall->appendList( src->forall );
672                                } else {
673                                        dst->forall = src->forall;
674                                } // if
[2298f728]675                                src->forall = nullptr;
[101e0bd]676                                dst->base = src;
[2298f728]677                                src = nullptr;
[68cd1ce]678                        } // switch
[101e0bd]679                } // switch
[68cd1ce]680        } // if
[3848e0e]681}
682
[ba7aa2d]683DeclarationNode * DeclarationNode::addType( DeclarationNode * o ) {
[b87a5ed]684        if ( o ) {
[a7c90d4]685                checkSpecifiers( o );
686                copySpecifiers( o );
[b87a5ed]687                if ( o->type ) {
688                        if ( ! type ) {
689                                if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
690                                        type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]691                                        type->aggInst.aggregate = o->type;
[b87a5ed]692                                        if ( o->type->kind == TypeData::Aggregate ) {
[43c89a7]693                                                type->aggInst.hoistType = o->type->aggregate.body;
[5bf685f]694                                                type->aggInst.params = maybeCopy( o->type->aggregate.actuals );
[43c89a7]695                                        } else {
696                                                type->aggInst.hoistType = o->type->enumeration.body;
[68cd1ce]697                                        } // if
[6f95000]698                                        type->qualifiers |= o->type->qualifiers;
[b87a5ed]699                                } else {
700                                        type = o->type;
[68cd1ce]701                                } // if
[2298f728]702                                o->type = nullptr;
[b87a5ed]703                        } else {
704                                addTypeToType( o->type, type );
[68cd1ce]705                        } // if
706                } // if
[b87a5ed]707                if ( o->bitfieldWidth ) {
708                        bitfieldWidth = o->bitfieldWidth;
[68cd1ce]709                } // if
[71bd8c6]710
711                // there may be typedefs chained onto the type
[1d4580a]712                if ( o->get_next() ) {
713                        set_last( o->get_next()->clone() );
[1db21619]714                } // if
[68cd1ce]715        } // if
[b87a5ed]716        delete o;
[66406f3]717
[b87a5ed]718        return this;
[3848e0e]719}
720
[f135b50]721DeclarationNode * DeclarationNode::addEnumBase( DeclarationNode * o ) {
[b38f6da]722        if ( o && o->type)  {
[f135b50]723                type->base= o->type;
[b38f6da]724        } // if
[f135b50]725        delete o;
726        return this;
727}
728
[ba7aa2d]729DeclarationNode * DeclarationNode::addTypedef() {
730        TypeData * newtype = new TypeData( TypeData::Symbolic );
[2298f728]731        newtype->symbolic.params = nullptr;
[8f6f47d7]732        newtype->symbolic.isTypedef = true;
[2298f728]733        newtype->symbolic.name = name ? new string( *name ) : nullptr;
[b87a5ed]734        newtype->base = type;
735        type = newtype;
736        return this;
[3848e0e]737}
738
[ba7aa2d]739DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
[bb7422a]740        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
[702e826]741                if ( variable.assertions ) {
742                        variable.assertions->appendList( assertions );
743                } else {
744                        variable.assertions = assertions;
745                } // if
746                return this;
[2298f728]747        } // if
748
[b87a5ed]749        assert( type );
750        switch ( type->kind ) {
[0d0931d]751        case TypeData::Symbolic:
[8f6f47d7]752                if ( type->symbolic.assertions ) {
753                        type->symbolic.assertions->appendList( assertions );
[b87a5ed]754                } else {
[8f6f47d7]755                        type->symbolic.assertions = assertions;
[68cd1ce]756                } // if
[b87a5ed]757                break;
[0d0931d]758        default:
[b87a5ed]759                assert( false );
[68cd1ce]760        } // switch
[974906e2]761
[b87a5ed]762        return this;
[51b7345]763}
764
[fb114fa1]765DeclarationNode * DeclarationNode::addName( string * newname ) {
[2298f728]766        assert( ! name );
767        name = newname;
[b87a5ed]768        return this;
[51b7345]769}
770
[c0aa336]771DeclarationNode * DeclarationNode::addAsmName( DeclarationNode * newname ) {
[58dd019]772        assert( ! asmName );
[c0aa336]773        asmName = newname ? newname->asmName : nullptr;
774        return this->addQualifiers( newname );
[58dd019]775}
776
[ba7aa2d]777DeclarationNode * DeclarationNode::addBitfield( ExpressionNode * size ) {
[b87a5ed]778        bitfieldWidth = size;
779        return this;
[51b7345]780}
781
[ba7aa2d]782DeclarationNode * DeclarationNode::addVarArgs() {
[b87a5ed]783        assert( type );
784        hasEllipsis = true;
785        return this;
[51b7345]786}
787
[c453ac4]788DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) {
[b87a5ed]789        assert( type );
790        assert( type->kind == TypeData::Function );
[2298f728]791        assert( ! type->function.body );
[8f6f47d7]792        type->function.body = body;
[c453ac4]793        type->function.withExprs = withExprs;
[b87a5ed]794        return this;
[51b7345]795}
796
[ba7aa2d]797DeclarationNode * DeclarationNode::addOldDeclList( DeclarationNode * list ) {
[b87a5ed]798        assert( type );
799        assert( type->kind == TypeData::Function );
[2298f728]800        assert( ! type->function.oldDeclList );
[8f6f47d7]801        type->function.oldDeclList = list;
[b87a5ed]802        return this;
[51b7345]803}
804
[c0aa336]805DeclarationNode * DeclarationNode::setBase( TypeData * newType ) {
[b87a5ed]806        if ( type ) {
[ba7aa2d]807                TypeData * prevBase = type;
808                TypeData * curBase = type->base;
[2298f728]809                while ( curBase != nullptr ) {
[b87a5ed]810                        prevBase = curBase;
811                        curBase = curBase->base;
[68cd1ce]812                } // while
[b87a5ed]813                prevBase->base = newType;
814        } else {
815                type = newType;
[68cd1ce]816        } // if
[c0aa336]817        return this;
[3848e0e]818}
819
[c0aa336]820DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
821        if ( a ) {
[bb7422a]822                spliceBegin( attributes, a->attributes );
[c0aa336]823                a->attributes.clear();
824        } // if
825        return this;
826} // copyAttribute
827
[ba7aa2d]828DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) {
[b87a5ed]829        if ( p ) {
[6926a6d]830                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
[c0aa336]831                setBase( p->type );
[2298f728]832                p->type = nullptr;
[c0aa336]833                copyAttribute( p );
[b87a5ed]834                delete p;
[68cd1ce]835        } // if
[b87a5ed]836        return this;
[3848e0e]837}
838
[ba7aa2d]839DeclarationNode * DeclarationNode::addArray( DeclarationNode * a ) {
[b87a5ed]840        if ( a ) {
841                assert( a->type->kind == TypeData::Array );
[c0aa336]842                setBase( a->type );
[2298f728]843                a->type = nullptr;
[c0aa336]844                copyAttribute( a );
[b87a5ed]845                delete a;
[68cd1ce]846        } // if
[b87a5ed]847        return this;
[51b7345]848}
849
[ba7aa2d]850DeclarationNode * DeclarationNode::addNewPointer( DeclarationNode * p ) {
[b87a5ed]851        if ( p ) {
[e6cee92]852                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
[b87a5ed]853                if ( type ) {
854                        switch ( type->kind ) {
[0d0931d]855                        case TypeData::Aggregate:
856                        case TypeData::Enum:
[b87a5ed]857                                p->type->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]858                                p->type->base->aggInst.aggregate = type;
[b87a5ed]859                                if ( type->kind == TypeData::Aggregate ) {
[5bf685f]860                                        p->type->base->aggInst.params = maybeCopy( type->aggregate.actuals );
[68cd1ce]861                                } // if
[6f95000]862                                p->type->base->qualifiers |= type->qualifiers;
[b87a5ed]863                                break;
864
[0d0931d]865                        default:
[b87a5ed]866                                p->type->base = type;
[68cd1ce]867                        } // switch
[2298f728]868                        type = nullptr;
[68cd1ce]869                } // if
[b87a5ed]870                delete this;
871                return p;
872        } else {
873                return this;
[68cd1ce]874        } // if
[51b7345]875}
876
[ba7aa2d]877static TypeData * findLast( TypeData * a ) {
[b87a5ed]878        assert( a );
[ba7aa2d]879        TypeData * cur = a;
[a32b204]880        while ( cur->base ) {
[b87a5ed]881                cur = cur->base;
[68cd1ce]882        } // while
[b87a5ed]883        return cur;
[3848e0e]884}
885
[ba7aa2d]886DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
[0d0931d]887        if ( ! a ) return this;
[738e304]888        assert( a->type->kind == TypeData::Array );
889        TypeData * lastArray = findLast( a->type );
890        if ( type ) {
891                switch ( type->kind ) {
[0d0931d]892                case TypeData::Aggregate:
893                case TypeData::Enum:
[738e304]894                        lastArray->base = new TypeData( TypeData::AggregateInst );
895                        lastArray->base->aggInst.aggregate = type;
896                        if ( type->kind == TypeData::Aggregate ) {
[5bf685f]897                                lastArray->base->aggInst.params = maybeCopy( type->aggregate.actuals );
[738e304]898                        } // if
[6f95000]899                        lastArray->base->qualifiers |= type->qualifiers;
[738e304]900                        break;
[0d0931d]901                default:
[738e304]902                        lastArray->base = type;
903                } // switch
904                type = nullptr;
[68cd1ce]905        } // if
[738e304]906        delete this;
907        return a;
[51b7345]908}
[3848e0e]909
[ba7aa2d]910DeclarationNode * DeclarationNode::addParamList( DeclarationNode * params ) {
911        TypeData * ftype = new TypeData( TypeData::Function );
[8f6f47d7]912        ftype->function.params = params;
[c0aa336]913        setBase( ftype );
[b87a5ed]914        return this;
[3848e0e]915}
916
[ba7aa2d]917static TypeData * addIdListToType( TypeData * type, DeclarationNode * ids ) {
[b87a5ed]918        if ( type ) {
919                if ( type->kind != TypeData::Function ) {
920                        type->base = addIdListToType( type->base, ids );
921                } else {
[8f6f47d7]922                        type->function.idList = ids;
[68cd1ce]923                } // if
[b87a5ed]924                return type;
[3848e0e]925        } else {
[ba7aa2d]926                TypeData * newtype = new TypeData( TypeData::Function );
[8f6f47d7]927                newtype->function.idList = ids;
[b87a5ed]928                return newtype;
[68cd1ce]929        } // if
[2298f728]930} // addIdListToType
[974906e2]931
[ba7aa2d]932DeclarationNode * DeclarationNode::addIdList( DeclarationNode * ids ) {
[b87a5ed]933        type = addIdListToType( type, ids );
934        return this;
[3848e0e]935}
936
[ba7aa2d]937DeclarationNode * DeclarationNode::addInitializer( InitializerNode * init ) {
[b87a5ed]938        initializer = init;
939        return this;
[3848e0e]940}
941
[67cf18c]942DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
[bb7422a]943        assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
[67cf18c]944        variable.initializer = init;
945        return this;
946}
947
[a46b69c]948DeclarationNode * DeclarationNode::cloneType( string * name ) {
949        DeclarationNode * newnode = newName( name );
[5bf685f]950        newnode->type = maybeCopy( type );
[a7c90d4]951        newnode->copySpecifiers( this );
[b87a5ed]952        return newnode;
[3848e0e]953}
954
[2298f728]955DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode * o ) {
956        if ( ! o ) return nullptr;
957
[a7c90d4]958        o->copySpecifiers( this );
[2298f728]959        if ( type ) {
960                TypeData * srcType = type;
961
[c0aa336]962                // search for the base type by scanning off pointers and array designators
[2298f728]963                while ( srcType->base ) {
964                        srcType = srcType->base;
965                } // while
966
967                TypeData * newType = srcType->clone();
968                if ( newType->kind == TypeData::AggregateInst ) {
969                        // don't duplicate members
970                        if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
971                                delete newType->aggInst.aggregate->enumeration.constants;
972                                newType->aggInst.aggregate->enumeration.constants = nullptr;
[b2da0574]973                                newType->aggInst.aggregate->enumeration.body = false;
[b87a5ed]974                        } else {
[2298f728]975                                assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
976                                delete newType->aggInst.aggregate->aggregate.fields;
977                                newType->aggInst.aggregate->aggregate.fields = nullptr;
[b2da0574]978                                newType->aggInst.aggregate->aggregate.body = false;
[68cd1ce]979                        } // if
[43c89a7]980                        // don't hoist twice
981                        newType->aggInst.hoistType = false;
[68cd1ce]982                } // if
[2298f728]983
[5bf685f]984                newType->forall = maybeCopy( type->forall );
[2298f728]985                if ( ! o->type ) {
986                        o->type = newType;
987                } else {
988                        addTypeToType( newType, o->type );
989                        delete newType;
990                } // if
[68cd1ce]991        } // if
[b87a5ed]992        return o;
[51b7345]993}
994
[ba7aa2d]995DeclarationNode * DeclarationNode::extractAggregate() const {
[b87a5ed]996        if ( type ) {
[ba7aa2d]997                TypeData * ret = typeextractAggregate( type );
[b87a5ed]998                if ( ret ) {
[ba7aa2d]999                        DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]1000                        newnode->type = ret;
1001                        return newnode;
[843054c2]1002                } // if
1003        } // if
[2298f728]1004        return nullptr;
[3848e0e]1005}
1006
[b38f6da]1007// If a typedef wraps an anonymous declaration, name the inner declaration so it has a consistent name across
1008// translation units.
[45e753c]1009static void nameTypedefedDecl(
1010                DeclarationNode * innerDecl,
1011                const DeclarationNode * outerDecl ) {
1012        TypeData * outer = outerDecl->type;
1013        assert( outer );
1014        // First make sure this is a typedef:
1015        if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) {
1016                return;
1017        }
1018        TypeData * inner = innerDecl->type;
1019        assert( inner );
1020        // Always clear any CVs associated with the aggregate:
1021        inner->qualifiers.reset();
1022        // Handle anonymous aggregates: typedef struct { int i; } foo
1023        if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) {
1024                delete inner->aggregate.name;
1025                inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
1026                inner->aggregate.anon = false;
1027                assert( outer->base );
1028                delete outer->base->aggInst.aggregate->aggregate.name;
1029                outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
1030                outer->base->aggInst.aggregate->aggregate.anon = false;
1031                outer->base->aggInst.aggregate->qualifiers.reset();
1032        // Handle anonymous enumeration: typedef enum { A, B, C } foo
1033        } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) {
1034                delete inner->enumeration.name;
1035                inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
1036                inner->enumeration.anon = false;
1037                assert( outer->base );
1038                delete outer->base->aggInst.aggregate->enumeration.name;
1039                outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
1040                outer->base->aggInst.aggregate->enumeration.anon = false;
1041                // No qualifiers.reset() here.
1042        }
1043}
1044
1045// This code handles a special issue with the attribute transparent_union.
1046//
1047//    typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))
1048//
1049// Here the attribute aligned goes with the typedef_name, so variables declared of this type are
1050// aligned.  However, the attribute transparent_union must be moved from the typedef_name to
1051// alias union U.  Currently, this is the only know attribute that must be moved from typedef to
1052// alias.
1053static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) {
1054        if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {
1055                // Is the typedef alias a union aggregate?
1056                if ( nullptr == unionDecl ) return;
1057
1058                // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
1059                if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {
1060                        auto instType = ast::mutate( unionInstType );
1061                        // Remove all transparent_union attributes from typedef and move to alias union.
1062                        for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) {
1063                                assert( *attr );
1064                                if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
1065                                        unionDecl->attributes.emplace_back( attr->release() );
1066                                        attr = instType->attributes.erase( attr );
1067                                } else {
1068                                        attr++;
1069                                }
1070                        }
1071                        typedefDecl->base = instType;
1072                }
1073        }
1074}
1075
1076// Get the non-anonymous name of the instance type of the declaration,
1077// if one exists.
1078static const std::string * getInstTypeOfName( ast::Decl * decl ) {
1079        if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
1080                if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) {
1081                        if ( aggr->name.find("anonymous") == std::string::npos ) {
1082                                return &aggr->name;
1083                        }
1084                }
1085        }
1086        return nullptr;
1087}
1088
[b38f6da]1089void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList ) {
[a16764a6]1090        SemanticErrorException errors;
[bb7422a]1091        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
[2298f728]1092
[45e753c]1093        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
[b87a5ed]1094                try {
[45e753c]1095                        bool extracted_named = false;
1096                        ast::UnionDecl * unionDecl = nullptr;
[692c1cc]1097
[ba7aa2d]1098                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
[78e2fca]1099                                assert( cur->type );
[45e753c]1100                                nameTypedefedDecl( extr, cur );
[692c1cc]1101
[45e753c]1102                                if ( ast::Decl * decl = extr->build() ) {
[692c1cc]1103                                        // Remember the declaration if it is a union aggregate ?
[bb7422a]1104                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
[692c1cc]1105
1106                                        *out++ = decl;
[3d7e53b]1107
1108                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
1109                                        assert( extr->type );
1110                                        if ( extr->type->kind == TypeData::Aggregate ) {
[692c1cc]1111                                                // typedef struct { int A } B is the only case?
[45e753c]1112                                                extracted_named = !extr->type->aggregate.anon;
[3d7e53b]1113                                        } else if ( extr->type->kind == TypeData::Enum ) {
[692c1cc]1114                                                // typedef enum { A } B is the only case?
[45e753c]1115                                                extracted_named = !extr->type->enumeration.anon;
1116                                        } else {
1117                                                extracted_named = true;
[3d7e53b]1118                                        }
[843054c2]1119                                } // if
[f39096c]1120                                delete extr;
[843054c2]1121                        } // if
[2298f728]1122
[45e753c]1123                        if ( ast::Decl * decl = cur->build() ) {
1124                                moveUnionAttribute( decl, unionDecl );
1125
1126                                if ( "" == decl->name && !cur->get_inLine() ) {
1127                                        // Don't include anonymous declaration for named aggregates,
1128                                        // but do include them for anonymous aggregates, e.g.:
1129                                        // struct S {
1130                                        //   struct T { int x; }; // no anonymous member
1131                                        //   struct { int y; };   // anonymous member
1132                                        //   struct T;            // anonymous member
1133                                        // };
1134                                        if ( extracted_named ) {
1135                                                continue;
1136                                        }
[692c1cc]1137
[45e753c]1138                                        if ( auto name = getInstTypeOfName( decl ) ) {
1139                                                // Temporary: warn about anonymous member declarations of named types, since
1140                                                // this conflicts with the syntax for the forward declaration of an anonymous type.
1141                                                SemanticWarning( cur->location, Warning::AggrForwardDecl, name->c_str() );
1142                                        }
[e07caa2]1143                                } // if
[45e753c]1144                                *out++ = decl;
[843054c2]1145                        } // if
[45e753c]1146                } catch ( SemanticErrorException & e ) {
[b87a5ed]1147                        errors.append( e );
[843054c2]1148                } // try
[e07caa2]1149        } // for
[2298f728]1150
[b87a5ed]1151        if ( ! errors.isEmpty() ) {
1152                throw errors;
[843054c2]1153        } // if
[2298f728]1154} // buildList
[3848e0e]1155
[3d7e53b]1156// currently only builds assertions, function parameters, and return values
[6611177]1157void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
[a16764a6]1158        SemanticErrorException errors;
[bb7422a]1159        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
[43c89a7]1160
[45e753c]1161        for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
[b87a5ed]1162                try {
[bb7422a]1163                        ast::Decl * decl = cur->build();
[45e753c]1164                        assertf( decl, "buildList: build for ast::DeclWithType." );
[bb7422a]1165                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
[47498bd]1166                                dwt->location = cur->location;
[3ca7ef3]1167                                *out++ = dwt;
[bb7422a]1168                        } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
[3d7e53b]1169                                // e.g., int foo(struct S) {}
[bb7422a]1170                                auto inst = new ast::StructInstType( agg->name );
1171                                auto obj = new ast::ObjectDecl( cur->location, "", inst );
1172                                obj->linkage = linkage;
[3ca7ef3]1173                                *out++ = obj;
[47498bd]1174                                delete agg;
[bb7422a]1175                        } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
[3d7e53b]1176                                // e.g., int foo(union U) {}
[bb7422a]1177                                auto inst = new ast::UnionInstType( agg->name );
1178                                auto obj = new ast::ObjectDecl( cur->location,
1179                                        "", inst, nullptr, ast::Storage::Classes(),
1180                                        linkage );
[3ca7ef3]1181                                *out++ = obj;
[bb7422a]1182                        } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
[3d7e53b]1183                                // e.g., int foo(enum E) {}
[bb7422a]1184                                auto inst = new ast::EnumInstType( agg->name );
1185                                auto obj = new ast::ObjectDecl( cur->location,
1186                                        "",
1187                                        inst,
1188                                        nullptr,
1189                                        ast::Storage::Classes(),
1190                                        linkage
1191                                );
[3ca7ef3]1192                                *out++ = obj;
[45e753c]1193                        } else {
1194                                assertf( false, "buildList: Could not convert to ast::DeclWithType." );
[843054c2]1195                        } // if
[45e753c]1196                } catch ( SemanticErrorException & e ) {
[b87a5ed]1197                        errors.append( e );
[843054c2]1198                } // try
[3a5131ed]1199        } // for
1200
[b87a5ed]1201        if ( ! errors.isEmpty() ) {
1202                throw errors;
[843054c2]1203        } // if
[2298f728]1204} // buildList
[3848e0e]1205
[bb7422a]1206void buildTypeList( const DeclarationNode * firstNode,
1207                std::vector<ast::ptr<ast::Type>> & outputList ) {
[a16764a6]1208        SemanticErrorException errors;
[bb7422a]1209        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
[2298f728]1210
[45e753c]1211        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
[b87a5ed]1212                try {
[ba7aa2d]1213                        * out++ = cur->buildType();
[45e753c]1214                } catch ( SemanticErrorException & e ) {
[b87a5ed]1215                        errors.append( e );
[843054c2]1216                } // try
[45e753c]1217        } // for
[2298f728]1218
[b87a5ed]1219        if ( ! errors.isEmpty() ) {
1220                throw errors;
[843054c2]1221        } // if
[2298f728]1222} // buildTypeList
[51b7345]1223
[bb7422a]1224ast::Decl * DeclarationNode::build() const {
[a16764a6]1225        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
[2298f728]1226
[e994912]1227        if ( asmStmt ) {
[bb7422a]1228                auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
1229                return new ast::AsmDecl( stmt->location, stmt );
[e994912]1230        } // if
[2d019af]1231        if ( directiveStmt ) {
[bb7422a]1232                auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
1233                return new ast::DirectiveDecl( stmt->location, stmt );
[2d019af]1234        } // if
[e994912]1235
[bb7422a]1236        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
[f0ecf9b]1237                // otype is internally converted to dtype + otype parameters
[bb7422a]1238                static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };
1239                static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
[8f60f0b]1240                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
[bb7422a]1241                ast::TypeDecl * ret = new ast::TypeDecl( location,
1242                        *name,
1243                        ast::Storage::Classes(),
1244                        (ast::Type *)nullptr,
1245                        kindMap[ variable.tyClass ],
1246                        variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype,
1247                        variable.initializer ? variable.initializer->buildType() : nullptr
1248                );
1249                buildList( variable.assertions, ret->assertions );
[2298f728]1250                return ret;
1251        } // if
1252
[843054c2]1253        if ( type ) {
[dd020c0]1254                // Function specifiers can only appear on a function definition/declaration.
1255                //
1256                //    inline _Noreturn int f();                 // allowed
1257                //    inline _Noreturn int g( int i );  // allowed
1258                //    inline _Noreturn int i;                   // disallowed
[fb04321]1259                if ( type->kind != TypeData::Function && funcSpecs.any() ) {
[a16764a6]1260                        SemanticError( this, "invalid function specifier for " );
[dd020c0]1261                } // if
[284da8c]1262                // Forall qualifier can only appear on a function/aggregate definition/declaration.
1263                //
1264                //    forall int f();                                   // allowed
1265                //    forall int g( int i );                    // allowed
1266                //    forall int i;                                             // disallowed
1267                if ( type->kind != TypeData::Function && type->forall ) {
1268                        SemanticError( this, "invalid type qualifier for " );
1269                } // if
[3ed994e]1270                bool isDelete = initializer && initializer->get_isDelete();
[bb7422a]1271                ast::Decl * decl = buildDecl(
1272                        type,
1273                        name ? *name : string( "" ),
1274                        storageClasses,
1275                        maybeBuild( bitfieldWidth ),
1276                        funcSpecs,
1277                        linkage,
1278                        asmName,
1279                        isDelete ? nullptr : maybeBuild( initializer ),
1280                        copy( attributes )
1281                )->set_extension( extension );
[3ed994e]1282                if ( isDelete ) {
[bb7422a]1283                        auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
[3ed994e]1284                        dwt->isDeleted = true;
1285                }
1286                return decl;
[843054c2]1287        } // if
[2298f728]1288
[f6e3e34]1289        if ( assert.condition ) {
[bb7422a]1290                auto cond = maybeBuild( assert.condition );
1291                auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) );
1292                return new ast::StaticAssertDecl( location, cond, msg );
[f6e3e34]1293        }
1294
[dd020c0]1295        // SUE's cannot have function specifiers, either
1296        //
[79aae15]1297        //    inline _Noreturn struct S { ... };                // disallowed
1298        //    inline _Noreturn enum   E { ... };                // disallowed
[fb04321]1299        if ( funcSpecs.any() ) {
[a16764a6]1300                SemanticError( this, "invalid function specifier for " );
[843054c2]1301        } // if
[e874605]1302        if ( enumInLine ) {
[bb7422a]1303                return new ast::InlineMemberDecl( location,
1304                        *name, (ast::Type*)nullptr, storageClasses, linkage );
[e874605]1305        } // if
[dd020c0]1306        assertf( name, "ObjectDecl must a have name\n" );
[bb7422a]1307        auto ret = new ast::ObjectDecl( location,
1308                *name,
1309                (ast::Type*)nullptr,
1310                maybeBuild( initializer ),
1311                storageClasses,
1312                linkage,
1313                maybeBuild( bitfieldWidth )
1314        );
1315        ret->asmName = asmName;
1316        ret->extension = extension;
1317        return ret;
[51b7345]1318}
1319
[bb7422a]1320ast::Type * DeclarationNode::buildType() const {
[b87a5ed]1321        assert( type );
[974906e2]1322
[b87a5ed]1323        switch ( type->kind ) {
[0d0931d]1324        case TypeData::Enum:
1325        case TypeData::Aggregate: {
[bb7422a]1326                ast::BaseInstType * ret =
1327                        buildComAggInst( type, copy( attributes ), linkage );
1328                buildList( type->aggregate.actuals, ret->params );
[0d0931d]1329                return ret;
1330        }
1331        case TypeData::Symbolic: {
[bb7422a]1332                ast::TypeInstType * ret = new ast::TypeInstType(
1333                        *type->symbolic.name,
1334                        // This is just a default, the true value is not known yet.
1335                        ast::TypeDecl::Dtype,
1336                        buildQualifiers( type ),
1337                        copy( attributes ) );
1338                buildList( type->symbolic.actuals, ret->params );
[0d0931d]1339                return ret;
1340        }
1341        default:
[bb7422a]1342                ast::Type * simpletypes = typebuild( type );
1343                // copy because member is const
1344                simpletypes->attributes = attributes;
[c0aa336]1345                return simpletypes;
[b87a5ed]1346        } // switch
[3848e0e]1347}
1348
[b87a5ed]1349// Local Variables: //
1350// tab-width: 4 //
1351// mode: c++ //
1352// compile-command: "make install" //
1353// End: //
Note: See TracBrowser for help on using the repository browser.