source: src/Parser/DeclarationNode.cc@ ae7014e

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

only implicitly generate typedef for structures if name not in use and overwrite typedef name if explicit name appears, upate parser symbol table

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