source: src/Parser/DeclarationNode.cc@ f6d7e0f

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

include file with keywords, fix type of label address expressions, fix computed goto to any expressions, generic types first attempt

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