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
Line 
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//
7// DeclarationNode.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 12:34:05 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Dec 14 19:05:17 2023
13// Update Count     : 1407
14//
15
16#include "DeclarationNode.h"
17
18#include <cassert>                 // for assert, assertf, strict_dynamic_cast
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...
24
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
35#include "Common/SemanticError.h"  // for SemanticError
36#include "Common/UniqueName.h"     // for UniqueName
37#include "Common/utility.h"        // for copy, spliceBegin
38#include "Parser/ExpressionNode.h" // for ExpressionNode
39#include "Parser/InitializerNode.h"// for InitializerNode
40#include "Parser/StatementNode.h"  // for StatementNode
41#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
42#include "TypedefTable.h"          // for TypedefTable
43
44extern TypedefTable typedefTable;
45
46using namespace std;
47
48// These must harmonize with the corresponding DeclarationNode enumerations.
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};
66
67UniqueName DeclarationNode::anonymous( "__anonymous" );
68
69extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
70
71DeclarationNode::DeclarationNode() :
72        linkage( ::linkage ) {
73
74//      variable.name = nullptr;
75        variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
76        variable.assertions = nullptr;
77        variable.initializer = nullptr;
78
79        assert.condition = nullptr;
80        assert.message = nullptr;
81}
82
83DeclarationNode::~DeclarationNode() {
84//      delete variable.name;
85        delete variable.assertions;
86        delete variable.initializer;
87
88//      delete type;
89        delete bitfieldWidth;
90
91        delete asmStmt;
92        // asmName, no delete, passed to next stage
93        delete initializer;
94
95        delete assert.condition;
96        delete assert.message;
97}
98
99DeclarationNode * DeclarationNode::clone() const {
100        DeclarationNode * newnode = new DeclarationNode;
101        newnode->set_next( maybeCopy( get_next() ) );
102        newnode->name = name ? new string( *name ) : nullptr;
103
104        newnode->builtin = NoBuiltinType;
105        newnode->type = maybeCopy( type );
106        newnode->inLine = inLine;
107        newnode->storageClasses = storageClasses;
108        newnode->funcSpecs = funcSpecs;
109        newnode->bitfieldWidth = maybeCopy( bitfieldWidth );
110        newnode->enumeratorValue.reset( maybeCopy( enumeratorValue.get() ) );
111        newnode->hasEllipsis = hasEllipsis;
112        newnode->linkage = linkage;
113        newnode->asmName = maybeCopy( asmName );
114        newnode->attributes = attributes;
115        newnode->initializer = maybeCopy( initializer );
116        newnode->extension = extension;
117        newnode->asmStmt = maybeCopy( asmStmt );
118        newnode->error = error;
119
120//      newnode->variable.name = variable.name ? new string( *variable.name ) : nullptr;
121        newnode->variable.tyClass = variable.tyClass;
122        newnode->variable.assertions = maybeCopy( variable.assertions );
123        newnode->variable.initializer = maybeCopy( variable.initializer );
124
125        newnode->assert.condition = maybeCopy( assert.condition );
126        newnode->assert.message = maybeCopy( assert.message );
127        return newnode;
128} // DeclarationNode::clone
129
130void DeclarationNode::print( std::ostream & os, int indent ) const {
131        os << string( indent, ' ' );
132        if ( name ) {
133                os << *name << ": ";
134        } // if
135
136        if ( linkage != ast::Linkage::Cforall ) {
137                os << ast::Linkage::name( linkage ) << " ";
138        } // if
139
140        ast::print( os, storageClasses );
141        ast::print( os, funcSpecs );
142
143        if ( type ) {
144                type->print( os, indent );
145        } else {
146                os << "untyped entity ";
147        } // if
148
149        if ( bitfieldWidth ) {
150                os << endl << string( indent + 2, ' ' ) << "with bitfield width ";
151                bitfieldWidth->printOneLine( os );
152        } // if
153
154        if ( initializer ) {
155                os << endl << string( indent + 2, ' ' ) << "with initializer ";
156                initializer->printOneLine( os );
157                os << " maybe constructed? " << initializer->get_maybeConstructed();
158        } // if
159
160        if ( ! attributes.empty() ) {
161                os << string( indent + 2, ' ' ) << "with attributes " << endl;
162                for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
163                        os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
164                } // for
165        } // if
166
167        os << endl;
168}
169
170void DeclarationNode::printList( std::ostream & os, int indent ) const {
171        ParseNode::printList( os, indent );
172        if ( hasEllipsis ) {
173                os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
174        } // if
175}
176
177DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
178        DeclarationNode * newnode = new DeclarationNode;
179        newnode->storageClasses = sc;
180        return newnode;
181} // DeclarationNode::newStorageClass
182
183DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
184        DeclarationNode * newnode = new DeclarationNode;
185        newnode->funcSpecs = fs;
186        return newnode;
187} // DeclarationNode::newFuncSpecifier
188
189DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
190        DeclarationNode * newnode = new DeclarationNode;
191        newnode->type = new TypeData();
192        newnode->type->qualifiers = tq;
193        return newnode;
194} // DeclarationNode::newQualifier
195
196DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) {
197        DeclarationNode * newnode = new DeclarationNode;
198        newnode->type = new TypeData( TypeData::Basic );
199        newnode->type->basictype = bt;
200        return newnode;
201} // DeclarationNode::newBasicType
202
203DeclarationNode * DeclarationNode::newComplexType( ComplexType ct ) {
204        DeclarationNode * newnode = new DeclarationNode;
205        newnode->type = new TypeData( TypeData::Basic );
206        newnode->type->complextype = ct;
207        return newnode;
208} // DeclarationNode::newComplexType
209
210DeclarationNode * DeclarationNode::newSignedNess( Signedness sn ) {
211        DeclarationNode * newnode = new DeclarationNode;
212        newnode->type = new TypeData( TypeData::Basic );
213        newnode->type->signedness = sn;
214        return newnode;
215} // DeclarationNode::newSignedNess
216
217DeclarationNode * DeclarationNode::newLength( Length lnth ) {
218        DeclarationNode * newnode = new DeclarationNode;
219        newnode->type = new TypeData( TypeData::Basic );
220        newnode->type->length = lnth;
221        return newnode;
222} // DeclarationNode::newLength
223
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
231DeclarationNode * DeclarationNode::newFromGlobalScope() {
232        DeclarationNode * newnode = new DeclarationNode;
233        newnode->type = new TypeData( TypeData::GlobalScope );
234        return newnode;
235}
236
237DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {
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;
247}
248
249DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
250        DeclarationNode * newnode = new DeclarationNode;
251        newnode->type = new TypeData( TypeData::Aggregate );
252        newnode->type->aggregate.kind = kind;
253        newnode->type->aggregate.anon = name == nullptr;
254        newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
255        newnode->type->aggregate.actuals = actuals;
256        newnode->type->aggregate.fields = fields;
257        newnode->type->aggregate.body = body;
258        newnode->type->aggregate.tagged = false;
259        newnode->type->aggregate.parent = nullptr;
260        return newnode;
261} // DeclarationNode::newAggregate
262
263DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
264        DeclarationNode * newnode = new DeclarationNode;
265        newnode->type = new TypeData( TypeData::Enum );
266        newnode->type->enumeration.anon = name == nullptr;
267        newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
268        newnode->type->enumeration.constants = constants;
269        newnode->type->enumeration.body = body;
270        newnode->type->enumeration.typed = typed;
271        newnode->type->enumeration.hiding = hiding;
272        if ( base && base->type )  {
273                newnode->type->base = base->type;
274        } // if
275
276        return newnode;
277} // DeclarationNode::newEnum
278
279DeclarationNode * DeclarationNode::newName( const string * name ) {
280        DeclarationNode * newnode = new DeclarationNode;
281        assert( ! newnode->name );
282        newnode->name = name;
283        return newnode;
284} // DeclarationNode::newName
285
286DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) {
287        DeclarationNode * newnode = newName( name );
288        newnode->enumeratorValue.reset( constant );
289        return newnode;
290} // DeclarationNode::newEnumConstant
291
292DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) {
293        if ( init ) {
294                if ( init->get_expression() ) {
295                        return newEnumConstant( name, init->get_expression() );
296                } else {
297                        DeclarationNode * newnode = newName( name );
298                        newnode->initializer = init;
299                        return newnode;
300                } // if
301        } else {
302                return newName( name );
303        } // if
304} // DeclarationNode::newEnumValueGeneric
305
306DeclarationNode * DeclarationNode::newEnumInLine( const string name ) {
307        DeclarationNode * newnode = newName( new std::string(name) );
308        newnode->enumInLine = true;
309        return newnode;
310}
311
312DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
313        DeclarationNode * newnode = new DeclarationNode;
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;
318        return newnode;
319} // DeclarationNode::newFromTypedef
320
321DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) {
322        DeclarationNode * newnode = new DeclarationNode;
323        newnode->type = new TypeData( TypeData::SymbolicInst );
324        newnode->type->symbolic.name = name;
325        newnode->type->symbolic.isTypedef = false;
326        newnode->type->symbolic.actuals = params;
327        return newnode;
328} // DeclarationNode::newFromTypeGen
329
330DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
331        DeclarationNode * newnode = newName( name );
332        newnode->type = nullptr;
333        newnode->variable.tyClass = tc;
334        newnode->variable.assertions = nullptr;
335        return newnode;
336} // DeclarationNode::newTypeParam
337
338DeclarationNode * DeclarationNode::newTrait( const string * name, DeclarationNode * params, DeclarationNode * asserts ) {
339        DeclarationNode * newnode = new DeclarationNode;
340        newnode->type = new TypeData( TypeData::Aggregate );
341        newnode->type->aggregate.name = name;
342        newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
343        newnode->type->aggregate.params = params;
344        newnode->type->aggregate.fields = asserts;
345        return newnode;
346} // DeclarationNode::newTrait
347
348DeclarationNode * DeclarationNode::newTraitUse( const string * name, ExpressionNode * params ) {
349        DeclarationNode * newnode = new DeclarationNode;
350        newnode->type = new TypeData( TypeData::AggregateInst );
351        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
352        newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
353        newnode->type->aggInst.aggregate->aggregate.name = name;
354        newnode->type->aggInst.params = params;
355        return newnode;
356} // DeclarationNode::newTraitUse
357
358DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) {
359        DeclarationNode * newnode = newName( name );
360        newnode->type = new TypeData( TypeData::Symbolic );
361        newnode->type->symbolic.isTypedef = false;
362        newnode->type->symbolic.params = typeParams;
363        return newnode;
364} // DeclarationNode::newTypeDecl
365
366DeclarationNode * DeclarationNode::newPointer( DeclarationNode * qualifiers, OperKinds kind ) {
367        DeclarationNode * newnode = new DeclarationNode;
368        newnode->type = new TypeData( kind == OperKinds::PointTo ? TypeData::Pointer : TypeData::Reference );
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        }
375        if ( qualifiers ) {
376                return newnode->addQualifiers( qualifiers );
377        } else {
378                return newnode;
379        } // if
380} // DeclarationNode::newPointer
381
382DeclarationNode * DeclarationNode::newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic ) {
383        DeclarationNode * newnode = new DeclarationNode;
384        newnode->type = new TypeData( TypeData::Array );
385        newnode->type->array.dimension = size;
386        newnode->type->array.isStatic = isStatic;
387        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
388                newnode->type->array.isVarLen = false;
389        } else {
390                newnode->type->array.isVarLen = true;
391        } // if
392        return newnode->addQualifiers( qualifiers );
393} // DeclarationNode::newArray
394
395DeclarationNode * DeclarationNode::newVarArray( DeclarationNode * qualifiers ) {
396        DeclarationNode * newnode = new DeclarationNode;
397        newnode->type = new TypeData( TypeData::Array );
398        newnode->type->array.dimension = nullptr;
399        newnode->type->array.isStatic = false;
400        newnode->type->array.isVarLen = true;
401        return newnode->addQualifiers( qualifiers );
402}
403
404DeclarationNode * DeclarationNode::newBitfield( ExpressionNode * size ) {
405        DeclarationNode * newnode = new DeclarationNode;
406        newnode->bitfieldWidth = size;
407        return newnode;
408}
409
410DeclarationNode * DeclarationNode::newTuple( DeclarationNode * members ) {
411        DeclarationNode * newnode = new DeclarationNode;
412        newnode->type = new TypeData( TypeData::Tuple );
413        newnode->type->tuple = members;
414        return newnode;
415}
416
417DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) {
418        DeclarationNode * newnode = new DeclarationNode;
419        newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof );
420        newnode->type->typeexpr = expr;
421        return newnode;
422}
423
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
431DeclarationNode * DeclarationNode::newBuiltinType( BuiltinType bt ) {
432        DeclarationNode * newnode = new DeclarationNode;
433        newnode->type = new TypeData( TypeData::Builtin );
434        newnode->builtin = bt;
435        newnode->type->builtintype = newnode->builtin;
436        return newnode;
437} // DeclarationNode::newBuiltinType
438
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
454DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
455        DeclarationNode * newnode = new DeclarationNode;
456        newnode->type = nullptr;
457        std::vector<ast::ptr<ast::Expr>> exprs;
458        buildList( expr, exprs );
459        newnode->attributes.push_back( new ast::Attribute( *name, std::move( exprs ) ) );
460        delete name;
461        return newnode;
462}
463
464DeclarationNode * DeclarationNode::newDirectiveStmt( StatementNode * stmt ) {
465        DeclarationNode * newnode = new DeclarationNode;
466        newnode->directiveStmt = stmt;
467        return newnode;
468}
469
470DeclarationNode * DeclarationNode::newAsmStmt( StatementNode * stmt ) {
471        DeclarationNode * newnode = new DeclarationNode;
472        newnode->asmStmt = stmt;
473        return newnode;
474}
475
476DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
477        DeclarationNode * newnode = new DeclarationNode;
478        newnode->assert.condition = condition;
479        newnode->assert.message = message;
480        return newnode;
481}
482
483static void appendError( string & dst, const string & src ) {
484        if ( src.empty() ) return;
485        if ( dst.empty() ) { dst = src; return; }
486        dst += ", " + src;
487} // appendError
488
489void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
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() );
499        } // for
500} // DeclarationNode::checkQualifiers
501
502void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
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() );
510        } // if
511
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                }
534        } // if
535
536        appendError( error, src->error );
537} // DeclarationNode::checkSpecifiers
538
539DeclarationNode * DeclarationNode::copySpecifiers( DeclarationNode * q ) {
540        funcSpecs |= q->funcSpecs;
541        storageClasses |= q->storageClasses;
542
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
550        return this;
551} // DeclarationNode::copySpecifiers
552
553static void addQualifiersToType( TypeData *& src, TypeData * dst ) {
554        if ( dst->base ) {
555                addQualifiersToType( src, dst->base );
556        } else if ( dst->kind == TypeData::Function ) {
557                dst->base = src;
558                src = nullptr;
559        } else {
560                dst->qualifiers |= src->qualifiers;
561        } // if
562} // addQualifiersToType
563
564DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) {
565        if ( ! q ) { return this; }                                                     // empty qualifier
566
567        checkSpecifiers( q );
568        copySpecifiers( q );
569
570        if ( ! q->type ) { delete q; return this; }
571
572        if ( ! type ) {
573                type = q->type;                                                                 // reuse structure
574                q->type = nullptr;
575                delete q;
576                return this;
577        } // if
578
579        if ( q->type->forall ) {                                                        // forall qualifier ?
580                if ( type->forall ) {                                                   // polymorphic routine ?
581                        type->forall->appendList( q->type->forall ); // augment forall qualifier
582                } else {
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
587                                        type->aggregate.params = q->type->forall; // set forall qualifier
588                                } // if
589                        } else {                                                                        // not polymorphic
590                                type->forall = q->type->forall;                 // make polymorphic routine
591                        } // if
592                } // if
593                q->type->forall = nullptr;                                              // forall qualifier moved
594        } // if
595
596        checkQualifiers( type, q->type );
597        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
598                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
599        } // if
600        addQualifiersToType( q->type, type );
601
602        delete q;
603        return this;
604} // addQualifiers
605
606static void addTypeToType( TypeData *& src, TypeData *& dst ) {
607        if ( src->forall && dst->kind == TypeData::Function ) {
608                if ( dst->forall ) {
609                        dst->forall->appendList( src->forall );
610                } else {
611                        dst->forall = src->forall;
612                } // if
613                src->forall = nullptr;
614        } // if
615        if ( dst->base ) {
616                addTypeToType( src, dst->base );
617        } else {
618                switch ( dst->kind ) {
619                case TypeData::Unknown:
620                        src->qualifiers |= dst->qualifiers;
621                        dst = src;
622                        src = nullptr;
623                        break;
624                case TypeData::Basic:
625                        dst->qualifiers |= src->qualifiers;
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 )
632                                        SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
633                                                                   DeclarationNode::basicTypeNames[ dst->basictype ],
634                                                                   DeclarationNode::basicTypeNames[ src->basictype ] );
635                                if ( dst->complextype == DeclarationNode::NoComplexType ) {
636                                        dst->complextype = src->complextype;
637                                } else if ( src->complextype != DeclarationNode::NoComplexType )
638                                        SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
639                                                                   DeclarationNode::complexTypeNames[ src->complextype ],
640                                                                   DeclarationNode::complexTypeNames[ src->complextype ] );
641                                if ( dst->signedness == DeclarationNode::NoSignedness ) {
642                                        dst->signedness = src->signedness;
643                                } else if ( src->signedness != DeclarationNode::NoSignedness )
644                                        SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
645                                                                   DeclarationNode::signednessNames[ dst->signedness ],
646                                                                   DeclarationNode::signednessNames[ src->signedness ] );
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 )
652                                        SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
653                                                                   DeclarationNode::lengthNames[ dst->length ],
654                                                                   DeclarationNode::lengthNames[ src->length ] );
655                        } // if
656                        break;
657                default:
658                        switch ( src->kind ) {
659                        case TypeData::Aggregate:
660                        case TypeData::Enum:
661                                dst->base = new TypeData( TypeData::AggregateInst );
662                                dst->base->aggInst.aggregate = src;
663                                if ( src->kind == TypeData::Aggregate ) {
664                                        dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
665                                } // if
666                                dst->base->qualifiers |= src->qualifiers;
667                                src = nullptr;
668                                break;
669                        default:
670                                if ( dst->forall ) {
671                                        dst->forall->appendList( src->forall );
672                                } else {
673                                        dst->forall = src->forall;
674                                } // if
675                                src->forall = nullptr;
676                                dst->base = src;
677                                src = nullptr;
678                        } // switch
679                } // switch
680        } // if
681}
682
683DeclarationNode * DeclarationNode::addType( DeclarationNode * o ) {
684        if ( o ) {
685                checkSpecifiers( o );
686                copySpecifiers( o );
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 );
691                                        type->aggInst.aggregate = o->type;
692                                        if ( o->type->kind == TypeData::Aggregate ) {
693                                                type->aggInst.hoistType = o->type->aggregate.body;
694                                                type->aggInst.params = maybeCopy( o->type->aggregate.actuals );
695                                        } else {
696                                                type->aggInst.hoistType = o->type->enumeration.body;
697                                        } // if
698                                        type->qualifiers |= o->type->qualifiers;
699                                } else {
700                                        type = o->type;
701                                } // if
702                                o->type = nullptr;
703                        } else {
704                                addTypeToType( o->type, type );
705                        } // if
706                } // if
707                if ( o->bitfieldWidth ) {
708                        bitfieldWidth = o->bitfieldWidth;
709                } // if
710
711                // there may be typedefs chained onto the type
712                if ( o->get_next() ) {
713                        set_last( o->get_next()->clone() );
714                } // if
715        } // if
716        delete o;
717
718        return this;
719}
720
721DeclarationNode * DeclarationNode::addEnumBase( DeclarationNode * o ) {
722        if ( o && o->type)  {
723                type->base= o->type;
724        } // if
725        delete o;
726        return this;
727}
728
729DeclarationNode * DeclarationNode::addTypedef() {
730        TypeData * newtype = new TypeData( TypeData::Symbolic );
731        newtype->symbolic.params = nullptr;
732        newtype->symbolic.isTypedef = true;
733        newtype->symbolic.name = name ? new string( *name ) : nullptr;
734        newtype->base = type;
735        type = newtype;
736        return this;
737}
738
739DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
740        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
741                if ( variable.assertions ) {
742                        variable.assertions->appendList( assertions );
743                } else {
744                        variable.assertions = assertions;
745                } // if
746                return this;
747        } // if
748
749        assert( type );
750        switch ( type->kind ) {
751        case TypeData::Symbolic:
752                if ( type->symbolic.assertions ) {
753                        type->symbolic.assertions->appendList( assertions );
754                } else {
755                        type->symbolic.assertions = assertions;
756                } // if
757                break;
758        default:
759                assert( false );
760        } // switch
761
762        return this;
763}
764
765DeclarationNode * DeclarationNode::addName( string * newname ) {
766        assert( ! name );
767        name = newname;
768        return this;
769}
770
771DeclarationNode * DeclarationNode::addAsmName( DeclarationNode * newname ) {
772        assert( ! asmName );
773        asmName = newname ? newname->asmName : nullptr;
774        return this->addQualifiers( newname );
775}
776
777DeclarationNode * DeclarationNode::addBitfield( ExpressionNode * size ) {
778        bitfieldWidth = size;
779        return this;
780}
781
782DeclarationNode * DeclarationNode::addVarArgs() {
783        assert( type );
784        hasEllipsis = true;
785        return this;
786}
787
788DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) {
789        assert( type );
790        assert( type->kind == TypeData::Function );
791        assert( ! type->function.body );
792        type->function.body = body;
793        type->function.withExprs = withExprs;
794        return this;
795}
796
797DeclarationNode * DeclarationNode::addOldDeclList( DeclarationNode * list ) {
798        assert( type );
799        assert( type->kind == TypeData::Function );
800        assert( ! type->function.oldDeclList );
801        type->function.oldDeclList = list;
802        return this;
803}
804
805DeclarationNode * DeclarationNode::setBase( TypeData * newType ) {
806        if ( type ) {
807                TypeData * prevBase = type;
808                TypeData * curBase = type->base;
809                while ( curBase != nullptr ) {
810                        prevBase = curBase;
811                        curBase = curBase->base;
812                } // while
813                prevBase->base = newType;
814        } else {
815                type = newType;
816        } // if
817        return this;
818}
819
820DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
821        if ( a ) {
822                spliceBegin( attributes, a->attributes );
823                a->attributes.clear();
824        } // if
825        return this;
826} // copyAttribute
827
828DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) {
829        if ( p ) {
830                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
831                setBase( p->type );
832                p->type = nullptr;
833                copyAttribute( p );
834                delete p;
835        } // if
836        return this;
837}
838
839DeclarationNode * DeclarationNode::addArray( DeclarationNode * a ) {
840        if ( a ) {
841                assert( a->type->kind == TypeData::Array );
842                setBase( a->type );
843                a->type = nullptr;
844                copyAttribute( a );
845                delete a;
846        } // if
847        return this;
848}
849
850DeclarationNode * DeclarationNode::addNewPointer( DeclarationNode * p ) {
851        if ( p ) {
852                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
853                if ( type ) {
854                        switch ( type->kind ) {
855                        case TypeData::Aggregate:
856                        case TypeData::Enum:
857                                p->type->base = new TypeData( TypeData::AggregateInst );
858                                p->type->base->aggInst.aggregate = type;
859                                if ( type->kind == TypeData::Aggregate ) {
860                                        p->type->base->aggInst.params = maybeCopy( type->aggregate.actuals );
861                                } // if
862                                p->type->base->qualifiers |= type->qualifiers;
863                                break;
864
865                        default:
866                                p->type->base = type;
867                        } // switch
868                        type = nullptr;
869                } // if
870                delete this;
871                return p;
872        } else {
873                return this;
874        } // if
875}
876
877static TypeData * findLast( TypeData * a ) {
878        assert( a );
879        TypeData * cur = a;
880        while ( cur->base ) {
881                cur = cur->base;
882        } // while
883        return cur;
884}
885
886DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
887        if ( ! a ) return this;
888        assert( a->type->kind == TypeData::Array );
889        TypeData * lastArray = findLast( a->type );
890        if ( type ) {
891                switch ( type->kind ) {
892                case TypeData::Aggregate:
893                case TypeData::Enum:
894                        lastArray->base = new TypeData( TypeData::AggregateInst );
895                        lastArray->base->aggInst.aggregate = type;
896                        if ( type->kind == TypeData::Aggregate ) {
897                                lastArray->base->aggInst.params = maybeCopy( type->aggregate.actuals );
898                        } // if
899                        lastArray->base->qualifiers |= type->qualifiers;
900                        break;
901                default:
902                        lastArray->base = type;
903                } // switch
904                type = nullptr;
905        } // if
906        delete this;
907        return a;
908}
909
910DeclarationNode * DeclarationNode::addParamList( DeclarationNode * params ) {
911        TypeData * ftype = new TypeData( TypeData::Function );
912        ftype->function.params = params;
913        setBase( ftype );
914        return this;
915}
916
917static TypeData * addIdListToType( TypeData * type, DeclarationNode * ids ) {
918        if ( type ) {
919                if ( type->kind != TypeData::Function ) {
920                        type->base = addIdListToType( type->base, ids );
921                } else {
922                        type->function.idList = ids;
923                } // if
924                return type;
925        } else {
926                TypeData * newtype = new TypeData( TypeData::Function );
927                newtype->function.idList = ids;
928                return newtype;
929        } // if
930} // addIdListToType
931
932DeclarationNode * DeclarationNode::addIdList( DeclarationNode * ids ) {
933        type = addIdListToType( type, ids );
934        return this;
935}
936
937DeclarationNode * DeclarationNode::addInitializer( InitializerNode * init ) {
938        initializer = init;
939        return this;
940}
941
942DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
943        assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
944        variable.initializer = init;
945        return this;
946}
947
948DeclarationNode * DeclarationNode::cloneType( string * name ) {
949        DeclarationNode * newnode = newName( name );
950        newnode->type = maybeCopy( type );
951        newnode->copySpecifiers( this );
952        return newnode;
953}
954
955DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode * o ) {
956        if ( ! o ) return nullptr;
957
958        o->copySpecifiers( this );
959        if ( type ) {
960                TypeData * srcType = type;
961
962                // search for the base type by scanning off pointers and array designators
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;
973                                newType->aggInst.aggregate->enumeration.body = false;
974                        } else {
975                                assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
976                                delete newType->aggInst.aggregate->aggregate.fields;
977                                newType->aggInst.aggregate->aggregate.fields = nullptr;
978                                newType->aggInst.aggregate->aggregate.body = false;
979                        } // if
980                        // don't hoist twice
981                        newType->aggInst.hoistType = false;
982                } // if
983
984                newType->forall = maybeCopy( type->forall );
985                if ( ! o->type ) {
986                        o->type = newType;
987                } else {
988                        addTypeToType( newType, o->type );
989                        delete newType;
990                } // if
991        } // if
992        return o;
993}
994
995DeclarationNode * DeclarationNode::extractAggregate() const {
996        if ( type ) {
997                TypeData * ret = typeextractAggregate( type );
998                if ( ret ) {
999                        DeclarationNode * newnode = new DeclarationNode;
1000                        newnode->type = ret;
1001                        return newnode;
1002                } // if
1003        } // if
1004        return nullptr;
1005}
1006
1007// If a typedef wraps an anonymous declaration, name the inner declaration so it has a consistent name across
1008// translation units.
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
1089void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList ) {
1090        SemanticErrorException errors;
1091        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
1092
1093        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
1094                try {
1095                        bool extracted_named = false;
1096                        ast::UnionDecl * unionDecl = nullptr;
1097
1098                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
1099                                assert( cur->type );
1100                                nameTypedefedDecl( extr, cur );
1101
1102                                if ( ast::Decl * decl = extr->build() ) {
1103                                        // Remember the declaration if it is a union aggregate ?
1104                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
1105
1106                                        *out++ = decl;
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 ) {
1111                                                // typedef struct { int A } B is the only case?
1112                                                extracted_named = !extr->type->aggregate.anon;
1113                                        } else if ( extr->type->kind == TypeData::Enum ) {
1114                                                // typedef enum { A } B is the only case?
1115                                                extracted_named = !extr->type->enumeration.anon;
1116                                        } else {
1117                                                extracted_named = true;
1118                                        }
1119                                } // if
1120                                delete extr;
1121                        } // if
1122
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                                        }
1137
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                                        }
1143                                } // if
1144                                *out++ = decl;
1145                        } // if
1146                } catch ( SemanticErrorException & e ) {
1147                        errors.append( e );
1148                } // try
1149        } // for
1150
1151        if ( ! errors.isEmpty() ) {
1152                throw errors;
1153        } // if
1154} // buildList
1155
1156// currently only builds assertions, function parameters, and return values
1157void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
1158        SemanticErrorException errors;
1159        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
1160
1161        for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
1162                try {
1163                        ast::Decl * decl = cur->build();
1164                        assertf( decl, "buildList: build for ast::DeclWithType." );
1165                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
1166                                dwt->location = cur->location;
1167                                *out++ = dwt;
1168                        } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
1169                                // e.g., int foo(struct S) {}
1170                                auto inst = new ast::StructInstType( agg->name );
1171                                auto obj = new ast::ObjectDecl( cur->location, "", inst );
1172                                obj->linkage = linkage;
1173                                *out++ = obj;
1174                                delete agg;
1175                        } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
1176                                // e.g., int foo(union U) {}
1177                                auto inst = new ast::UnionInstType( agg->name );
1178                                auto obj = new ast::ObjectDecl( cur->location,
1179                                        "", inst, nullptr, ast::Storage::Classes(),
1180                                        linkage );
1181                                *out++ = obj;
1182                        } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
1183                                // e.g., int foo(enum E) {}
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                                );
1192                                *out++ = obj;
1193                        } else {
1194                                assertf( false, "buildList: Could not convert to ast::DeclWithType." );
1195                        } // if
1196                } catch ( SemanticErrorException & e ) {
1197                        errors.append( e );
1198                } // try
1199        } // for
1200
1201        if ( ! errors.isEmpty() ) {
1202                throw errors;
1203        } // if
1204} // buildList
1205
1206void buildTypeList( const DeclarationNode * firstNode,
1207                std::vector<ast::ptr<ast::Type>> & outputList ) {
1208        SemanticErrorException errors;
1209        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
1210
1211        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
1212                try {
1213                        * out++ = cur->buildType();
1214                } catch ( SemanticErrorException & e ) {
1215                        errors.append( e );
1216                } // try
1217        } // for
1218
1219        if ( ! errors.isEmpty() ) {
1220                throw errors;
1221        } // if
1222} // buildTypeList
1223
1224ast::Decl * DeclarationNode::build() const {
1225        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
1226
1227        if ( asmStmt ) {
1228                auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
1229                return new ast::AsmDecl( stmt->location, stmt );
1230        } // if
1231        if ( directiveStmt ) {
1232                auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
1233                return new ast::DirectiveDecl( stmt->location, stmt );
1234        } // if
1235
1236        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
1237                // otype is internally converted to dtype + otype parameters
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." );
1240                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
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 );
1250                return ret;
1251        } // if
1252
1253        if ( type ) {
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
1259                if ( type->kind != TypeData::Function && funcSpecs.any() ) {
1260                        SemanticError( this, "invalid function specifier for " );
1261                } // if
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
1270                bool isDelete = initializer && initializer->get_isDelete();
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 );
1282                if ( isDelete ) {
1283                        auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
1284                        dwt->isDeleted = true;
1285                }
1286                return decl;
1287        } // if
1288
1289        if ( assert.condition ) {
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 );
1293        }
1294
1295        // SUE's cannot have function specifiers, either
1296        //
1297        //    inline _Noreturn struct S { ... };                // disallowed
1298        //    inline _Noreturn enum   E { ... };                // disallowed
1299        if ( funcSpecs.any() ) {
1300                SemanticError( this, "invalid function specifier for " );
1301        } // if
1302        if ( enumInLine ) {
1303                return new ast::InlineMemberDecl( location,
1304                        *name, (ast::Type*)nullptr, storageClasses, linkage );
1305        } // if
1306        assertf( name, "ObjectDecl must a have name\n" );
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;
1318}
1319
1320ast::Type * DeclarationNode::buildType() const {
1321        assert( type );
1322
1323        switch ( type->kind ) {
1324        case TypeData::Enum:
1325        case TypeData::Aggregate: {
1326                ast::BaseInstType * ret =
1327                        buildComAggInst( type, copy( attributes ), linkage );
1328                buildList( type->aggregate.actuals, ret->params );
1329                return ret;
1330        }
1331        case TypeData::Symbolic: {
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 );
1339                return ret;
1340        }
1341        default:
1342                ast::Type * simpletypes = typebuild( type );
1343                // copy because member is const
1344                simpletypes->attributes = attributes;
1345                return simpletypes;
1346        } // switch
1347}
1348
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.