source: src/Parser/DeclarationNode.cc@ 74e5a3aa

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 74e5a3aa was 58dd019, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

add asm_name clause to declarations

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