source: src/Parser/TypeData.cc @ b5bfb16

Last change on this file since b5bfb16 was 67467a3, checked in by Andrew Beach <ajbeach@…>, 8 weeks ago

Fused TypeData::Enum and TypeData::Aggregate, an enumeration is a kind of aggregate after all. There will always be some unused fields in Aggregate_t (but less in TypeData? overall) but the code is almost always simpler.

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