source: src/Parser/DeclarationNode.cc @ dc3fbe5

Last change on this file since dc3fbe5 was dc3fbe5, checked in by Andrew Beach <ajbeach@…>, 3 months ago

Factored out the ParseNode?'s next field into a new child type. This is only type safe when used in the given one level curiously reoccurring template pattern, as it is now. This allowed most of the intermedate helpers to be removed.

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