source: src/Parser/TypeData.cpp @ a933489b

Last change on this file since a933489b was db19e1d, checked in by Andrew Beach <ajbeach@…>, 8 days ago

Changed the interpritation of () to be no parameters instead of any parameters. This had a lot of little changes because of this and some nearby clean-up. This includes some changes, including changing some generated functions to be fixed-args instead of variable-args, stripping out the place holder void parameter earlier, but it still shows up earlier in some cases that examine the parser directly. Also had to update the function generation tools. Have only tested with one --arch. Hopefully this all works out.

  • Property mode set to 100644
File size: 49.2 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 buildArgumentFlag( const TypeData * td ) {
1544        assert( td->kind == TypeData::Function );
1545        bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
1546        return (isVarArgs) ? ast::VariableArgs : ast::FixedArgs;
1547}
1548
1549
1550// Wrapper to convert the void parameter into the empty explicit list.
1551static void buildParamList( DeclarationNode * decl,
1552                std::vector<ast::ptr<ast::DeclWithType>> & params ) {
1553        buildList( decl, params );
1554        if ( 1 == params.size() && params[0]->get_type()->isVoid() ) {
1555                params.pop_back();
1556        }
1557}
1558
1559
1560ast::FunctionDecl * buildFunctionDecl(
1561                const TypeData * td,
1562                const string &name,
1563                ast::Storage::Classes scs,
1564                ast::Function::Specs funcSpec,
1565                ast::Linkage::Spec linkage,
1566                ast::Expr * asmName,
1567                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1568        assert( td->kind == TypeData::Function );
1569        ast::CV::Qualifiers cvq = buildQualifiers( td );
1570        std::vector<ast::ptr<ast::TypeDecl>> forall;
1571        std::vector<ast::ptr<ast::DeclWithType>> assertions;
1572        std::vector<ast::ptr<ast::DeclWithType>> params;
1573        std::vector<ast::ptr<ast::DeclWithType>> returns;
1574        buildParamList( td->function.params, params );
1575        buildForall( td->forall, forall );
1576        // Functions do not store their assertions there anymore.
1577        for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1578                auto mut = type_param.get_and_mutate();
1579                splice( assertions, mut->assertions );
1580        }
1581        if ( td->base ) {
1582                switch ( td->base->kind ) {
1583                case TypeData::Tuple:
1584                        buildList( td->base->tuple, returns );
1585                        break;
1586                default:
1587                        returns.push_back( dynamic_cast<ast::DeclWithType *>(
1588                                buildDecl(
1589                                        td->base,
1590                                        "",
1591                                        ast::Storage::Classes(),
1592                                        (ast::Expr *)nullptr, // bitfieldWidth
1593                                        ast::Function::Specs(),
1594                                        ast::Linkage::Cforall,
1595                                        (ast::Expr *)nullptr // asmName
1596                                )
1597                        ) );
1598                } // switch
1599        } else {
1600                returns.push_back( new ast::ObjectDecl(
1601                        td->location,
1602                        "",
1603                        new ast::BasicType( ast::BasicKind::SignedInt ),
1604                        (ast::Init *)nullptr,
1605                        ast::Storage::Classes(),
1606                        ast::Linkage::Cforall
1607                ) );
1608        } // if
1609        ast::Stmt * stmt = maybeBuild( td->function.body );
1610        ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1611        ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1612                name,
1613                std::move( forall ),
1614                std::move( assertions ),
1615                std::move( params ),
1616                std::move( returns ),
1617                body,
1618                scs,
1619                linkage,
1620                std::move( attributes ),
1621                funcSpec,
1622                buildArgumentFlag( td )
1623        );
1624        buildList( td->function.withExprs, decl->withExprs );
1625        decl->asmName = asmName;
1626        // This may be redundant on a declaration.
1627        decl->type.get_and_mutate()->qualifiers = cvq;
1628        return decl;
1629} // buildFunctionDecl
1630
1631
1632ast::Decl * buildDecl(
1633                const TypeData * td,
1634                const string &name,
1635                ast::Storage::Classes scs,
1636                ast::Expr * bitfieldWidth,
1637                ast::Function::Specs funcSpec,
1638                ast::Linkage::Spec linkage,
1639                ast::Expr * asmName,
1640                ast::Init * init,
1641                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1642        if ( td->kind == TypeData::Function ) {
1643                if ( td->function.idList ) {                                    // KR function ?
1644                        buildKRFunction( td->function );                        // transform into C11 function
1645                } // if
1646
1647                return buildFunctionDecl(
1648                        td, name, scs, funcSpec, linkage,
1649                        asmName, std::move( attributes ) );
1650        } else if ( td->kind == TypeData::Aggregate ) {
1651                return buildAggregate( td, std::move( attributes ), linkage );
1652        } else if ( td->kind == TypeData::Symbolic ) {
1653                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1654        } else {
1655                auto ret = new ast::ObjectDecl( td->location,
1656                        name,
1657                        typebuild( td ),
1658                        init,
1659                        scs,
1660                        linkage,
1661                        bitfieldWidth,
1662                        std::move( attributes )
1663                );
1664                ret->asmName = asmName;
1665                return ret;
1666        } // if
1667        return nullptr;
1668} // buildDecl
1669
1670
1671ast::FunctionType * buildFunctionType( const TypeData * td ) {
1672        assert( td->kind == TypeData::Function );
1673        ast::FunctionType * ft = new ast::FunctionType(
1674                buildArgumentFlag( td ),
1675                buildQualifiers( td )
1676        );
1677        buildTypeList( td->function.params, ft->params );
1678        buildForall( td->forall, ft->forall );
1679        if ( td->base ) {
1680                switch ( td->base->kind ) {
1681                case TypeData::Tuple:
1682                        buildTypeList( td->base->tuple, ft->returns );
1683                        break;
1684                default:
1685                        ft->returns.push_back( typebuild( td->base ) );
1686                        break;
1687                } // switch
1688        } else {
1689                ft->returns.push_back(
1690                        new ast::BasicType( ast::BasicKind::SignedInt ) );
1691        } // if
1692        return ft;
1693} // buildFunctionType
1694
1695
1696// Transform KR routine declarations into C99 routine declarations:
1697//
1698//    rtn( a, b, c ) int a, c; double b {}  =>  int rtn( int a, double c, int b ) {}
1699//
1700// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1701// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1702// extra names are disallowed.
1703//
1704// Note, there is no KR routine-prototype syntax:
1705//
1706//    rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1707//    rtn(); // valid KR prototype
1708
1709void buildKRFunction( const TypeData::Function_t & function ) {
1710        assert( ! function.params );
1711        // loop over declaration first as it is easier to spot errors
1712        for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) {
1713                // scan ALL parameter names for each declaration name to check for duplicates
1714                for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1715                        if ( *decl->name == *param->name ) {
1716                                // type set => parameter name already transformed by a declaration names so there is a duplicate
1717                                // declaration name attempting a second transformation
1718                                if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1719                                // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1720                                // parameter name attempting a second transformation
1721                                if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1722                                param->type = decl->type;                               // set copy declaration type to parameter type
1723                                decl->type = nullptr;                                   // reset declaration type
1724                                // Copy and reset attributes from declaration to parameter:
1725                                splice( param->attributes, decl->attributes );
1726                        } // if
1727                } // for
1728                // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1729                if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1730        } // for
1731
1732        // Parameter names without a declaration default to type int:
1733        //
1734        //    rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1735
1736        for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1737                if ( ! param->type ) {                                                  // generate type int for empty parameter type
1738                        param->type = new TypeData( TypeData::Basic );
1739                        param->type->basictype = TypeData::Int;
1740                } // if
1741        } // for
1742
1743        function.params = function.idList;                                      // newly modified idList becomes parameters
1744        function.idList = nullptr;                                                      // idList now empty
1745        delete function.oldDeclList;                                            // deletes entire list
1746        function.oldDeclList = nullptr;                                         // reset
1747} // buildKRFunction
1748
1749// Local Variables: //
1750// tab-width: 4 //
1751// mode: c++ //
1752// compile-command: "make install" //
1753// End: //
Note: See TracBrowser for help on using the repository browser.