source: src/Parser/TypeData.cc @ 4ee3b0c1

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumwith_gc
Last change on this file since 4ee3b0c1 was 4ee3b0c1, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

Push float80/float128 through the system

  • Property mode set to 100644
File size: 33.9 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//
[f1e012b]7// TypeData.cc --
[b87a5ed]8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 15:12:51 2015
[e612146c]11// Last Modified By : Peter A. Buhr
[6926a6d]12// Last Modified On : Thu Apr 26 13:46:07 2018
13// Update Count     : 603
[b87a5ed]14//
15
[d180746]16#include <cassert>                 // for assert
17#include <ostream>                 // for operator<<, ostream, basic_ostream
18
19#include "Common/SemanticError.h"  // for SemanticError
20#include "Common/utility.h"        // for maybeClone, maybeBuild, maybeMoveB...
21#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
22#include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, FunctionDecl
23#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
24#include "SynTree/Initializer.h"   // for SingleInit, Initializer (ptr only)
25#include "SynTree/Statement.h"     // for CompoundStmt, Statement
26#include "SynTree/Type.h"          // for BasicType, Type, Type::ForallList
[51b7345]27#include "TypeData.h"
[d180746]28
29class Attribute;
30
[2298f728]31using namespace std;
[51b7345]32
[0b0f1dd]33TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
[b87a5ed]34        switch ( kind ) {
35          case Unknown:
36          case Pointer:
[ce8c12f]37          case Reference:
[b87a5ed]38          case EnumConstant:
39                // nothing else to initialize
40                break;
41          case Basic:
[8f6f47d7]42                // basic = new Basic_t;
[b87a5ed]43                break;
44          case Array:
[8f6f47d7]45                // array = new Array_t;
[2298f728]46                array.dimension = nullptr;
[8f6f47d7]47                array.isVarLen = false;
48                array.isStatic = false;
[b87a5ed]49                break;
50          case Function:
[8f6f47d7]51                // function = new Function_t;
[2298f728]52                function.params = nullptr;
53                function.idList = nullptr;
54                function.oldDeclList = nullptr;
55                function.body = nullptr;
[84276ba]56                function.withExprs = nullptr;
[b87a5ed]57                break;
[e496303]58                // Enum is an Aggregate, so both structures are initialized together.
59          case Enum:
60                // enumeration = new Enumeration_t;
61                enumeration.name = nullptr;
62                enumeration.constants = nullptr;
63                enumeration.body = false;
[6926a6d]64                break;
[b87a5ed]65          case Aggregate:
[8f6f47d7]66                // aggregate = new Aggregate_t;
[2298f728]67                aggregate.name = nullptr;
68                aggregate.params = nullptr;
69                aggregate.actuals = nullptr;
70                aggregate.fields = nullptr;
[4a9ccc3]71                aggregate.body = false;
[b87a5ed]72                break;
73          case AggregateInst:
[8f6f47d7]74                // aggInst = new AggInst_t;
[2298f728]75                aggInst.aggregate = nullptr;
76                aggInst.params = nullptr;
[43c89a7]77                aggInst.hoistType = false;;
[b87a5ed]78                break;
79          case Symbolic:
80          case SymbolicInst:
[8f6f47d7]81                // symbolic = new Symbolic_t;
[2298f728]82                symbolic.name = nullptr;
83                symbolic.params = nullptr;
84                symbolic.actuals = nullptr;
85                symbolic.assertions = nullptr;
[b87a5ed]86                break;
87          case Tuple:
[8f6f47d7]88                // tuple = new Tuple_t;
89                tuple = nullptr;
[b87a5ed]90                break;
91          case Typeof:
[8f6f47d7]92                // typeexpr = new Typeof_t;
93                typeexpr = nullptr;
[b87a5ed]94                break;
[28307be]95          case Builtin:
96                // builtin = new Builtin_t;
[b87a5ed]97                break;
[68cd1ce]98        } // switch
[413ad05]99} // TypeData::TypeData
[51b7345]100
[201aeb9]101
[c8ffe20b]102TypeData::~TypeData() {
[b87a5ed]103        delete base;
104        delete forall;
105
106        switch ( kind ) {
107          case Unknown:
108          case Pointer:
[ce8c12f]109          case Reference:
[b87a5ed]110          case EnumConstant:
111                // nothing to destroy
112                break;
113          case Basic:
[8f6f47d7]114                // delete basic;
[b87a5ed]115                break;
116          case Array:
[8f6f47d7]117                delete array.dimension;
118                // delete array;
[b87a5ed]119                break;
120          case Function:
[8f6f47d7]121                delete function.params;
122                delete function.idList;
123                delete function.oldDeclList;
124                delete function.body;
[84276ba]125                delete function.withExprs;
[8f6f47d7]126                // delete function;
[b87a5ed]127                break;
128          case Aggregate:
[2298f728]129                delete aggregate.name;
[8f6f47d7]130                delete aggregate.params;
131                delete aggregate.actuals;
132                delete aggregate.fields;
133                // delete aggregate;
[b87a5ed]134                break;
135          case AggregateInst:
[8f6f47d7]136                delete aggInst.aggregate;
137                delete aggInst.params;
138                // delete aggInst;
[b87a5ed]139                break;
140          case Enum:
[2298f728]141                delete enumeration.name;
[8f6f47d7]142                delete enumeration.constants;
143                // delete enumeration;
[b87a5ed]144                break;
145          case Symbolic:
146          case SymbolicInst:
[2298f728]147                delete symbolic.name;
[8f6f47d7]148                delete symbolic.params;
149                delete symbolic.actuals;
150                delete symbolic.assertions;
151                // delete symbolic;
[b87a5ed]152                break;
153          case Tuple:
[8f6f47d7]154                // delete tuple->members;
[b87a5ed]155                delete tuple;
156                break;
157          case Typeof:
[8f6f47d7]158                // delete typeexpr->expr;
[b87a5ed]159                delete typeexpr;
160                break;
[28307be]161          case Builtin:
162                // delete builtin;
163                break;
[68cd1ce]164        } // switch
[413ad05]165} // TypeData::~TypeData
[51b7345]166
[201aeb9]167
[413ad05]168TypeData * TypeData::clone() const {
169        TypeData * newtype = new TypeData( kind );
[738e304]170        newtype->qualifiers = qualifiers;
[b87a5ed]171        newtype->base = maybeClone( base );
172        newtype->forall = maybeClone( forall );
173
174        switch ( kind ) {
175          case Unknown:
176          case EnumConstant:
177          case Pointer:
[ce8c12f]178          case Reference:
[b87a5ed]179                // nothing else to copy
180                break;
181          case Basic:
[5b639ee]182                newtype->basictype = basictype;
183                newtype->complextype = complextype;
184                newtype->signedness = signedness;
185                newtype->length = length;
[b87a5ed]186                break;
187          case Array:
[8f6f47d7]188                newtype->array.dimension = maybeClone( array.dimension );
189                newtype->array.isVarLen = array.isVarLen;
190                newtype->array.isStatic = array.isStatic;
[b87a5ed]191                break;
192          case Function:
[8f6f47d7]193                newtype->function.params = maybeClone( function.params );
194                newtype->function.idList = maybeClone( function.idList );
195                newtype->function.oldDeclList = maybeClone( function.oldDeclList );
196                newtype->function.body = maybeClone( function.body );
[84276ba]197                newtype->function.withExprs = maybeClone( function.withExprs );
[b87a5ed]198                break;
199          case Aggregate:
[2298f728]200                newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
[8f6f47d7]201                newtype->aggregate.params = maybeClone( aggregate.params );
202                newtype->aggregate.actuals = maybeClone( aggregate.actuals );
203                newtype->aggregate.fields = maybeClone( aggregate.fields );
204                newtype->aggregate.kind = aggregate.kind;
205                newtype->aggregate.body = aggregate.body;
[6ea87486]206                newtype->aggregate.tagged = aggregate.tagged;
207                newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;
[b87a5ed]208                break;
209          case AggregateInst:
[8f6f47d7]210                newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
211                newtype->aggInst.params = maybeClone( aggInst.params );
[43c89a7]212                newtype->aggInst.hoistType = aggInst.hoistType;
[b87a5ed]213                break;
214          case Enum:
[2298f728]215                newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
[8f6f47d7]216                newtype->enumeration.constants = maybeClone( enumeration.constants );
[ca1a547]217                newtype->enumeration.body = enumeration.body;
[b87a5ed]218                break;
219          case Symbolic:
220          case SymbolicInst:
[2298f728]221                newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr;
[8f6f47d7]222                newtype->symbolic.params = maybeClone( symbolic.params );
223                newtype->symbolic.actuals = maybeClone( symbolic.actuals );
224                newtype->symbolic.assertions = maybeClone( symbolic.assertions );
225                newtype->symbolic.isTypedef = symbolic.isTypedef;
[b87a5ed]226                break;
227          case Tuple:
[8f6f47d7]228                newtype->tuple = maybeClone( tuple );
[b87a5ed]229                break;
230          case Typeof:
[8f6f47d7]231                newtype->typeexpr = maybeClone( typeexpr );
[b87a5ed]232                break;
[90c3b1c]233          case Builtin:
[4cb935e]234                assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One );
235                newtype->builtintype = builtintype;
[90c3b1c]236                break;
[68cd1ce]237        } // switch
[b87a5ed]238        return newtype;
[413ad05]239} // TypeData::clone
[51b7345]240
[201aeb9]241
[2298f728]242void TypeData::print( ostream &os, int indent ) const {
[738e304]243        for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
[615a096]244                if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' ';
[c1c1112]245        } // for
[b87a5ed]246
247        if ( forall ) {
248                os << "forall " << endl;
[721f17a]249                forall->printList( os, indent + 4 );
[68cd1ce]250        } // if
[b87a5ed]251
252        switch ( kind ) {
253          case Unknown:
254                os << "entity of unknown type ";
255                break;
256          case Pointer:
257                os << "pointer ";
258                if ( base ) {
259                        os << "to ";
260                        base->print( os, indent );
[68cd1ce]261                } // if
[b87a5ed]262                break;
263          case EnumConstant:
264                os << "enumeration constant ";
265                break;
266          case Basic:
[dd020c0]267                if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
268                if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
[5b639ee]269                assert( basictype != DeclarationNode::NoBasicType );
[dd020c0]270                os << DeclarationNode::basicTypeNames[ basictype ] << " ";
271                if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " ";
[b87a5ed]272                break;
273          case Array:
[8f6f47d7]274                if ( array.isStatic ) {
[b87a5ed]275                        os << "static ";
[68cd1ce]276                } // if
[8f6f47d7]277                if ( array.dimension ) {
[b87a5ed]278                        os << "array of ";
[8f6f47d7]279                        array.dimension->printOneLine( os, indent );
280                } else if ( array.isVarLen ) {
[b87a5ed]281                        os << "variable-length array of ";
282                } else {
283                        os << "open array of ";
[68cd1ce]284                } // if
[b87a5ed]285                if ( base ) {
286                        base->print( os, indent );
[68cd1ce]287                } // if
[b87a5ed]288                break;
289          case Function:
290                os << "function" << endl;
[8f6f47d7]291                if ( function.params ) {
[721f17a]292                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
[8f6f47d7]293                        function.params->printList( os, indent + 4 );
[b87a5ed]294                } else {
[721f17a]295                        os << string( indent + 2, ' ' ) << "with no parameters " << endl;
[68cd1ce]296                } // if
[8f6f47d7]297                if ( function.idList ) {
[721f17a]298                        os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
[8f6f47d7]299                        function.idList->printList( os, indent + 4 );
[68cd1ce]300                } // if
[8f6f47d7]301                if ( function.oldDeclList ) {
[721f17a]302                        os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
[8f6f47d7]303                        function.oldDeclList->printList( os, indent + 4 );
[68cd1ce]304                } // if
[721f17a]305                os << string( indent + 2, ' ' ) << "returning ";
[b87a5ed]306                if ( base ) {
[721f17a]307                        base->print( os, indent + 4 );
[b87a5ed]308                } else {
309                        os << "nothing ";
[68cd1ce]310                } // if
[b87a5ed]311                os << endl;
[8f6f47d7]312                if ( function.body ) {
[ca1a547]313                        os << string( indent + 2, ' ' ) << "with body " << endl;
[8f6f47d7]314                        function.body->printList( os, indent + 2 );
[68cd1ce]315                } // if
[b87a5ed]316                break;
317          case Aggregate:
[dd020c0]318                os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl;
[8f6f47d7]319                if ( aggregate.params ) {
[721f17a]320                        os << string( indent + 2, ' ' ) << "with type parameters " << endl;
[8f6f47d7]321                        aggregate.params->printList( os, indent + 4 );
[68cd1ce]322                } // if
[8f6f47d7]323                if ( aggregate.actuals ) {
[721f17a]324                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
[8f6f47d7]325                        aggregate.actuals->printList( os, indent + 4 );
[68cd1ce]326                } // if
[8f6f47d7]327                if ( aggregate.fields ) {
[721f17a]328                        os << string( indent + 2, ' ' ) << "with members " << endl;
[8f6f47d7]329                        aggregate.fields->printList( os, indent + 4 );
[5d125e4]330                } // if
[8f6f47d7]331                if ( aggregate.body ) {
[5d125e4]332                        os << string( indent + 2, ' ' ) << " with body " << endl;
[68cd1ce]333                } // if
[b87a5ed]334                break;
335          case AggregateInst:
[8f6f47d7]336                if ( aggInst.aggregate ) {
[b87a5ed]337                        os << "instance of " ;
[8f6f47d7]338                        aggInst.aggregate->print( os, indent );
[b87a5ed]339                } else {
340                        os << "instance of an unspecified aggregate ";
[68cd1ce]341                } // if
[8f6f47d7]342                if ( aggInst.params ) {
[721f17a]343                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
[8f6f47d7]344                        aggInst.params->printList( os, indent + 2 );
[68cd1ce]345                } // if
[b87a5ed]346                break;
347          case Enum:
348                os << "enumeration ";
[8f6f47d7]349                if ( enumeration.constants ) {
[b87a5ed]350                        os << "with constants" << endl;
[8f6f47d7]351                        enumeration.constants->printList( os, indent + 2 );
[68cd1ce]352                } // if
[ca1a547]353                if ( enumeration.body ) {
354                        os << string( indent + 2, ' ' ) << " with body " << endl;
355                } // if
[b87a5ed]356                break;
357          case SymbolicInst:
[2298f728]358                os << "instance of type " << *symbolic.name;
[8f6f47d7]359                if ( symbolic.actuals ) {
[b87a5ed]360                        os << " with parameters" << endl;
[8f6f47d7]361                        symbolic.actuals->printList( os, indent + 2 );
[68cd1ce]362                } // if
[b87a5ed]363                break;
364          case Symbolic:
[8f6f47d7]365                if ( symbolic.isTypedef ) {
[b87a5ed]366                        os << "typedef definition ";
367                } else {
368                        os << "type definition ";
[68cd1ce]369                } // if
[8f6f47d7]370                if ( symbolic.params ) {
[721f17a]371                        os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
[8f6f47d7]372                        symbolic.params->printList( os, indent + 2 );
[68cd1ce]373                } // if
[8f6f47d7]374                if ( symbolic.assertions ) {
[721f17a]375                        os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
[8f6f47d7]376                        symbolic.assertions->printList( os, indent + 4 );
[721f17a]377                        os << string( indent + 2, ' ' );
[68cd1ce]378                } // if
[b87a5ed]379                if ( base ) {
380                        os << "for ";
381                        base->print( os, indent + 2 );
[68cd1ce]382                } // if
[b87a5ed]383                break;
384          case Tuple:
385                os << "tuple ";
[8f6f47d7]386                if ( tuple ) {
[b87a5ed]387                        os << "with members " << endl;
[8f6f47d7]388                        tuple->printList( os, indent + 2 );
[68cd1ce]389                } // if
[b87a5ed]390                break;
391          case Typeof:
392                os << "type-of expression ";
[8f6f47d7]393                if ( typeexpr ) {
394                        typeexpr->print( os, indent + 2 );
[68cd1ce]395                } // if
[b87a5ed]396                break;
[90c3b1c]397          case Builtin:
[9dc31c10]398                os << DeclarationNode::builtinTypeNames[builtintype];
[90c3b1c]399                break;
[1db21619]400          default:
[5b639ee]401                os << "internal error: TypeData::print " << kind << endl;
[1db21619]402                assert( false );
[68cd1ce]403        } // switch
[413ad05]404} // TypeData::print
[51b7345]405
[201aeb9]406
[8c49c0e]407template< typename ForallList >
408void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
[b87a5ed]409        buildList( firstNode, outputList );
[f0ecf9b]410        auto n = firstNode;
411        for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) {
[a7c90d4]412                TypeDecl * td = static_cast<TypeDecl *>(*i);
[f0ecf9b]413                if ( n->variable.tyClass == DeclarationNode::Otype ) {
[6943f051]414                        // add assertion parameters to `type' tyvars in reverse order
415                        // add dtor:  void ^?{}(T *)
[413ad05]416                        FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
[cda7889]417                        dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
[68fe077a]418                        td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) );
[4cc4286]419
[a9a259c]420                        // add copy ctor:  void ?{}(T *, T)
[413ad05]421                        FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
[cda7889]422                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
[68fe077a]423                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
424                        td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) );
[a9a259c]425
[6943f051]426                        // add default ctor:  void ?{}(T *)
[413ad05]427                        FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
[cda7889]428                        ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
[68fe077a]429                        td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) );
[6943f051]430
431                        // add assignment operator:  T * ?=?(T *, T)
[413ad05]432                        FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
[cda7889]433                        assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
[68fe077a]434                        assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
435                        assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
436                        td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) );
[68cd1ce]437                } // if
438        } // for
[201aeb9]439} // buildForall
440
[51b7345]441
[413ad05]442Type * typebuild( const TypeData * td ) {
443        assert( td );
444        switch ( td->kind ) {
445          case TypeData::Unknown:
[b87a5ed]446                // fill in implicit int
[413ad05]447                return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
448          case TypeData::Basic:
449                return buildBasicType( td );
450          case TypeData::Pointer:
451                return buildPointer( td );
452          case TypeData::Array:
453                return buildArray( td );
[ce8c12f]454          case TypeData::Reference:
455                return buildReference( td );
[413ad05]456          case TypeData::Function:
457                return buildFunction( td );
458          case TypeData::AggregateInst:
459                return buildAggInst( td );
460          case TypeData::EnumConstant:
[b87a5ed]461                // the name gets filled in later -- by SymTab::Validate
[413ad05]462                return new EnumInstType( buildQualifiers( td ), "" );
463          case TypeData::SymbolicInst:
464                return buildSymbolicInst( td );;
465          case TypeData::Tuple:
466                return buildTuple( td );
467          case TypeData::Typeof:
468                return buildTypeof( td );
469          case TypeData::Builtin:
[148f7290]470                if(td->builtintype == DeclarationNode::Zero) {
[ac10576]471                        return new ZeroType( noQualifiers );
[148f7290]472                }
473                else if(td->builtintype == DeclarationNode::One) {
[ac10576]474                        return new OneType( noQualifiers );
[148f7290]475                }
476                else {
477                        return new VarArgsType( buildQualifiers( td ) );
478                }
[413ad05]479          case TypeData::Symbolic:
480          case TypeData::Enum:
481          case TypeData::Aggregate:
[b87a5ed]482                assert( false );
[68cd1ce]483        } // switch
[2298f728]484        return nullptr;
[413ad05]485} // typebuild
486
[201aeb9]487
[413ad05]488TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
[2298f728]489        TypeData * ret = nullptr;
[51b7345]490
[413ad05]491        switch ( td->kind ) {
492          case TypeData::Aggregate:
[b2da0574]493                if ( ! toplevel && td->aggregate.body ) {
[413ad05]494                        ret = td->clone();
495                } // if
496                break;
497          case TypeData::Enum:
[b2da0574]498                if ( ! toplevel && td->enumeration.body ) {
[413ad05]499                        ret = td->clone();
500                } // if
501                break;
502          case TypeData::AggregateInst:
[8f6f47d7]503                if ( td->aggInst.aggregate ) {
504                        ret = typeextractAggregate( td->aggInst.aggregate, false );
[413ad05]505                } // if
506                break;
507          default:
508                if ( td->base ) {
509                        ret = typeextractAggregate( td->base, false );
510                } // if
511        } // switch
512        return ret;
513} // typeextractAggregate
514
[201aeb9]515
[413ad05]516Type::Qualifiers buildQualifiers( const TypeData * td ) {
[738e304]517        return td->qualifiers;
[413ad05]518} // buildQualifiers
[51b7345]519
[201aeb9]520
521static string genTSError( string msg, DeclarationNode::BasicType basictype ) {
[a16764a6]522        SemanticError( yylloc, string( "invalid type specifier \"" ) + msg + "\" for type \"" + DeclarationNode::basicTypeNames[basictype] + "\"." );
[201aeb9]523} // genTSError
524
[413ad05]525Type * buildBasicType( const TypeData * td ) {
[b87a5ed]526        BasicType::Kind ret;
527
[5b639ee]528        switch ( td->basictype ) {
529          case DeclarationNode::Void:
[201aeb9]530                if ( td->signedness != DeclarationNode::NoSignedness ) {
531                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
532                } // if
533                if ( td->length != DeclarationNode::NoLength ) {
534                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
[68cd1ce]535                } // if
[5b639ee]536                return new VoidType( buildQualifiers( td ) );
537                break;
538
539          case DeclarationNode::Bool:
540                if ( td->signedness != DeclarationNode::NoSignedness ) {
[201aeb9]541                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
[5b639ee]542                } // if
543                if ( td->length != DeclarationNode::NoLength ) {
[201aeb9]544                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
[68cd1ce]545                } // if
[51b7345]546
[5b639ee]547                ret = BasicType::Bool;
548                break;
549
550          case DeclarationNode::Char:
551                // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
552                // character types. The implementation shall define char to have the same range, representation, and behavior as
553                // either signed char or unsigned char.
[8c49c0e]554                static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
[5b639ee]555
556                if ( td->length != DeclarationNode::NoLength ) {
[201aeb9]557                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
[5b639ee]558                } // if
559
560                ret = chartype[ td->signedness ];
561                break;
562
563          case DeclarationNode::Int:
564                static BasicType::Kind inttype[2][4] = {
565                        { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
566                        { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
567                };
568
569          Integral: ;
570                if ( td->signedness == DeclarationNode::NoSignedness ) {
571                        const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
572                } // if
573                ret = inttype[ td->signedness ][ td->length ];
574                break;
575
[201aeb9]576          case DeclarationNode::Int128:
[4ee3b0c1]577                ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
[201aeb9]578                if ( td->length != DeclarationNode::NoLength ) {
579                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
580                } // if
581                break;
582
[5b639ee]583          case DeclarationNode::Float:
[201aeb9]584          case DeclarationNode::Float80:
585          case DeclarationNode::Float128:
[5b639ee]586          case DeclarationNode::Double:
587          case DeclarationNode::LongDouble:                                     // not set until below
588                static BasicType::Kind floattype[3][3] = {
589                        { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
590                        { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
591                        { BasicType::Float, BasicType::Double, BasicType::LongDouble },
592                };
593
594          FloatingPoint: ;
595                if ( td->signedness != DeclarationNode::NoSignedness ) {
[201aeb9]596                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
[5b639ee]597                } // if
598                if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
[201aeb9]599                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
[5b639ee]600                } // if
[4ee3b0c1]601                if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) {
[201aeb9]602                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
[5b639ee]603                } // if
604                if ( td->length == DeclarationNode::Long ) {
605                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
606                } // if
607
[4ee3b0c1]608                if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
609                        if ( td->complextype != DeclarationNode::NoComplexType ) {
610                                genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
611                        }
612                        if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
613                        else ret = BasicType::Float128;
614                        break;
615                }
616
[5b639ee]617                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
618                break;
619
620          case DeclarationNode::NoBasicType:
621                // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
622                if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
623                        const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
624                        goto FloatingPoint;
625                } // if
626
627                const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
628                goto Integral;
[2ee5426]629          default:
[201aeb9]630                assertf( false, "unknown basic type" );
[2ee5426]631                return nullptr;
[5b639ee]632        } // switch
633
634        BasicType * bt = new BasicType( buildQualifiers( td ), ret );
[413ad05]635        buildForall( td->forall, bt->get_forall() );
[b87a5ed]636        return bt;
[413ad05]637} // buildBasicType
[51b7345]638
[201aeb9]639
[413ad05]640PointerType * buildPointer( const TypeData * td ) {
641        PointerType * pt;
642        if ( td->base ) {
643                pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
[b87a5ed]644        } else {
[413ad05]645                pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
[68cd1ce]646        } // if
[413ad05]647        buildForall( td->forall, pt->get_forall() );
[b87a5ed]648        return pt;
[413ad05]649} // buildPointer
[51b7345]650
[201aeb9]651
[413ad05]652ArrayType * buildArray( const TypeData * td ) {
653        ArrayType * at;
654        if ( td->base ) {
[8f6f47d7]655                at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
656                                                        td->array.isVarLen, td->array.isStatic );
[b87a5ed]657        } else {
[413ad05]658                at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
[8f6f47d7]659                                                        maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
[68cd1ce]660        } // if
[413ad05]661        buildForall( td->forall, at->get_forall() );
[b87a5ed]662        return at;
[ce8c12f]663} // buildArray
664
[201aeb9]665
[ce8c12f]666ReferenceType * buildReference( const TypeData * td ) {
667        ReferenceType * rt;
668        if ( td->base ) {
669                rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) );
670        } else {
671                rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
672        } // if
673        buildForall( td->forall, rt->get_forall() );
674        return rt;
675} // buildReference
[51b7345]676
[201aeb9]677
[fa4805f]678AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
[413ad05]679        assert( td->kind == TypeData::Aggregate );
680        AggregateDecl * at;
[8f6f47d7]681        switch ( td->aggregate.kind ) {
[b87a5ed]682          case DeclarationNode::Struct:
[409433da]683          case DeclarationNode::Coroutine:
684          case DeclarationNode::Monitor:
685          case DeclarationNode::Thread:
[fa4805f]686                at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
[8f6f47d7]687                buildForall( td->aggregate.params, at->get_parameters() );
[b87a5ed]688                break;
689          case DeclarationNode::Union:
[bd46af4]690                at = new UnionDecl( *td->aggregate.name, attributes, linkage );
[8f6f47d7]691                buildForall( td->aggregate.params, at->get_parameters() );
[b87a5ed]692                break;
[4040425]693          case DeclarationNode::Trait:
[bd46af4]694                at = new TraitDecl( *td->aggregate.name, attributes, linkage );
[8f6f47d7]695                buildList( td->aggregate.params, at->get_parameters() );
[b87a5ed]696                break;
697          default:
698                assert( false );
[68cd1ce]699        } // switch
[4e06c1e]700
[8f6f47d7]701        buildList( td->aggregate.fields, at->get_members() );
702        at->set_body( td->aggregate.body );
[b87a5ed]703
704        return at;
[413ad05]705} // buildAggregate
[51b7345]706
[201aeb9]707
[fa4805f]708ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
[43c89a7]709        switch ( type->kind ) {
710          case TypeData::Enum: {
711                  if ( type->enumeration.body ) {
[bd46af4]712                          EnumDecl * typedecl = buildEnum( type, attributes, linkage );
[43c89a7]713                          return new EnumInstType( buildQualifiers( type ), typedecl );
714                  } else {
715                          return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
716                  } // if
717          }
718          case TypeData::Aggregate: {
719                  ReferenceToType * ret;
720                  if ( type->aggregate.body ) {
[fa4805f]721                          AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
[43c89a7]722                          switch ( type->aggregate.kind ) {
723                                case DeclarationNode::Struct:
[409433da]724                                case DeclarationNode::Coroutine:
725                                case DeclarationNode::Monitor:
726                                case DeclarationNode::Thread:
[43c89a7]727                                  ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
728                                  break;
729                                case DeclarationNode::Union:
730                                  ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
731                                  break;
732                                case DeclarationNode::Trait:
733                                  assert( false );
734                                  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
735                                  break;
736                                default:
737                                  assert( false );
738                          } // switch
739                  } else {
740                          switch ( type->aggregate.kind ) {
741                                case DeclarationNode::Struct:
[409433da]742                                case DeclarationNode::Coroutine:
743                                case DeclarationNode::Monitor:
744                                case DeclarationNode::Thread:
[43c89a7]745                                  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
746                                  break;
747                                case DeclarationNode::Union:
748                                  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
749                                  break;
750                                case DeclarationNode::Trait:
751                                  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
752                                  break;
753                                default:
754                                  assert( false );
755                          } // switch
756                  } // if
757                  return ret;
758          }
759          default:
760                assert( false );
761        } // switch
762} // buildAggInst
763
[201aeb9]764
[413ad05]765ReferenceToType * buildAggInst( const TypeData * td ) {
766        assert( td->kind == TypeData::AggregateInst );
[b87a5ed]767
[43c89a7]768        // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() );
769        ReferenceToType * ret = nullptr;
770        TypeData * type = td->aggInst.aggregate;
771        switch ( type->kind ) {
772          case TypeData::Enum: {
773                  return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
774          }
775          case TypeData::Aggregate: {
776                  switch ( type->aggregate.kind ) {
777                        case DeclarationNode::Struct:
[409433da]778                        case DeclarationNode::Coroutine:
779                        case DeclarationNode::Monitor:
780                        case DeclarationNode::Thread:
[43c89a7]781                          ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
782                          break;
783                        case DeclarationNode::Union:
784                          ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
785                          break;
786                        case DeclarationNode::Trait:
787                          ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
788                          break;
789                        default:
790                          assert( false );
791                  } // switch
792          }
793          break;
794          default:
795                assert( false );
796        } // switch
797
798        ret->set_hoistType( td->aggInst.hoistType );
[8f6f47d7]799        buildList( td->aggInst.params, ret->get_parameters() );
[413ad05]800        buildForall( td->forall, ret->get_forall() );
[b87a5ed]801        return ret;
[413ad05]802} // buildAggInst
803
[201aeb9]804
[1f370451]805NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
[413ad05]806        assert( td->kind == TypeData::Symbolic );
807        NamedTypeDecl * ret;
808        assert( td->base );
[8f6f47d7]809        if ( td->symbolic.isTypedef ) {
[0b0f1dd]810                ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage );
[b87a5ed]811        } else {
[f0ecf9b]812                ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true );
[68cd1ce]813        } // if
[8f6f47d7]814        buildList( td->symbolic.params, ret->get_parameters() );
815        buildList( td->symbolic.assertions, ret->get_assertions() );
[1f370451]816        ret->base->attributes.splice( ret->base->attributes.end(), attributes );
[b87a5ed]817        return ret;
[413ad05]818} // buildSymbolic
[51b7345]819
[201aeb9]820
[bd46af4]821EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
[413ad05]822        assert( td->kind == TypeData::Enum );
[bd46af4]823        EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage );
[8f6f47d7]824        buildList( td->enumeration.constants, ret->get_members() );
[2298f728]825        list< Declaration * >::iterator members = ret->get_members().begin();
[8f6f47d7]826        for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
[4f147cc]827                if ( cur->has_enumeratorValue() ) {
[413ad05]828                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
[e4d829b]829                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
[90c3b1c]830                } // if
831        } // for
[ca1a547]832        ret->set_body( td->enumeration.body );
[b87a5ed]833        return ret;
[413ad05]834} // buildEnum
[51b7345]835
[201aeb9]836
[413ad05]837TypeInstType * buildSymbolicInst( const TypeData * td ) {
838        assert( td->kind == TypeData::SymbolicInst );
[2298f728]839        TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
[8f6f47d7]840        buildList( td->symbolic.actuals, ret->get_parameters() );
[413ad05]841        buildForall( td->forall, ret->get_forall() );
[b87a5ed]842        return ret;
[413ad05]843} // buildSymbolicInst
[51b7345]844
[201aeb9]845
[413ad05]846TupleType * buildTuple( const TypeData * td ) {
847        assert( td->kind == TypeData::Tuple );
[62423350]848        std::list< Type * > types;
849        buildTypeList( td->tuple, types );
850        TupleType * ret = new TupleType( buildQualifiers( td ), types );
[413ad05]851        buildForall( td->forall, ret->get_forall() );
[b87a5ed]852        return ret;
[413ad05]853} // buildTuple
854
[201aeb9]855
[413ad05]856TypeofType * buildTypeof( const TypeData * td ) {
857        assert( td->kind == TypeData::Typeof );
858        assert( td->typeexpr );
[8f6f47d7]859        // assert( td->typeexpr->expr );
860        return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
[413ad05]861} // buildTypeof
862
[201aeb9]863
[e612146c]864Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
[413ad05]865        if ( td->kind == TypeData::Function ) {
[ca1a547]866                if ( td->function.idList ) {                                    // KR function ?
867                        buildKRFunction( td->function );                        // transform into C11 function
[3a5131ed]868                } // if
869
[413ad05]870                FunctionDecl * decl;
[ca1a547]871                Statement * stmt = maybeBuild<Statement>( td->function.body );
[a7c90d4]872                CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
873                decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
[c453ac4]874                buildList( td->function.withExprs, decl->withExprs );
[58dd019]875                return decl->set_asmName( asmName );
[413ad05]876        } else if ( td->kind == TypeData::Aggregate ) {
[fa4805f]877                return buildAggregate( td, attributes, linkage );
[413ad05]878        } else if ( td->kind == TypeData::Enum ) {
[bd46af4]879                return buildEnum( td, attributes, linkage );
[413ad05]880        } else if ( td->kind == TypeData::Symbolic ) {
[1f370451]881                return buildSymbolic( td, attributes, name, scs, linkage );
[413ad05]882        } else {
[a7c90d4]883                return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName );
[413ad05]884        } // if
[2298f728]885        return nullptr;
[413ad05]886} // buildDecl
887
[201aeb9]888
[413ad05]889FunctionType * buildFunction( const TypeData * td ) {
890        assert( td->kind == TypeData::Function );
[2a8427c6]891        FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
[8f6f47d7]892        buildList( td->function.params, ft->get_parameters() );
[413ad05]893        buildForall( td->forall, ft->get_forall() );
894        if ( td->base ) {
895                switch ( td->base->kind ) {
896                  case TypeData::Tuple:
[8f6f47d7]897                        buildList( td->base->tuple, ft->get_returnVals() );
[413ad05]898                        break;
899                  default:
[ddfd945]900                        ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) );
[413ad05]901                } // switch
902        } else {
[68fe077a]903                ft->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
[413ad05]904        } // if
905        return ft;
906} // buildFunction
[b87a5ed]907
[201aeb9]908
[a7c4921]909// Transform KR routine declarations into C99 routine declarations:
910//
911//    rtn( a, b, c ) int a, c; double b {}  =>  int rtn( int a, double c, int b ) {}
912//
913// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
914// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
915// extra names are disallowed.
916//
917// Note, there is no KR routine-prototype syntax:
918//
919//    rtn( a, b, c ) int a, c; double b; // invalid KR prototype
920//    rtn(); // valid KR prototype
921
[3a5131ed]922void buildKRFunction( const TypeData::Function_t & function ) {
923        assert( ! function.params );
[a7c4921]924        // loop over declaration first as it is easier to spot errors
925        for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = dynamic_cast< DeclarationNode * >( decl->get_next() ) ) {
926                // scan ALL parameter names for each declaration name to check for duplicates
[a7c90d4]927                for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() ) ) {
[3a5131ed]928                        if ( *decl->name == *param->name ) {
[a7c4921]929                                // type set => parameter name already transformed by a declaration names so there is a duplicate
930                                // declaration name attempting a second transformation
[a16764a6]931                                if ( param->type ) SemanticError( param->location, string( "duplicate declaration name " ) + *param->name );
[a7c4921]932                                // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
933                                // parameter name attempting a second transformation
[a16764a6]934                                if ( ! decl->type ) SemanticError( param->location, string( "duplicate parameter name " ) + *param->name );
[a7c4921]935                                param->type = decl->type;                               // set copy declaration type to parameter type
936                                decl->type = nullptr;                                   // reset declaration type
937                                param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter
[3a5131ed]938                        } // if
939                } // for
[a7c4921]940                // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
[a16764a6]941                if ( decl->type ) SemanticError( decl->location, string( "missing name in parameter list " ) + *decl->name );
[3a5131ed]942        } // for
[a7c4921]943
944        // Parameter names without a declaration default to type int:
945        //
946        //    rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
947
[a7c90d4]948        for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() ) ) {
[ca1a547]949                if ( ! param->type ) {                                                  // generate type int for empty parameter type
[3a5131ed]950                        param->type = new TypeData( TypeData::Basic );
951                        param->type->basictype = DeclarationNode::Int;
952                } // if
953        } // for
954
[a7c4921]955        function.params = function.idList;                                      // newly modified idList becomes parameters
956        function.idList = nullptr;                                                      // idList now empty
957        delete function.oldDeclList;                                            // deletes entire list
958        function.oldDeclList = nullptr;                                         // reset
[3a5131ed]959} // buildKRFunction
960
[b87a5ed]961// Local Variables: //
962// tab-width: 4 //
963// mode: c++ //
964// compile-command: "make install" //
965// End: //
Note: See TracBrowser for help on using the repository browser.