source: src/Parser/TypeData.cc @ d734fa1

Last change on this file since d734fa1 was bf050c5, checked in by Andrew Beach <ajbeach@…>, 3 months ago

Removed unused field from TypeData?.

  • Property mode set to 100644
File size: 50.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// TypeData.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 15:12:51 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Feb 23 08:58:30 2024
13// Update Count     : 734
14//
15
16#include "TypeData.h"
17
18#include <cassert>                 // for assert
19#include <ostream>                 // for operator<<, ostream, basic_ostream
20
21#include "AST/Decl.hpp"            // for AggregateDecl, ObjectDecl, TypeDe...
22#include "AST/Attribute.hpp"       // for Attribute
23#include "AST/Init.hpp"            // for SingleInit, ListInit
24#include "AST/Print.hpp"           // for print
25#include "Common/SemanticError.h"  // for SemanticError
26#include "Common/utility.h"        // for splice, spliceBegin
27#include "Common/Iterate.hpp"      // for reverseIterate
28#include "Parser/ExpressionNode.h" // for ExpressionNode
29#include "Parser/StatementNode.h"  // for StatementNode
30
31class Attribute;
32
33using namespace std;
34
35// These must harmonize with the corresponding enumerations in the header.
36const char * TypeData::basicTypeNames[] = {
37        "void", "_Bool", "char", "int", "int128",
38        "float", "double", "long double", "float80", "float128",
39        "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x",
40        "NoBasicTypeNames"
41};
42const char * TypeData::complexTypeNames[] = {
43        "_Complex", "NoComplexTypeNames", "_Imaginary"
44}; // Imaginary unsupported => parse, but make invisible and print error message
45const char * TypeData::signednessNames[] = {
46        "signed", "unsigned", "NoSignednessNames"
47};
48const char * TypeData::lengthNames[] = {
49        "short", "long", "long long", "NoLengthNames"
50};
51const char * TypeData::builtinTypeNames[] = {
52        "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames"
53};
54
55TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
56        switch ( kind ) {
57        case Unknown:
58        case Pointer:
59        case Reference:
60        case EnumConstant:
61        case GlobalScope:
62        case Basic:
63                // No unique data to initialize.
64                break;
65        case Array:
66                array.dimension = nullptr;
67                array.isVarLen = false;
68                array.isStatic = false;
69                break;
70        case Function:
71                function.params = nullptr;
72                function.idList = nullptr;
73                function.oldDeclList = nullptr;
74                function.body = nullptr;
75                function.withExprs = nullptr;
76                break;
77        case Enum:
78                enumeration.name = nullptr;
79                enumeration.constants = nullptr;
80                enumeration.body = false;
81                enumeration.anon = false;
82                break;
83        case Aggregate:
84                aggregate.kind = ast::AggregateDecl::NoAggregate;
85                aggregate.name = nullptr;
86                aggregate.params = nullptr;
87                aggregate.actuals = nullptr;
88                aggregate.fields = nullptr;
89                aggregate.body = false;
90                aggregate.anon = false;
91                break;
92        case AggregateInst:
93                aggInst.aggregate = nullptr;
94                aggInst.params = nullptr;
95                aggInst.hoistType = false;
96                break;
97        case Symbolic:
98        case SymbolicInst:
99                symbolic.name = nullptr;
100                symbolic.params = nullptr;
101                symbolic.actuals = nullptr;
102                symbolic.assertions = nullptr;
103                break;
104        case Tuple:
105                tuple = nullptr;
106                break;
107        case Typeof:
108        case Basetypeof:
109                typeexpr = nullptr;
110                break;
111        case Vtable:
112        case Builtin:
113                // No unique data to initialize.
114                break;
115        case Qualified:
116                qualified.parent = nullptr;
117                qualified.child = nullptr;
118                break;
119        } // switch
120} // TypeData::TypeData
121
122
123TypeData::~TypeData() {
124        delete base;
125        delete forall;
126
127        switch ( kind ) {
128        case Unknown:
129        case Pointer:
130        case Reference:
131        case EnumConstant:
132        case GlobalScope:
133        case Basic:
134                // No unique data to deconstruct.
135                break;
136        case Array:
137                delete array.dimension;
138                break;
139        case Function:
140                delete function.params;
141                delete function.idList;
142                delete function.oldDeclList;
143                delete function.body;
144                delete function.withExprs;
145                break;
146        case Aggregate:
147                delete aggregate.name;
148                delete aggregate.params;
149                delete aggregate.actuals;
150                delete aggregate.fields;
151                break;
152        case AggregateInst:
153                delete aggInst.aggregate;
154                delete aggInst.params;
155                break;
156        case Enum:
157                delete enumeration.name;
158                delete enumeration.constants;
159                break;
160        case Symbolic:
161        case SymbolicInst:
162                delete symbolic.name;
163                delete symbolic.params;
164                delete symbolic.actuals;
165                delete symbolic.assertions;
166                break;
167        case Tuple:
168                delete tuple;
169                break;
170        case Typeof:
171        case Basetypeof:
172                delete typeexpr;
173                break;
174        case Vtable:
175        case Builtin:
176                // No unique data to deconstruct.
177                break;
178        case Qualified:
179                delete qualified.parent;
180                delete qualified.child;
181                break;
182        } // switch
183} // TypeData::~TypeData
184
185
186TypeData * TypeData::clone() const {
187        TypeData * newtype = new TypeData( kind );
188        newtype->qualifiers = qualifiers;
189        newtype->base = maybeCopy( base );
190        newtype->forall = maybeCopy( forall );
191
192        switch ( kind ) {
193        case Unknown:
194        case EnumConstant:
195        case Pointer:
196        case Reference:
197        case GlobalScope:
198                // nothing else to copy
199                break;
200        case Basic:
201                newtype->basictype = basictype;
202                newtype->complextype = complextype;
203                newtype->signedness = signedness;
204                newtype->length = length;
205                break;
206        case Array:
207                newtype->array.dimension = maybeCopy( array.dimension );
208                newtype->array.isVarLen = array.isVarLen;
209                newtype->array.isStatic = array.isStatic;
210                break;
211        case Function:
212                newtype->function.params = maybeCopy( function.params );
213                newtype->function.idList = maybeCopy( function.idList );
214                newtype->function.oldDeclList = maybeCopy( function.oldDeclList );
215                newtype->function.body = maybeCopy( function.body );
216                newtype->function.withExprs = maybeCopy( function.withExprs );
217                break;
218        case Aggregate:
219                newtype->aggregate.kind = aggregate.kind;
220                newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
221                newtype->aggregate.params = maybeCopy( aggregate.params );
222                newtype->aggregate.actuals = maybeCopy( aggregate.actuals );
223                newtype->aggregate.fields = maybeCopy( aggregate.fields );
224                newtype->aggregate.attributes = aggregate.attributes;
225                newtype->aggregate.body = aggregate.body;
226                newtype->aggregate.anon = aggregate.anon;
227                break;
228        case AggregateInst:
229                newtype->aggInst.aggregate = maybeCopy( aggInst.aggregate );
230                newtype->aggInst.params = maybeCopy( aggInst.params );
231                newtype->aggInst.hoistType = aggInst.hoistType;
232                break;
233        case Enum:
234                newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
235                newtype->enumeration.constants = maybeCopy( enumeration.constants );
236                newtype->enumeration.body = enumeration.body;
237                newtype->enumeration.anon = enumeration.anon;
238                break;
239        case Symbolic:
240        case SymbolicInst:
241                newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr;
242                newtype->symbolic.params = maybeCopy( symbolic.params );
243                newtype->symbolic.actuals = maybeCopy( symbolic.actuals );
244                newtype->symbolic.assertions = maybeCopy( symbolic.assertions );
245                newtype->symbolic.isTypedef = symbolic.isTypedef;
246                break;
247        case Tuple:
248                newtype->tuple = maybeCopy( tuple );
249                break;
250        case Typeof:
251        case Basetypeof:
252                newtype->typeexpr = maybeCopy( typeexpr );
253                break;
254        case Vtable:
255                break;
256        case Builtin:
257                assert( builtintype == Zero || builtintype == One );
258                newtype->builtintype = builtintype;
259                break;
260        case Qualified:
261                newtype->qualified.parent = maybeCopy( qualified.parent );
262                newtype->qualified.child = maybeCopy( qualified.child );
263                break;
264        } // switch
265        return newtype;
266} // TypeData::clone
267
268
269void TypeData::print( ostream &os, int indent ) const {
270        ast::print( os, qualifiers );
271
272        if ( forall ) {
273                os << "forall " << endl;
274                forall->printList( os, indent + 4 );
275        } // if
276
277        switch ( kind ) {
278        case Basic:
279                if ( signedness != NoSignedness ) os << signednessNames[ signedness ] << " ";
280                if ( length != NoLength ) os << lengthNames[ length ] << " ";
281                if ( complextype != NoComplexType ) os << complexTypeNames[ complextype ] << " ";
282                if ( basictype != NoBasicType ) os << basicTypeNames[ basictype ] << " ";
283                break;
284        case Pointer:
285                os << "pointer ";
286                if ( base ) {
287                        os << "to ";
288                        base->print( os, indent );
289                } // if
290                break;
291        case Reference:
292                os << "reference ";
293                if ( base ) {
294                        os << "to ";
295                        base->print( os, indent );
296                } // if
297                break;
298        case Array:
299                if ( array.isStatic ) {
300                        os << "static ";
301                } // if
302                if ( array.dimension ) {
303                        os << "array of ";
304                        array.dimension->printOneLine( os, indent );
305                } else if ( array.isVarLen ) {
306                        os << "variable-length array of ";
307                } else {
308                        os << "open array of ";
309                } // if
310                if ( base ) {
311                        base->print( os, indent );
312                } // if
313                break;
314        case Function:
315                os << "function" << endl;
316                if ( function.params ) {
317                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
318                        function.params->printList( os, indent + 4 );
319                } else {
320                        os << string( indent + 2, ' ' ) << "with no parameters" << endl;
321                } // if
322                if ( function.idList ) {
323                        os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
324                        function.idList->printList( os, indent + 4 );
325                } // if
326                if ( function.oldDeclList ) {
327                        os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
328                        function.oldDeclList->printList( os, indent + 4 );
329                } // if
330                os << string( indent + 2, ' ' ) << "returning ";
331                if ( base ) {
332                        base->print( os, indent + 4 );
333                } else {
334                        os << "nothing ";
335                } // if
336                os << endl;
337                if ( function.body ) {
338                        os << string( indent + 2, ' ' ) << "with body " << endl;
339                        function.body->printList( os, indent + 2 );
340                } // if
341                break;
342        case Aggregate:
343                os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
344                if ( aggregate.params ) {
345                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
346                        aggregate.params->printList( os, indent + 4 );
347                } // if
348                if ( aggregate.actuals ) {
349                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl;
350                        aggregate.actuals->printList( os, indent + 4 );
351                } // if
352                if ( aggregate.fields ) {
353                        os << string( indent + 2, ' ' ) << "with members" << endl;
354                        aggregate.fields->printList( os, indent + 4 );
355                } // if
356                if ( aggregate.body ) {
357                        os << string( indent + 2, ' ' ) << "with body" << endl;
358                } // if
359                if ( ! aggregate.attributes.empty() ) {
360                        os << string( indent + 2, ' ' ) << "with attributes" << endl;
361                        for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( aggregate.attributes ) ) {
362                                os << string( indent + 4, ' ' );
363                                ast::print( os, attr, indent + 2 );
364                        } // for
365                } // if
366                break;
367        case AggregateInst:
368                if ( aggInst.aggregate ) {
369                        os << "instance of " ;
370                        aggInst.aggregate->print( os, indent );
371                } else {
372                        os << "instance of an unspecified aggregate ";
373                } // if
374                if ( aggInst.params ) {
375                        os << string( indent + 2, ' ' ) << "with parameters" << endl;
376                        aggInst.params->printList( os, indent + 2 );
377                } // if
378                break;
379        case Enum:
380                os << "enumeration " << *enumeration.name << endl;;
381                if ( enumeration.constants ) {
382                        os << "with constants" << endl;
383                        enumeration.constants->printList( os, indent + 2 );
384                } // if
385                if ( enumeration.body ) {
386                        os << string( indent + 2, ' ' ) << "with body" << endl;
387                } // if
388                if ( base ) {
389                        os << "for ";
390                        base->print( os, indent + 2 );
391                } // if
392                break;
393        case EnumConstant:
394                os << "enumeration constant ";
395                break;
396        case Symbolic:
397                if ( symbolic.isTypedef ) {
398                        os << "typedef definition ";
399                } else {
400                        os << "type definition ";
401                } // if
402                if ( symbolic.params ) {
403                        os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
404                        symbolic.params->printList( os, indent + 2 );
405                } // if
406                if ( symbolic.assertions ) {
407                        os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
408                        symbolic.assertions->printList( os, indent + 4 );
409                        os << string( indent + 2, ' ' );
410                } // if
411                if ( base ) {
412                        os << "for ";
413                        base->print( os, indent + 2 );
414                } // if
415                break;
416        case SymbolicInst:
417                os << *symbolic.name;
418                if ( symbolic.actuals ) {
419                        os << "(";
420                        symbolic.actuals->printList( os, indent + 2 );
421                        os << ")";
422                } // if
423                break;
424        case Tuple:
425                os << "tuple ";
426                if ( tuple ) {
427                        os << "with members" << endl;
428                        tuple->printList( os, indent + 2 );
429                } // if
430                break;
431        case Basetypeof:
432                os << "base-";
433                #if defined(__GNUC__) && __GNUC__ >= 7
434                        __attribute__((fallthrough));
435                #endif
436                // FALL THROUGH
437        case Typeof:
438                os << "type-of expression ";
439                if ( typeexpr ) {
440                        typeexpr->print( os, indent + 2 );
441                } // if
442                break;
443        case Vtable:
444                os << "vtable";
445                break;
446        case Builtin:
447                os << builtinTypeNames[builtintype];
448                break;
449        case GlobalScope:
450                break;
451        case Qualified:
452                qualified.parent->print( os );
453                os << ".";
454                qualified.child->print( os );
455                break;
456        case Unknown:
457                os << "entity of unknown type ";
458                break;
459        default:
460                os << "internal error: TypeData::print " << kind << endl;
461                assert( false );
462        } // switch
463} // TypeData::print
464
465const std::string * TypeData::leafName() const {
466        switch ( kind ) {
467        case Unknown:
468        case Pointer:
469        case Reference:
470        case EnumConstant:
471        case GlobalScope:
472        case Array:
473        case Basic:
474        case Function:
475        case AggregateInst:
476        case Tuple:
477        case Typeof:
478        case Basetypeof:
479        case Builtin:
480        case Vtable:
481                assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
482                break;
483        case Aggregate:
484                return aggregate.name;
485        case Enum:
486                return enumeration.name;
487        case Symbolic:
488        case SymbolicInst:
489                return symbolic.name;
490        case Qualified:
491                return qualified.child->leafName();
492        } // switch
493        assert(false);
494}
495
496TypeData * TypeData::getLastBase() {
497        TypeData * cur = this;
498        while ( cur->base ) cur = cur->base;
499        return cur;
500}
501
502void TypeData::setLastBase( TypeData * newBase ) {
503        getLastBase()->base = newBase;
504}
505
506
507TypeData * build_type_qualifier( ast::CV::Qualifiers tq ) {
508        TypeData * type = new TypeData;
509        type->qualifiers = tq;
510        return type;
511}
512
513TypeData * build_basic_type( TypeData::BasicType basic ) {
514        TypeData * type = new TypeData( TypeData::Basic );
515        type->basictype = basic;
516        return type;
517}
518
519TypeData * build_complex_type( TypeData::ComplexType complex ) {
520        TypeData * type = new TypeData( TypeData::Basic );
521        type->complextype = complex;
522        return type;
523}
524
525TypeData * build_signedness( TypeData::Signedness signedness ) {
526        TypeData * type = new TypeData( TypeData::Basic );
527        type->signedness = signedness;
528        return type;
529}
530
531TypeData * build_builtin_type( TypeData::BuiltinType bit ) {
532        TypeData * type = new TypeData( TypeData::Builtin );
533        type->builtintype = bit;
534        return type;
535}
536
537TypeData * build_length( TypeData::Length length ) {
538        TypeData * type = new TypeData( TypeData::Basic );
539        type->length = length;
540        return type;
541}
542
543TypeData * build_forall( DeclarationNode * forall ) {
544        TypeData * type = new TypeData( TypeData::Unknown );
545        type->forall = forall;
546        return type;
547}
548
549TypeData * build_global_scope() {
550        return new TypeData( TypeData::GlobalScope );
551}
552
553TypeData * build_qualified_type( TypeData * parent, TypeData * child ) {
554        TypeData * type = new TypeData( TypeData::Qualified );
555        type->qualified.parent = parent;
556        type->qualified.child = child;
557        return type;
558}
559
560TypeData * build_typedef( const std::string * name ) {
561        TypeData * type = new TypeData( TypeData::SymbolicInst );
562        type->symbolic.name = name;
563        type->symbolic.isTypedef = true;
564        type->symbolic.actuals = nullptr;
565        return type;
566}
567
568TypeData * build_type_gen( const std::string * name, ExpressionNode * params ) {
569        TypeData * type = new TypeData( TypeData::SymbolicInst );
570        type->symbolic.name = name;
571        type->symbolic.isTypedef = false;
572        type->symbolic.actuals = params;
573        return type;
574}
575
576TypeData * build_vtable_type( TypeData * base ) {
577        TypeData * type = new TypeData( TypeData::Vtable );
578        type->base = base;
579        return type;
580}
581
582// Takes ownership of src.
583static void addQualifiersToType( TypeData * dst, TypeData * src ) {
584        if ( dst->base ) {
585                addQualifiersToType( dst->base, src );
586        } else if ( dst->kind == TypeData::Function ) {
587                dst->base = src;
588                src = nullptr;
589    } else {
590                dst->qualifiers |= src->qualifiers;
591                delete src;
592        } // if
593}
594
595// Takes ownership of all arguments, gives ownership of return value.
596TypeData * addQualifiers( TypeData * ltype, TypeData * rtype ) {
597        if ( ltype->forall ) {
598                if ( rtype->forall ) {
599                        rtype->forall->set_last( ltype->forall );
600                } else if ( TypeData::Aggregate != rtype->kind ) {
601                        rtype->forall = ltype->forall;
602                } else if ( rtype->aggregate.params ) {
603                        rtype->aggregate.params->set_last( ltype->forall );
604                } else {
605                        rtype->aggregate.params = ltype->forall;
606                }
607                ltype->forall = nullptr;
608        }
609
610        addQualifiersToType( rtype, ltype );
611        return rtype;
612}
613
614// Helper for addType and cloneBaseType.
615static void addTypeToType( TypeData *& dst, TypeData *& src ) {
616        if ( src->forall && dst->kind == TypeData::Function ) {
617                if ( dst->forall ) {
618                        dst->forall->set_last( src->forall );
619                } else {
620                        dst->forall = src->forall;
621                } // if
622                src->forall = nullptr;
623        } // if
624        if ( dst->base ) {
625                addTypeToType( dst->base, src );
626                return;
627        }
628        switch ( dst->kind ) {
629        case TypeData::Unknown:
630                src->qualifiers |= dst->qualifiers;
631                // LEAKS dst?
632                dst = src;
633                src = nullptr;
634                break;
635        case TypeData::Basic:
636                dst->qualifiers |= src->qualifiers;
637                if ( src->kind != TypeData::Unknown ) {
638                        assert( src->kind == TypeData::Basic );
639
640                        if ( dst->basictype == TypeData::NoBasicType ) {
641                                dst->basictype = src->basictype;
642                        } else if ( src->basictype != TypeData::NoBasicType ) {
643                                SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
644                                        TypeData::basicTypeNames[ dst->basictype ],
645                                        TypeData::basicTypeNames[ src->basictype ] );
646                        }
647                        if ( dst->complextype == TypeData::NoComplexType ) {
648                                dst->complextype = src->complextype;
649                        } else if ( src->complextype != TypeData::NoComplexType ) {
650                                SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
651                                        TypeData::complexTypeNames[ src->complextype ],
652                                        TypeData::complexTypeNames[ src->complextype ] );
653                        }
654                        if ( dst->signedness == TypeData::NoSignedness ) {
655                                dst->signedness = src->signedness;
656                        } else if ( src->signedness != TypeData::NoSignedness ) {
657                                SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
658                                        TypeData::signednessNames[ dst->signedness ],
659                                        TypeData::signednessNames[ src->signedness ] );
660                        }
661                        if ( dst->length == TypeData::NoLength ) {
662                                dst->length = src->length;
663                        } else if ( dst->length == TypeData::Long && src->length == TypeData::Long ) {
664                                dst->length = TypeData::LongLong;
665                        } else if ( src->length != TypeData::NoLength ) {
666                                SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
667                                        TypeData::lengthNames[ dst->length ],
668                                        TypeData::lengthNames[ src->length ] );
669                        }
670                } // if
671                break;
672        default:
673                switch ( src->kind ) {
674                case TypeData::Aggregate:
675                case TypeData::Enum:
676                        dst->base = new TypeData( TypeData::AggregateInst );
677                        dst->base->aggInst.aggregate = src;
678                        if ( src->kind == TypeData::Aggregate ) {
679                                dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
680                        } // if
681                        dst->base->qualifiers |= src->qualifiers;
682                        src = nullptr;
683                        break;
684                default:
685                        if ( dst->forall ) {
686                                dst->forall->set_last( src->forall );
687                        } else {
688                                dst->forall = src->forall;
689                        } // if
690                        src->forall = nullptr;
691                        dst->base = src;
692                        src = nullptr;
693                } // switch
694        } // switch
695}
696
697// Takes ownership of all arguments, gives ownership of return value.
698TypeData * addType( TypeData * ltype, TypeData * rtype, std::vector<ast::ptr<ast::Attribute>> & attributes ) {
699        if ( rtype ) {
700                addTypeToType( rtype, ltype );
701                return rtype;
702        } else {
703                if ( ltype->kind == TypeData::Aggregate || ltype->kind == TypeData::Enum ) {
704                        // Hide type information aggregate instances.
705                        rtype = new TypeData( TypeData::AggregateInst );
706                        rtype->aggInst.aggregate = ltype;
707                        rtype->aggInst.aggregate->aggregate.attributes.swap( attributes ); // change ownership
708                        if ( ltype->kind == TypeData::Aggregate ) {
709                                rtype->aggInst.hoistType = ltype->aggregate.body;
710                                rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals );
711                        } else {
712                                rtype->aggInst.hoistType = ltype->enumeration.body;
713                        } // if
714                        rtype->qualifiers |= ltype->qualifiers;
715                } else {
716                        rtype = ltype;
717                } // if
718                return rtype;
719        } // if
720}
721
722TypeData * addType( TypeData * ltype, TypeData * rtype ) {
723        std::vector<ast::ptr<ast::Attribute>> attributes;
724        return addType( ltype, rtype, attributes );
725}
726
727// Takes ownership of both arguments, gives ownership of return value.
728TypeData * cloneBaseType( TypeData * type, TypeData * other ) {
729        TypeData * newType = type->getLastBase()->clone();
730        if ( newType->kind == TypeData::AggregateInst ) {
731                // don't duplicate members
732                if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
733                        delete newType->aggInst.aggregate->enumeration.constants;
734                        newType->aggInst.aggregate->enumeration.constants = nullptr;
735                        newType->aggInst.aggregate->enumeration.body = false;
736                } else {
737                        assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
738                        delete newType->aggInst.aggregate->aggregate.fields;
739                        newType->aggInst.aggregate->aggregate.fields = nullptr;
740                        newType->aggInst.aggregate->aggregate.body = false;
741                } // if
742                // don't hoist twice
743                newType->aggInst.hoistType = false;
744        } // if
745        newType->forall = maybeCopy( type->forall );
746
747        if ( other ) {
748                addTypeToType( other, newType );
749                delete newType;
750                return other;
751        } // if
752        return newType;
753}
754
755TypeData * makeNewBase( TypeData * type ) {
756        switch ( type->kind ) {
757        case TypeData::Aggregate:
758        case TypeData::Enum: {
759                TypeData * out = new TypeData( TypeData::AggregateInst );
760                out->aggInst.aggregate = type;
761                if ( TypeData::Aggregate == type->kind ) {
762                        out->aggInst.params = maybeCopy( type->aggregate.actuals );
763                }
764                out->qualifiers |= type->qualifiers;
765                return out;
766        }
767        default:
768                return type;
769        } // switch
770}
771
772
773void buildForall(
774                const DeclarationNode * firstNode,
775                std::vector<ast::ptr<ast::TypeInstType>> &outputList ) {
776        {
777                std::vector<ast::ptr<ast::Type>> tmpList;
778                buildTypeList( firstNode, tmpList );
779                for ( auto tmp : tmpList ) {
780                        outputList.emplace_back(
781                                strict_dynamic_cast<const ast::TypeInstType *>(
782                                        tmp.release() ) );
783                }
784        }
785        auto n = firstNode;
786        for ( auto i = outputList.begin() ;
787                        i != outputList.end() ;
788                        ++i, n = n->next ) {
789                // Only the object type class adds additional assertions.
790                if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
791                        continue;
792                }
793
794                ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
795                std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
796                auto mutTypeDecl = ast::mutate( td );
797                const CodeLocation & location = mutTypeDecl->location;
798                *i = mutTypeDecl;
799
800                // add assertion parameters to `type' tyvars in reverse order
801                // add assignment operator:  T * ?=?(T *, T)
802                newAssertions.push_back( new ast::FunctionDecl(
803                        location,
804                        "?=?",
805                        {}, // forall
806                        {}, // assertions
807                        {
808                                new ast::ObjectDecl(
809                                        location,
810                                        "",
811                                        new ast::ReferenceType( i->get() ),
812                                        (ast::Init *)nullptr,
813                                        ast::Storage::Classes(),
814                                        ast::Linkage::Cforall,
815                                        (ast::Expr *)nullptr
816                                ),
817                                new ast::ObjectDecl(
818                                        location,
819                                        "",
820                                        i->get(),
821                                        (ast::Init *)nullptr,
822                                        ast::Storage::Classes(),
823                                        ast::Linkage::Cforall,
824                                        (ast::Expr *)nullptr
825                                ),
826                        }, // params
827                        {
828                                new ast::ObjectDecl(
829                                        location,
830                                        "",
831                                        i->get(),
832                                        (ast::Init *)nullptr,
833                                        ast::Storage::Classes(),
834                                        ast::Linkage::Cforall,
835                                        (ast::Expr *)nullptr
836                                ),
837                        }, // returns
838                        (ast::CompoundStmt *)nullptr,
839                        ast::Storage::Classes(),
840                        ast::Linkage::Cforall
841                ) );
842
843                // add default ctor:  void ?{}(T *)
844                newAssertions.push_back( new ast::FunctionDecl(
845                        location,
846                        "?{}",
847                        {}, // forall
848                        {}, // assertions
849                        {
850                                new ast::ObjectDecl(
851                                        location,
852                                        "",
853                                        new ast::ReferenceType( i->get() ),
854                                        (ast::Init *)nullptr,
855                                        ast::Storage::Classes(),
856                                        ast::Linkage::Cforall,
857                                        (ast::Expr *)nullptr
858                                ),
859                        }, // params
860                        {}, // returns
861                        (ast::CompoundStmt *)nullptr,
862                        ast::Storage::Classes(),
863                        ast::Linkage::Cforall
864                ) );
865
866                // add copy ctor:  void ?{}(T *, T)
867                newAssertions.push_back( new ast::FunctionDecl(
868                        location,
869                        "?{}",
870                        {}, // forall
871                        {}, // assertions
872                        {
873                                new ast::ObjectDecl(
874                                        location,
875                                        "",
876                                        new ast::ReferenceType( i->get() ),
877                                        (ast::Init *)nullptr,
878                                        ast::Storage::Classes(),
879                                        ast::Linkage::Cforall,
880                                        (ast::Expr *)nullptr
881                                ),
882                                new ast::ObjectDecl(
883                                        location,
884                                        "",
885                                        i->get(),
886                                        (ast::Init *)nullptr,
887                                        ast::Storage::Classes(),
888                                        ast::Linkage::Cforall,
889                                        (ast::Expr *)nullptr
890                                ),
891                        }, // params
892                        {}, // returns
893                        (ast::CompoundStmt *)nullptr,
894                        ast::Storage::Classes(),
895                        ast::Linkage::Cforall
896                ) );
897
898                // add dtor:  void ^?{}(T *)
899                newAssertions.push_back( new ast::FunctionDecl(
900                        location,
901                        "^?{}",
902                        {}, // forall
903                        {}, // assertions
904                        {
905                                new ast::ObjectDecl(
906                                        location,
907                                        "",
908                                        new ast::ReferenceType( i->get() ),
909                                        (ast::Init *)nullptr,
910                                        ast::Storage::Classes(),
911                                        ast::Linkage::Cforall,
912                                        (ast::Expr *)nullptr
913                                ),
914                        }, // params
915                        {}, // returns
916                        (ast::CompoundStmt *)nullptr,
917                        ast::Storage::Classes(),
918                        ast::Linkage::Cforall
919                ) );
920
921                spliceBegin( mutTypeDecl->assertions, newAssertions );
922        } // for
923}
924
925
926void buildForall(
927                const DeclarationNode * firstNode,
928                std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
929        buildList( firstNode, outputForall );
930        auto n = firstNode;
931        for ( auto i = outputForall.begin() ;
932                        i != outputForall.end() ;
933                        ++i, n = n->next ) {
934                // Only the object type class adds additional assertions.
935                if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
936                        continue;
937                }
938
939                ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
940                std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
941                auto mutTypeDecl = ast::mutate( td );
942                const CodeLocation & location = mutTypeDecl->location;
943                *i = mutTypeDecl;
944
945                // add assertion parameters to `type' tyvars in reverse order
946                // add assignment operator:  T * ?=?(T *, T)
947                newAssertions.push_back( new ast::FunctionDecl(
948                        location,
949                        "?=?",
950                        {}, // forall
951                        {}, // assertions
952                        {
953                                new ast::ObjectDecl(
954                                        location,
955                                        "",
956                                        new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
957                                        (ast::Init *)nullptr,
958                                        ast::Storage::Classes(),
959                                        ast::Linkage::Cforall,
960                                        (ast::Expr *)nullptr
961                                ),
962                                new ast::ObjectDecl(
963                                        location,
964                                        "",
965                                        new ast::TypeInstType( td->name, *i ),
966                                        (ast::Init *)nullptr,
967                                        ast::Storage::Classes(),
968                                        ast::Linkage::Cforall,
969                                        (ast::Expr *)nullptr
970                                ),
971                        }, // params
972                        {
973                                new ast::ObjectDecl(
974                                        location,
975                                        "",
976                                        new ast::TypeInstType( td->name, *i ),
977                                        (ast::Init *)nullptr,
978                                        ast::Storage::Classes(),
979                                        ast::Linkage::Cforall,
980                                        (ast::Expr *)nullptr
981                                ),
982                        }, // returns
983                        (ast::CompoundStmt *)nullptr,
984                        ast::Storage::Classes(),
985                        ast::Linkage::Cforall
986                ) );
987
988                // add default ctor:  void ?{}(T *)
989                newAssertions.push_back( new ast::FunctionDecl(
990                        location,
991                        "?{}",
992                        {}, // forall
993                        {}, // assertions
994                        {
995                                new ast::ObjectDecl(
996                                        location,
997                                        "",
998                                        new ast::ReferenceType(
999                                                new ast::TypeInstType( td->name, i->get() ) ),
1000                                        (ast::Init *)nullptr,
1001                                        ast::Storage::Classes(),
1002                                        ast::Linkage::Cforall,
1003                                        (ast::Expr *)nullptr
1004                                ),
1005                        }, // params
1006                        {}, // returns
1007                        (ast::CompoundStmt *)nullptr,
1008                        ast::Storage::Classes(),
1009                        ast::Linkage::Cforall
1010                ) );
1011
1012                // add copy ctor:  void ?{}(T *, T)
1013                newAssertions.push_back( new ast::FunctionDecl(
1014                        location,
1015                        "?{}",
1016                        {}, // forall
1017                        {}, // assertions
1018                        {
1019                                new ast::ObjectDecl(
1020                                        location,
1021                                        "",
1022                                        new ast::ReferenceType(
1023                                                new ast::TypeInstType( td->name, *i ) ),
1024                                        (ast::Init *)nullptr,
1025                                        ast::Storage::Classes(),
1026                                        ast::Linkage::Cforall,
1027                                        (ast::Expr *)nullptr
1028                                ),
1029                                new ast::ObjectDecl(
1030                                        location,
1031                                        "",
1032                                        new ast::TypeInstType( td->name, *i ),
1033                                        (ast::Init *)nullptr,
1034                                        ast::Storage::Classes(),
1035                                        ast::Linkage::Cforall,
1036                                        (ast::Expr *)nullptr
1037                                ),
1038                        }, // params
1039                        {}, // returns
1040                        (ast::CompoundStmt *)nullptr,
1041                        ast::Storage::Classes(),
1042                        ast::Linkage::Cforall
1043                ) );
1044
1045                // add dtor:  void ^?{}(T *)
1046                newAssertions.push_back( new ast::FunctionDecl(
1047                        location,
1048                        "^?{}",
1049                        {}, // forall
1050                        {}, // assertions
1051                        {
1052                                new ast::ObjectDecl(
1053                                        location,
1054                                        "",
1055                                        new ast::ReferenceType(
1056                                                new ast::TypeInstType( i->get() )
1057                                        ),
1058                                        (ast::Init *)nullptr,
1059                                        ast::Storage::Classes(),
1060                                        ast::Linkage::Cforall,
1061                                        (ast::Expr *)nullptr
1062                                ),
1063                        }, // params
1064                        {}, // returns
1065                        (ast::CompoundStmt *)nullptr,
1066                        ast::Storage::Classes(),
1067                        ast::Linkage::Cforall
1068                ) );
1069
1070                spliceBegin( mutTypeDecl->assertions, newAssertions );
1071        } // for
1072} // buildForall
1073
1074
1075ast::Type * typebuild( const TypeData * td ) {
1076        assert( td );
1077        switch ( td->kind ) {
1078        case TypeData::Unknown:
1079                // fill in implicit int
1080                return new ast::BasicType(
1081                        ast::BasicType::SignedInt,
1082                        buildQualifiers( td )
1083                );
1084        case TypeData::Basic:
1085                return buildBasicType( td );
1086        case TypeData::Pointer:
1087                return buildPointer( td );
1088        case TypeData::Array:
1089                return buildArray( td );
1090        case TypeData::Reference:
1091                return buildReference( td );
1092        case TypeData::Function:
1093                return buildFunctionType( td );
1094        case TypeData::AggregateInst:
1095                return buildAggInst( td );
1096        case TypeData::EnumConstant:
1097                return new ast::EnumInstType( "", buildQualifiers( td ) );
1098        case TypeData::SymbolicInst:
1099                return buildSymbolicInst( td );
1100        case TypeData::Tuple:
1101                return buildTuple( td );
1102        case TypeData::Typeof:
1103        case TypeData::Basetypeof:
1104                return buildTypeof( td );
1105        case TypeData::Vtable:
1106                return buildVtable( td );
1107        case TypeData::Builtin:
1108                switch ( td->builtintype ) {
1109                case TypeData::Zero:
1110                        return new ast::ZeroType();
1111                case TypeData::One:
1112                        return new ast::OneType();
1113                default:
1114                        return new ast::VarArgsType( buildQualifiers( td ) );
1115                } // switch
1116        case TypeData::GlobalScope:
1117                return new ast::GlobalScopeType();
1118        case TypeData::Qualified:
1119                return new ast::QualifiedType(
1120                        typebuild( td->qualified.parent ),
1121                        typebuild( td->qualified.child ),
1122                        buildQualifiers( td )
1123                );
1124        case TypeData::Symbolic:
1125        case TypeData::Enum:
1126        case TypeData::Aggregate:
1127                assert( false );
1128        } // switch
1129
1130        return nullptr;
1131} // typebuild
1132
1133
1134TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
1135        TypeData * ret = nullptr;
1136
1137        switch ( td->kind ) {
1138        case TypeData::Aggregate:
1139                if ( ! toplevel && td->aggregate.body ) {
1140                        ret = td->clone();
1141                } // if
1142                break;
1143        case TypeData::Enum:
1144                if ( ! toplevel && td->enumeration.body ) {
1145                        ret = td->clone();
1146                } // if
1147                break;
1148        case TypeData::AggregateInst:
1149                if ( td->aggInst.aggregate ) {
1150                        ret = typeextractAggregate( td->aggInst.aggregate, false );
1151                } // if
1152                break;
1153        default:
1154                if ( td->base ) {
1155                        ret = typeextractAggregate( td->base, false );
1156                } // if
1157        } // switch
1158        return ret;
1159} // typeextractAggregate
1160
1161
1162ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
1163        return td->qualifiers;
1164} // buildQualifiers
1165
1166
1167static string genTSError( string msg, TypeData::BasicType basictype ) {
1168        SemanticError( yylloc, "invalid type specifier \"%s\" for type \"%s\".", msg.c_str(), TypeData::basicTypeNames[basictype] );
1169} // genTSError
1170
1171ast::Type * buildBasicType( const TypeData * td ) {
1172        ast::BasicType::Kind ret;
1173
1174        switch ( td->basictype ) {
1175        case TypeData::Void:
1176                if ( td->signedness != TypeData::NoSignedness ) {
1177                        genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1178                } // if
1179                if ( td->length != TypeData::NoLength ) {
1180                        genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1181                } // if
1182                return new ast::VoidType( buildQualifiers( td ) );
1183                break;
1184
1185        case TypeData::Bool:
1186                if ( td->signedness != TypeData::NoSignedness ) {
1187                        genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1188                } // if
1189                if ( td->length != TypeData::NoLength ) {
1190                        genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1191                } // if
1192
1193                ret = ast::BasicType::Bool;
1194                break;
1195
1196        case TypeData::Char:
1197                // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
1198                // character types. The implementation shall define char to have the same range, representation, and behavior as
1199                // either signed char or unsigned char.
1200                static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };
1201
1202                if ( td->length != TypeData::NoLength ) {
1203                        genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1204                } // if
1205
1206                ret = chartype[ td->signedness ];
1207                break;
1208
1209        case TypeData::Int:
1210                static ast::BasicType::Kind inttype[2][4] = {
1211                        { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },
1212                        { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },
1213                };
1214
1215        Integral: ;
1216                if ( td->signedness == TypeData::NoSignedness ) {
1217                        const_cast<TypeData *>(td)->signedness = TypeData::Signed;
1218                } // if
1219                ret = inttype[ td->signedness ][ td->length ];
1220                break;
1221
1222        case TypeData::Int128:
1223                ret = td->signedness == TypeData::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
1224                if ( td->length != TypeData::NoLength ) {
1225                        genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1226                } // if
1227                break;
1228
1229        case TypeData::Float:
1230        case TypeData::Double:
1231        case TypeData::LongDouble:                                      // not set until below
1232        case TypeData::uuFloat80:
1233        case TypeData::uuFloat128:
1234        case TypeData::uFloat16:
1235        case TypeData::uFloat32:
1236        case TypeData::uFloat32x:
1237        case TypeData::uFloat64:
1238        case TypeData::uFloat64x:
1239        case TypeData::uFloat128:
1240        case TypeData::uFloat128x:
1241                static ast::BasicType::Kind floattype[2][12] = {
1242                        { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, (ast::BasicType::Kind)-1, (ast::BasicType::Kind)-1, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex, },
1243                        { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x, },
1244                };
1245
1246        FloatingPoint: ;
1247                if ( td->signedness != TypeData::NoSignedness ) {
1248                        genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1249                } // if
1250                if ( td->length == TypeData::Short || td->length == TypeData::LongLong ) {
1251                        genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1252                } // if
1253                if ( td->basictype != TypeData::Double && td->length == TypeData::Long ) {
1254                        genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1255                } // if
1256                if ( td->complextype == TypeData::Imaginary ) {
1257                        genTSError( TypeData::complexTypeNames[ td->complextype ], td->basictype );
1258                } // if
1259                if ( (td->basictype == TypeData::uuFloat80 || td->basictype == TypeData::uuFloat128) && td->complextype == TypeData::Complex ) { // gcc unsupported
1260                        genTSError( TypeData::complexTypeNames[ td->complextype ], td->basictype );
1261                } // if
1262                if ( td->length == TypeData::Long ) {
1263                        const_cast<TypeData *>(td)->basictype = TypeData::LongDouble;
1264                } // if
1265
1266                ret = floattype[ td->complextype ][ td->basictype - TypeData::Float ];
1267                //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, TypeData::Float, ret );
1268                break;
1269
1270        case TypeData::NoBasicType:
1271                // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
1272                if ( td->complextype == TypeData::Complex || td->complextype == TypeData::Imaginary ) {
1273                        const_cast<TypeData *>(td)->basictype = TypeData::Double;
1274                        goto FloatingPoint;
1275                } // if
1276
1277                const_cast<TypeData *>(td)->basictype = TypeData::Int;
1278                goto Integral;
1279        default:
1280                assertf( false, "unknown basic type" );
1281                return nullptr;
1282        } // switch
1283
1284        ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
1285        return bt;
1286} // buildBasicType
1287
1288
1289static ast::Type * buildDefaultType( const TypeData * td ) {
1290        return ( td ) ? typebuild( td ) : new ast::BasicType( ast::BasicType::SignedInt );
1291} // buildDefaultType
1292
1293
1294ast::PointerType * buildPointer( const TypeData * td ) {
1295        return new ast::PointerType(
1296                buildDefaultType( td->base ),
1297                buildQualifiers( td )
1298        );
1299} // buildPointer
1300
1301
1302ast::ArrayType * buildArray( const TypeData * td ) {
1303        return new ast::ArrayType(
1304                buildDefaultType( td->base ),
1305                maybeBuild( td->array.dimension ),
1306                td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1307                td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1308                buildQualifiers( td )
1309        );
1310} // buildArray
1311
1312
1313ast::ReferenceType * buildReference( const TypeData * td ) {
1314        return new ast::ReferenceType(
1315                buildDefaultType( td->base ),
1316                buildQualifiers( td )
1317        );
1318} // buildReference
1319
1320
1321ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
1322        assert( td->kind == TypeData::Aggregate );
1323        ast::AggregateDecl * at;
1324        switch ( td->aggregate.kind ) {
1325        case ast::AggregateDecl::Struct:
1326        case ast::AggregateDecl::Coroutine:
1327        case ast::AggregateDecl::Exception:
1328        case ast::AggregateDecl::Generator:
1329        case ast::AggregateDecl::Monitor:
1330        case ast::AggregateDecl::Thread:
1331                at = new ast::StructDecl( td->location,
1332                        *td->aggregate.name,
1333                        td->aggregate.kind,
1334                        std::move( attributes ),
1335                        linkage
1336                );
1337                buildForall( td->aggregate.params, at->params );
1338                break;
1339        case ast::AggregateDecl::Union:
1340                at = new ast::UnionDecl( td->location,
1341                        *td->aggregate.name,
1342                        std::move( attributes ),
1343                        linkage
1344                );
1345                buildForall( td->aggregate.params, at->params );
1346                break;
1347        case ast::AggregateDecl::Trait:
1348                at = new ast::TraitDecl( td->location,
1349                        *td->aggregate.name,
1350                        std::move( attributes ),
1351                        linkage
1352                );
1353                buildList( td->aggregate.params, at->params );
1354                break;
1355        default:
1356                assert( false );
1357        } // switch
1358
1359        buildList( td->aggregate.fields, at->members );
1360        at->set_body( td->aggregate.body );
1361
1362        return at;
1363} // buildAggregate
1364
1365
1366ast::BaseInstType * buildComAggInst(
1367                const TypeData * td,
1368                std::vector<ast::ptr<ast::Attribute>> && attributes,
1369                ast::Linkage::Spec linkage ) {
1370        switch ( td->kind ) {
1371        case TypeData::Enum:
1372                if ( td->enumeration.body ) {
1373                        ast::EnumDecl * typedecl =
1374                                buildEnum( td, std::move( attributes ), linkage );
1375                        return new ast::EnumInstType(
1376                                typedecl,
1377                                buildQualifiers( td )
1378                        );
1379                } else {
1380                        return new ast::EnumInstType(
1381                                *td->enumeration.name,
1382                                buildQualifiers( td )
1383                        );
1384                } // if
1385                break;
1386        case TypeData::Aggregate:
1387                if ( td->aggregate.body ) {
1388                        ast::AggregateDecl * typedecl =
1389                                buildAggregate( td, std::move( attributes ), linkage );
1390                        switch ( td->aggregate.kind ) {
1391                        case ast::AggregateDecl::Struct:
1392                        case ast::AggregateDecl::Coroutine:
1393                        case ast::AggregateDecl::Monitor:
1394                        case ast::AggregateDecl::Thread:
1395                                return new ast::StructInstType(
1396                                        strict_dynamic_cast<ast::StructDecl *>( typedecl ),
1397                                        buildQualifiers( td )
1398                                );
1399                        case ast::AggregateDecl::Union:
1400                                return new ast::UnionInstType(
1401                                        strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
1402                                        buildQualifiers( td )
1403                                );
1404                        case ast::AggregateDecl::Trait:
1405                                assert( false );
1406                                break;
1407                        default:
1408                                assert( false );
1409                        } // switch
1410                } else {
1411                        switch ( td->aggregate.kind ) {
1412                        case ast::AggregateDecl::Struct:
1413                        case ast::AggregateDecl::Coroutine:
1414                        case ast::AggregateDecl::Monitor:
1415                        case ast::AggregateDecl::Thread:
1416                                return new ast::StructInstType(
1417                                        *td->aggregate.name,
1418                                        buildQualifiers( td )
1419                                );
1420                        case ast::AggregateDecl::Union:
1421                                return new ast::UnionInstType(
1422                                        *td->aggregate.name,
1423                                        buildQualifiers( td )
1424                                );
1425                        case ast::AggregateDecl::Trait:
1426                                return new ast::TraitInstType(
1427                                        *td->aggregate.name,
1428                                        buildQualifiers( td )
1429                                );
1430                        default:
1431                                assert( false );
1432                        } // switch
1433                        break;
1434                } // if
1435                break;
1436        default:
1437                assert( false );
1438        } // switch
1439        assert( false );
1440} // buildAggInst
1441
1442
1443ast::BaseInstType * buildAggInst( const TypeData * td ) {
1444        assert( td->kind == TypeData::AggregateInst );
1445
1446        ast::BaseInstType * ret = nullptr;
1447        TypeData * type = td->aggInst.aggregate;
1448        switch ( type->kind ) {
1449        case TypeData::Enum:
1450                return new ast::EnumInstType(
1451                        *type->enumeration.name,
1452                        buildQualifiers( type )
1453                );
1454        case TypeData::Aggregate:
1455                switch ( type->aggregate.kind ) {
1456                case ast::AggregateDecl::Struct:
1457                case ast::AggregateDecl::Coroutine:
1458                case ast::AggregateDecl::Monitor:
1459                case ast::AggregateDecl::Thread:
1460                        ret = new ast::StructInstType(
1461                                *type->aggregate.name,
1462                                buildQualifiers( type )
1463                        );
1464                        break;
1465                case ast::AggregateDecl::Union:
1466                        ret = new ast::UnionInstType(
1467                                *type->aggregate.name,
1468                                buildQualifiers( type )
1469                        );
1470                        break;
1471                case ast::AggregateDecl::Trait:
1472                        ret = new ast::TraitInstType(
1473                                *type->aggregate.name,
1474                                buildQualifiers( type )
1475                        );
1476                        break;
1477                default:
1478                        assert( false );
1479                } // switch
1480                break;
1481        default:
1482                assert( false );
1483        } // switch
1484
1485        ret->hoistType = td->aggInst.hoistType;
1486        buildList( td->aggInst.params, ret->params );
1487        return ret;
1488} // buildAggInst
1489
1490
1491ast::NamedTypeDecl * buildSymbolic(
1492                const TypeData * td,
1493                std::vector<ast::ptr<ast::Attribute>> attributes,
1494                const std::string & name,
1495                ast::Storage::Classes scs,
1496                ast::Linkage::Spec linkage ) {
1497        assert( td->kind == TypeData::Symbolic );
1498        ast::NamedTypeDecl * ret;
1499        assert( td->base );
1500        if ( td->symbolic.isTypedef ) {
1501                ret = new ast::TypedefDecl(
1502                        td->location,
1503                        name,
1504                        scs,
1505                        typebuild( td->base ),
1506                        linkage
1507                );
1508        } else {
1509                ret = new ast::TypeDecl(
1510                        td->location,
1511                        name,
1512                        scs,
1513                        typebuild( td->base ),
1514                        ast::TypeDecl::Dtype,
1515                        true
1516                );
1517        } // if
1518        buildList( td->symbolic.assertions, ret->assertions );
1519        splice( ret->base.get_and_mutate()->attributes, attributes );
1520        return ret;
1521} // buildSymbolic
1522
1523
1524ast::EnumDecl * buildEnum(
1525                const TypeData * td,
1526                std::vector<ast::ptr<ast::Attribute>> && attributes,
1527                ast::Linkage::Spec linkage ) {
1528        assert( td->kind == TypeData::Enum );
1529        ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
1530        ast::EnumDecl * ret = new ast::EnumDecl(
1531                td->location,
1532                *td->enumeration.name,
1533                td->enumeration.typed,
1534                std::move( attributes ),
1535                linkage,
1536                baseType
1537        );
1538        buildList( td->enumeration.constants, ret->members );
1539        auto members = ret->members.begin();
1540        ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
1541        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = cur->next, ++members ) {
1542                if ( cur->enumInLine ) {
1543                        // Do Nothing
1544                } else if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
1545                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
1546                } else if ( cur->has_enumeratorValue() ) {
1547                        ast::Decl * member = members->get_and_mutate();
1548                        ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
1549                        object->init = new ast::SingleInit(
1550                                td->location,
1551                                maybeMoveBuild( cur->consume_enumeratorValue() ),
1552                                ast::NoConstruct
1553                        );
1554                } else if ( !cur->initializer ) {
1555                        if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
1556                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
1557                        }
1558                }
1559                // else cur is a List Initializer and has been set as init in buildList()
1560                // if
1561        } // for
1562        ret->body = td->enumeration.body;
1563        return ret;
1564} // buildEnum
1565
1566
1567ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
1568        assert( td->kind == TypeData::SymbolicInst );
1569        ast::TypeInstType * ret = new ast::TypeInstType(
1570                *td->symbolic.name,
1571                ast::TypeDecl::Dtype,
1572                buildQualifiers( td )
1573        );
1574        buildList( td->symbolic.actuals, ret->params );
1575        return ret;
1576} // buildSymbolicInst
1577
1578
1579ast::TupleType * buildTuple( const TypeData * td ) {
1580        assert( td->kind == TypeData::Tuple );
1581        std::vector<ast::ptr<ast::Type>> types;
1582        buildTypeList( td->tuple, types );
1583        ast::TupleType * ret = new ast::TupleType(
1584                std::move( types ),
1585                buildQualifiers( td )
1586        );
1587        return ret;
1588} // buildTuple
1589
1590
1591ast::TypeofType * buildTypeof( const TypeData * td ) {
1592        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
1593        assert( td->typeexpr );
1594        return new ast::TypeofType(
1595                td->typeexpr->build(),
1596                td->kind == TypeData::Typeof
1597                        ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
1598                buildQualifiers( td )
1599        );
1600} // buildTypeof
1601
1602
1603ast::VTableType * buildVtable( const TypeData * td ) {
1604        assert( td->base );
1605        return new ast::VTableType(
1606                typebuild( td->base ),
1607                buildQualifiers( td )
1608        );
1609} // buildVtable
1610
1611
1612ast::FunctionDecl * buildFunctionDecl(
1613                const TypeData * td,
1614                const string &name,
1615                ast::Storage::Classes scs,
1616                ast::Function::Specs funcSpec,
1617                ast::Linkage::Spec linkage,
1618                ast::Expr * asmName,
1619                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1620        assert( td->kind == TypeData::Function );
1621        // For some reason FunctionDecl takes a bool instead of an ArgumentFlag.
1622        bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
1623        ast::CV::Qualifiers cvq = buildQualifiers( td );
1624        std::vector<ast::ptr<ast::TypeDecl>> forall;
1625        std::vector<ast::ptr<ast::DeclWithType>> assertions;
1626        std::vector<ast::ptr<ast::DeclWithType>> params;
1627        std::vector<ast::ptr<ast::DeclWithType>> returns;
1628        buildList( td->function.params, params );
1629        buildForall( td->forall, forall );
1630        // Functions do not store their assertions there anymore.
1631        for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1632                auto mut = type_param.get_and_mutate();
1633                splice( assertions, mut->assertions );
1634        }
1635        if ( td->base ) {
1636                switch ( td->base->kind ) {
1637                case TypeData::Tuple:
1638                        buildList( td->base->tuple, returns );
1639                        break;
1640                default:
1641                        returns.push_back( dynamic_cast<ast::DeclWithType *>(
1642                                buildDecl(
1643                                        td->base,
1644                                        "",
1645                                        ast::Storage::Classes(),
1646                                        (ast::Expr *)nullptr, // bitfieldWidth
1647                                        ast::Function::Specs(),
1648                                        ast::Linkage::Cforall,
1649                                        (ast::Expr *)nullptr // asmName
1650                                )
1651                        ) );
1652                } // switch
1653        } else {
1654                returns.push_back( new ast::ObjectDecl(
1655                        td->location,
1656                        "",
1657                        new ast::BasicType( ast::BasicType::SignedInt ),
1658                        (ast::Init *)nullptr,
1659                        ast::Storage::Classes(),
1660                        ast::Linkage::Cforall
1661                ) );
1662        } // if
1663        ast::Stmt * stmt = maybeBuild( td->function.body );
1664        ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1665        ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1666                name,
1667                std::move( forall ),
1668                std::move( assertions ),
1669                std::move( params ),
1670                std::move( returns ),
1671                body,
1672                scs,
1673                linkage,
1674                std::move( attributes ),
1675                funcSpec,
1676                (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
1677        );
1678        buildList( td->function.withExprs, decl->withExprs );
1679        decl->asmName = asmName;
1680        // This may be redundant on a declaration.
1681        decl->type.get_and_mutate()->qualifiers = cvq;
1682        return decl;
1683} // buildFunctionDecl
1684
1685
1686ast::Decl * buildDecl(
1687                const TypeData * td,
1688                const string &name,
1689                ast::Storage::Classes scs,
1690                ast::Expr * bitfieldWidth,
1691                ast::Function::Specs funcSpec,
1692                ast::Linkage::Spec linkage,
1693                ast::Expr * asmName,
1694                ast::Init * init,
1695                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1696        if ( td->kind == TypeData::Function ) {
1697                if ( td->function.idList ) {                                    // KR function ?
1698                        buildKRFunction( td->function );                        // transform into C11 function
1699                } // if
1700
1701                return buildFunctionDecl(
1702                        td, name, scs, funcSpec, linkage,
1703                        asmName, std::move( attributes ) );
1704        } else if ( td->kind == TypeData::Aggregate ) {
1705                return buildAggregate( td, std::move( attributes ), linkage );
1706        } else if ( td->kind == TypeData::Enum ) {
1707                return buildEnum( td, std::move( attributes ), linkage );
1708        } else if ( td->kind == TypeData::Symbolic ) {
1709                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1710        } else {
1711                auto ret = new ast::ObjectDecl( td->location,
1712                        name,
1713                        typebuild( td ),
1714                        init,
1715                        scs,
1716                        linkage,
1717                        bitfieldWidth,
1718                        std::move( attributes )
1719                );
1720                ret->asmName = asmName;
1721                return ret;
1722        } // if
1723        return nullptr;
1724} // buildDecl
1725
1726
1727ast::FunctionType * buildFunctionType( const TypeData * td ) {
1728        assert( td->kind == TypeData::Function );
1729        ast::FunctionType * ft = new ast::FunctionType(
1730                ( !td->function.params || td->function.params->hasEllipsis )
1731                        ? ast::VariableArgs : ast::FixedArgs,
1732                buildQualifiers( td )
1733        );
1734        buildTypeList( td->function.params, ft->params );
1735        buildForall( td->forall, ft->forall );
1736        if ( td->base ) {
1737                switch ( td->base->kind ) {
1738                case TypeData::Tuple:
1739                        buildTypeList( td->base->tuple, ft->returns );
1740                        break;
1741                default:
1742                        ft->returns.push_back( typebuild( td->base ) );
1743                        break;
1744                } // switch
1745        } else {
1746                ft->returns.push_back(
1747                        new ast::BasicType( ast::BasicType::SignedInt ) );
1748        } // if
1749        return ft;
1750} // buildFunctionType
1751
1752
1753// Transform KR routine declarations into C99 routine declarations:
1754//
1755//    rtn( a, b, c ) int a, c; double b {}  =>  int rtn( int a, double c, int b ) {}
1756//
1757// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1758// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1759// extra names are disallowed.
1760//
1761// Note, there is no KR routine-prototype syntax:
1762//
1763//    rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1764//    rtn(); // valid KR prototype
1765
1766void buildKRFunction( const TypeData::Function_t & function ) {
1767        assert( ! function.params );
1768        // loop over declaration first as it is easier to spot errors
1769        for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) {
1770                // scan ALL parameter names for each declaration name to check for duplicates
1771                for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1772                        if ( *decl->name == *param->name ) {
1773                                // type set => parameter name already transformed by a declaration names so there is a duplicate
1774                                // declaration name attempting a second transformation
1775                                if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1776                                // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1777                                // parameter name attempting a second transformation
1778                                if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1779                                param->type = decl->type;                               // set copy declaration type to parameter type
1780                                decl->type = nullptr;                                   // reset declaration type
1781                                // Copy and reset attributes from declaration to parameter:
1782                                splice( param->attributes, decl->attributes );
1783                        } // if
1784                } // for
1785                // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1786                if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1787        } // for
1788
1789        // Parameter names without a declaration default to type int:
1790        //
1791        //    rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1792
1793        for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1794                if ( ! param->type ) {                                                  // generate type int for empty parameter type
1795                        param->type = new TypeData( TypeData::Basic );
1796                        param->type->basictype = TypeData::Int;
1797                } // if
1798        } // for
1799
1800        function.params = function.idList;                                      // newly modified idList becomes parameters
1801        function.idList = nullptr;                                                      // idList now empty
1802        delete function.oldDeclList;                                            // deletes entire list
1803        function.oldDeclList = nullptr;                                         // reset
1804} // buildKRFunction
1805
1806// Local Variables: //
1807// tab-width: 4 //
1808// mode: c++ //
1809// compile-command: "make install" //
1810// End: //
Note: See TracBrowser for help on using the repository browser.