source: src/Parser/TypeData.cc @ 1cfe640

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

One more bit of clean-up, improving some names.

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