source: src/Parser/TypeData.cc @ 083e637

Last change on this file since 083e637 was 7a780ad, checked in by Andrew Beach <ajbeach@…>, 7 months ago

Moved ast::BasicType::Kind to ast::BasicKind? in its own hearder. This is more consistent with other utility enums (although we still use this as a enum class) and reduces what some files need to include. Also did a upgrade in a comment with MAX_INTEGER_TYPE, it is now part of the enum.

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