source: src/Parser/DeclarationNode.cc@ a465caff

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox 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 a465caff was 5d125e4, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

start code allowing structures to no fields

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