source: src/Parser/TypeData.cc @ 423c0cd

Last change on this file since 423c0cd was e048ece, checked in by Andrew Beach <ajbeach@…>, 4 months ago

Moved the DeclarationNode? enums over to TypeData? where they are actually used.

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