source: src/Parser/DeclarationNode.cc@ f2898df

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