source: src/Parser/DeclarationNode.cc@ fe26fbf

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 fe26fbf was c0aa336, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

third attempt at gcc attributes

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