source: src/Parser/TypeData.cc @ a3525c4

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

Some Parser clean-up I did while investigating.

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