source: src/Parser/DeclarationNode.cc@ 0df292b

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

fix OT_LABELADDRESS warning, parse genric types

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