source: src/Parser/DeclarationNode.cc@ 2e60a1a

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

change keyword type to otype and context to trait

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