source: src/Parser/DeclarationNode.cc @ dd020c0

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since dd020c0 was dd020c0, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

first attempt to create function specifiers

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