source: src/Parser/DeclarationNode.cc@ aefcc3b

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since aefcc3b was 101e0bd, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

more refactoring of parser code

  • Property mode set to 100644
File size: 32.3 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
[8e9cbb2]11// Last Modified By : Peter A. Buhr
[101e0bd]12// Last Modified On : Wed Sep 14 23:13:28 2016
13// Update Count : 502
[b87a5ed]14//
15
[51b73452]16#include <string>
17#include <list>
18#include <iterator>
19#include <algorithm>
20#include <cassert>
21
22#include "TypeData.h"
[bdd516a]23
[68cd1ce]24#include "SynTree/Declaration.h"
25#include "SynTree/Expression.h"
[51b73452]26
[de62360d]27#include "TypedefTable.h"
28extern TypedefTable typedefTable;
29
[51b73452]30using namespace std;
31
[bdd516a]32// These must remain in the same order as the corresponding DeclarationNode enumerations.
[b6424d9]33const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "NoStorageClass" };
[5b639ee]34const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic", "NoQualifier" };
35const char *DeclarationNode::basicTypeName[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "NoBasicType" };
36const char *DeclarationNode::complexTypeName[] = { "_Complex", "_Imaginary", "NoComplexType" };
37const char *DeclarationNode::signednessName[] = { "signed", "unsigned", "NoSignedness" };
38const char *DeclarationNode::lengthName[] = { "short", "long", "long long", "NoLength" };
[68cd1ce]39const char *DeclarationNode::aggregateName[] = { "struct", "union", "context" };
[5b639ee]40const char *DeclarationNode::typeClassName[] = { "otype", "dtype", "ftype" };
[90c3b1c]41const char *DeclarationNode::builtinTypeName[] = { "__builtin_va_list" };
[51b73452]42
43UniqueName DeclarationNode::anonymous( "__anonymous" );
44
[8b7ee09]45extern LinkageSpec::Spec linkage; // defined in parser.yy
[51b73452]46
[7d05e7e]47DeclarationNode::DeclarationNode() :
48 type( 0 ),
49 storageClass( NoStorageClass ),
50 isInline( false ),
51 isNoreturn( false ),
52 bitfieldWidth( 0 ),
53 initializer( 0 ),
54 hasEllipsis( false ),
55 linkage( ::linkage ),
56 extension( false ) {
[5b639ee]57 variable.tyClass = DeclarationNode::Otype;
[28307be]58 variable.assertions = nullptr;
[7d05e7e]59
60 attr.expr = nullptr;
61 attr.type = nullptr;
[28307be]62}
63
64DeclarationNode::~DeclarationNode() {
65 delete attr.expr;
66 delete attr.type;
67 delete type;
68 delete bitfieldWidth;
69 delete initializer;
70}
71
[3848e0e]72DeclarationNode *DeclarationNode::clone() const {
[b87a5ed]73 DeclarationNode *newnode = new DeclarationNode;
74 newnode->type = maybeClone( type );
75 newnode->name = name;
[13e3b50]76 newnode->storageClass = storageClass;
77 newnode->isInline = isInline;
78 newnode->isNoreturn = isNoreturn;
[f39096c]79 newnode->bitfieldWidth = maybeClone( bitfieldWidth );
[b87a5ed]80 newnode->hasEllipsis = hasEllipsis;
[f39096c]81 newnode->initializer = maybeClone( initializer );
[7880579]82 newnode->set_next( maybeClone( get_next() ) );
[b87a5ed]83 newnode->linkage = linkage;
[3848e0e]84
[28307be]85 newnode->variable.assertions = maybeClone( variable.assertions );
86 newnode->variable.name = variable.name;
87 newnode->variable.tyClass = variable.tyClass;
[3848e0e]88
[28307be]89 newnode->attr.expr = maybeClone( attr.expr );
90 newnode->attr.type = maybeClone( attr.type );
91 return newnode;
92} // DeclarationNode::clone
[3848e0e]93
94bool DeclarationNode::get_hasEllipsis() const {
[b87a5ed]95 return hasEllipsis;
[3848e0e]96}
97
98void DeclarationNode::print( std::ostream &os, int indent ) const {
[59db689]99 os << string( indent, ' ' );
[b87a5ed]100 if ( name == "" ) {
101 os << "unnamed: ";
102 } else {
103 os << name << ": ";
[68cd1ce]104 } // if
[51b73452]105
[b87a5ed]106 if ( linkage != LinkageSpec::Cforall ) {
107 os << LinkageSpec::toString( linkage ) << " ";
[68cd1ce]108 } // if
[3848e0e]109
[c1c1112]110 if ( storageClass != NoStorageClass ) os << DeclarationNode::storageName[storageClass] << ' ';
111 if ( isInline ) os << DeclarationNode::storageName[Inline] << ' ';
112 if ( isNoreturn ) os << DeclarationNode::storageName[Noreturn] << ' ';
[b87a5ed]113 if ( type ) {
114 type->print( os, indent );
115 } else {
116 os << "untyped entity ";
[68cd1ce]117 } // if
[3848e0e]118
[b87a5ed]119 if ( bitfieldWidth ) {
[59db689]120 os << endl << string( indent + 2, ' ' ) << "with bitfield width ";
[b87a5ed]121 bitfieldWidth->printOneLine( os );
[68cd1ce]122 } // if
[3848e0e]123
[b87a5ed]124 if ( initializer != 0 ) {
[59db689]125 os << endl << string( indent + 2, ' ' ) << "with initializer ";
[b87a5ed]126 initializer->printOneLine( os );
[974906e2]127 os << " maybe constructed? " << initializer->get_maybeConstructed();
128
[68cd1ce]129 } // if
[3848e0e]130
[b87a5ed]131 os << endl;
[51b73452]132}
133
[3848e0e]134void DeclarationNode::printList( std::ostream &os, int indent ) const {
[b87a5ed]135 ParseNode::printList( os, indent );
136 if ( hasEllipsis ) {
137 os << string( indent, ' ' ) << "and a variable number of other arguments" << endl;
[68cd1ce]138 } // if
[51b73452]139}
140
[d9a0e76]141DeclarationNode *DeclarationNode::newFunction( std::string *name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) {
[b87a5ed]142 DeclarationNode *newnode = new DeclarationNode;
143 newnode->name = assign_strptr( name );
[3848e0e]144
[b87a5ed]145 newnode->type = new TypeData( TypeData::Function );
[8f6f47d7]146 newnode->type->function.params = param;
147 newnode->type->function.newStyle = newStyle;
148 newnode->type->function.body = body;
[984dce6]149 typedefTable.addToEnclosingScope( newnode->name, TypedefTable::ID );
[3848e0e]150
[b87a5ed]151 if ( body ) {
[8f6f47d7]152 newnode->type->function.hasBody = true;
[68cd1ce]153 } // if
[51b73452]154
[b87a5ed]155 if ( ret ) {
156 newnode->type->base = ret->type;
157 ret->type = 0;
158 delete ret;
[68cd1ce]159 } // if
[51b73452]160
[b87a5ed]161 return newnode;
[984dce6]162} // DeclarationNode::newFunction
[3848e0e]163
[c1c1112]164DeclarationNode * DeclarationNode::newQualifier( Qualifier q ) {
[b87a5ed]165 DeclarationNode *newnode = new DeclarationNode;
166 newnode->type = new TypeData();
[c1c1112]167 newnode->type->qualifiers[ q ] = 1;
[b87a5ed]168 return newnode;
[984dce6]169} // DeclarationNode::newQualifier
[3848e0e]170
[c1c1112]171DeclarationNode * DeclarationNode::newForall( DeclarationNode *forall ) {
[b87a5ed]172 DeclarationNode *newnode = new DeclarationNode;
[c1c1112]173 newnode->type = new TypeData( TypeData::Unknown );
174 newnode->type->forall = forall;
175 return newnode;
176} // DeclarationNode::newForall
177
178DeclarationNode * DeclarationNode::newStorageClass( DeclarationNode::StorageClass sc ) {
179 DeclarationNode *newnode = new DeclarationNode;
180 //switch (sc) {
181 // case Inline: newnode->isInline = true; break;
182 // case Noreturn: newnode->isNoreturn = true; break;
183 // default: newnode->storageClass = sc; break;
184 //}
185 newnode->storageClass = sc;
[b87a5ed]186 return newnode;
[984dce6]187} // DeclarationNode::newStorageClass
[3848e0e]188
[c1c1112]189DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) {
[b87a5ed]190 DeclarationNode *newnode = new DeclarationNode;
191 newnode->type = new TypeData( TypeData::Basic );
[5b639ee]192 newnode->type->basictype = bt;
[b87a5ed]193 return newnode;
[984dce6]194} // DeclarationNode::newBasicType
[3848e0e]195
[5b639ee]196DeclarationNode * DeclarationNode::newComplexType( ComplexType ct ) {
[b87a5ed]197 DeclarationNode *newnode = new DeclarationNode;
198 newnode->type = new TypeData( TypeData::Basic );
[5b639ee]199 newnode->type->complextype = ct;
[b87a5ed]200 return newnode;
[5b639ee]201} // DeclarationNode::newComplexType
202
203DeclarationNode * DeclarationNode::newSignedNess( Signedness sn ) {
204 DeclarationNode *newnode = new DeclarationNode;
205 newnode->type = new TypeData( TypeData::Basic );
206 newnode->type->signedness = sn;
207 return newnode;
208} // DeclarationNode::newSignedNess
209
210DeclarationNode * DeclarationNode::newLength( Length lnth ) {
211 DeclarationNode *newnode = new DeclarationNode;
212 newnode->type = new TypeData( TypeData::Basic );
213 newnode->type->length = lnth;
214 return newnode;
215} // DeclarationNode::newLength
[3848e0e]216
[c1c1112]217DeclarationNode * DeclarationNode::newFromTypedef( std::string *name ) {
[b87a5ed]218 DeclarationNode *newnode = new DeclarationNode;
219 newnode->type = new TypeData( TypeData::SymbolicInst );
[8f6f47d7]220 newnode->type->symbolic.name = assign_strptr( name );
221 newnode->type->symbolic.isTypedef = true;
222 newnode->type->symbolic.params = 0;
[b87a5ed]223 return newnode;
[984dce6]224} // DeclarationNode::newFromTypedef
[3848e0e]225
[c1c1112]226DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const std::string *name, ExpressionNode *actuals, DeclarationNode *fields, bool body ) {
[b87a5ed]227 DeclarationNode *newnode = new DeclarationNode;
228 newnode->type = new TypeData( TypeData::Aggregate );
[8f6f47d7]229 newnode->type->aggregate.kind = kind;
230 newnode->type->aggregate.name = assign_strptr( name );
231 if ( newnode->type->aggregate.name == "" ) { // anonymous aggregate ?
232 newnode->type->aggregate.name = anonymous.newName();
233 } // if
234 newnode->type->aggregate.actuals = actuals;
235 newnode->type->aggregate.fields = fields;
236 newnode->type->aggregate.body = body;
[b87a5ed]237 return newnode;
[984dce6]238} // DeclarationNode::newAggregate
[3848e0e]239
240DeclarationNode *DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) {
[b87a5ed]241 DeclarationNode *newnode = new DeclarationNode;
242 newnode->name = assign_strptr( name );
243 newnode->type = new TypeData( TypeData::Enum );
[8f6f47d7]244 newnode->type->enumeration.name = newnode->name;
245 if ( newnode->type->enumeration.name == "" ) { // anonymous enumeration ?
246 newnode->type->enumeration.name = DeclarationNode::anonymous.newName();
[68cd1ce]247 } // if
[8f6f47d7]248 newnode->type->enumeration.constants = constants;
[b87a5ed]249 return newnode;
[984dce6]250} // DeclarationNode::newEnum
[3848e0e]251
[59db689]252DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) {
[b87a5ed]253 DeclarationNode *newnode = new DeclarationNode;
254 newnode->name = assign_strptr( name );
[4f147cc]255 newnode->enumeratorValue.reset( constant );
[984dce6]256 typedefTable.addToEnclosingScope( newnode->name, TypedefTable::ID );
[b87a5ed]257 return newnode;
[984dce6]258} // DeclarationNode::newEnumConstant
[3848e0e]259
[59db689]260DeclarationNode *DeclarationNode::newName( std::string *name ) {
[b87a5ed]261 DeclarationNode *newnode = new DeclarationNode;
262 newnode->name = assign_strptr( name );
263 return newnode;
[984dce6]264} // DeclarationNode::newName
[3848e0e]265
[59db689]266DeclarationNode *DeclarationNode::newFromTypeGen( std::string *name, ExpressionNode *params ) {
[b87a5ed]267 DeclarationNode *newnode = new DeclarationNode;
268 newnode->type = new TypeData( TypeData::SymbolicInst );
[8f6f47d7]269 newnode->type->symbolic.name = assign_strptr( name );
270 newnode->type->symbolic.isTypedef = false;
271 newnode->type->symbolic.actuals = params;
[b87a5ed]272 return newnode;
[984dce6]273} // DeclarationNode::newFromTypeGen
[3848e0e]274
[59db689]275DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string *name ) {
[b87a5ed]276 DeclarationNode *newnode = new DeclarationNode;
277 newnode->name = assign_strptr( name );
278 newnode->type = new TypeData( TypeData::Variable );
[28307be]279 newnode->variable.tyClass = tc;
280 newnode->variable.name = newnode->name;
[b87a5ed]281 return newnode;
[984dce6]282} // DeclarationNode::newTypeParam
[3848e0e]283
[4040425]284DeclarationNode *DeclarationNode::newTrait( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) {
[b87a5ed]285 DeclarationNode *newnode = new DeclarationNode;
286 newnode->type = new TypeData( TypeData::Aggregate );
[8f6f47d7]287 newnode->type->aggregate.kind = Trait;
288 newnode->type->aggregate.params = params;
289 newnode->type->aggregate.fields = asserts;
290 newnode->type->aggregate.name = assign_strptr( name );
[b87a5ed]291 return newnode;
[984dce6]292} // DeclarationNode::newTrait
[3848e0e]293
[4040425]294DeclarationNode *DeclarationNode::newTraitUse( std::string *name, ExpressionNode *params ) {
[b87a5ed]295 DeclarationNode *newnode = new DeclarationNode;
296 newnode->type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]297 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
298 newnode->type->aggInst.aggregate->aggregate.kind = Trait;
299 newnode->type->aggInst.aggregate->aggregate.name = assign_strptr( name );
300 newnode->type->aggInst.params = params;
[b87a5ed]301 return newnode;
[984dce6]302} // DeclarationNode::newTraitUse
[3848e0e]303
304DeclarationNode *DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) {
[b87a5ed]305 DeclarationNode *newnode = new DeclarationNode;
306 newnode->name = assign_strptr( name );
307 newnode->type = new TypeData( TypeData::Symbolic );
[8f6f47d7]308 newnode->type->symbolic.isTypedef = false;
309 newnode->type->symbolic.params = typeParams;
310 newnode->type->symbolic.name = newnode->name;
[b87a5ed]311 return newnode;
[984dce6]312} // DeclarationNode::newTypeDecl
[3848e0e]313
314DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) {
[b87a5ed]315 DeclarationNode *newnode = new DeclarationNode;
316 newnode->type = new TypeData( TypeData::Pointer );
317 return newnode->addQualifiers( qualifiers );
[984dce6]318} // DeclarationNode::newPointer
[3848e0e]319
320DeclarationNode *DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) {
[b87a5ed]321 DeclarationNode *newnode = new DeclarationNode;
322 newnode->type = new TypeData( TypeData::Array );
[8f6f47d7]323 newnode->type->array.dimension = size;
324 newnode->type->array.isStatic = isStatic;
325 if ( newnode->type->array.dimension == 0 || newnode->type->array.dimension->isExpressionType<ConstantExpr *>() ) {
326 newnode->type->array.isVarLen = false;
[71bd8c6]327 } else {
[8f6f47d7]328 newnode->type->array.isVarLen = true;
[71bd8c6]329 } // if
[b87a5ed]330 return newnode->addQualifiers( qualifiers );
[984dce6]331} // DeclarationNode::newArray
[3848e0e]332
333DeclarationNode *DeclarationNode::newVarArray( DeclarationNode *qualifiers ) {
[b87a5ed]334 DeclarationNode *newnode = new DeclarationNode;
335 newnode->type = new TypeData( TypeData::Array );
[8f6f47d7]336 newnode->type->array.dimension = 0;
337 newnode->type->array.isStatic = false;
338 newnode->type->array.isVarLen = true;
[b87a5ed]339 return newnode->addQualifiers( qualifiers );
[3848e0e]340}
341
342DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) {
[b87a5ed]343 DeclarationNode *newnode = new DeclarationNode;
344 newnode->bitfieldWidth = size;
345 return newnode;
[3848e0e]346}
347
348DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) {
[b87a5ed]349 DeclarationNode *newnode = new DeclarationNode;
350 newnode->type = new TypeData( TypeData::Tuple );
[8f6f47d7]351 newnode->type->tuple = members;
[b87a5ed]352 return newnode;
[3848e0e]353}
354
355DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) {
[b87a5ed]356 DeclarationNode *newnode = new DeclarationNode;
357 newnode->type = new TypeData( TypeData::Typeof );
[8f6f47d7]358 newnode->type->typeexpr = expr;
[b87a5ed]359 return newnode;
[3848e0e]360}
361
[8f6f47d7]362DeclarationNode * DeclarationNode::newBuiltinType( BuiltinType bt ) {
363 DeclarationNode *newnode = new DeclarationNode;
364 newnode->type = new TypeData( TypeData::Builtin );
365 newnode->builtin = bt;
366 return newnode;
367} // DeclarationNode::newBuiltinType
368
[3848e0e]369DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) {
[b87a5ed]370 DeclarationNode *newnode = new DeclarationNode;
371 newnode->type = new TypeData( TypeData::Attr );
[28307be]372 newnode->attr.name = assign_strptr( name );
373 newnode->attr.expr = expr;
[b87a5ed]374 return newnode;
[3848e0e]375}
376
377DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) {
[b87a5ed]378 DeclarationNode *newnode = new DeclarationNode;
379 newnode->type = new TypeData( TypeData::Attr );
[28307be]380 newnode->attr.name = assign_strptr( name );
381 newnode->attr.type = type;
[b87a5ed]382 return newnode;
[3848e0e]383}
384
[5b639ee]385void appendError( string & dst, const string & src ) {
386 if ( src.empty() ) return;
387 if ( dst.empty() ) { dst = src; return; }
388 dst += ", " + src;
389} // appendError
390
[413ad05]391void DeclarationNode::checkQualifiers( const TypeData *src, const TypeData *dst ) {
[b6424d9]392 TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
[c1c1112]393
[b6424d9]394 if ( (qsrc & qdst).any() ) { // common qualifier ?
[5b639ee]395 for ( int i = 0; i < NoQualifier; i += 1 ) { // find common qualifiers
396 if ( qsrc[i] && qdst[i] ) {
397 appendError( error, string( "duplicate " ) + DeclarationNode::qualifierName[i] );
[c1c1112]398 } // if
399 } // for
400 } // if
401} // DeclarationNode::checkQualifiers
402
[b6424d9]403void DeclarationNode::checkStorageClasses( DeclarationNode *q ) {
404 if ( storageClass != NoStorageClass && q->storageClass != NoStorageClass ) {
405 if ( storageClass == q->storageClass ) { // duplicate qualifier
[5b639ee]406 appendError( error, string( "duplicate " ) + storageName[ storageClass ] );
[b6424d9]407 } else { // only one storage class
[5b639ee]408 appendError( error, string( "conflicting " ) + storageName[ storageClass ] + " & " + storageName[ q->storageClass ] );
409 q->storageClass = storageClass; // FIX ERROR, prevent assertions from triggering
[b6424d9]410 } // if
411 } // if
[5b639ee]412 appendError( error, q->error );
[b6424d9]413} // DeclarationNode::copyStorageClasses
414
415DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
[5b639ee]416 isInline = isInline || q->isInline;
417 isNoreturn = isNoreturn || q->isNoreturn;
[b6424d9]418 // do not overwrite an existing value with NoStorageClass
419 if ( q->storageClass != NoStorageClass ) {
420 assert( storageClass == NoStorageClass || storageClass == q->storageClass );
421 storageClass = q->storageClass;
422 } // if
423 return this;
424} // DeclarationNode::copyStorageClasses
425
[101e0bd]426static void addQualifiersToType( TypeData *&src, TypeData *dst ) {
427 if ( src->forall && dst->kind == TypeData::Function ) {
428 if ( dst->forall ) {
429 dst->forall->appendList( src->forall );
430 } else {
431 dst->forall = src->forall;
432 } // if
433 src->forall = 0;
434 } // if
435 if ( dst->base ) {
436 addQualifiersToType( src, dst->base );
437 } else if ( dst->kind == TypeData::Function ) {
438 dst->base = src;
439 src = 0;
440 } else {
441 dst->qualifiers |= src->qualifiers;
442 } // if
443} // addQualifiersToType
444
[3848e0e]445DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
[101e0bd]446 if ( ! q ) return this;
447
448 checkStorageClasses( q );
449 copyStorageClasses( q );
450
451 if ( ! q->type ) { delete q; return this; }
452
453 if ( ! type ) {
454// type = new TypeData;
455 type = q->type;
456 return this;
457 } // if
458
459 checkQualifiers( q->type, type );
460 addQualifiersToType( q->type, type );
461
462 if ( q->type->forall ) {
463 if ( type->forall ) {
464 type->forall->appendList( q->type->forall );
465 } else {
466 if ( type->kind == TypeData::Aggregate ) {
467 type->aggregate.params = q->type->forall;
468 // change implicit typedef from TYPEDEFname to TYPEGENname
469 typedefTable.changeKind( type->aggregate.name, TypedefTable::TG );
[c1c1112]470 } else {
[101e0bd]471 type->forall = q->type->forall;
[68cd1ce]472 } // if
473 } // if
[101e0bd]474 q->type->forall = 0;
[68cd1ce]475 } // if
[b87a5ed]476 delete q;
477 return this;
[101e0bd]478} // addQualifiers
[3848e0e]479
480static void addTypeToType( TypeData *&src, TypeData *&dst ) {
[101e0bd]481 if ( src->forall && dst->kind == TypeData::Function ) {
482 if ( dst->forall ) {
483 dst->forall->appendList( src->forall );
[b87a5ed]484 } else {
[101e0bd]485 dst->forall = src->forall;
486 } // if
487 src->forall = 0;
488 } // if
489 if ( dst->base ) {
490 addTypeToType( src, dst->base );
491 } else {
492 switch ( dst->kind ) {
493 case TypeData::Unknown:
494 src->qualifiers |= dst->qualifiers;
495 dst = src;
496 src = 0;
497 break;
498 case TypeData::Basic:
499 dst->qualifiers |= src->qualifiers;
500 if ( src->kind != TypeData::Unknown ) {
501 assert( src->kind == TypeData::Basic );
502
503 if ( dst->basictype == DeclarationNode::NoBasicType ) {
504 dst->basictype = src->basictype;
505 } else if ( src->basictype != DeclarationNode::NoBasicType )
506 throw SemanticError( std::string( "conflicting type specifier " ) + DeclarationNode::basicTypeName[ src->basictype ] + " in type: ", src );
507
508 if ( dst->complextype == DeclarationNode::NoComplexType ) {
509 dst->complextype = src->complextype;
510 } else if ( src->complextype != DeclarationNode::NoComplexType )
511 throw SemanticError( std::string( "conflicting type specifier " ) + DeclarationNode::complexTypeName[ src->complextype ] + " in type: ", src );
512
513 if ( dst->signedness == DeclarationNode::NoSignedness ) {
514 dst->signedness = src->signedness;
515 } else if ( src->signedness != DeclarationNode::NoSignedness )
516 throw SemanticError( std::string( "conflicting type specifier " ) + DeclarationNode::signednessName[ src->signedness ] + " in type: ", src );
517
518 if ( dst->length == DeclarationNode::NoLength ) {
519 dst->length = src->length;
520 } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) {
521 dst->length = DeclarationNode::LongLong;
522 } else if ( src->length != DeclarationNode::NoLength )
523 throw SemanticError( std::string( "conflicting type specifier " ) + DeclarationNode::lengthName[ src->length ] + " in type: ", src );
524 } // if
525 break;
526 default:
527 switch ( src->kind ) {
528 case TypeData::Aggregate:
529 case TypeData::Enum:
530 dst->base = new TypeData( TypeData::AggregateInst );
531 dst->base->aggInst.aggregate = src;
532 if ( src->kind == TypeData::Aggregate ) {
533 dst->base->aggInst.params = maybeClone( src->aggregate.actuals );
[68cd1ce]534 } // if
[101e0bd]535 dst->base->qualifiers |= src->qualifiers;
536 src = 0;
[b87a5ed]537 break;
538 default:
[101e0bd]539 if ( dst->forall ) {
540 dst->forall->appendList( src->forall );
541 } else {
542 dst->forall = src->forall;
543 } // if
544 src->forall = 0;
545 dst->base = src;
546 src = 0;
[68cd1ce]547 } // switch
[101e0bd]548 } // switch
[68cd1ce]549 } // if
[3848e0e]550}
551
552DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
[b87a5ed]553 if ( o ) {
[b6424d9]554 checkStorageClasses( o );
[13e3b50]555 copyStorageClasses( o );
[b87a5ed]556 if ( o->type ) {
557 if ( ! type ) {
558 if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
559 type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]560 type->aggInst.aggregate = o->type;
[b87a5ed]561 if ( o->type->kind == TypeData::Aggregate ) {
[8f6f47d7]562 type->aggInst.params = maybeClone( o->type->aggregate.actuals );
[68cd1ce]563 } // if
[c1c1112]564 type->qualifiers |= o->type->qualifiers;
[b87a5ed]565 } else {
566 type = o->type;
[68cd1ce]567 } // if
[b87a5ed]568 o->type = 0;
569 } else {
570 addTypeToType( o->type, type );
[68cd1ce]571 } // if
572 } // if
[b87a5ed]573 if ( o->bitfieldWidth ) {
574 bitfieldWidth = o->bitfieldWidth;
[68cd1ce]575 } // if
[71bd8c6]576
577 // there may be typedefs chained onto the type
[1d4580a]578 if ( o->get_next() ) {
579 set_last( o->get_next()->clone() );
[1db21619]580 } // if
[68cd1ce]581 } // if
[b87a5ed]582 delete o;
583 return this;
[3848e0e]584}
585
586DeclarationNode *DeclarationNode::addTypedef() {
[b87a5ed]587 TypeData *newtype = new TypeData( TypeData::Symbolic );
[8f6f47d7]588 newtype->symbolic.params = 0;
589 newtype->symbolic.isTypedef = true;
590 newtype->symbolic.name = name;
[b87a5ed]591 newtype->base = type;
592 type = newtype;
593 return this;
[3848e0e]594}
595
[59db689]596DeclarationNode *DeclarationNode::addAssertions( DeclarationNode *assertions ) {
[b87a5ed]597 assert( type );
598 switch ( type->kind ) {
599 case TypeData::Symbolic:
[8f6f47d7]600 if ( type->symbolic.assertions ) {
601 type->symbolic.assertions->appendList( assertions );
[b87a5ed]602 } else {
[8f6f47d7]603 type->symbolic.assertions = assertions;
[68cd1ce]604 } // if
[b87a5ed]605 break;
606 case TypeData::Variable:
[28307be]607 if ( variable.assertions ) {
608 variable.assertions->appendList( assertions );
[b87a5ed]609 } else {
[28307be]610 variable.assertions = assertions;
[68cd1ce]611 } // if
[b87a5ed]612 break;
613 default:
614 assert( false );
[68cd1ce]615 } // switch
[974906e2]616
[b87a5ed]617 return this;
[51b73452]618}
619
[59db689]620DeclarationNode *DeclarationNode::addName( std::string *newname ) {
[b87a5ed]621 name = assign_strptr( newname );
622 return this;
[51b73452]623}
624
[3848e0e]625DeclarationNode *DeclarationNode::addBitfield( ExpressionNode *size ) {
[b87a5ed]626 bitfieldWidth = size;
627 return this;
[51b73452]628}
629
[3848e0e]630DeclarationNode *DeclarationNode::addVarArgs() {
[b87a5ed]631 assert( type );
632 hasEllipsis = true;
633 return this;
[51b73452]634}
635
[3848e0e]636DeclarationNode *DeclarationNode::addFunctionBody( StatementNode *body ) {
[b87a5ed]637 assert( type );
638 assert( type->kind == TypeData::Function );
[8f6f47d7]639 assert( type->function.body == 0 );
640 type->function.body = body;
641 type->function.hasBody = true;
[b87a5ed]642 return this;
[51b73452]643}
644
[3848e0e]645DeclarationNode *DeclarationNode::addOldDeclList( DeclarationNode *list ) {
[b87a5ed]646 assert( type );
647 assert( type->kind == TypeData::Function );
[8f6f47d7]648 assert( type->function.oldDeclList == 0 );
649 type->function.oldDeclList = list;
[b87a5ed]650 return this;
[51b73452]651}
652
[68cd1ce]653static void setBase( TypeData *&type, TypeData *newType ) {
[b87a5ed]654 if ( type ) {
655 TypeData *prevBase = type;
656 TypeData *curBase = type->base;
[a32b204]657 while ( curBase != 0 ) {
[b87a5ed]658 prevBase = curBase;
659 curBase = curBase->base;
[68cd1ce]660 } // while
[b87a5ed]661 prevBase->base = newType;
662 } else {
663 type = newType;
[68cd1ce]664 } // if
[3848e0e]665}
666
667DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) {
[b87a5ed]668 if ( p ) {
669 assert( p->type->kind == TypeData::Pointer );
670 setBase( type, p->type );
671 p->type = 0;
672 delete p;
[68cd1ce]673 } // if
[b87a5ed]674 return this;
[3848e0e]675}
676
677DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) {
[b87a5ed]678 if ( a ) {
679 assert( a->type->kind == TypeData::Array );
680 setBase( type, a->type );
681 a->type = 0;
682 delete a;
[68cd1ce]683 } // if
[b87a5ed]684 return this;
[51b73452]685}
686
[3848e0e]687DeclarationNode *DeclarationNode::addNewPointer( DeclarationNode *p ) {
[b87a5ed]688 if ( p ) {
689 assert( p->type->kind == TypeData::Pointer );
690 if ( type ) {
691 switch ( type->kind ) {
692 case TypeData::Aggregate:
693 case TypeData::Enum:
694 p->type->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]695 p->type->base->aggInst.aggregate = type;
[b87a5ed]696 if ( type->kind == TypeData::Aggregate ) {
[8f6f47d7]697 p->type->base->aggInst.params = maybeClone( type->aggregate.actuals );
[68cd1ce]698 } // if
[c1c1112]699 p->type->base->qualifiers |= type->qualifiers;
[b87a5ed]700 break;
701
702 default:
703 p->type->base = type;
[68cd1ce]704 } // switch
[b87a5ed]705 type = 0;
[68cd1ce]706 } // if
[b87a5ed]707 delete this;
708 return p;
709 } else {
710 return this;
[68cd1ce]711 } // if
[51b73452]712}
713
[3848e0e]714static TypeData *findLast( TypeData *a ) {
[b87a5ed]715 assert( a );
716 TypeData *cur = a;
[a32b204]717 while ( cur->base ) {
[b87a5ed]718 cur = cur->base;
[68cd1ce]719 } // while
[b87a5ed]720 return cur;
[3848e0e]721}
722
723DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
[b87a5ed]724 if ( a ) {
725 assert( a->type->kind == TypeData::Array );
726 TypeData *lastArray = findLast( a->type );
[974906e2]727 if ( type ) {
[b87a5ed]728 switch ( type->kind ) {
729 case TypeData::Aggregate:
730 case TypeData::Enum:
731 lastArray->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]732 lastArray->base->aggInst.aggregate = type;
[b87a5ed]733 if ( type->kind == TypeData::Aggregate ) {
[8f6f47d7]734 lastArray->base->aggInst.params = maybeClone( type->aggregate.actuals );
[68cd1ce]735 } // if
[c1c1112]736 lastArray->base->qualifiers |= type->qualifiers;
[b87a5ed]737 break;
738 default:
739 lastArray->base = type;
[68cd1ce]740 } // switch
[b87a5ed]741 type = 0;
[68cd1ce]742 } // if
[b87a5ed]743 delete this;
744 return a;
745 } else {
746 return this;
[68cd1ce]747 } // if
[51b73452]748}
[3848e0e]749
750DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
[b87a5ed]751 TypeData *ftype = new TypeData( TypeData::Function );
[8f6f47d7]752 ftype->function.params = params;
[b87a5ed]753 setBase( type, ftype );
754 return this;
[3848e0e]755}
756
757static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
[b87a5ed]758 if ( type ) {
759 if ( type->kind != TypeData::Function ) {
760 type->base = addIdListToType( type->base, ids );
761 } else {
[8f6f47d7]762 type->function.idList = ids;
[68cd1ce]763 } // if
[b87a5ed]764 return type;
[3848e0e]765 } else {
[b87a5ed]766 TypeData *newtype = new TypeData( TypeData::Function );
[8f6f47d7]767 newtype->function.idList = ids;
[b87a5ed]768 return newtype;
[68cd1ce]769 } // if
[3848e0e]770}
[974906e2]771
[3848e0e]772DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
[b87a5ed]773 type = addIdListToType( type, ids );
774 return this;
[3848e0e]775}
776
777DeclarationNode *DeclarationNode::addInitializer( InitializerNode *init ) {
[b87a5ed]778 //assert
779 initializer = init;
780 return this;
[3848e0e]781}
782
783DeclarationNode *DeclarationNode::cloneBaseType( string *newName ) {
[b87a5ed]784 DeclarationNode *newnode = new DeclarationNode;
785 TypeData *srcType = type;
[a32b204]786 while ( srcType->base ) {
[b87a5ed]787 srcType = srcType->base;
[68cd1ce]788 } // while
[b87a5ed]789 newnode->type = maybeClone( srcType );
790 if ( newnode->type->kind == TypeData::AggregateInst ) {
791 // don't duplicate members
[8f6f47d7]792 if ( newnode->type->aggInst.aggregate->kind == TypeData::Enum ) {
793 delete newnode->type->aggInst.aggregate->enumeration.constants;
794 newnode->type->aggInst.aggregate->enumeration.constants = 0;
[b87a5ed]795 } else {
[8f6f47d7]796 assert( newnode->type->aggInst.aggregate->kind == TypeData::Aggregate );
797 delete newnode->type->aggInst.aggregate->aggregate.fields;
798 newnode->type->aggInst.aggregate->aggregate.fields = 0;
[68cd1ce]799 } // if
800 } // if
[b87a5ed]801 newnode->type->forall = maybeClone( type->forall );
[b6424d9]802 assert( storageClass == NoStorageClass );
[13e3b50]803 newnode->copyStorageClasses( this );
[b87a5ed]804 newnode->name = assign_strptr( newName );
805 return newnode;
[3848e0e]806}
807
808DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
[b87a5ed]809 if ( o ) {
[13e3b50]810 o->copyStorageClasses( this );
[b87a5ed]811 if ( type ) {
812 TypeData *srcType = type;
[a32b204]813 while ( srcType->base ) {
[b87a5ed]814 srcType = srcType->base;
[68cd1ce]815 } // while
[b87a5ed]816 TypeData *newType = srcType->clone();
817 if ( newType->kind == TypeData::AggregateInst ) {
818 // don't duplicate members
[8f6f47d7]819 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
820 delete newType->aggInst.aggregate->enumeration.constants;
821 newType->aggInst.aggregate->enumeration.constants = 0;
[b87a5ed]822 } else {
[8f6f47d7]823 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
824 delete newType->aggInst.aggregate->aggregate.fields;
825 newType->aggInst.aggregate->aggregate.fields = 0;
[68cd1ce]826 } // if
827 } // if
[b87a5ed]828 newType->forall = maybeClone( type->forall );
829 if ( ! o->type ) {
830 o->type = newType;
831 } else {
832 addTypeToType( newType, o->type );
833 delete newType;
[68cd1ce]834 } // if
835 } // if
836 } // if
[b87a5ed]837 return o;
[3848e0e]838}
839
840DeclarationNode *DeclarationNode::cloneType( string *newName ) {
[b87a5ed]841 DeclarationNode *newnode = new DeclarationNode;
842 newnode->type = maybeClone( type );
[b6424d9]843 assert( storageClass == NoStorageClass );
[13e3b50]844 newnode->copyStorageClasses( this );
[b87a5ed]845 newnode->name = assign_strptr( newName );
846 return newnode;
[3848e0e]847}
848
849DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
[b87a5ed]850 if ( o ) {
[b6424d9]851 assert( storageClass == NoStorageClass );
[13e3b50]852 o->copyStorageClasses( this );
[b87a5ed]853 if ( type ) {
854 TypeData *newType = type->clone();
855 if ( ! o->type ) {
856 o->type = newType;
857 } else {
858 addTypeToType( newType, o->type );
859 delete newType;
[68cd1ce]860 } // if
861 } // if
862 } // if
[2037f82]863 delete o;
[b87a5ed]864 return o;
[51b73452]865}
866
[3848e0e]867DeclarationNode *DeclarationNode::extractAggregate() const {
[b87a5ed]868 if ( type ) {
[413ad05]869 TypeData *ret = typeextractAggregate( type );
[b87a5ed]870 if ( ret ) {
871 DeclarationNode *newnode = new DeclarationNode;
872 newnode->type = ret;
873 return newnode;
[843054c2]874 } // if
875 } // if
876 return 0;
[3848e0e]877}
878
[a61fea9a]879void buildList( const DeclarationNode *firstNode, std::list< Declaration * > &outputList ) {
[b87a5ed]880 SemanticError errors;
[7880579]881 std::back_insert_iterator< std::list< Declaration * > > out( outputList );
[b87a5ed]882 const DeclarationNode *cur = firstNode;
[a32b204]883 while ( cur ) {
[b87a5ed]884 try {
885 if ( DeclarationNode *extr = cur->extractAggregate() ) {
886 // handle the case where a structure declaration is contained within an object or type declaration
887 Declaration *decl = extr->build();
888 if ( decl ) {
889 *out++ = decl;
[843054c2]890 } // if
[f39096c]891 delete extr;
[843054c2]892 } // if
[b87a5ed]893 Declaration *decl = cur->build();
894 if ( decl ) {
895 *out++ = decl;
[843054c2]896 } // if
[b87a5ed]897 } catch( SemanticError &e ) {
898 errors.append( e );
[843054c2]899 } // try
[7880579]900 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
[843054c2]901 } // while
[b87a5ed]902 if ( ! errors.isEmpty() ) {
903 throw errors;
[843054c2]904 } // if
[3848e0e]905}
906
[7880579]907void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType * > &outputList ) {
[b87a5ed]908 SemanticError errors;
[7880579]909 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
[b87a5ed]910 const DeclarationNode *cur = firstNode;
[a32b204]911 while ( cur ) {
[b87a5ed]912 try {
913 Declaration *decl = cur->build();
914 if ( decl ) {
[7880579]915 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
[b87a5ed]916 *out++ = dwt;
[7880579]917 } else if ( StructDecl *agg = dynamic_cast< StructDecl * >( decl ) ) {
[b87a5ed]918 StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
[68cd1ce]919 *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
[b87a5ed]920 delete agg;
[7880579]921 } else if ( UnionDecl *agg = dynamic_cast< UnionDecl * >( decl ) ) {
[b87a5ed]922 UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
[68cd1ce]923 *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
[843054c2]924 } // if
925 } // if
[b87a5ed]926 } catch( SemanticError &e ) {
927 errors.append( e );
[843054c2]928 } // try
[7880579]929 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
[843054c2]930 } // while
[b87a5ed]931 if ( ! errors.isEmpty() ) {
932 throw errors;
[843054c2]933 } // if
[3848e0e]934}
935
[7880579]936void buildTypeList( const DeclarationNode *firstNode, std::list< Type * > &outputList ) {
[b87a5ed]937 SemanticError errors;
[7880579]938 std::back_insert_iterator< std::list< Type * > > out( outputList );
[b87a5ed]939 const DeclarationNode *cur = firstNode;
[a32b204]940 while ( cur ) {
[b87a5ed]941 try {
942 *out++ = cur->buildType();
943 } catch( SemanticError &e ) {
944 errors.append( e );
[843054c2]945 } // try
[7880579]946 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
[843054c2]947 } // while
[b87a5ed]948 if ( ! errors.isEmpty() ) {
949 throw errors;
[843054c2]950 } // if
[51b73452]951}
952
[3848e0e]953Declaration *DeclarationNode::build() const {
[7d05e7e]954 if ( ! error.empty() ) throw SemanticError( error + " in declaration of ", this );
[843054c2]955 if ( type ) {
[28307be]956 if ( type->kind == TypeData::Variable ) {
957 static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
958 TypeDecl * ret = new TypeDecl( variable.name, DeclarationNode::NoStorageClass, 0, kindMap[ variable.tyClass ] );
959 buildList( variable.assertions, ret->get_assertions() );
960 return ret;
961 } else {
962 return buildDecl( type, name, storageClass, maybeBuild< Expression >( bitfieldWidth ), isInline, isNoreturn, linkage, maybeBuild< Initializer >(initializer) )->set_extension( extension );
963 } // if
[843054c2]964 } // if
[13e3b50]965 if ( ! isInline && ! isNoreturn ) {
966 return (new ObjectDecl( name, storageClass, linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ))->set_extension( extension );
[843054c2]967 } // if
[7d05e7e]968 throw SemanticError( "invalid function specifier ", this );
[51b73452]969}
970
[3848e0e]971Type *DeclarationNode::buildType() const {
[b87a5ed]972 assert( type );
[974906e2]973
[b87a5ed]974 switch ( type->kind ) {
975 case TypeData::Enum:
[8f6f47d7]976 return new EnumInstType( buildQualifiers( type ), type->enumeration.name );
[b87a5ed]977 case TypeData::Aggregate: {
978 ReferenceToType *ret;
[8f6f47d7]979 switch ( type->aggregate.kind ) {
[b87a5ed]980 case DeclarationNode::Struct:
[8f6f47d7]981 ret = new StructInstType( buildQualifiers( type ), type->aggregate.name );
[b87a5ed]982 break;
983 case DeclarationNode::Union:
[8f6f47d7]984 ret = new UnionInstType( buildQualifiers( type ), type->aggregate.name );
[b87a5ed]985 break;
[4040425]986 case DeclarationNode::Trait:
[8f6f47d7]987 ret = new TraitInstType( buildQualifiers( type ), type->aggregate.name );
[b87a5ed]988 break;
989 default:
990 assert( false );
991 } // switch
[8f6f47d7]992 buildList( type->aggregate.actuals, ret->get_parameters() );
[b87a5ed]993 return ret;
994 }
995 case TypeData::Symbolic: {
[8f6f47d7]996 TypeInstType *ret = new TypeInstType( buildQualifiers( type ), type->symbolic.name, false );
997 buildList( type->symbolic.actuals, ret->get_parameters() );
[b87a5ed]998 return ret;
999 }
[28307be]1000 case TypeData::Attr: {
1001 assert( type->kind == TypeData::Attr );
1002 // assert( type->attr );
1003 AttrType * ret;
1004 if ( attr.expr ) {
1005 ret = new AttrType( buildQualifiers( type ), attr.name, attr.expr->build() );
1006 } else {
1007 assert( attr.type );
1008 ret = new AttrType( buildQualifiers( type ), attr.name, attr.type->buildType() );
1009 } // if
1010 return ret;
1011 }
[b87a5ed]1012 default:
[413ad05]1013 return typebuild( type );
[b87a5ed]1014 } // switch
[3848e0e]1015}
1016
[b87a5ed]1017// Local Variables: //
1018// tab-width: 4 //
1019// mode: c++ //
1020// compile-command: "make install" //
1021// End: //
Note: See TracBrowser for help on using the repository browser.