source: src/Parser/DeclarationNode.cc@ fbfb38e

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 with_gc
Last change on this file since fbfb38e was 70a06f6, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

Merge branch 'master' into ctor

Conflicts:

src/CodeGen/CodeGenerator.cc
src/GenPoly/Box.cc
src/Parser/DeclarationNode.cc
src/Parser/ParseNode.h
src/Parser/parser.cc
src/Parser/parser.yy
src/SymTab/AddVisit.h
src/SymTab/Validate.cc
src/SynTree/Expression.cc
src/SynTree/Expression.h
src/SynTree/Mutator.cc
src/SynTree/Mutator.h
src/SynTree/SynTree.h
src/SynTree/Visitor.cc
src/SynTree/Visitor.h
src/libcfa/iostream.c

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