source: src/Parser/DeclarationNode.cc@ aefcc3b

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors 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 aefcc3b was 101e0bd, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

more refactoring of parser code

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