source: src/Parser/DeclarationNode.cc@ b5b0907

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 b5b0907 was 68cd1ce, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

unify and fix storage class

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