source: src/Parser/TypeData.cpp @ e37d45e1

Last change on this file since e37d45e1 was 5ef4008, checked in by JiadaL <j82liang@…>, 2 months ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

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