source: src/Parser/DeclarationNode.cc@ 924534e

Last change on this file since 924534e was dc3fbe5, checked in by Andrew Beach <ajbeach@…>, 21 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.