source: src/Parser/DeclarationNode.cc@ 77bc259

Last change on this file since 77bc259 was 5bf685f, checked in by Andrew Beach <ajbeach@…>, 20 months ago

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

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