source: src/Parser/TypeData.cpp @ c92bdcc

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

Updated the rest of the names in src/ (except for the generated files).

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