source: src/Parser/DeclarationNode.cc@ dac593fd

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

more refactoring of parser code

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