source: src/Parser/TypeData.cpp @ d6b7d1d

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

Isolated the logic to decide if a function is a var-args function or not.

  • Property mode set to 100644
File size: 48.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// TypeData.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 : Fri Feb 23 08:58:30 2024
13// Update Count     : 734
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::uuFloat80:
1161        case TypeData::uuFloat128:
1162        case TypeData::uFloat16:
1163        case TypeData::uFloat32:
1164        case TypeData::uFloat32x:
1165        case TypeData::uFloat64:
1166        case TypeData::uFloat64x:
1167        case TypeData::uFloat128:
1168        case TypeData::uFloat128x:
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::uFloat16Complex, ast::BasicKind::uFloat32Complex, ast::BasicKind::uFloat32xComplex, ast::BasicKind::uFloat64Complex, ast::BasicKind::uFloat64xComplex, ast::BasicKind::uFloat128Complex, ast::BasicKind::uFloat128xComplex, },
1171                        { 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, },
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::uuFloat80 || 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        default:
1208                assertf( false, "unknown basic type" );
1209                return nullptr;
1210        } // switch
1211
1212        ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
1213        return bt;
1214} // buildBasicType
1215
1216
1217static ast::Type * buildDefaultType( const TypeData * td ) {
1218        return ( td ) ? typebuild( td ) : new ast::BasicType( ast::BasicKind::SignedInt );
1219} // buildDefaultType
1220
1221
1222ast::PointerType * buildPointer( const TypeData * td ) {
1223        return new ast::PointerType(
1224                buildDefaultType( td->base ),
1225                buildQualifiers( td )
1226        );
1227} // buildPointer
1228
1229
1230ast::ArrayType * buildArray( const TypeData * td ) {
1231        return new ast::ArrayType(
1232                buildDefaultType( td->base ),
1233                maybeBuild( td->array.dimension ),
1234                td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1235                td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1236                buildQualifiers( td )
1237        );
1238} // buildArray
1239
1240
1241ast::ReferenceType * buildReference( const TypeData * td ) {
1242        return new ast::ReferenceType(
1243                buildDefaultType( td->base ),
1244                buildQualifiers( td )
1245        );
1246} // buildReference
1247
1248
1249ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
1250        assert( td->kind == TypeData::Aggregate );
1251        ast::AggregateDecl * at;
1252        switch ( td->aggregate.kind ) {
1253        case ast::AggregateDecl::Struct:
1254        case ast::AggregateDecl::Coroutine:
1255        case ast::AggregateDecl::Exception:
1256        case ast::AggregateDecl::Generator:
1257        case ast::AggregateDecl::Monitor:
1258        case ast::AggregateDecl::Thread:
1259                at = new ast::StructDecl( td->location,
1260                        *td->aggregate.name,
1261                        td->aggregate.kind,
1262                        std::move( attributes ),
1263                        linkage
1264                );
1265                buildForall( td->aggregate.params, at->params );
1266                break;
1267        case ast::AggregateDecl::Union:
1268                at = new ast::UnionDecl( td->location,
1269                        *td->aggregate.name,
1270                        std::move( attributes ),
1271                        linkage
1272                );
1273                buildForall( td->aggregate.params, at->params );
1274                break;
1275        case ast::AggregateDecl::Enum:
1276                return buildEnum( td, std::move( attributes ), linkage );
1277        case ast::AggregateDecl::Trait:
1278                at = new ast::TraitDecl( td->location,
1279                        *td->aggregate.name,
1280                        std::move( attributes ),
1281                        linkage
1282                );
1283                buildList( td->aggregate.params, at->params );
1284                break;
1285        default:
1286                assert( false );
1287        } // switch
1288
1289        buildList( td->aggregate.fields, at->members );
1290        at->set_body( td->aggregate.body );
1291
1292        return at;
1293} // buildAggregate
1294
1295
1296ast::BaseInstType * buildComAggInst(
1297                const TypeData * td,
1298                std::vector<ast::ptr<ast::Attribute>> && attributes,
1299                ast::Linkage::Spec linkage ) {
1300        switch ( td->kind ) {
1301        case TypeData::Aggregate:
1302                if ( td->aggregate.body ) {
1303                        ast::AggregateDecl * typedecl =
1304                                buildAggregate( td, std::move( attributes ), linkage );
1305                        switch ( td->aggregate.kind ) {
1306                        case ast::AggregateDecl::Struct:
1307                        case ast::AggregateDecl::Coroutine:
1308                        case ast::AggregateDecl::Monitor:
1309                        case ast::AggregateDecl::Thread:
1310                                return new ast::StructInstType(
1311                                        strict_dynamic_cast<ast::StructDecl *>( typedecl ),
1312                                        buildQualifiers( td )
1313                                );
1314                        case ast::AggregateDecl::Union:
1315                                return new ast::UnionInstType(
1316                                        strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
1317                                        buildQualifiers( td )
1318                                );
1319                        case ast::AggregateDecl::Enum:
1320                                return new ast::EnumInstType(
1321                                        strict_dynamic_cast<ast::EnumDecl *>( typedecl ),
1322                                        buildQualifiers( td )
1323                                );
1324                        case ast::AggregateDecl::Trait:
1325                                assert( false );
1326                                break;
1327                        default:
1328                                assert( false );
1329                        } // switch
1330                } else {
1331                        switch ( td->aggregate.kind ) {
1332                        case ast::AggregateDecl::Struct:
1333                        case ast::AggregateDecl::Coroutine:
1334                        case ast::AggregateDecl::Monitor:
1335                        case ast::AggregateDecl::Thread:
1336                                return new ast::StructInstType(
1337                                        *td->aggregate.name,
1338                                        buildQualifiers( td )
1339                                );
1340                        case ast::AggregateDecl::Union:
1341                                return new ast::UnionInstType(
1342                                        *td->aggregate.name,
1343                                        buildQualifiers( td )
1344                                );
1345                        case ast::AggregateDecl::Enum:
1346                                return new ast::EnumInstType(
1347                                        *td->aggregate.name,
1348                                        buildQualifiers( td )
1349                                );
1350                        case ast::AggregateDecl::Trait:
1351                                return new ast::TraitInstType(
1352                                        *td->aggregate.name,
1353                                        buildQualifiers( td )
1354                                );
1355                        default:
1356                                assert( false );
1357                        } // switch
1358                        break;
1359                } // if
1360                break;
1361        default:
1362                assert( false );
1363        } // switch
1364        assert( false );
1365} // buildAggInst
1366
1367
1368ast::BaseInstType * buildAggInst( const TypeData * td ) {
1369        assert( td->kind == TypeData::AggregateInst );
1370
1371        ast::BaseInstType * ret = nullptr;
1372        TypeData * type = td->aggInst.aggregate;
1373        switch ( type->kind ) {
1374        case TypeData::Aggregate:
1375                switch ( type->aggregate.kind ) {
1376                case ast::AggregateDecl::Struct:
1377                case ast::AggregateDecl::Coroutine:
1378                case ast::AggregateDecl::Monitor:
1379                case ast::AggregateDecl::Thread:
1380                        ret = new ast::StructInstType(
1381                                *type->aggregate.name,
1382                                buildQualifiers( type )
1383                        );
1384                        break;
1385                case ast::AggregateDecl::Union:
1386                        ret = new ast::UnionInstType(
1387                                *type->aggregate.name,
1388                                buildQualifiers( type )
1389                        );
1390                        break;
1391                case ast::AggregateDecl::Enum:
1392                        ret = new ast::EnumInstType(
1393                                *type->aggregate.name,
1394                                buildQualifiers( type )
1395                        );
1396                        break;
1397                case ast::AggregateDecl::Trait:
1398                        ret = new ast::TraitInstType(
1399                                *type->aggregate.name,
1400                                buildQualifiers( type )
1401                        );
1402                        break;
1403                default:
1404                        assert( false );
1405                } // switch
1406                break;
1407        default:
1408                assert( false );
1409        } // switch
1410
1411        ret->hoistType = td->aggInst.hoistType;
1412        buildList( td->aggInst.params, ret->params );
1413        return ret;
1414} // buildAggInst
1415
1416
1417ast::NamedTypeDecl * buildSymbolic(
1418                const TypeData * td,
1419                std::vector<ast::ptr<ast::Attribute>> attributes,
1420                const std::string & name,
1421                ast::Storage::Classes scs,
1422                ast::Linkage::Spec linkage ) {
1423        assert( td->kind == TypeData::Symbolic );
1424        ast::NamedTypeDecl * ret;
1425        assert( td->base );
1426        if ( td->symbolic.isTypedef ) {
1427                ret = new ast::TypedefDecl(
1428                        td->location,
1429                        name,
1430                        scs,
1431                        typebuild( td->base ),
1432                        linkage
1433                );
1434        } else {
1435                ret = new ast::TypeDecl(
1436                        td->location,
1437                        name,
1438                        scs,
1439                        typebuild( td->base ),
1440                        ast::TypeDecl::Dtype,
1441                        true
1442                );
1443        } // if
1444        buildList( td->symbolic.assertions, ret->assertions );
1445        splice( ret->base.get_and_mutate()->attributes, attributes );
1446        return ret;
1447} // buildSymbolic
1448
1449
1450ast::EnumDecl * buildEnum(
1451                const TypeData * td,
1452                std::vector<ast::ptr<ast::Attribute>> && attributes,
1453                ast::Linkage::Spec linkage ) {
1454        assert( td->kind == TypeData::Aggregate );
1455        assert( td->aggregate.kind == ast::AggregateDecl::Enum );
1456        ast::ptr<ast::Type> baseType = td->base ? typebuild(td->base) : nullptr;
1457
1458        ast::EnumDecl * ret = new ast::EnumDecl(
1459                td->location,
1460                *td->aggregate.name,
1461                td->aggregate.isCfa,
1462                std::move( attributes ),
1463                linkage,
1464                baseType
1465        );
1466        buildList( td->aggregate.fields, ret->members );
1467        auto members = ret->members.begin();
1468        ret->hide = td->aggregate.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
1469        for ( const DeclarationNode * cur = td->aggregate.fields ; cur != nullptr ; cur = cur->next, ++members ) {
1470                if (cur->enumInLine) continue;
1471                ast::Decl * member = members->get_and_mutate();
1472                ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
1473                object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
1474                if ( ret->isOpaque() && cur->has_enumeratorValue() ) {
1475                        SemanticError( td->location, "Opague cannot have an explicit initializer value." );
1476                } else if ( cur->has_enumeratorValue() ) {
1477                        ast::Expr * initValue;
1478                        if (ret->isCfa && ret->base) {
1479                                initValue = new ast::CastExpr( cur->enumeratorValue->location, maybeMoveBuild( cur->consume_enumeratorValue() ), ret->base  );
1480                        } else {
1481                                initValue = maybeMoveBuild( cur->consume_enumeratorValue() );
1482                        }
1483                        object->init = new ast::SingleInit(
1484                                td->location,
1485                                initValue,
1486                                ast::NoConstruct
1487                        );
1488                }
1489                // else cur is a List Initializer and has been set as init in buildList()
1490                // if
1491        } // for
1492        ret->body = td->aggregate.body;
1493        return ret;
1494} // buildEnum
1495
1496
1497ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
1498        assert( td->kind == TypeData::SymbolicInst );
1499        ast::TypeInstType * ret = new ast::TypeInstType(
1500                *td->symbolic.name,
1501                ast::TypeDecl::Dtype,
1502                buildQualifiers( td )
1503        );
1504        buildList( td->symbolic.actuals, ret->params );
1505        return ret;
1506} // buildSymbolicInst
1507
1508
1509ast::TupleType * buildTuple( const TypeData * td ) {
1510        assert( td->kind == TypeData::Tuple );
1511        std::vector<ast::ptr<ast::Type>> types;
1512        buildTypeList( td->tuple, types );
1513        ast::TupleType * ret = new ast::TupleType(
1514                std::move( types ),
1515                buildQualifiers( td )
1516        );
1517        return ret;
1518} // buildTuple
1519
1520
1521ast::TypeofType * buildTypeof( const TypeData * td ) {
1522        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
1523        assert( td->typeexpr );
1524        return new ast::TypeofType(
1525                td->typeexpr->build(),
1526                td->kind == TypeData::Typeof
1527                        ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
1528                buildQualifiers( td )
1529        );
1530} // buildTypeof
1531
1532
1533ast::VTableType * buildVtable( const TypeData * td ) {
1534        assert( td->base );
1535        return new ast::VTableType(
1536                typebuild( td->base ),
1537                buildQualifiers( td )
1538        );
1539} // buildVtable
1540
1541
1542// The argument flag (is/is not var-args) of a computed property.
1543static ast::ArgumentFlag argumentFlag( const TypeData * td ) {
1544        assert( td->kind == TypeData::Function );
1545        bool isVaArgs = !td->function.params || td->function.params->hasEllipsis;
1546        return (isVaArgs) ? ast::VariableArgs : ast::FixedArgs;
1547} // argumentFlag
1548
1549
1550ast::FunctionDecl * buildFunctionDecl(
1551                const TypeData * td,
1552                const string &name,
1553                ast::Storage::Classes scs,
1554                ast::Function::Specs funcSpec,
1555                ast::Linkage::Spec linkage,
1556                ast::Expr * asmName,
1557                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1558        assert( td->kind == TypeData::Function );
1559        ast::CV::Qualifiers cvq = buildQualifiers( td );
1560        std::vector<ast::ptr<ast::TypeDecl>> forall;
1561        std::vector<ast::ptr<ast::DeclWithType>> assertions;
1562        std::vector<ast::ptr<ast::DeclWithType>> params;
1563        std::vector<ast::ptr<ast::DeclWithType>> returns;
1564        buildList( td->function.params, params );
1565        buildForall( td->forall, forall );
1566        // Functions do not store their assertions there anymore.
1567        for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1568                auto mut = type_param.get_and_mutate();
1569                splice( assertions, mut->assertions );
1570        }
1571        if ( td->base ) {
1572                switch ( td->base->kind ) {
1573                case TypeData::Tuple:
1574                        buildList( td->base->tuple, returns );
1575                        break;
1576                default:
1577                        returns.push_back( dynamic_cast<ast::DeclWithType *>(
1578                                buildDecl(
1579                                        td->base,
1580                                        "",
1581                                        ast::Storage::Classes(),
1582                                        (ast::Expr *)nullptr, // bitfieldWidth
1583                                        ast::Function::Specs(),
1584                                        ast::Linkage::Cforall,
1585                                        (ast::Expr *)nullptr // asmName
1586                                )
1587                        ) );
1588                } // switch
1589        } else {
1590                returns.push_back( new ast::ObjectDecl(
1591                        td->location,
1592                        "",
1593                        new ast::BasicType( ast::BasicKind::SignedInt ),
1594                        (ast::Init *)nullptr,
1595                        ast::Storage::Classes(),
1596                        ast::Linkage::Cforall
1597                ) );
1598        } // if
1599        ast::Stmt * stmt = maybeBuild( td->function.body );
1600        ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1601        ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1602                name,
1603                std::move( forall ),
1604                std::move( assertions ),
1605                std::move( params ),
1606                std::move( returns ),
1607                body,
1608                scs,
1609                linkage,
1610                std::move( attributes ),
1611                funcSpec,
1612                argumentFlag( td )
1613        );
1614        buildList( td->function.withExprs, decl->withExprs );
1615        decl->asmName = asmName;
1616        // This may be redundant on a declaration.
1617        decl->type.get_and_mutate()->qualifiers = cvq;
1618        return decl;
1619} // buildFunctionDecl
1620
1621
1622ast::Decl * buildDecl(
1623                const TypeData * td,
1624                const string &name,
1625                ast::Storage::Classes scs,
1626                ast::Expr * bitfieldWidth,
1627                ast::Function::Specs funcSpec,
1628                ast::Linkage::Spec linkage,
1629                ast::Expr * asmName,
1630                ast::Init * init,
1631                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1632        if ( td->kind == TypeData::Function ) {
1633                if ( td->function.idList ) {                                    // KR function ?
1634                        buildKRFunction( td->function );                        // transform into C11 function
1635                } // if
1636
1637                return buildFunctionDecl(
1638                        td, name, scs, funcSpec, linkage,
1639                        asmName, std::move( attributes ) );
1640        } else if ( td->kind == TypeData::Aggregate ) {
1641                return buildAggregate( td, std::move( attributes ), linkage );
1642        } else if ( td->kind == TypeData::Symbolic ) {
1643                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1644        } else {
1645                auto ret = new ast::ObjectDecl( td->location,
1646                        name,
1647                        typebuild( td ),
1648                        init,
1649                        scs,
1650                        linkage,
1651                        bitfieldWidth,
1652                        std::move( attributes )
1653                );
1654                ret->asmName = asmName;
1655                return ret;
1656        } // if
1657        return nullptr;
1658} // buildDecl
1659
1660
1661ast::FunctionType * buildFunctionType( const TypeData * td ) {
1662        assert( td->kind == TypeData::Function );
1663        ast::FunctionType * ft = new ast::FunctionType(
1664                argumentFlag( td ),
1665                buildQualifiers( td )
1666        );
1667        buildTypeList( td->function.params, ft->params );
1668        buildForall( td->forall, ft->forall );
1669        if ( td->base ) {
1670                switch ( td->base->kind ) {
1671                case TypeData::Tuple:
1672                        buildTypeList( td->base->tuple, ft->returns );
1673                        break;
1674                default:
1675                        ft->returns.push_back( typebuild( td->base ) );
1676                        break;
1677                } // switch
1678        } else {
1679                ft->returns.push_back(
1680                        new ast::BasicType( ast::BasicKind::SignedInt ) );
1681        } // if
1682        return ft;
1683} // buildFunctionType
1684
1685
1686// Transform KR routine declarations into C99 routine declarations:
1687//
1688//    rtn( a, b, c ) int a, c; double b {}  =>  int rtn( int a, double c, int b ) {}
1689//
1690// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1691// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1692// extra names are disallowed.
1693//
1694// Note, there is no KR routine-prototype syntax:
1695//
1696//    rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1697//    rtn(); // valid KR prototype
1698
1699void buildKRFunction( const TypeData::Function_t & function ) {
1700        assert( ! function.params );
1701        // loop over declaration first as it is easier to spot errors
1702        for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) {
1703                // scan ALL parameter names for each declaration name to check for duplicates
1704                for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1705                        if ( *decl->name == *param->name ) {
1706                                // type set => parameter name already transformed by a declaration names so there is a duplicate
1707                                // declaration name attempting a second transformation
1708                                if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1709                                // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1710                                // parameter name attempting a second transformation
1711                                if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1712                                param->type = decl->type;                               // set copy declaration type to parameter type
1713                                decl->type = nullptr;                                   // reset declaration type
1714                                // Copy and reset attributes from declaration to parameter:
1715                                splice( param->attributes, decl->attributes );
1716                        } // if
1717                } // for
1718                // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1719                if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1720        } // for
1721
1722        // Parameter names without a declaration default to type int:
1723        //
1724        //    rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1725
1726        for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1727                if ( ! param->type ) {                                                  // generate type int for empty parameter type
1728                        param->type = new TypeData( TypeData::Basic );
1729                        param->type->basictype = TypeData::Int;
1730                } // if
1731        } // for
1732
1733        function.params = function.idList;                                      // newly modified idList becomes parameters
1734        function.idList = nullptr;                                                      // idList now empty
1735        delete function.oldDeclList;                                            // deletes entire list
1736        function.oldDeclList = nullptr;                                         // reset
1737} // buildKRFunction
1738
1739// Local Variables: //
1740// tab-width: 4 //
1741// mode: c++ //
1742// compile-command: "make install" //
1743// End: //
Note: See TracBrowser for help on using the repository browser.