source: src/Parser/TypeData.cc @ 8c49c0e

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

decouple code that uses Type's forall list from std::list in preparation for trying to replace with a managed list

  • Property mode set to 100644
File size: 28.4 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
[4e06c1e]11// Last Modified By : Peter A. Buhr
[5b639ee]12// Last Modified On : Mon Sep 12 21:11:22 2016
13// Update Count     : 377
[b87a5ed]14//
15
[51b7345]16#include <cassert>
17#include <algorithm>
18#include <iterator>
[d3b7937]19#include "Common/utility.h"
[51b7345]20#include "TypeData.h"
21#include "SynTree/Type.h"
22#include "SynTree/Declaration.h"
23#include "SynTree/Expression.h"
24#include "SynTree/Statement.h"
[90c3b1c]25#include "SynTree/Initializer.h"
[51b7345]26
[c8ffe20b]27TypeData::TypeData( Kind k ) : kind( k ), base( 0 ), forall( 0 ) {
[b87a5ed]28        switch ( kind ) {
29          case Unknown:
30          case Pointer:
31          case EnumConstant:
32                // nothing else to initialize
33                break;
34          case Basic:
[8f6f47d7]35                // basic = new Basic_t;
[b87a5ed]36                break;
37          case Array:
[8f6f47d7]38                // array = new Array_t;
39                array.dimension = 0;
40                array.isVarLen = false;
41                array.isStatic = false;
[b87a5ed]42                break;
43          case Function:
[8f6f47d7]44                // function = new Function_t;
45                function.params = 0;
46                function.idList = 0;
47                function.oldDeclList = 0;
48                function.body = 0;
49                function.hasBody = false;
50                function.newStyle = false;
[b87a5ed]51                break;
52          case Aggregate:
[8f6f47d7]53                // aggregate = new Aggregate_t;
54                aggregate.params = 0;
55                aggregate.actuals = 0;
56                aggregate.fields = 0;
[b87a5ed]57                break;
58          case AggregateInst:
[8f6f47d7]59                // aggInst = new AggInst_t;
60                aggInst.aggregate = 0;
61                aggInst.params = 0;
[b87a5ed]62                break;
63          case Enum:
[8f6f47d7]64                // enumeration = new Enumeration_t;
65                enumeration.constants = 0;
[b87a5ed]66                break;
67          case Symbolic:
68          case SymbolicInst:
[8f6f47d7]69                // symbolic = new Symbolic_t;
70                symbolic.params = 0;
71                symbolic.actuals = 0;
72                symbolic.assertions = 0;
[b87a5ed]73                break;
74          case Variable:
[8f6f47d7]75                // variable = new Variable_t;
[28307be]76                // variable.tyClass = DeclarationNode::Type;
77                // variable.assertions = 0;
[b87a5ed]78                break;
79          case Tuple:
[8f6f47d7]80                // tuple = new Tuple_t;
81                tuple = nullptr;
[b87a5ed]82                break;
83          case Typeof:
[8f6f47d7]84                // typeexpr = new Typeof_t;
85                typeexpr = nullptr;
[b87a5ed]86                break;
87          case Attr:
[8f6f47d7]88                // attr = new Attr_t;
[28307be]89                // attr.expr = nullptr;
90                // attr.type = nullptr;
91                break;
92          case Builtin:
93                // builtin = new Builtin_t;
[b87a5ed]94                break;
[68cd1ce]95        } // switch
[413ad05]96} // TypeData::TypeData
[51b7345]97
[c8ffe20b]98TypeData::~TypeData() {
[b87a5ed]99        delete base;
100        delete forall;
101
102        switch ( kind ) {
103          case Unknown:
104          case Pointer:
105          case EnumConstant:
106                // nothing to destroy
107                break;
108          case Basic:
[8f6f47d7]109                // delete basic;
[b87a5ed]110                break;
111          case Array:
[8f6f47d7]112                delete array.dimension;
113                // delete array;
[b87a5ed]114                break;
115          case Function:
[8f6f47d7]116                delete function.params;
117                delete function.idList;
118                delete function.oldDeclList;
119                delete function.body;
120                // delete function;
[b87a5ed]121                break;
122          case Aggregate:
[8f6f47d7]123                delete aggregate.params;
124                delete aggregate.actuals;
125                delete aggregate.fields;
126                // delete aggregate;
[b87a5ed]127                break;
128          case AggregateInst:
[8f6f47d7]129                delete aggInst.aggregate;
130                delete aggInst.params;
131                // delete aggInst;
[b87a5ed]132                break;
133          case Enum:
[8f6f47d7]134                delete enumeration.constants;
135                // delete enumeration;
[b87a5ed]136                break;
137          case Symbolic:
138          case SymbolicInst:
[8f6f47d7]139                delete symbolic.params;
140                delete symbolic.actuals;
141                delete symbolic.assertions;
142                // delete symbolic;
[b87a5ed]143                break;
144          case Variable:
[28307be]145                // delete variable.assertions;
[8f6f47d7]146                // delete variable;
[b87a5ed]147                break;
148          case Tuple:
[8f6f47d7]149                // delete tuple->members;
[b87a5ed]150                delete tuple;
151                break;
152          case Typeof:
[8f6f47d7]153                // delete typeexpr->expr;
[b87a5ed]154                delete typeexpr;
155                break;
156          case Attr:
[28307be]157                // delete attr.expr;
158                // delete attr.type;
[8f6f47d7]159                // delete attr;
[b87a5ed]160                break;
[28307be]161          case Builtin:
162                // delete builtin;
163                break;
[68cd1ce]164        } // switch
[413ad05]165} // TypeData::~TypeData
[51b7345]166
[413ad05]167TypeData * TypeData::clone() const {
168        TypeData * newtype = new TypeData( kind );
[b87a5ed]169        newtype->qualifiers = qualifiers;
170        newtype->base = maybeClone( base );
171        newtype->forall = maybeClone( forall );
172
173        switch ( kind ) {
174          case Unknown:
175          case EnumConstant:
176          case Pointer:
177                // nothing else to copy
178                break;
179          case Basic:
[5b639ee]180                newtype->basictype = basictype;
181                newtype->complextype = complextype;
182                newtype->signedness = signedness;
183                newtype->length = length;
[b87a5ed]184                break;
185          case Array:
[8f6f47d7]186                newtype->array.dimension = maybeClone( array.dimension );
187                newtype->array.isVarLen = array.isVarLen;
188                newtype->array.isStatic = array.isStatic;
[b87a5ed]189                break;
190          case Function:
[8f6f47d7]191                newtype->function.params = maybeClone( function.params );
192                newtype->function.idList = maybeClone( function.idList );
193                newtype->function.oldDeclList = maybeClone( function.oldDeclList );
194                newtype->function.body = maybeClone( function.body );
195                newtype->function.hasBody = function.hasBody;
196                newtype->function.newStyle = function.newStyle;
[b87a5ed]197                break;
198          case Aggregate:
[8f6f47d7]199                newtype->aggregate.params = maybeClone( aggregate.params );
200                newtype->aggregate.actuals = maybeClone( aggregate.actuals );
201                newtype->aggregate.fields = maybeClone( aggregate.fields );
202                newtype->aggregate.name = aggregate.name;
203                newtype->aggregate.kind = aggregate.kind;
204                newtype->aggregate.body = aggregate.body;
[b87a5ed]205                break;
206          case AggregateInst:
[8f6f47d7]207                newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
208                newtype->aggInst.params = maybeClone( aggInst.params );
[b87a5ed]209                break;
210          case Enum:
[8f6f47d7]211                newtype->enumeration.name = enumeration.name;
212                newtype->enumeration.constants = maybeClone( enumeration.constants );
[b87a5ed]213                break;
214          case Symbolic:
215          case SymbolicInst:
[8f6f47d7]216                newtype->symbolic.params = maybeClone( symbolic.params );
217                newtype->symbolic.actuals = maybeClone( symbolic.actuals );
218                newtype->symbolic.assertions = maybeClone( symbolic.assertions );
219                newtype->symbolic.isTypedef = symbolic.isTypedef;
220                newtype->symbolic.name = symbolic.name;
[b87a5ed]221                break;
222          case Variable:
[28307be]223                assert( false );
224                // newtype->variable.assertions = maybeClone( variable.assertions );
225                // newtype->variable.name = variable.name;
226                // newtype->variable.tyClass = variable.tyClass;
[b87a5ed]227                break;
228          case Tuple:
[8f6f47d7]229                newtype->tuple = maybeClone( tuple );
[b87a5ed]230                break;
231          case Typeof:
[8f6f47d7]232                newtype->typeexpr = maybeClone( typeexpr );
[b87a5ed]233                break;
[28307be]234          case Attr:
235                assert( false );
236                // newtype->attr.expr = maybeClone( attr.expr );
237                // newtype->attr.type = maybeClone( attr.type );
238                break;
[90c3b1c]239          case Builtin:
[28307be]240                assert( false );
[8f6f47d7]241                // newtype->builtin = builtin;
[90c3b1c]242                break;
[68cd1ce]243        } // switch
[b87a5ed]244        return newtype;
[413ad05]245} // TypeData::clone
[51b7345]246
[c8ffe20b]247void TypeData::print( std::ostream &os, int indent ) const {
[b87a5ed]248        using std::endl;
249        using std::string;
250
[5b639ee]251        for ( int i = 0; i < DeclarationNode::NoQualifier; i += 1 ) {
[c1c1112]252                if ( qualifiers[i] ) os << DeclarationNode::qualifierName[ i ] << ' ';
253        } // for
[b87a5ed]254
255        if ( forall ) {
256                os << "forall " << endl;
[721f17a]257                forall->printList( os, indent + 4 );
[68cd1ce]258        } // if
[b87a5ed]259
260        switch ( kind ) {
261          case Unknown:
262                os << "entity of unknown type ";
263                break;
264          case Pointer:
265                os << "pointer ";
266                if ( base ) {
267                        os << "to ";
268                        base->print( os, indent );
[68cd1ce]269                } // if
[b87a5ed]270                break;
271          case EnumConstant:
272                os << "enumeration constant ";
273                break;
274          case Basic:
[5b639ee]275                if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessName[ signedness ] << " ";
276                if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthName[ length ] << " ";
277                assert( basictype != DeclarationNode::NoBasicType );
278                os << DeclarationNode::basicTypeName[ basictype ] << " ";
279                if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeName[ complextype ] << " ";
[b87a5ed]280                break;
281          case Array:
[8f6f47d7]282                if ( array.isStatic ) {
[b87a5ed]283                        os << "static ";
[68cd1ce]284                } // if
[8f6f47d7]285                if ( array.dimension ) {
[b87a5ed]286                        os << "array of ";
[8f6f47d7]287                        array.dimension->printOneLine( os, indent );
288                } else if ( array.isVarLen ) {
[b87a5ed]289                        os << "variable-length array of ";
290                } else {
291                        os << "open array of ";
[68cd1ce]292                } // if
[b87a5ed]293                if ( base ) {
294                        base->print( os, indent );
[68cd1ce]295                } // if
[b87a5ed]296                break;
297          case Function:
298                os << "function" << endl;
[8f6f47d7]299                if ( function.params ) {
[721f17a]300                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
[8f6f47d7]301                        function.params->printList( os, indent + 4 );
[b87a5ed]302                } else {
[721f17a]303                        os << string( indent + 2, ' ' ) << "with no parameters " << endl;
[68cd1ce]304                } // if
[8f6f47d7]305                if ( function.idList ) {
[721f17a]306                        os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
[8f6f47d7]307                        function.idList->printList( os, indent + 4 );
[68cd1ce]308                } // if
[8f6f47d7]309                if ( function.oldDeclList ) {
[721f17a]310                        os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
[8f6f47d7]311                        function.oldDeclList->printList( os, indent + 4 );
[68cd1ce]312                } // if
[721f17a]313                os << string( indent + 2, ' ' ) << "returning ";
[b87a5ed]314                if ( base ) {
[721f17a]315                        base->print( os, indent + 4 );
[b87a5ed]316                } else {
317                        os << "nothing ";
[68cd1ce]318                } // if
[b87a5ed]319                os << endl;
[8f6f47d7]320                if ( function.hasBody ) {
[721f17a]321                        os << string( indent + 2, ' ' ) << "with body " << endl;
[68cd1ce]322                } // if
[8f6f47d7]323                if ( function.body ) {
324                        function.body->printList( os, indent + 2 );
[68cd1ce]325                } // if
[b87a5ed]326                break;
327          case Aggregate:
[8f6f47d7]328                os << DeclarationNode::aggregateName[ aggregate.kind ] << ' ' << aggregate.name << endl;
329                if ( aggregate.params ) {
[721f17a]330                        os << string( indent + 2, ' ' ) << "with type parameters " << endl;
[8f6f47d7]331                        aggregate.params->printList( os, indent + 4 );
[68cd1ce]332                } // if
[8f6f47d7]333                if ( aggregate.actuals ) {
[721f17a]334                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
[8f6f47d7]335                        aggregate.actuals->printList( os, indent + 4 );
[68cd1ce]336                } // if
[8f6f47d7]337                if ( aggregate.fields ) {
[721f17a]338                        os << string( indent + 2, ' ' ) << "with members " << endl;
[8f6f47d7]339                        aggregate.fields->printList( os, indent + 4 );
[5d125e4]340                } // if
[8f6f47d7]341                if ( aggregate.body ) {
[5d125e4]342                        os << string( indent + 2, ' ' ) << " with body " << endl;
[68cd1ce]343                } // if
[b87a5ed]344                break;
345          case AggregateInst:
[8f6f47d7]346                if ( aggInst.aggregate ) {
[b87a5ed]347                        os << "instance of " ;
[8f6f47d7]348                        aggInst.aggregate->print( os, indent );
[b87a5ed]349                } else {
350                        os << "instance of an unspecified aggregate ";
[68cd1ce]351                } // if
[8f6f47d7]352                if ( aggInst.params ) {
[721f17a]353                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
[8f6f47d7]354                        aggInst.params->printList( os, indent + 2 );
[68cd1ce]355                } // if
[b87a5ed]356                break;
357          case Enum:
358                os << "enumeration ";
[8f6f47d7]359                if ( enumeration.constants ) {
[b87a5ed]360                        os << "with constants" << endl;
[8f6f47d7]361                        enumeration.constants->printList( os, indent + 2 );
[68cd1ce]362                } // if
[b87a5ed]363                break;
364          case SymbolicInst:
[8f6f47d7]365                os << "instance of type " << symbolic.name;
366                if ( symbolic.actuals ) {
[b87a5ed]367                        os << " with parameters" << endl;
[8f6f47d7]368                        symbolic.actuals->printList( os, indent + 2 );
[68cd1ce]369                } // if
[b87a5ed]370                break;
371          case Symbolic:
[8f6f47d7]372                if ( symbolic.isTypedef ) {
[b87a5ed]373                        os << "typedef definition ";
374                } else {
375                        os << "type definition ";
[68cd1ce]376                } // if
[8f6f47d7]377                if ( symbolic.params ) {
[721f17a]378                        os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
[8f6f47d7]379                        symbolic.params->printList( os, indent + 2 );
[68cd1ce]380                } // if
[8f6f47d7]381                if ( symbolic.assertions ) {
[721f17a]382                        os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
[8f6f47d7]383                        symbolic.assertions->printList( os, indent + 4 );
[721f17a]384                        os << string( indent + 2, ' ' );
[68cd1ce]385                } // if
[b87a5ed]386                if ( base ) {
387                        os << "for ";
388                        base->print( os, indent + 2 );
[68cd1ce]389                } // if
[b87a5ed]390                break;
391          case Variable:
[28307be]392                // os << DeclarationNode::typeClassName[ variable.tyClass ] << " variable ";
393                // if ( variable.assertions ) {
394                //      os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
395                //      variable.assertions->printList( os, indent + 4 );
396                //      os << string( indent + 2, ' ' );
397                // } // if
[b87a5ed]398                break;
399          case Tuple:
400                os << "tuple ";
[8f6f47d7]401                if ( tuple ) {
[b87a5ed]402                        os << "with members " << endl;
[8f6f47d7]403                        tuple->printList( os, indent + 2 );
[68cd1ce]404                } // if
[b87a5ed]405                break;
406          case Typeof:
407                os << "type-of expression ";
[8f6f47d7]408                if ( typeexpr ) {
409                        typeexpr->print( os, indent + 2 );
[68cd1ce]410                } // if
[b87a5ed]411                break;
412          case Attr:
[28307be]413                // os << "attribute type decl " << attr.name << " applied to ";
414                // if ( attr.expr ) {
415                //      attr.expr->print( os, indent + 2 );
416                // } // if
417                // if ( attr.type ) {
418                //      attr.type->print( os, indent + 2 );
419                // } // if
[b87a5ed]420                break;
[90c3b1c]421          case Builtin:
422                os << "gcc builtin type";
423                break;
[1db21619]424          default:
[5b639ee]425                os << "internal error: TypeData::print " << kind << endl;
[1db21619]426                assert( false );
[68cd1ce]427        } // switch
[413ad05]428} // TypeData::print
[51b7345]429
[8c49c0e]430template< typename ForallList >
431void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
[b87a5ed]432        buildList( firstNode, outputList );
[8c49c0e]433        for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
434                TypeDecl * td = static_cast<TypeDecl*>(*i);
435                if ( td->get_kind() == TypeDecl::Any ) {
[6943f051]436                        // add assertion parameters to `type' tyvars in reverse order
437                        // add dtor:  void ^?{}(T *)
[413ad05]438                        FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
[8c49c0e]439                        dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), td ) ), 0 ) );
440                        td->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
[4cc4286]441
[a9a259c]442                        // add copy ctor:  void ?{}(T *, T)
[413ad05]443                        FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
[8c49c0e]444                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), td ) ), 0 ) );
445                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), td->get_name(), td ), 0 ) );
446                        td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
[a9a259c]447
[6943f051]448                        // add default ctor:  void ?{}(T *)
[413ad05]449                        FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
[8c49c0e]450                        ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), td ) ), 0 ) );
451                        td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
[6943f051]452
453                        // add assignment operator:  T * ?=?(T *, T)
[413ad05]454                        FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
[8c49c0e]455                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), td ) ), 0 ) );
456                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), td->get_name(), td ), 0 ) );
457                        assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), td->get_name(), td ), 0 ) );
458                        td->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
[68cd1ce]459                } // if
460        } // for
[51b7345]461}
462
[413ad05]463Type * typebuild( const TypeData * td ) {
464        assert( td );
465        switch ( td->kind ) {
466          case TypeData::Unknown:
[b87a5ed]467                // fill in implicit int
[413ad05]468                return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
469          case TypeData::Basic:
470                return buildBasicType( td );
471          case TypeData::Pointer:
472                return buildPointer( td );
473          case TypeData::Array:
474                return buildArray( td );
475          case TypeData::Function:
476                return buildFunction( td );
477          case TypeData::AggregateInst:
478                return buildAggInst( td );
479          case TypeData::EnumConstant:
[b87a5ed]480                // the name gets filled in later -- by SymTab::Validate
[413ad05]481                return new EnumInstType( buildQualifiers( td ), "" );
482          case TypeData::SymbolicInst:
483                return buildSymbolicInst( td );;
484          case TypeData::Tuple:
485                return buildTuple( td );
486          case TypeData::Typeof:
487                return buildTypeof( td );
488          case TypeData::Builtin:
489                return new VarArgsType( buildQualifiers( td ) );
490          case TypeData::Attr:
[28307be]491                assert( false );
[413ad05]492                return buildAttr( td );
493          case TypeData::Symbolic:
494          case TypeData::Enum:
495          case TypeData::Aggregate:
496          case TypeData::Variable:
[b87a5ed]497                assert( false );
[68cd1ce]498        } // switch
[b87a5ed]499        return 0;
[413ad05]500} // typebuild
501
502TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
503        TypeData * ret = 0;
[51b7345]504
[413ad05]505        switch ( td->kind ) {
506          case TypeData::Aggregate:
[8f6f47d7]507                if ( ! toplevel && td->aggregate.fields ) {
[413ad05]508                        ret = td->clone();
509                } // if
510                break;
511          case TypeData::Enum:
[8f6f47d7]512                if ( ! toplevel && td->enumeration.constants ) {
[413ad05]513                        ret = td->clone();
514                } // if
515                break;
516          case TypeData::AggregateInst:
[8f6f47d7]517                if ( td->aggInst.aggregate ) {
518                        ret = typeextractAggregate( td->aggInst.aggregate, false );
[413ad05]519                } // if
520                break;
521          default:
522                if ( td->base ) {
523                        ret = typeextractAggregate( td->base, false );
524                } // if
525        } // switch
526        return ret;
527} // typeextractAggregate
528
529Type::Qualifiers buildQualifiers( const TypeData * td ) {
[b87a5ed]530        Type::Qualifiers q;
[413ad05]531        q.isConst = td->qualifiers[ DeclarationNode::Const ];
532        q.isVolatile = td->qualifiers[ DeclarationNode::Volatile ];
533        q.isRestrict = td->qualifiers[ DeclarationNode::Restrict ];
534        q.isLvalue = td->qualifiers[ DeclarationNode::Lvalue ];
535        q.isAtomic = td->qualifiers[ DeclarationNode::Atomic ];;
[b87a5ed]536        return q;
[413ad05]537} // buildQualifiers
[51b7345]538
[413ad05]539Type * buildBasicType( const TypeData * td ) {
[b87a5ed]540        BasicType::Kind ret;
541
[5b639ee]542        switch ( td->basictype ) {
543          case DeclarationNode::Void:
544                if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) {
545                        throw SemanticError( "invalid type specifier \"void\" in type: ", td );
[68cd1ce]546                } // if
[b87a5ed]547
[5b639ee]548                return new VoidType( buildQualifiers( td ) );
549                break;
550
551          case DeclarationNode::Bool:
552                if ( td->signedness != DeclarationNode::NoSignedness ) {
553                        throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td );
554                } // if
555                if ( td->length != DeclarationNode::NoLength ) {
556                        throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
[68cd1ce]557                } // if
[51b7345]558
[5b639ee]559                ret = BasicType::Bool;
560                break;
561
562          case DeclarationNode::Char:
563                // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
564                // character types. The implementation shall define char to have the same range, representation, and behavior as
565                // either signed char or unsigned char.
[8c49c0e]566                static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
[5b639ee]567
568                if ( td->length != DeclarationNode::NoLength ) {
569                        throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
570                } // if
571
572                ret = chartype[ td->signedness ];
573                break;
574
575          case DeclarationNode::Int:
576                static BasicType::Kind inttype[2][4] = {
577                        { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
578                        { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
579                };
580
581          Integral: ;
582                if ( td->signedness == DeclarationNode::NoSignedness ) {
583                        const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
584                } // if
585                ret = inttype[ td->signedness ][ td->length ];
586                break;
587
588          case DeclarationNode::Float:
589          case DeclarationNode::Double:
590          case DeclarationNode::LongDouble:                                     // not set until below
591                static BasicType::Kind floattype[3][3] = {
592                        { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
593                        { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
594                        { BasicType::Float, BasicType::Double, BasicType::LongDouble },
595                };
596
597          FloatingPoint: ;
598                if ( td->signedness != DeclarationNode::NoSignedness ) {
599                        throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td );
600                } // if
601                if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
602                        throw SemanticError( std::string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
603                } // if
604                if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) {
605                        throw SemanticError( "invalid type specifier \"long\" in type: ", td );
606                } // if
607                if ( td->length == DeclarationNode::Long ) {
608                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
609                } // if
610
611                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
612                break;
613
614          case DeclarationNode::NoBasicType:
615                // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
616                if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
617                        const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
618                        goto FloatingPoint;
619                } // if
620
621                const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
622                goto Integral;
623        } // switch
624
625        BasicType * bt = new BasicType( buildQualifiers( td ), ret );
[413ad05]626        buildForall( td->forall, bt->get_forall() );
[b87a5ed]627        return bt;
[413ad05]628} // buildBasicType
[51b7345]629
[413ad05]630PointerType * buildPointer( const TypeData * td ) {
631        PointerType * pt;
632        if ( td->base ) {
633                pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
[b87a5ed]634        } else {
[413ad05]635                pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
[68cd1ce]636        } // if
[413ad05]637        buildForall( td->forall, pt->get_forall() );
[b87a5ed]638        return pt;
[413ad05]639} // buildPointer
[51b7345]640
[413ad05]641ArrayType * buildArray( const TypeData * td ) {
642        ArrayType * at;
643        if ( td->base ) {
[8f6f47d7]644                at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
645                                                        td->array.isVarLen, td->array.isStatic );
[b87a5ed]646        } else {
[413ad05]647                at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
[8f6f47d7]648                                                        maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
[68cd1ce]649        } // if
[413ad05]650        buildForall( td->forall, at->get_forall() );
[b87a5ed]651        return at;
[413ad05]652} // buildPointer
[51b7345]653
[413ad05]654AggregateDecl * buildAggregate( const TypeData * td ) {
655        assert( td->kind == TypeData::Aggregate );
656        AggregateDecl * at;
[8f6f47d7]657        switch ( td->aggregate.kind ) {
[b87a5ed]658          case DeclarationNode::Struct:
[8f6f47d7]659                at = new StructDecl( td->aggregate.name );
660                buildForall( td->aggregate.params, at->get_parameters() );
[b87a5ed]661                break;
662          case DeclarationNode::Union:
[8f6f47d7]663                at = new UnionDecl( td->aggregate.name );
664                buildForall( td->aggregate.params, at->get_parameters() );
[b87a5ed]665                break;
[4040425]666          case DeclarationNode::Trait:
[8f6f47d7]667                at = new TraitDecl( td->aggregate.name );
668                buildList( td->aggregate.params, at->get_parameters() );
[b87a5ed]669                break;
670          default:
671                assert( false );
[68cd1ce]672        } // switch
[4e06c1e]673
[8f6f47d7]674        buildList( td->aggregate.fields, at->get_members() );
675        at->set_body( td->aggregate.body );
[b87a5ed]676
677        return at;
[413ad05]678} // buildAggregate
[51b7345]679
[413ad05]680ReferenceToType * buildAggInst( const TypeData * td ) {
681        assert( td->kind == TypeData::AggregateInst );
[b87a5ed]682
[413ad05]683        ReferenceToType * ret;
[8f6f47d7]684        if ( td->aggInst.aggregate->kind == TypeData::Enum ) {
685                ret = new EnumInstType( buildQualifiers( td ), td->aggInst.aggregate->enumeration.name );
[b87a5ed]686        } else {
[8f6f47d7]687                assert( td->aggInst.aggregate->kind == TypeData::Aggregate );
688                switch ( td->aggInst.aggregate->aggregate.kind ) {
[b87a5ed]689                  case DeclarationNode::Struct:
[8f6f47d7]690                        ret = new StructInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
[b87a5ed]691                        break;
692                  case DeclarationNode::Union:
[8f6f47d7]693                        ret = new UnionInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
[b87a5ed]694                        break;
[4040425]695                  case DeclarationNode::Trait:
[8f6f47d7]696                        ret = new TraitInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
[b87a5ed]697                        break;
698                  default:
699                        assert( false );
[68cd1ce]700                } // switch
701        } // if
[8f6f47d7]702        buildList( td->aggInst.params, ret->get_parameters() );
[413ad05]703        buildForall( td->forall, ret->get_forall() );
[b87a5ed]704        return ret;
[413ad05]705} // buildAggInst
706
707NamedTypeDecl * buildSymbolic( const TypeData * td, const std::string & name, DeclarationNode::StorageClass sc ) {
708        assert( td->kind == TypeData::Symbolic );
709        NamedTypeDecl * ret;
710        assert( td->base );
[8f6f47d7]711        if ( td->symbolic.isTypedef ) {
[413ad05]712                ret = new TypedefDecl( name, sc, typebuild( td->base ) );
[b87a5ed]713        } else {
[413ad05]714                ret = new TypeDecl( name, sc, typebuild( td->base ), TypeDecl::Any );
[68cd1ce]715        } // if
[8f6f47d7]716        buildList( td->symbolic.params, ret->get_parameters() );
717        buildList( td->symbolic.assertions, ret->get_assertions() );
[b87a5ed]718        return ret;
[413ad05]719} // buildSymbolic
[51b7345]720
[413ad05]721TypeDecl * buildVariable( const TypeData * td ) {
[28307be]722        assert( false );
723        return nullptr;
724        // assert( td->kind == TypeData::Variable );
725        // static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
726
727        // TypeDecl * ret = new TypeDecl( td->variable.name, DeclarationNode::NoStorageClass, 0, kindMap[ td->variable.tyClass ] );
728        // buildList( td->variable.assertions, ret->get_assertions() );
729        // return ret;
[413ad05]730} // buildSymbolic
[51b7345]731
[413ad05]732EnumDecl * buildEnum( const TypeData * td ) {
733        assert( td->kind == TypeData::Enum );
[8f6f47d7]734        EnumDecl * ret = new EnumDecl( td->enumeration.name );
735        buildList( td->enumeration.constants, ret->get_members() );
[90c3b1c]736        std::list< Declaration * >::iterator members = ret->get_members().begin();
[8f6f47d7]737        for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
[4f147cc]738                if ( cur->has_enumeratorValue() ) {
[413ad05]739                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
[4f147cc]740                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), std::list< Expression * >() ) );
[90c3b1c]741                } // if
742        } // for
[b87a5ed]743        return ret;
[413ad05]744} // buildEnum
[51b7345]745
[413ad05]746TypeInstType * buildSymbolicInst( const TypeData * td ) {
747        assert( td->kind == TypeData::SymbolicInst );
[8f6f47d7]748        TypeInstType * ret = new TypeInstType( buildQualifiers( td ), td->symbolic.name, false );
749        buildList( td->symbolic.actuals, ret->get_parameters() );
[413ad05]750        buildForall( td->forall, ret->get_forall() );
[b87a5ed]751        return ret;
[413ad05]752} // buildSymbolicInst
[51b7345]753
[413ad05]754TupleType * buildTuple( const TypeData * td ) {
755        assert( td->kind == TypeData::Tuple );
756        TupleType * ret = new TupleType( buildQualifiers( td ) );
[8f6f47d7]757        buildTypeList( td->tuple, ret->get_types() );
[413ad05]758        buildForall( td->forall, ret->get_forall() );
[b87a5ed]759        return ret;
[413ad05]760} // buildTuple
761
762TypeofType * buildTypeof( const TypeData * td ) {
763        assert( td->kind == TypeData::Typeof );
764        assert( td->typeexpr );
[8f6f47d7]765        // assert( td->typeexpr->expr );
766        return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
[413ad05]767} // buildTypeof
768
769AttrType * buildAttr( const TypeData * td ) {
[28307be]770        assert( false );
771        return nullptr;
772        // assert( td->kind == TypeData::Attr );
773        // // assert( td->attr );
774        // AttrType * ret;
775        // if ( td->attr.expr ) {
776        //      ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.expr->build() );
777        // } else {
778        //      assert( td->attr.type );
779        //      ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.type->buildType() );
780        // } // if
781        // return ret;
[413ad05]782} // buildAttr
783
784Declaration * buildDecl( const TypeData * td, std::string name, DeclarationNode::StorageClass sc, Expression * bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Spec linkage, Initializer * init ) {
785        if ( td->kind == TypeData::Function ) {
786                FunctionDecl * decl;
[8f6f47d7]787                if ( td->function.hasBody ) {
788                        if ( td->function.body ) {
789                                Statement * stmt = td->function.body->build();
[413ad05]790                                CompoundStmt * body = dynamic_cast< CompoundStmt* >( stmt );
791                                assert( body );
792                                decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), body, isInline, isNoreturn );
793                        } else {
794                                // std::list< Label > ls;
795                                decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), new CompoundStmt( std::list< Label >() ), isInline, isNoreturn );
796                        } // if
797                } else {
798                        decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), 0, isInline, isNoreturn );
799                } // if
[8f6f47d7]800                for ( DeclarationNode * cur = td->function.idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_next() ) ) {
[413ad05]801                        if ( cur->get_name() != "" ) {
802                                decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
803                        } // if
804                } // for
[8f6f47d7]805                buildList( td->function.oldDeclList, decl->get_oldDecls() );
[413ad05]806                return decl;
807        } else if ( td->kind == TypeData::Aggregate ) {
808                return buildAggregate( td );
809        } else if ( td->kind == TypeData::Enum ) {
810                return buildEnum( td );
811        } else if ( td->kind == TypeData::Symbolic ) {
812                return buildSymbolic( td, name, sc );
813        } else if ( td->kind == TypeData::Variable ) {
[28307be]814                assert( false );
[413ad05]815                return buildVariable( td );
816        } else {
817                return new ObjectDecl( name, sc, linkage, bitfieldWidth, typebuild( td ), init, std::list< Attribute * >(), isInline, isNoreturn );
818        } // if
819        return 0;
820} // buildDecl
821
822FunctionType * buildFunction( const TypeData * td ) {
823        assert( td->kind == TypeData::Function );
[8f6f47d7]824        bool hasEllipsis = td->function.params ? td->function.params->get_hasEllipsis() : true;
825        if ( ! td->function.params ) hasEllipsis = ! td->function.newStyle;
[413ad05]826        FunctionType * ft = new FunctionType( buildQualifiers( td ), hasEllipsis );
[8f6f47d7]827        buildList( td->function.params, ft->get_parameters() );
[413ad05]828        buildForall( td->forall, ft->get_forall() );
829        if ( td->base ) {
830                switch ( td->base->kind ) {
831                  case TypeData::Tuple:
[8f6f47d7]832                        buildList( td->base->tuple, ft->get_returnVals() );
[413ad05]833                        break;
834                  default:
835                        ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( buildDecl( td->base,  "", DeclarationNode::NoStorageClass, 0, false, false, LinkageSpec::Cforall ) ) );
836                } // switch
837        } else {
838                ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
839        } // if
840        return ft;
841} // buildFunction
[b87a5ed]842
843// Local Variables: //
844// tab-width: 4 //
845// mode: c++ //
846// compile-command: "make install" //
847// End: //
Note: See TracBrowser for help on using the repository browser.