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
RevLine 
[b87a5ed]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[974906e2]7// DeclarationNode.cc --
[b87a5ed]8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 12:34:05 2015
[b38f6da]11// Last Modified By : Peter A. Buhr
[4eb3a7c5]12// Last Modified On : Fri Feb 23 18:25:57 2024
13// Update Count : 1533
[b87a5ed]14//
15
[c468150]16#include "DeclarationNode.h"
17
[e3e16bc]18#include <cassert> // for assert, assertf, strict_dynamic_cast
[d180746]19#include <iterator> // for back_insert_iterator
20#include <list> // for list
21#include <memory> // for unique_ptr
22#include <ostream> // for operator<<, ostream, basic_ostream
23#include <string> // for string, operator+, allocator, char...
[51b73452]24
[bb7422a]25#include "AST/Attribute.hpp" // for Attribute
26#include "AST/Copy.hpp" // for shallowCopy
27#include "AST/Decl.hpp" // for Decl
28#include "AST/Expr.hpp" // for Expr
29#include "AST/Print.hpp" // for print
30#include "AST/Stmt.hpp" // for AsmStmt, DirectiveStmt
31#include "AST/StorageClasses.hpp" // for Storage::Class
32#include "AST/Type.hpp" // for Type
33#include "Common/CodeLocation.h" // for CodeLocation
34#include "Common/Iterate.hpp" // for reverseIterate
[d180746]35#include "Common/SemanticError.h" // for SemanticError
36#include "Common/UniqueName.h" // for UniqueName
[5bf685f]37#include "Common/utility.h" // for copy, spliceBegin
[c468150]38#include "Parser/ExpressionNode.h" // for ExpressionNode
39#include "Parser/InitializerNode.h"// for InitializerNode
40#include "Parser/StatementNode.h" // for StatementNode
[d180746]41#include "TypeData.h" // for TypeData, TypeData::Aggregate_t
[2f0a0678]42#include "TypedefTable.h" // for TypedefTable
[bdd516a]43
[de62360d]44extern TypedefTable typedefTable;
45
[51b73452]46using namespace std;
47
[201aeb9]48// These must harmonize with the corresponding DeclarationNode enumerations.
[702e826]49const char * DeclarationNode::basicTypeNames[] = {
50 "void", "_Bool", "char", "int", "int128",
51 "float", "double", "long double", "float80", "float128",
52 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames"
53};
54const char * DeclarationNode::complexTypeNames[] = {
55 "_Complex", "NoComplexTypeNames", "_Imaginary"
56}; // Imaginary unsupported => parse, but make invisible and print error message
57const char * DeclarationNode::signednessNames[] = {
58 "signed", "unsigned", "NoSignednessNames"
59};
60const char * DeclarationNode::lengthNames[] = {
61 "short", "long", "long long", "NoLengthNames"
62};
63const char * DeclarationNode::builtinTypeNames[] = {
64 "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames"
65};
[51b73452]66
67UniqueName DeclarationNode::anonymous( "__anonymous" );
68
[bb7422a]69extern ast::Linkage::Spec linkage; // defined in parser.yy
[51b73452]70
[7d05e7e]71DeclarationNode::DeclarationNode() :
[e07caa2]72 linkage( ::linkage ) {
[2298f728]73
[faddbd8]74// variable.name = nullptr;
[bb7422a]75 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
[28307be]76 variable.assertions = nullptr;
[67cf18c]77 variable.initializer = nullptr;
[7d05e7e]78
[f6e3e34]79 assert.condition = nullptr;
80 assert.message = nullptr;
[28307be]81}
82
83DeclarationNode::~DeclarationNode() {
[4c0b674]84 delete name;
85
[faddbd8]86// delete variable.name;
[2298f728]87 delete variable.assertions;
[67cf18c]88 delete variable.initializer;
[2298f728]89
[702e826]90// delete type;
[28307be]91 delete bitfieldWidth;
[e994912]92
93 delete asmStmt;
[58dd019]94 // asmName, no delete, passed to next stage
[28307be]95 delete initializer;
[f6e3e34]96
97 delete assert.condition;
98 delete assert.message;
[28307be]99}
100
[ba7aa2d]101DeclarationNode * DeclarationNode::clone() const {
102 DeclarationNode * newnode = new DeclarationNode;
[5bf685f]103 newnode->set_next( maybeCopy( get_next() ) );
[2298f728]104 newnode->name = name ? new string( *name ) : nullptr;
[c0aa336]105
[2e5fa345]106 newnode->builtin = NoBuiltinType;
[5bf685f]107 newnode->type = maybeCopy( type );
[679e644]108 newnode->inLine = inLine;
[a7c90d4]109 newnode->storageClasses = storageClasses;
110 newnode->funcSpecs = funcSpecs;
[5bf685f]111 newnode->bitfieldWidth = maybeCopy( bitfieldWidth );
112 newnode->enumeratorValue.reset( maybeCopy( enumeratorValue.get() ) );
[b87a5ed]113 newnode->hasEllipsis = hasEllipsis;
114 newnode->linkage = linkage;
[bb7422a]115 newnode->asmName = maybeCopy( asmName );
116 newnode->attributes = attributes;
[5bf685f]117 newnode->initializer = maybeCopy( initializer );
[c0aa336]118 newnode->extension = extension;
[5bf685f]119 newnode->asmStmt = maybeCopy( asmStmt );
[c0aa336]120 newnode->error = error;
[3848e0e]121
[faddbd8]122// newnode->variable.name = variable.name ? new string( *variable.name ) : nullptr;
[28307be]123 newnode->variable.tyClass = variable.tyClass;
[5bf685f]124 newnode->variable.assertions = maybeCopy( variable.assertions );
125 newnode->variable.initializer = maybeCopy( variable.initializer );
[3848e0e]126
[5bf685f]127 newnode->assert.condition = maybeCopy( assert.condition );
[bb7422a]128 newnode->assert.message = maybeCopy( assert.message );
[28307be]129 return newnode;
130} // DeclarationNode::clone
[3848e0e]131
[f2f512ba]132void DeclarationNode::print( std::ostream & os, int indent ) const {
[59db689]133 os << string( indent, ' ' );
[2298f728]134 if ( name ) {
135 os << *name << ": ";
[68cd1ce]136 } // if
[51b73452]137
[bb7422a]138 if ( linkage != ast::Linkage::Cforall ) {
139 os << ast::Linkage::name( linkage ) << " ";
[68cd1ce]140 } // if
[3848e0e]141
[bb7422a]142 ast::print( os, storageClasses );
143 ast::print( os, funcSpecs );
[dd020c0]144
[b87a5ed]145 if ( type ) {
146 type->print( os, indent );
147 } else {
148 os << "untyped entity ";
[68cd1ce]149 } // if
[3848e0e]150
[b87a5ed]151 if ( bitfieldWidth ) {
[59db689]152 os << endl << string( indent + 2, ' ' ) << "with bitfield width ";
[b87a5ed]153 bitfieldWidth->printOneLine( os );
[68cd1ce]154 } // if
[3848e0e]155
[2298f728]156 if ( initializer ) {
[59db689]157 os << endl << string( indent + 2, ' ' ) << "with initializer ";
[b87a5ed]158 initializer->printOneLine( os );
[974906e2]159 os << " maybe constructed? " << initializer->get_maybeConstructed();
[68cd1ce]160 } // if
[3848e0e]161
[692c1cc]162 if ( ! attributes.empty() ) {
[4eb3a7c5]163 os << string( indent + 2, ' ' ) << "with attributes" << endl;
[bb7422a]164 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
[4eb3a7c5]165 os << string( indent + 4, ' ' );
166 ast::print( os, attr, indent + 2 );
[692c1cc]167 } // for
168 } // if
[66406f3]169
[b87a5ed]170 os << endl;
[51b73452]171}
172
[f2f512ba]173void DeclarationNode::printList( std::ostream & os, int indent ) const {
[dc3fbe5]174 ParseList::printList( os, indent );
[b87a5ed]175 if ( hasEllipsis ) {
176 os << string( indent, ' ' ) << "and a variable number of other arguments" << endl;
[68cd1ce]177 } // if
[51b73452]178}
179
[bb7422a]180DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
[ba7aa2d]181 DeclarationNode * newnode = new DeclarationNode;
[08d5507b]182 newnode->storageClasses = sc;
[b87a5ed]183 return newnode;
[dd020c0]184} // DeclarationNode::newStorageClass
[3848e0e]185
[bb7422a]186DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
[ba7aa2d]187 DeclarationNode * newnode = new DeclarationNode;
[08d5507b]188 newnode->funcSpecs = fs;
[c1c1112]189 return newnode;
[dd020c0]190} // DeclarationNode::newFuncSpecifier
[c1c1112]191
[bb7422a]192DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
[ba7aa2d]193 DeclarationNode * newnode = new DeclarationNode;
[dd020c0]194 newnode->type = new TypeData();
[738e304]195 newnode->type->qualifiers = tq;
[b87a5ed]196 return newnode;
[dd020c0]197} // DeclarationNode::newQualifier
[3848e0e]198
[c1c1112]199DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) {
[ba7aa2d]200 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]201 newnode->type = new TypeData( TypeData::Basic );
[5b639ee]202 newnode->type->basictype = bt;
[b87a5ed]203 return newnode;
[984dce6]204} // DeclarationNode::newBasicType
[3848e0e]205
[5b639ee]206DeclarationNode * DeclarationNode::newComplexType( ComplexType ct ) {
[ba7aa2d]207 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]208 newnode->type = new TypeData( TypeData::Basic );
[5b639ee]209 newnode->type->complextype = ct;
[b87a5ed]210 return newnode;
[5b639ee]211} // DeclarationNode::newComplexType
212
213DeclarationNode * DeclarationNode::newSignedNess( Signedness sn ) {
[ba7aa2d]214 DeclarationNode * newnode = new DeclarationNode;
[5b639ee]215 newnode->type = new TypeData( TypeData::Basic );
216 newnode->type->signedness = sn;
217 return newnode;
218} // DeclarationNode::newSignedNess
219
220DeclarationNode * DeclarationNode::newLength( Length lnth ) {
[ba7aa2d]221 DeclarationNode * newnode = new DeclarationNode;
[5b639ee]222 newnode->type = new TypeData( TypeData::Basic );
223 newnode->type->length = lnth;
224 return newnode;
225} // DeclarationNode::newLength
[3848e0e]226
[dd020c0]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
[47498bd]234DeclarationNode * DeclarationNode::newFromGlobalScope() {
235 DeclarationNode * newnode = new DeclarationNode;
236 newnode->type = new TypeData( TypeData::GlobalScope );
237 return newnode;
238}
239
[c5d7701]240DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {
[c194661]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;
[c5d7701]250}
251
[bb7422a]252DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
[ba7aa2d]253 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]254 newnode->type = new TypeData( TypeData::Aggregate );
[8f6f47d7]255 newnode->type->aggregate.kind = kind;
[692c1cc]256 newnode->type->aggregate.anon = name == nullptr;
257 newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
[8f6f47d7]258 newnode->type->aggregate.actuals = actuals;
259 newnode->type->aggregate.fields = fields;
260 newnode->type->aggregate.body = body;
[6ea87486]261 newnode->type->aggregate.tagged = false;
262 newnode->type->aggregate.parent = nullptr;
[b87a5ed]263 return newnode;
[984dce6]264} // DeclarationNode::newAggregate
[3848e0e]265
[e4d7c1c]266DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
[ba7aa2d]267 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]268 newnode->type = new TypeData( TypeData::Enum );
[692c1cc]269 newnode->type->enumeration.anon = name == nullptr;
270 newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
[8f6f47d7]271 newnode->type->enumeration.constants = constants;
[ca1a547]272 newnode->type->enumeration.body = body;
[b0d9ff7]273 newnode->type->enumeration.typed = typed;
[e4d7c1c]274 newnode->type->enumeration.hiding = hiding;
[78e2fca]275 if ( base && base->type ) {
[ed9a1ae]276 newnode->type->base = base->type;
[9e7236f4]277 } // if
278
[b87a5ed]279 return newnode;
[984dce6]280} // DeclarationNode::newEnum
[3848e0e]281
[a46b69c]282DeclarationNode * DeclarationNode::newName( const string * name ) {
[ba7aa2d]283 DeclarationNode * newnode = new DeclarationNode;
[a46b69c]284 assert( ! newnode->name );
[2298f728]285 newnode->name = name;
[a46b69c]286 return newnode;
287} // DeclarationNode::newName
288
[374cb117]289DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) {
[a46b69c]290 DeclarationNode * newnode = newName( name );
[4f147cc]291 newnode->enumeratorValue.reset( constant );
[b87a5ed]292 return newnode;
[984dce6]293} // DeclarationNode::newEnumConstant
[3848e0e]294
[374cb117]295DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) {
[b0d9ff7]296 if ( init ) {
297 if ( init->get_expression() ) {
[374cb117]298 return newEnumConstant( name, init->get_expression() );
[b0d9ff7]299 } else {
[374cb117]300 DeclarationNode * newnode = newName( name );
301 newnode->initializer = init;
302 return newnode;
303 } // if
304 } else {
[b0d9ff7]305 return newName( name );
[374cb117]306 } // if
[9e7236f4]307} // DeclarationNode::newEnumValueGeneric
[374cb117]308
[1e30df7]309DeclarationNode * DeclarationNode::newEnumInLine( const string name ) {
310 DeclarationNode * newnode = newName( new std::string(name) );
311 newnode->enumInLine = true;
312 return newnode;
313}
314
[a46b69c]315DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
[ba7aa2d]316 DeclarationNode * newnode = new DeclarationNode;
[a46b69c]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;
[b87a5ed]321 return newnode;
[a46b69c]322} // DeclarationNode::newFromTypedef
[3848e0e]323
[25bca42]324DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) {
[ba7aa2d]325 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]326 newnode->type = new TypeData( TypeData::SymbolicInst );
[fb114fa1]327 newnode->type->symbolic.name = name;
[8f6f47d7]328 newnode->type->symbolic.isTypedef = false;
329 newnode->type->symbolic.actuals = params;
[b87a5ed]330 return newnode;
[984dce6]331} // DeclarationNode::newFromTypeGen
[3848e0e]332
[bb7422a]333DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
[a46b69c]334 DeclarationNode * newnode = newName( name );
[2298f728]335 newnode->type = nullptr;
[28307be]336 newnode->variable.tyClass = tc;
[faddbd8]337 newnode->variable.assertions = nullptr;
[b87a5ed]338 return newnode;
[984dce6]339} // DeclarationNode::newTypeParam
[3848e0e]340
[fb114fa1]341DeclarationNode * DeclarationNode::newTrait( const string * name, DeclarationNode * params, DeclarationNode * asserts ) {
[ba7aa2d]342 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]343 newnode->type = new TypeData( TypeData::Aggregate );
[2298f728]344 newnode->type->aggregate.name = name;
[bb7422a]345 newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
[8f6f47d7]346 newnode->type->aggregate.params = params;
347 newnode->type->aggregate.fields = asserts;
[b87a5ed]348 return newnode;
[984dce6]349} // DeclarationNode::newTrait
[3848e0e]350
[fb114fa1]351DeclarationNode * DeclarationNode::newTraitUse( const string * name, ExpressionNode * params ) {
[ba7aa2d]352 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]353 newnode->type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]354 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
[bb7422a]355 newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
[2298f728]356 newnode->type->aggInst.aggregate->aggregate.name = name;
[8f6f47d7]357 newnode->type->aggInst.params = params;
[b87a5ed]358 return newnode;
[984dce6]359} // DeclarationNode::newTraitUse
[3848e0e]360
[25bca42]361DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) {
[a46b69c]362 DeclarationNode * newnode = newName( name );
[b87a5ed]363 newnode->type = new TypeData( TypeData::Symbolic );
[8f6f47d7]364 newnode->type->symbolic.isTypedef = false;
365 newnode->type->symbolic.params = typeParams;
[b87a5ed]366 return newnode;
[984dce6]367} // DeclarationNode::newTypeDecl
[3848e0e]368
[ce8c12f]369DeclarationNode * DeclarationNode::newPointer( DeclarationNode * qualifiers, OperKinds kind ) {
[ba7aa2d]370 DeclarationNode * newnode = new DeclarationNode;
[ce8c12f]371 newnode->type = new TypeData( kind == OperKinds::PointTo ? TypeData::Pointer : TypeData::Reference );
[71d0eab]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 }
[c3396e0]378 if ( qualifiers ) {
379 return newnode->addQualifiers( qualifiers );
380 } else {
381 return newnode;
382 } // if
[984dce6]383} // DeclarationNode::newPointer
[3848e0e]384
[ba7aa2d]385DeclarationNode * DeclarationNode::newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic ) {
386 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]387 newnode->type = new TypeData( TypeData::Array );
[8f6f47d7]388 newnode->type->array.dimension = size;
389 newnode->type->array.isStatic = isStatic;
[bb7422a]390 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
[8f6f47d7]391 newnode->type->array.isVarLen = false;
[71bd8c6]392 } else {
[8f6f47d7]393 newnode->type->array.isVarLen = true;
[71bd8c6]394 } // if
[b87a5ed]395 return newnode->addQualifiers( qualifiers );
[984dce6]396} // DeclarationNode::newArray
[3848e0e]397
[ba7aa2d]398DeclarationNode * DeclarationNode::newVarArray( DeclarationNode * qualifiers ) {
399 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]400 newnode->type = new TypeData( TypeData::Array );
[2298f728]401 newnode->type->array.dimension = nullptr;
[8f6f47d7]402 newnode->type->array.isStatic = false;
403 newnode->type->array.isVarLen = true;
[b87a5ed]404 return newnode->addQualifiers( qualifiers );
[3848e0e]405}
406
[ba7aa2d]407DeclarationNode * DeclarationNode::newBitfield( ExpressionNode * size ) {
408 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]409 newnode->bitfieldWidth = size;
410 return newnode;
[3848e0e]411}
412
[ba7aa2d]413DeclarationNode * DeclarationNode::newTuple( DeclarationNode * members ) {
414 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]415 newnode->type = new TypeData( TypeData::Tuple );
[8f6f47d7]416 newnode->type->tuple = members;
[b87a5ed]417 return newnode;
[3848e0e]418}
419
[f855545]420DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) {
[ba7aa2d]421 DeclarationNode * newnode = new DeclarationNode;
[f855545]422 newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof );
[8f6f47d7]423 newnode->type->typeexpr = expr;
[b87a5ed]424 return newnode;
[3848e0e]425}
426
[93bbbc4]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
[8f6f47d7]434DeclarationNode * DeclarationNode::newBuiltinType( BuiltinType bt ) {
[ba7aa2d]435 DeclarationNode * newnode = new DeclarationNode;
[8f6f47d7]436 newnode->type = new TypeData( TypeData::Builtin );
437 newnode->builtin = bt;
[148f7290]438 newnode->type->builtintype = newnode->builtin;
[8f6f47d7]439 return newnode;
440} // DeclarationNode::newBuiltinType
441
[a46b69c]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
[25bca42]457DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
[44a81853]458 DeclarationNode * newnode = new DeclarationNode;
459 newnode->type = nullptr;
[bb7422a]460 std::vector<ast::ptr<ast::Expr>> exprs;
[44a81853]461 buildList( expr, exprs );
[b38f6da]462 newnode->attributes.push_back( new ast::Attribute( *name, std::move( exprs ) ) );
[44a81853]463 delete name;
464 return newnode;
465}
466
[2d019af]467DeclarationNode * DeclarationNode::newDirectiveStmt( StatementNode * stmt ) {
468 DeclarationNode * newnode = new DeclarationNode;
469 newnode->directiveStmt = stmt;
470 return newnode;
471}
472
[e994912]473DeclarationNode * DeclarationNode::newAsmStmt( StatementNode * stmt ) {
474 DeclarationNode * newnode = new DeclarationNode;
475 newnode->asmStmt = stmt;
476 return newnode;
477}
478
[bb7422a]479DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
[f6e3e34]480 DeclarationNode * newnode = new DeclarationNode;
481 newnode->assert.condition = condition;
482 newnode->assert.message = message;
483 return newnode;
484}
485
[bb7422a]486static void appendError( string & dst, const string & src ) {
[5b639ee]487 if ( src.empty() ) return;
488 if ( dst.empty() ) { dst = src; return; }
489 dst += ", " + src;
490} // appendError
491
[ba7aa2d]492void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
[bb7422a]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() );
[a7c90d4]502 } // for
[c1c1112]503} // DeclarationNode::checkQualifiers
504
[a7c90d4]505void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
[bb7422a]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() );
[dd020c0]513 } // if
514
[bb7422a]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 }
[b6424d9]537 } // if
[dd020c0]538
[a7c90d4]539 appendError( error, src->error );
540} // DeclarationNode::checkSpecifiers
[b6424d9]541
[4eb3a7c5]542DeclarationNode * DeclarationNode::copySpecifiers( DeclarationNode * q, bool copyattr ) {
[6f95000]543 funcSpecs |= q->funcSpecs;
544 storageClasses |= q->storageClasses;
[c0aa336]545
[4eb3a7c5]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
[bb7422a]554
[b6424d9]555 return this;
[a7c90d4]556} // DeclarationNode::copySpecifiers
[b6424d9]557
[f2f512ba]558static void addQualifiersToType( TypeData *& src, TypeData * dst ) {
[101e0bd]559 if ( dst->base ) {
560 addQualifiersToType( src, dst->base );
561 } else if ( dst->kind == TypeData::Function ) {
562 dst->base = src;
[2298f728]563 src = nullptr;
[101e0bd]564 } else {
[6f95000]565 dst->qualifiers |= src->qualifiers;
[101e0bd]566 } // if
567} // addQualifiersToType
568
[ba7aa2d]569DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) {
[af9da5f]570 if ( ! q ) { return this; } // empty qualifier
[101e0bd]571
[a7c90d4]572 checkSpecifiers( q );
573 copySpecifiers( q );
[101e0bd]574
[c38ae92]575 if ( ! q->type ) { delete q; return this; }
[101e0bd]576
577 if ( ! type ) {
[c38ae92]578 type = q->type; // reuse structure
[1b772749]579 q->type = nullptr;
580 delete q;
[101e0bd]581 return this;
582 } // if
583
[c38ae92]584 if ( q->type->forall ) { // forall qualifier ?
585 if ( type->forall ) { // polymorphic routine ?
[dc3fbe5]586 type->forall->set_last( q->type->forall ); // augment forall qualifier
[101e0bd]587 } else {
[c38ae92]588 if ( type->kind == TypeData::Aggregate ) { // struct/union ?
589 if ( type->aggregate.params ) { // polymorphic ?
[dc3fbe5]590 type->aggregate.params->set_last( q->type->forall ); // augment forall qualifier
[c38ae92]591 } else { // not polymorphic
[a1c9ddd]592 type->aggregate.params = q->type->forall; // set forall qualifier
[c38ae92]593 } // if
594 } else { // not polymorphic
595 type->forall = q->type->forall; // make polymorphic routine
[68cd1ce]596 } // if
597 } // if
[c38ae92]598 q->type->forall = nullptr; // forall qualifier moved
[68cd1ce]599 } // if
[6ef2d81]600
[a7c90d4]601 checkQualifiers( type, q->type );
[78e2fca]602 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
[be00a2d]603 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
[9dc31c10]604 } // if
[6ef2d81]605 addQualifiersToType( q->type, type );
606
[b87a5ed]607 delete q;
608 return this;
[101e0bd]609} // addQualifiers
[3848e0e]610
[f2f512ba]611static void addTypeToType( TypeData *& src, TypeData *& dst ) {
[101e0bd]612 if ( src->forall && dst->kind == TypeData::Function ) {
613 if ( dst->forall ) {
[dc3fbe5]614 dst->forall->set_last( src->forall );
[b87a5ed]615 } else {
[101e0bd]616 dst->forall = src->forall;
617 } // if
[2298f728]618 src->forall = nullptr;
[101e0bd]619 } // if
620 if ( dst->base ) {
621 addTypeToType( src, dst->base );
622 } else {
623 switch ( dst->kind ) {
[0d0931d]624 case TypeData::Unknown:
[6f95000]625 src->qualifiers |= dst->qualifiers;
[101e0bd]626 dst = src;
[2298f728]627 src = nullptr;
[101e0bd]628 break;
[0d0931d]629 case TypeData::Basic:
[6f95000]630 dst->qualifiers |= src->qualifiers;
[101e0bd]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 )
[ca9d65e]637 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
638 DeclarationNode::basicTypeNames[ dst->basictype ],
639 DeclarationNode::basicTypeNames[ src->basictype ] );
[101e0bd]640 if ( dst->complextype == DeclarationNode::NoComplexType ) {
641 dst->complextype = src->complextype;
642 } else if ( src->complextype != DeclarationNode::NoComplexType )
[ca9d65e]643 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
644 DeclarationNode::complexTypeNames[ src->complextype ],
645 DeclarationNode::complexTypeNames[ src->complextype ] );
[101e0bd]646 if ( dst->signedness == DeclarationNode::NoSignedness ) {
647 dst->signedness = src->signedness;
648 } else if ( src->signedness != DeclarationNode::NoSignedness )
[ca9d65e]649 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
650 DeclarationNode::signednessNames[ dst->signedness ],
651 DeclarationNode::signednessNames[ src->signedness ] );
[101e0bd]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 )
[ca9d65e]657 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
658 DeclarationNode::lengthNames[ dst->length ],
659 DeclarationNode::lengthNames[ src->length ] );
[101e0bd]660 } // if
661 break;
[0d0931d]662 default:
[101e0bd]663 switch ( src->kind ) {
[0d0931d]664 case TypeData::Aggregate:
665 case TypeData::Enum:
[101e0bd]666 dst->base = new TypeData( TypeData::AggregateInst );
667 dst->base->aggInst.aggregate = src;
668 if ( src->kind == TypeData::Aggregate ) {
[5bf685f]669 dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
[68cd1ce]670 } // if
[6f95000]671 dst->base->qualifiers |= src->qualifiers;
[2298f728]672 src = nullptr;
[b87a5ed]673 break;
[0d0931d]674 default:
[101e0bd]675 if ( dst->forall ) {
[dc3fbe5]676 dst->forall->set_last( src->forall );
[101e0bd]677 } else {
678 dst->forall = src->forall;
679 } // if
[2298f728]680 src->forall = nullptr;
[101e0bd]681 dst->base = src;
[2298f728]682 src = nullptr;
[68cd1ce]683 } // switch
[101e0bd]684 } // switch
[68cd1ce]685 } // if
[3848e0e]686}
687
[4eb3a7c5]688DeclarationNode * DeclarationNode::addType( DeclarationNode * o, bool copyattr ) {
[b87a5ed]689 if ( o ) {
[a7c90d4]690 checkSpecifiers( o );
[4eb3a7c5]691 copySpecifiers( o, copyattr );
[b87a5ed]692 if ( o->type ) {
693 if ( ! type ) {
694 if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
[4eb3a7c5]695 // Hide type information aggregate instances.
[b87a5ed]696 type = new TypeData( TypeData::AggregateInst );
[4eb3a7c5]697 type->aggInst.aggregate = o->type; // change ownership
698 type->aggInst.aggregate->aggregate.attributes.swap( o->attributes ); // change ownership
[b87a5ed]699 if ( o->type->kind == TypeData::Aggregate ) {
[43c89a7]700 type->aggInst.hoistType = o->type->aggregate.body;
[5bf685f]701 type->aggInst.params = maybeCopy( o->type->aggregate.actuals );
[43c89a7]702 } else {
703 type->aggInst.hoistType = o->type->enumeration.body;
[68cd1ce]704 } // if
[6f95000]705 type->qualifiers |= o->type->qualifiers;
[b87a5ed]706 } else {
707 type = o->type;
[68cd1ce]708 } // if
[4eb3a7c5]709 o->type = nullptr; // change ownership
[b87a5ed]710 } else {
711 addTypeToType( o->type, type );
[68cd1ce]712 } // if
713 } // if
[b87a5ed]714 if ( o->bitfieldWidth ) {
715 bitfieldWidth = o->bitfieldWidth;
[68cd1ce]716 } // if
[71bd8c6]717
718 // there may be typedefs chained onto the type
[1d4580a]719 if ( o->get_next() ) {
720 set_last( o->get_next()->clone() );
[1db21619]721 } // if
[68cd1ce]722 } // if
[b87a5ed]723 delete o;
[66406f3]724
[b87a5ed]725 return this;
[3848e0e]726}
727
[f135b50]728DeclarationNode * DeclarationNode::addEnumBase( DeclarationNode * o ) {
[b38f6da]729 if ( o && o->type) {
[f135b50]730 type->base= o->type;
[b38f6da]731 } // if
[f135b50]732 delete o;
733 return this;
734}
735
[ba7aa2d]736DeclarationNode * DeclarationNode::addTypedef() {
737 TypeData * newtype = new TypeData( TypeData::Symbolic );
[2298f728]738 newtype->symbolic.params = nullptr;
[8f6f47d7]739 newtype->symbolic.isTypedef = true;
[2298f728]740 newtype->symbolic.name = name ? new string( *name ) : nullptr;
[b87a5ed]741 newtype->base = type;
742 type = newtype;
743 return this;
[3848e0e]744}
745
[ba7aa2d]746DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
[bb7422a]747 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
[702e826]748 if ( variable.assertions ) {
[dc3fbe5]749 variable.assertions->set_last( assertions );
[702e826]750 } else {
751 variable.assertions = assertions;
752 } // if
753 return this;
[2298f728]754 } // if
755
[b87a5ed]756 assert( type );
757 switch ( type->kind ) {
[0d0931d]758 case TypeData::Symbolic:
[8f6f47d7]759 if ( type->symbolic.assertions ) {
[dc3fbe5]760 type->symbolic.assertions->set_last( assertions );
[b87a5ed]761 } else {
[8f6f47d7]762 type->symbolic.assertions = assertions;
[68cd1ce]763 } // if
[b87a5ed]764 break;
[0d0931d]765 default:
[b87a5ed]766 assert( false );
[68cd1ce]767 } // switch
[974906e2]768
[b87a5ed]769 return this;
[51b73452]770}
771
[fb114fa1]772DeclarationNode * DeclarationNode::addName( string * newname ) {
[2298f728]773 assert( ! name );
774 name = newname;
[b87a5ed]775 return this;
[51b73452]776}
777
[c0aa336]778DeclarationNode * DeclarationNode::addAsmName( DeclarationNode * newname ) {
[58dd019]779 assert( ! asmName );
[c0aa336]780 asmName = newname ? newname->asmName : nullptr;
781 return this->addQualifiers( newname );
[58dd019]782}
783
[ba7aa2d]784DeclarationNode * DeclarationNode::addBitfield( ExpressionNode * size ) {
[b87a5ed]785 bitfieldWidth = size;
786 return this;
[51b73452]787}
788
[ba7aa2d]789DeclarationNode * DeclarationNode::addVarArgs() {
[b87a5ed]790 assert( type );
791 hasEllipsis = true;
792 return this;
[51b73452]793}
794
[c453ac4]795DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) {
[b87a5ed]796 assert( type );
797 assert( type->kind == TypeData::Function );
[2298f728]798 assert( ! type->function.body );
[8f6f47d7]799 type->function.body = body;
[c453ac4]800 type->function.withExprs = withExprs;
[b87a5ed]801 return this;
[51b73452]802}
803
[ba7aa2d]804DeclarationNode * DeclarationNode::addOldDeclList( DeclarationNode * list ) {
[b87a5ed]805 assert( type );
806 assert( type->kind == TypeData::Function );
[2298f728]807 assert( ! type->function.oldDeclList );
[8f6f47d7]808 type->function.oldDeclList = list;
[b87a5ed]809 return this;
[51b73452]810}
811
[c0aa336]812DeclarationNode * DeclarationNode::setBase( TypeData * newType ) {
[b87a5ed]813 if ( type ) {
[ba7aa2d]814 TypeData * prevBase = type;
815 TypeData * curBase = type->base;
[2298f728]816 while ( curBase != nullptr ) {
[b87a5ed]817 prevBase = curBase;
818 curBase = curBase->base;
[68cd1ce]819 } // while
[b87a5ed]820 prevBase->base = newType;
821 } else {
822 type = newType;
[68cd1ce]823 } // if
[c0aa336]824 return this;
[3848e0e]825}
826
[c0aa336]827DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
828 if ( a ) {
[bb7422a]829 spliceBegin( attributes, a->attributes );
[c0aa336]830 a->attributes.clear();
831 } // if
832 return this;
833} // copyAttribute
834
[ba7aa2d]835DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) {
[b87a5ed]836 if ( p ) {
[6926a6d]837 assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
[c0aa336]838 setBase( p->type );
[2298f728]839 p->type = nullptr;
[c0aa336]840 copyAttribute( p );
[b87a5ed]841 delete p;
[68cd1ce]842 } // if
[b87a5ed]843 return this;
[3848e0e]844}
845
[ba7aa2d]846DeclarationNode * DeclarationNode::addArray( DeclarationNode * a ) {
[b87a5ed]847 if ( a ) {
848 assert( a->type->kind == TypeData::Array );
[c0aa336]849 setBase( a->type );
[2298f728]850 a->type = nullptr;
[c0aa336]851 copyAttribute( a );
[b87a5ed]852 delete a;
[68cd1ce]853 } // if
[b87a5ed]854 return this;
[51b73452]855}
856
[ba7aa2d]857DeclarationNode * DeclarationNode::addNewPointer( DeclarationNode * p ) {
[b87a5ed]858 if ( p ) {
[e6cee92]859 assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
[b87a5ed]860 if ( type ) {
861 switch ( type->kind ) {
[0d0931d]862 case TypeData::Aggregate:
863 case TypeData::Enum:
[b87a5ed]864 p->type->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]865 p->type->base->aggInst.aggregate = type;
[b87a5ed]866 if ( type->kind == TypeData::Aggregate ) {
[5bf685f]867 p->type->base->aggInst.params = maybeCopy( type->aggregate.actuals );
[68cd1ce]868 } // if
[6f95000]869 p->type->base->qualifiers |= type->qualifiers;
[b87a5ed]870 break;
871
[0d0931d]872 default:
[b87a5ed]873 p->type->base = type;
[68cd1ce]874 } // switch
[2298f728]875 type = nullptr;
[68cd1ce]876 } // if
[b87a5ed]877 delete this;
878 return p;
879 } else {
880 return this;
[68cd1ce]881 } // if
[51b73452]882}
883
[ba7aa2d]884static TypeData * findLast( TypeData * a ) {
[b87a5ed]885 assert( a );
[ba7aa2d]886 TypeData * cur = a;
[a32b204]887 while ( cur->base ) {
[b87a5ed]888 cur = cur->base;
[68cd1ce]889 } // while
[b87a5ed]890 return cur;
[3848e0e]891}
892
[ba7aa2d]893DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
[0d0931d]894 if ( ! a ) return this;
[738e304]895 assert( a->type->kind == TypeData::Array );
896 TypeData * lastArray = findLast( a->type );
897 if ( type ) {
898 switch ( type->kind ) {
[0d0931d]899 case TypeData::Aggregate:
900 case TypeData::Enum:
[738e304]901 lastArray->base = new TypeData( TypeData::AggregateInst );
902 lastArray->base->aggInst.aggregate = type;
903 if ( type->kind == TypeData::Aggregate ) {
[5bf685f]904 lastArray->base->aggInst.params = maybeCopy( type->aggregate.actuals );
[738e304]905 } // if
[6f95000]906 lastArray->base->qualifiers |= type->qualifiers;
[738e304]907 break;
[0d0931d]908 default:
[738e304]909 lastArray->base = type;
910 } // switch
911 type = nullptr;
[68cd1ce]912 } // if
[738e304]913 delete this;
914 return a;
[51b73452]915}
[3848e0e]916
[ba7aa2d]917DeclarationNode * DeclarationNode::addParamList( DeclarationNode * params ) {
918 TypeData * ftype = new TypeData( TypeData::Function );
[8f6f47d7]919 ftype->function.params = params;
[c0aa336]920 setBase( ftype );
[b87a5ed]921 return this;
[3848e0e]922}
923
[ba7aa2d]924static TypeData * addIdListToType( TypeData * type, DeclarationNode * ids ) {
[b87a5ed]925 if ( type ) {
926 if ( type->kind != TypeData::Function ) {
927 type->base = addIdListToType( type->base, ids );
928 } else {
[8f6f47d7]929 type->function.idList = ids;
[68cd1ce]930 } // if
[b87a5ed]931 return type;
[3848e0e]932 } else {
[ba7aa2d]933 TypeData * newtype = new TypeData( TypeData::Function );
[8f6f47d7]934 newtype->function.idList = ids;
[b87a5ed]935 return newtype;
[68cd1ce]936 } // if
[2298f728]937} // addIdListToType
[974906e2]938
[ba7aa2d]939DeclarationNode * DeclarationNode::addIdList( DeclarationNode * ids ) {
[b87a5ed]940 type = addIdListToType( type, ids );
941 return this;
[3848e0e]942}
943
[ba7aa2d]944DeclarationNode * DeclarationNode::addInitializer( InitializerNode * init ) {
[b87a5ed]945 initializer = init;
946 return this;
[3848e0e]947}
948
[67cf18c]949DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
[bb7422a]950 assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
[67cf18c]951 variable.initializer = init;
952 return this;
953}
954
[a46b69c]955DeclarationNode * DeclarationNode::cloneType( string * name ) {
956 DeclarationNode * newnode = newName( name );
[5bf685f]957 newnode->type = maybeCopy( type );
[a7c90d4]958 newnode->copySpecifiers( this );
[b87a5ed]959 return newnode;
[3848e0e]960}
961
[4eb3a7c5]962DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode * o, bool copyattr ) {
[2298f728]963 if ( ! o ) return nullptr;
964
[4eb3a7c5]965 o->copySpecifiers( this, copyattr );
[2298f728]966 if ( type ) {
967 TypeData * srcType = type;
968
[c0aa336]969 // search for the base type by scanning off pointers and array designators
[2298f728]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;
[b2da0574]980 newType->aggInst.aggregate->enumeration.body = false;
[b87a5ed]981 } else {
[2298f728]982 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
983 delete newType->aggInst.aggregate->aggregate.fields;
984 newType->aggInst.aggregate->aggregate.fields = nullptr;
[b2da0574]985 newType->aggInst.aggregate->aggregate.body = false;
[68cd1ce]986 } // if
[43c89a7]987 // don't hoist twice
988 newType->aggInst.hoistType = false;
[68cd1ce]989 } // if
[2298f728]990
[5bf685f]991 newType->forall = maybeCopy( type->forall );
[2298f728]992 if ( ! o->type ) {
993 o->type = newType;
994 } else {
995 addTypeToType( newType, o->type );
996 delete newType;
997 } // if
[68cd1ce]998 } // if
[b87a5ed]999 return o;
[51b73452]1000}
1001
[ba7aa2d]1002DeclarationNode * DeclarationNode::extractAggregate() const {
[b87a5ed]1003 if ( type ) {
[ba7aa2d]1004 TypeData * ret = typeextractAggregate( type );
[b87a5ed]1005 if ( ret ) {
[ba7aa2d]1006 DeclarationNode * newnode = new DeclarationNode;
[b87a5ed]1007 newnode->type = ret;
[4eb3a7c5]1008 if ( ret->kind == TypeData::Aggregate ) {
1009 newnode->attributes.swap( ret->aggregate.attributes );
1010 } // if
[b87a5ed]1011 return newnode;
[843054c2]1012 } // if
1013 } // if
[2298f728]1014 return nullptr;
[3848e0e]1015}
1016
[b38f6da]1017// If a typedef wraps an anonymous declaration, name the inner declaration so it has a consistent name across
1018// translation units.
[45e753c]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
[b38f6da]1099void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList ) {
[a16764a6]1100 SemanticErrorException errors;
[bb7422a]1101 std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
[2298f728]1102
[dc3fbe5]1103 for ( const DeclarationNode * cur = firstNode ; cur ; cur = cur->next ) {
[b87a5ed]1104 try {
[45e753c]1105 bool extracted_named = false;
1106 ast::UnionDecl * unionDecl = nullptr;
[692c1cc]1107
[ba7aa2d]1108 if ( DeclarationNode * extr = cur->extractAggregate() ) {
[78e2fca]1109 assert( cur->type );
[45e753c]1110 nameTypedefedDecl( extr, cur );
[692c1cc]1111
[45e753c]1112 if ( ast::Decl * decl = extr->build() ) {
[692c1cc]1113 // Remember the declaration if it is a union aggregate ?
[bb7422a]1114 unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
[692c1cc]1115
1116 *out++ = decl;
[3d7e53b]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 ) {
[692c1cc]1121 // typedef struct { int A } B is the only case?
[4eb3a7c5]1122 extracted_named = ! extr->type->aggregate.anon;
[3d7e53b]1123 } else if ( extr->type->kind == TypeData::Enum ) {
[692c1cc]1124 // typedef enum { A } B is the only case?
[4eb3a7c5]1125 extracted_named = ! extr->type->enumeration.anon;
[45e753c]1126 } else {
1127 extracted_named = true;
[3d7e53b]1128 }
[843054c2]1129 } // if
[f39096c]1130 delete extr;
[843054c2]1131 } // if
[2298f728]1132
[45e753c]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 }
[692c1cc]1147
[45e753c]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 }
[e07caa2]1153 } // if
[45e753c]1154 *out++ = decl;
[843054c2]1155 } // if
[45e753c]1156 } catch ( SemanticErrorException & e ) {
[b87a5ed]1157 errors.append( e );
[843054c2]1158 } // try
[e07caa2]1159 } // for
[2298f728]1160
[b87a5ed]1161 if ( ! errors.isEmpty() ) {
1162 throw errors;
[843054c2]1163 } // if
[2298f728]1164} // buildList
[3848e0e]1165
[3d7e53b]1166// currently only builds assertions, function parameters, and return values
[6611177]1167void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
[a16764a6]1168 SemanticErrorException errors;
[bb7422a]1169 std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
[43c89a7]1170
[dc3fbe5]1171 for ( const DeclarationNode * cur = firstNode; cur; cur = cur->next ) {
[b87a5ed]1172 try {
[bb7422a]1173 ast::Decl * decl = cur->build();
[45e753c]1174 assertf( decl, "buildList: build for ast::DeclWithType." );
[bb7422a]1175 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
[47498bd]1176 dwt->location = cur->location;
[3ca7ef3]1177 *out++ = dwt;
[bb7422a]1178 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
[3d7e53b]1179 // e.g., int foo(struct S) {}
[bb7422a]1180 auto inst = new ast::StructInstType( agg->name );
1181 auto obj = new ast::ObjectDecl( cur->location, "", inst );
1182 obj->linkage = linkage;
[3ca7ef3]1183 *out++ = obj;
[47498bd]1184 delete agg;
[bb7422a]1185 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
[3d7e53b]1186 // e.g., int foo(union U) {}
[bb7422a]1187 auto inst = new ast::UnionInstType( agg->name );
1188 auto obj = new ast::ObjectDecl( cur->location,
1189 "", inst, nullptr, ast::Storage::Classes(),
1190 linkage );
[3ca7ef3]1191 *out++ = obj;
[bb7422a]1192 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
[3d7e53b]1193 // e.g., int foo(enum E) {}
[bb7422a]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 );
[3ca7ef3]1202 *out++ = obj;
[45e753c]1203 } else {
1204 assertf( false, "buildList: Could not convert to ast::DeclWithType." );
[843054c2]1205 } // if
[45e753c]1206 } catch ( SemanticErrorException & e ) {
[b87a5ed]1207 errors.append( e );
[843054c2]1208 } // try
[3a5131ed]1209 } // for
1210
[b87a5ed]1211 if ( ! errors.isEmpty() ) {
1212 throw errors;
[843054c2]1213 } // if
[2298f728]1214} // buildList
[3848e0e]1215
[bb7422a]1216void buildTypeList( const DeclarationNode * firstNode,
1217 std::vector<ast::ptr<ast::Type>> & outputList ) {
[a16764a6]1218 SemanticErrorException errors;
[bb7422a]1219 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
[2298f728]1220
[dc3fbe5]1221 for ( const DeclarationNode * cur = firstNode ; cur ; cur = cur->next ) {
[b87a5ed]1222 try {
[ba7aa2d]1223 * out++ = cur->buildType();
[45e753c]1224 } catch ( SemanticErrorException & e ) {
[b87a5ed]1225 errors.append( e );
[843054c2]1226 } // try
[45e753c]1227 } // for
[2298f728]1228
[b87a5ed]1229 if ( ! errors.isEmpty() ) {
1230 throw errors;
[843054c2]1231 } // if
[2298f728]1232} // buildTypeList
[51b73452]1233
[bb7422a]1234ast::Decl * DeclarationNode::build() const {
[a16764a6]1235 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
[2298f728]1236
[e994912]1237 if ( asmStmt ) {
[bb7422a]1238 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
1239 return new ast::AsmDecl( stmt->location, stmt );
[e994912]1240 } // if
[2d019af]1241 if ( directiveStmt ) {
[bb7422a]1242 auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
1243 return new ast::DirectiveDecl( stmt->location, stmt );
[2d019af]1244 } // if
[e994912]1245
[bb7422a]1246 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
[f0ecf9b]1247 // otype is internally converted to dtype + otype parameters
[bb7422a]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." );
[8f60f0b]1250 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
[bb7422a]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 );
[2298f728]1260 return ret;
1261 } // if
1262
[843054c2]1263 if ( type ) {
[dd020c0]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
[fb04321]1269 if ( type->kind != TypeData::Function && funcSpecs.any() ) {
[a16764a6]1270 SemanticError( this, "invalid function specifier for " );
[dd020c0]1271 } // if
[284da8c]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
[3ed994e]1280 bool isDelete = initializer && initializer->get_isDelete();
[bb7422a]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 );
[3ed994e]1292 if ( isDelete ) {
[bb7422a]1293 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
[3ed994e]1294 dwt->isDeleted = true;
1295 }
1296 return decl;
[843054c2]1297 } // if
[2298f728]1298
[f6e3e34]1299 if ( assert.condition ) {
[bb7422a]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 );
[f6e3e34]1303 }
1304
[dd020c0]1305 // SUE's cannot have function specifiers, either
1306 //
[79aae15]1307 // inline _Noreturn struct S { ... }; // disallowed
1308 // inline _Noreturn enum E { ... }; // disallowed
[fb04321]1309 if ( funcSpecs.any() ) {
[a16764a6]1310 SemanticError( this, "invalid function specifier for " );
[843054c2]1311 } // if
[e874605]1312 if ( enumInLine ) {
[bb7422a]1313 return new ast::InlineMemberDecl( location,
1314 *name, (ast::Type*)nullptr, storageClasses, linkage );
[e874605]1315 } // if
[dd020c0]1316 assertf( name, "ObjectDecl must a have name\n" );
[bb7422a]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;
[51b73452]1328}
1329
[bb7422a]1330ast::Type * DeclarationNode::buildType() const {
[b87a5ed]1331 assert( type );
[974906e2]1332
[b87a5ed]1333 switch ( type->kind ) {
[0d0931d]1334 case TypeData::Enum:
1335 case TypeData::Aggregate: {
[bb7422a]1336 ast::BaseInstType * ret =
1337 buildComAggInst( type, copy( attributes ), linkage );
1338 buildList( type->aggregate.actuals, ret->params );
[0d0931d]1339 return ret;
1340 }
1341 case TypeData::Symbolic: {
[bb7422a]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 );
[0d0931d]1349 return ret;
1350 }
1351 default:
[bb7422a]1352 ast::Type * simpletypes = typebuild( type );
1353 // copy because member is const
1354 simpletypes->attributes = attributes;
[c0aa336]1355 return simpletypes;
[b87a5ed]1356 } // switch
[3848e0e]1357}
1358
[b87a5ed]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.