source: src/Parser/TypeData.cc @ 6eb8948

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 6eb8948 was 28307be, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

more refactoring of parser code

  • Property mode set to 100644
File size: 30.2 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
[28307be]12// Last Modified On : Mon Aug 29 22:31:53 2016
13// Update Count     : 277
[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:
[8f6f47d7]180                newtype->basic.typeSpec = basic.typeSpec;
181                newtype->basic.modifiers = basic.modifiers;
[b87a5ed]182                break;
183          case Array:
[8f6f47d7]184                newtype->array.dimension = maybeClone( array.dimension );
185                newtype->array.isVarLen = array.isVarLen;
186                newtype->array.isStatic = array.isStatic;
[b87a5ed]187                break;
188          case Function:
[8f6f47d7]189                newtype->function.params = maybeClone( function.params );
190                newtype->function.idList = maybeClone( function.idList );
191                newtype->function.oldDeclList = maybeClone( function.oldDeclList );
192                newtype->function.body = maybeClone( function.body );
193                newtype->function.hasBody = function.hasBody;
194                newtype->function.newStyle = function.newStyle;
[b87a5ed]195                break;
196          case Aggregate:
[8f6f47d7]197                newtype->aggregate.params = maybeClone( aggregate.params );
198                newtype->aggregate.actuals = maybeClone( aggregate.actuals );
199                newtype->aggregate.fields = maybeClone( aggregate.fields );
200                newtype->aggregate.name = aggregate.name;
201                newtype->aggregate.kind = aggregate.kind;
202                newtype->aggregate.body = aggregate.body;
[b87a5ed]203                break;
204          case AggregateInst:
[8f6f47d7]205                newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
206                newtype->aggInst.params = maybeClone( aggInst.params );
[b87a5ed]207                break;
208          case Enum:
[8f6f47d7]209                newtype->enumeration.name = enumeration.name;
210                newtype->enumeration.constants = maybeClone( enumeration.constants );
[b87a5ed]211                break;
212          case Symbolic:
213          case SymbolicInst:
[8f6f47d7]214                newtype->symbolic.params = maybeClone( symbolic.params );
215                newtype->symbolic.actuals = maybeClone( symbolic.actuals );
216                newtype->symbolic.assertions = maybeClone( symbolic.assertions );
217                newtype->symbolic.isTypedef = symbolic.isTypedef;
218                newtype->symbolic.name = symbolic.name;
[b87a5ed]219                break;
220          case Variable:
[28307be]221                assert( false );
222                // newtype->variable.assertions = maybeClone( variable.assertions );
223                // newtype->variable.name = variable.name;
224                // newtype->variable.tyClass = variable.tyClass;
[b87a5ed]225                break;
226          case Tuple:
[8f6f47d7]227                newtype->tuple = maybeClone( tuple );
[b87a5ed]228                break;
229          case Typeof:
[8f6f47d7]230                newtype->typeexpr = maybeClone( typeexpr );
[b87a5ed]231                break;
[28307be]232          case Attr:
233                assert( false );
234                // newtype->attr.expr = maybeClone( attr.expr );
235                // newtype->attr.type = maybeClone( attr.type );
236                break;
[90c3b1c]237          case Builtin:
[28307be]238                assert( false );
[8f6f47d7]239                // newtype->builtin = builtin;
[90c3b1c]240                break;
[68cd1ce]241        } // switch
[b87a5ed]242        return newtype;
[413ad05]243} // TypeData::clone
[51b7345]244
[c8ffe20b]245void TypeData::print( std::ostream &os, int indent ) const {
[b87a5ed]246        using std::endl;
247        using std::string;
248
[c1c1112]249        for ( int i = 0; i < DeclarationNode::NoOfQualifier; i += 1 ) {
250                if ( qualifiers[i] ) os << DeclarationNode::qualifierName[ i ] << ' ';
251        } // for
[b87a5ed]252
253        if ( forall ) {
254                os << "forall " << endl;
[721f17a]255                forall->printList( os, indent + 4 );
[68cd1ce]256        } // if
[b87a5ed]257
258        switch ( kind ) {
259          case Unknown:
260                os << "entity of unknown type ";
261                break;
262          case Pointer:
263                os << "pointer ";
264                if ( base ) {
265                        os << "to ";
266                        base->print( os, indent );
[68cd1ce]267                } // if
[b87a5ed]268                break;
269          case EnumConstant:
270                os << "enumeration constant ";
271                break;
272          case Basic:
[8f6f47d7]273                printEnums( basic.modifiers.begin(), basic.modifiers.end(), DeclarationNode::modifierName, os );
274                printEnums( basic.typeSpec.begin(), basic.typeSpec.end(), DeclarationNode::basicTypeName, os );
[b87a5ed]275                break;
276          case Array:
[8f6f47d7]277                if ( array.isStatic ) {
[b87a5ed]278                        os << "static ";
[68cd1ce]279                } // if
[8f6f47d7]280                if ( array.dimension ) {
[b87a5ed]281                        os << "array of ";
[8f6f47d7]282                        array.dimension->printOneLine( os, indent );
283                } else if ( array.isVarLen ) {
[b87a5ed]284                        os << "variable-length array of ";
285                } else {
286                        os << "open array of ";
[68cd1ce]287                } // if
[b87a5ed]288                if ( base ) {
289                        base->print( os, indent );
[68cd1ce]290                } // if
[b87a5ed]291                break;
292          case Function:
293                os << "function" << endl;
[8f6f47d7]294                if ( function.params ) {
[721f17a]295                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
[8f6f47d7]296                        function.params->printList( os, indent + 4 );
[b87a5ed]297                } else {
[721f17a]298                        os << string( indent + 2, ' ' ) << "with no parameters " << endl;
[68cd1ce]299                } // if
[8f6f47d7]300                if ( function.idList ) {
[721f17a]301                        os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
[8f6f47d7]302                        function.idList->printList( os, indent + 4 );
[68cd1ce]303                } // if
[8f6f47d7]304                if ( function.oldDeclList ) {
[721f17a]305                        os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
[8f6f47d7]306                        function.oldDeclList->printList( os, indent + 4 );
[68cd1ce]307                } // if
[721f17a]308                os << string( indent + 2, ' ' ) << "returning ";
[b87a5ed]309                if ( base ) {
[721f17a]310                        base->print( os, indent + 4 );
[b87a5ed]311                } else {
312                        os << "nothing ";
[68cd1ce]313                } // if
[b87a5ed]314                os << endl;
[8f6f47d7]315                if ( function.hasBody ) {
[721f17a]316                        os << string( indent + 2, ' ' ) << "with body " << endl;
[68cd1ce]317                } // if
[8f6f47d7]318                if ( function.body ) {
319                        function.body->printList( os, indent + 2 );
[68cd1ce]320                } // if
[b87a5ed]321                break;
322          case Aggregate:
[8f6f47d7]323                os << DeclarationNode::aggregateName[ aggregate.kind ] << ' ' << aggregate.name << endl;
324                if ( aggregate.params ) {
[721f17a]325                        os << string( indent + 2, ' ' ) << "with type parameters " << endl;
[8f6f47d7]326                        aggregate.params->printList( os, indent + 4 );
[68cd1ce]327                } // if
[8f6f47d7]328                if ( aggregate.actuals ) {
[721f17a]329                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
[8f6f47d7]330                        aggregate.actuals->printList( os, indent + 4 );
[68cd1ce]331                } // if
[8f6f47d7]332                if ( aggregate.fields ) {
[721f17a]333                        os << string( indent + 2, ' ' ) << "with members " << endl;
[8f6f47d7]334                        aggregate.fields->printList( os, indent + 4 );
[5d125e4]335                } // if
[8f6f47d7]336                if ( aggregate.body ) {
[5d125e4]337                        os << string( indent + 2, ' ' ) << " with body " << endl;
[68cd1ce]338                } // if
[b87a5ed]339                break;
340          case AggregateInst:
[8f6f47d7]341                if ( aggInst.aggregate ) {
[b87a5ed]342                        os << "instance of " ;
[8f6f47d7]343                        aggInst.aggregate->print( os, indent );
[b87a5ed]344                } else {
345                        os << "instance of an unspecified aggregate ";
[68cd1ce]346                } // if
[8f6f47d7]347                if ( aggInst.params ) {
[721f17a]348                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
[8f6f47d7]349                        aggInst.params->printList( os, indent + 2 );
[68cd1ce]350                } // if
[b87a5ed]351                break;
352          case Enum:
353                os << "enumeration ";
[8f6f47d7]354                if ( enumeration.constants ) {
[b87a5ed]355                        os << "with constants" << endl;
[8f6f47d7]356                        enumeration.constants->printList( os, indent + 2 );
[68cd1ce]357                } // if
[b87a5ed]358                break;
359          case SymbolicInst:
[8f6f47d7]360                os << "instance of type " << symbolic.name;
361                if ( symbolic.actuals ) {
[b87a5ed]362                        os << " with parameters" << endl;
[8f6f47d7]363                        symbolic.actuals->printList( os, indent + 2 );
[68cd1ce]364                } // if
[b87a5ed]365                break;
366          case Symbolic:
[8f6f47d7]367                if ( symbolic.isTypedef ) {
[b87a5ed]368                        os << "typedef definition ";
369                } else {
370                        os << "type definition ";
[68cd1ce]371                } // if
[8f6f47d7]372                if ( symbolic.params ) {
[721f17a]373                        os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
[8f6f47d7]374                        symbolic.params->printList( os, indent + 2 );
[68cd1ce]375                } // if
[8f6f47d7]376                if ( symbolic.assertions ) {
[721f17a]377                        os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
[8f6f47d7]378                        symbolic.assertions->printList( os, indent + 4 );
[721f17a]379                        os << string( indent + 2, ' ' );
[68cd1ce]380                } // if
[b87a5ed]381                if ( base ) {
382                        os << "for ";
383                        base->print( os, indent + 2 );
[68cd1ce]384                } // if
[b87a5ed]385                break;
386          case Variable:
[28307be]387                // os << DeclarationNode::typeClassName[ variable.tyClass ] << " variable ";
388                // if ( variable.assertions ) {
389                //      os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
390                //      variable.assertions->printList( os, indent + 4 );
391                //      os << string( indent + 2, ' ' );
392                // } // if
[b87a5ed]393                break;
394          case Tuple:
395                os << "tuple ";
[8f6f47d7]396                if ( tuple ) {
[b87a5ed]397                        os << "with members " << endl;
[8f6f47d7]398                        tuple->printList( os, indent + 2 );
[68cd1ce]399                } // if
[b87a5ed]400                break;
401          case Typeof:
402                os << "type-of expression ";
[8f6f47d7]403                if ( typeexpr ) {
404                        typeexpr->print( os, indent + 2 );
[68cd1ce]405                } // if
[b87a5ed]406                break;
407          case Attr:
[28307be]408                // os << "attribute type decl " << attr.name << " applied to ";
409                // if ( attr.expr ) {
410                //      attr.expr->print( os, indent + 2 );
411                // } // if
412                // if ( attr.type ) {
413                //      attr.type->print( os, indent + 2 );
414                // } // if
[b87a5ed]415                break;
[90c3b1c]416          case Builtin:
417                os << "gcc builtin type";
418                break;
[1db21619]419          default:
420                os << "internal error: TypeData::print " << kind  << endl;
421                assert( false );
[68cd1ce]422        } // switch
[413ad05]423} // TypeData::print
[51b7345]424
[413ad05]425void buildForall( const DeclarationNode * firstNode, std::list< TypeDecl* > &outputList ) {
[b87a5ed]426        buildList( firstNode, outputList );
427        for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
428                if ( (*i)->get_kind() == TypeDecl::Any ) {
[6943f051]429                        // add assertion parameters to `type' tyvars in reverse order
430                        // add dtor:  void ^?{}(T *)
[413ad05]431                        FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
[6943f051]432                        dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
433                        (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
[4cc4286]434
[a9a259c]435                        // add copy ctor:  void ?{}(T *, T)
[413ad05]436                        FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
[a9a259c]437                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
438                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
439                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
440
[6943f051]441                        // add default ctor:  void ?{}(T *)
[413ad05]442                        FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
[6943f051]443                        ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
444                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
445
446                        // add assignment operator:  T * ?=?(T *, T)
[413ad05]447                        FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
[6943f051]448                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
449                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
450                        assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
451                        (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
[68cd1ce]452                } // if
453        } // for
[51b7345]454}
455
[413ad05]456Type * typebuild( const TypeData * td ) {
457        assert( td );
458        switch ( td->kind ) {
459          case TypeData::Unknown:
[b87a5ed]460                // fill in implicit int
[413ad05]461                return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
462          case TypeData::Basic:
463                return buildBasicType( td );
464          case TypeData::Pointer:
465                return buildPointer( td );
466          case TypeData::Array:
467                return buildArray( td );
468          case TypeData::Function:
469                return buildFunction( td );
470          case TypeData::AggregateInst:
471                return buildAggInst( td );
472          case TypeData::EnumConstant:
[b87a5ed]473                // the name gets filled in later -- by SymTab::Validate
[413ad05]474                return new EnumInstType( buildQualifiers( td ), "" );
475          case TypeData::SymbolicInst:
476                return buildSymbolicInst( td );;
477          case TypeData::Tuple:
478                return buildTuple( td );
479          case TypeData::Typeof:
480                return buildTypeof( td );
481          case TypeData::Builtin:
482                return new VarArgsType( buildQualifiers( td ) );
483          case TypeData::Attr:
[28307be]484                assert( false );
[413ad05]485                return buildAttr( td );
486          case TypeData::Symbolic:
487          case TypeData::Enum:
488          case TypeData::Aggregate:
489          case TypeData::Variable:
[b87a5ed]490                assert( false );
[68cd1ce]491        } // switch
[b87a5ed]492        return 0;
[413ad05]493} // typebuild
494
495TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
496        TypeData * ret = 0;
[51b7345]497
[413ad05]498        switch ( td->kind ) {
499          case TypeData::Aggregate:
[8f6f47d7]500                if ( ! toplevel && td->aggregate.fields ) {
[413ad05]501                        ret = td->clone();
502                } // if
503                break;
504          case TypeData::Enum:
[8f6f47d7]505                if ( ! toplevel && td->enumeration.constants ) {
[413ad05]506                        ret = td->clone();
507                } // if
508                break;
509          case TypeData::AggregateInst:
[8f6f47d7]510                if ( td->aggInst.aggregate ) {
511                        ret = typeextractAggregate( td->aggInst.aggregate, false );
[413ad05]512                } // if
513                break;
514          default:
515                if ( td->base ) {
516                        ret = typeextractAggregate( td->base, false );
517                } // if
518        } // switch
519        return ret;
520} // typeextractAggregate
521
522Type::Qualifiers buildQualifiers( const TypeData * td ) {
[b87a5ed]523        Type::Qualifiers q;
[413ad05]524        q.isConst = td->qualifiers[ DeclarationNode::Const ];
525        q.isVolatile = td->qualifiers[ DeclarationNode::Volatile ];
526        q.isRestrict = td->qualifiers[ DeclarationNode::Restrict ];
527        q.isLvalue = td->qualifiers[ DeclarationNode::Lvalue ];
528        q.isAtomic = td->qualifiers[ DeclarationNode::Atomic ];;
[b87a5ed]529        return q;
[413ad05]530} // buildQualifiers
[51b7345]531
[413ad05]532Type * buildBasicType( const TypeData * td ) {
[b87a5ed]533        static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
534                                                                                           BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
535                                                                                           BasicType::DoubleImaginary };
536        bool init = false;
537        bool sawDouble = false;
538        bool sawSigned = false;
539        BasicType::Kind ret;
540
[8f6f47d7]541        for ( std::list< DeclarationNode::BasicType >::const_iterator i = td->basic.typeSpec.begin(); i != td->basic.typeSpec.end(); ++i ) {
[a32b204]542                if ( ! init ) {
[b87a5ed]543                        init = true;
544                        if ( *i == DeclarationNode::Void ) {
[8f6f47d7]545                                if ( td->basic.typeSpec.size() != 1 || ! td->basic.modifiers.empty() ) {
[413ad05]546                                        throw SemanticError( "invalid type specifier \"void\" in type: ", td );
[b87a5ed]547                                } else {
[413ad05]548                                        return new VoidType( buildQualifiers( td ) );
[68cd1ce]549                                } // if
[b87a5ed]550                        } else {
551                                ret = kindMap[ *i ];
[68cd1ce]552                        } // if
[c8ffe20b]553                } else {
[b87a5ed]554                        switch ( *i ) {
555                          case DeclarationNode::Float:
556                                if ( sawDouble ) {
[413ad05]557                                        throw SemanticError( "invalid type specifier \"float\" in type: ", td );
[b87a5ed]558                                } else {
559                                        switch ( ret ) {
560                                          case BasicType::DoubleComplex:
561                                                ret = BasicType::FloatComplex;
562                                                break;
563                                          case BasicType::DoubleImaginary:
564                                                ret = BasicType::FloatImaginary;
565                                                break;
566                                          default:
[413ad05]567                                                throw SemanticError( "invalid type specifier \"float\" in type: ", td );
[68cd1ce]568                                        } // switch
569                                } // if
[b87a5ed]570                                break;
571                          case DeclarationNode::Double:
572                                if ( sawDouble ) {
[413ad05]573                                        throw SemanticError( "duplicate type specifier \"double\" in type: ", td );
[b87a5ed]574                                } else {
575                                        switch ( ret ) {
576                                          case BasicType::DoubleComplex:
577                                          case BasicType::DoubleImaginary:
578                                                break;
579                                          default:
[413ad05]580                                                throw SemanticError( "invalid type specifier \"double\" in type: ", td );
[68cd1ce]581                                        } // switch
582                                } // if
[b87a5ed]583                                break;
584                          case DeclarationNode::Complex:
585                                switch ( ret ) {
586                                  case BasicType::Float:
587                                        ret = BasicType::FloatComplex;
588                                        break;
589                                  case BasicType::Double:
590                                        ret = BasicType::DoubleComplex;
591                                        break;
592                                  default:
[413ad05]593                                        throw SemanticError( "invalid type specifier \"_Complex\" in type: ", td );
[68cd1ce]594                                } // switch
[b87a5ed]595                                break;
596                          case DeclarationNode::Imaginary:
597                                switch ( ret ) {
598                                  case BasicType::Float:
599                                        ret = BasicType::FloatImaginary;
600                                        break;
601                                  case BasicType::Double:
602                                        ret = BasicType::DoubleImaginary;
603                                        break;
604                                  default:
[413ad05]605                                        throw SemanticError( "invalid type specifier \"_Imaginary\" in type: ", td );
[68cd1ce]606                                } // switch
[b87a5ed]607                                break;
608                          default:
[413ad05]609                                throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type: ", td );
[68cd1ce]610                        } // switch
611                } // if
[b87a5ed]612                if ( *i == DeclarationNode::Double ) {
613                        sawDouble = true;
[68cd1ce]614                } // if
615        } // for
[b87a5ed]616
[8f6f47d7]617        for ( std::list< DeclarationNode::Modifier >::const_iterator i = td->basic.modifiers.begin(); i != td->basic.modifiers.end(); ++i ) {
[b87a5ed]618                switch ( *i ) {
619                  case DeclarationNode::Long:
[a32b204]620                        if ( ! init ) {
[b87a5ed]621                                init = true;
622                                ret = BasicType::LongSignedInt;
623                        } else {
624                                switch ( ret ) {
625                                  case BasicType::SignedInt:
626                                        ret = BasicType::LongSignedInt;
627                                        break;
628                                  case BasicType::UnsignedInt:
629                                        ret = BasicType::LongUnsignedInt;
630                                        break;
631                                  case BasicType::LongSignedInt:
632                                        ret = BasicType::LongLongSignedInt;
633                                        break;
634                                  case BasicType::LongUnsignedInt:
635                                        ret = BasicType::LongLongUnsignedInt;
636                                        break;
637                                  case BasicType::Double:
638                                        ret = BasicType::LongDouble;
639                                        break;
640                                  case BasicType::DoubleComplex:
641                                        ret = BasicType::LongDoubleComplex;
642                                        break;
643                                  case BasicType::DoubleImaginary:
644                                        ret = BasicType::LongDoubleImaginary;
645                                        break;
646                                  default:
[413ad05]647                                        throw SemanticError( "invalid type modifier \"long\" in type: ", td );
[68cd1ce]648                                } // switch
649                        } // if
[c8ffe20b]650                        break;
[b87a5ed]651                  case DeclarationNode::Short:
[a32b204]652                        if ( ! init ) {
[b87a5ed]653                                init = true;
654                                ret = BasicType::ShortSignedInt;
655                        } else {
656                                switch ( ret ) {
657                                  case BasicType::SignedInt:
658                                        ret = BasicType::ShortSignedInt;
659                                        break;
660                                  case BasicType::UnsignedInt:
661                                        ret = BasicType::ShortUnsignedInt;
662                                        break;
663                                  default:
[413ad05]664                                        throw SemanticError( "invalid type modifier \"short\" in type: ", td );
[68cd1ce]665                                } // switch
666                        } // if
[c8ffe20b]667                        break;
[b87a5ed]668                  case DeclarationNode::Signed:
[a32b204]669                        if ( ! init ) {
[b87a5ed]670                                init = true;
671                                ret = BasicType::SignedInt;
672                        } else if ( sawSigned ) {
[413ad05]673                                throw SemanticError( "duplicate type modifer \"signed\" in type: ", td );
[b87a5ed]674                        } else {
675                                switch ( ret ) {
[59db689]676                                  case BasicType::LongLongSignedInt:
[b87a5ed]677                                        ret = BasicType::LongLongUnsignedInt;
678                                        break;
679                                  case BasicType::LongSignedInt:
680                                        ret = BasicType::LongUnsignedInt;
681                                        break;
682                                  case BasicType::SignedInt:
683                                  case BasicType::ShortSignedInt:
684                                        break;
685                                  case BasicType::Char:
686                                        ret = BasicType::SignedChar;
687                                        break;
688                                  default:
[413ad05]689                                        throw SemanticError( "invalid type modifer \"signed\" in type: ", td );
[68cd1ce]690                                } // switch
691                        } // if
[b87a5ed]692                        break;
693                  case DeclarationNode::Unsigned:
[a32b204]694                        if ( ! init ) {
[b87a5ed]695                                init = true;
696                                ret = BasicType::UnsignedInt;
697                        } else if ( sawSigned ) {
[413ad05]698                                throw SemanticError( "invalid type modifer \"unsigned\" in type: ", td );
[b87a5ed]699                        } else {
700                                switch ( ret ) {
[59db689]701                                  case BasicType::LongLongSignedInt:
[b87a5ed]702                                        ret = BasicType::LongLongUnsignedInt;
703                                        break;
704                                  case BasicType::LongSignedInt:
705                                        ret = BasicType::LongUnsignedInt;
706                                        break;
707                                  case BasicType::SignedInt:
708                                        ret = BasicType::UnsignedInt;
709                                        break;
710                                  case BasicType::ShortSignedInt:
711                                        ret = BasicType::ShortUnsignedInt;
712                                        break;
713                                  case BasicType::Char:
714                                        ret = BasicType::UnsignedChar;
715                                        break;
716                                  default:
[413ad05]717                                        throw SemanticError( "invalid type modifer \"unsigned\" in type: ", td );
[68cd1ce]718                                } // switch
719                        } // if
[c8ffe20b]720                        break;
[68cd1ce]721                } // switch
[b87a5ed]722
723                if ( *i == DeclarationNode::Signed ) {
724                        sawSigned = true;
[68cd1ce]725                } // if
726        } // for
[51b7345]727
[413ad05]728        BasicType * bt;
[a32b204]729        if ( ! init ) {
[413ad05]730                bt = new BasicType( buildQualifiers( td ), BasicType::SignedInt );
[b87a5ed]731        } else {
[413ad05]732                bt = new BasicType( buildQualifiers( td ), ret );
[68cd1ce]733        } // if
[413ad05]734        buildForall( td->forall, bt->get_forall() );
[b87a5ed]735        return bt;
[413ad05]736} // buildBasicType
[51b7345]737
[413ad05]738PointerType * buildPointer( const TypeData * td ) {
739        PointerType * pt;
740        if ( td->base ) {
741                pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
[b87a5ed]742        } else {
[413ad05]743                pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
[68cd1ce]744        } // if
[413ad05]745        buildForall( td->forall, pt->get_forall() );
[b87a5ed]746        return pt;
[413ad05]747} // buildPointer
[51b7345]748
[413ad05]749ArrayType * buildArray( const TypeData * td ) {
750        ArrayType * at;
751        if ( td->base ) {
[8f6f47d7]752                at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
753                                                        td->array.isVarLen, td->array.isStatic );
[b87a5ed]754        } else {
[413ad05]755                at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
[8f6f47d7]756                                                        maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
[68cd1ce]757        } // if
[413ad05]758        buildForall( td->forall, at->get_forall() );
[b87a5ed]759        return at;
[413ad05]760} // buildPointer
[51b7345]761
[413ad05]762AggregateDecl * buildAggregate( const TypeData * td ) {
763        assert( td->kind == TypeData::Aggregate );
764        AggregateDecl * at;
[8f6f47d7]765        switch ( td->aggregate.kind ) {
[b87a5ed]766          case DeclarationNode::Struct:
[8f6f47d7]767                at = new StructDecl( td->aggregate.name );
768                buildForall( td->aggregate.params, at->get_parameters() );
[b87a5ed]769                break;
770          case DeclarationNode::Union:
[8f6f47d7]771                at = new UnionDecl( td->aggregate.name );
772                buildForall( td->aggregate.params, at->get_parameters() );
[b87a5ed]773                break;
[4040425]774          case DeclarationNode::Trait:
[8f6f47d7]775                at = new TraitDecl( td->aggregate.name );
776                buildList( td->aggregate.params, at->get_parameters() );
[b87a5ed]777                break;
778          default:
779                assert( false );
[68cd1ce]780        } // switch
[4e06c1e]781
[8f6f47d7]782        buildList( td->aggregate.fields, at->get_members() );
783        at->set_body( td->aggregate.body );
[b87a5ed]784
785        return at;
[413ad05]786} // buildAggregate
[51b7345]787
[413ad05]788ReferenceToType * buildAggInst( const TypeData * td ) {
789        assert( td->kind == TypeData::AggregateInst );
[b87a5ed]790
[413ad05]791        ReferenceToType * ret;
[8f6f47d7]792        if ( td->aggInst.aggregate->kind == TypeData::Enum ) {
793                ret = new EnumInstType( buildQualifiers( td ), td->aggInst.aggregate->enumeration.name );
[b87a5ed]794        } else {
[8f6f47d7]795                assert( td->aggInst.aggregate->kind == TypeData::Aggregate );
796                switch ( td->aggInst.aggregate->aggregate.kind ) {
[b87a5ed]797                  case DeclarationNode::Struct:
[8f6f47d7]798                        ret = new StructInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
[b87a5ed]799                        break;
800                  case DeclarationNode::Union:
[8f6f47d7]801                        ret = new UnionInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
[b87a5ed]802                        break;
[4040425]803                  case DeclarationNode::Trait:
[8f6f47d7]804                        ret = new TraitInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
[b87a5ed]805                        break;
806                  default:
807                        assert( false );
[68cd1ce]808                } // switch
809        } // if
[8f6f47d7]810        buildList( td->aggInst.params, ret->get_parameters() );
[413ad05]811        buildForall( td->forall, ret->get_forall() );
[b87a5ed]812        return ret;
[413ad05]813} // buildAggInst
814
815NamedTypeDecl * buildSymbolic( const TypeData * td, const std::string & name, DeclarationNode::StorageClass sc ) {
816        assert( td->kind == TypeData::Symbolic );
817        NamedTypeDecl * ret;
818        assert( td->base );
[8f6f47d7]819        if ( td->symbolic.isTypedef ) {
[413ad05]820                ret = new TypedefDecl( name, sc, typebuild( td->base ) );
[b87a5ed]821        } else {
[413ad05]822                ret = new TypeDecl( name, sc, typebuild( td->base ), TypeDecl::Any );
[68cd1ce]823        } // if
[8f6f47d7]824        buildList( td->symbolic.params, ret->get_parameters() );
825        buildList( td->symbolic.assertions, ret->get_assertions() );
[b87a5ed]826        return ret;
[413ad05]827} // buildSymbolic
[51b7345]828
[413ad05]829TypeDecl * buildVariable( const TypeData * td ) {
[28307be]830        assert( false );
831        return nullptr;
832        // assert( td->kind == TypeData::Variable );
833        // static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
834
835        // TypeDecl * ret = new TypeDecl( td->variable.name, DeclarationNode::NoStorageClass, 0, kindMap[ td->variable.tyClass ] );
836        // buildList( td->variable.assertions, ret->get_assertions() );
837        // return ret;
[413ad05]838} // buildSymbolic
[51b7345]839
[413ad05]840EnumDecl * buildEnum( const TypeData * td ) {
841        assert( td->kind == TypeData::Enum );
[8f6f47d7]842        EnumDecl * ret = new EnumDecl( td->enumeration.name );
843        buildList( td->enumeration.constants, ret->get_members() );
[90c3b1c]844        std::list< Declaration * >::iterator members = ret->get_members().begin();
[8f6f47d7]845        for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
[4f147cc]846                if ( cur->has_enumeratorValue() ) {
[413ad05]847                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
[4f147cc]848                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), std::list< Expression * >() ) );
[90c3b1c]849                } // if
850        } // for
[b87a5ed]851        return ret;
[413ad05]852} // buildEnum
[51b7345]853
[413ad05]854TypeInstType * buildSymbolicInst( const TypeData * td ) {
855        assert( td->kind == TypeData::SymbolicInst );
[8f6f47d7]856        TypeInstType * ret = new TypeInstType( buildQualifiers( td ), td->symbolic.name, false );
857        buildList( td->symbolic.actuals, ret->get_parameters() );
[413ad05]858        buildForall( td->forall, ret->get_forall() );
[b87a5ed]859        return ret;
[413ad05]860} // buildSymbolicInst
[51b7345]861
[413ad05]862TupleType * buildTuple( const TypeData * td ) {
863        assert( td->kind == TypeData::Tuple );
864        TupleType * ret = new TupleType( buildQualifiers( td ) );
[8f6f47d7]865        buildTypeList( td->tuple, ret->get_types() );
[413ad05]866        buildForall( td->forall, ret->get_forall() );
[b87a5ed]867        return ret;
[413ad05]868} // buildTuple
869
870TypeofType * buildTypeof( const TypeData * td ) {
871        assert( td->kind == TypeData::Typeof );
872        assert( td->typeexpr );
[8f6f47d7]873        // assert( td->typeexpr->expr );
874        return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
[413ad05]875} // buildTypeof
876
877AttrType * buildAttr( const TypeData * td ) {
[28307be]878        assert( false );
879        return nullptr;
880        // assert( td->kind == TypeData::Attr );
881        // // assert( td->attr );
882        // AttrType * ret;
883        // if ( td->attr.expr ) {
884        //      ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.expr->build() );
885        // } else {
886        //      assert( td->attr.type );
887        //      ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.type->buildType() );
888        // } // if
889        // return ret;
[413ad05]890} // buildAttr
891
892Declaration * buildDecl( const TypeData * td, std::string name, DeclarationNode::StorageClass sc, Expression * bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Spec linkage, Initializer * init ) {
893        if ( td->kind == TypeData::Function ) {
894                FunctionDecl * decl;
[8f6f47d7]895                if ( td->function.hasBody ) {
896                        if ( td->function.body ) {
897                                Statement * stmt = td->function.body->build();
[413ad05]898                                CompoundStmt * body = dynamic_cast< CompoundStmt* >( stmt );
899                                assert( body );
900                                decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), body, isInline, isNoreturn );
901                        } else {
902                                // std::list< Label > ls;
903                                decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), new CompoundStmt( std::list< Label >() ), isInline, isNoreturn );
904                        } // if
905                } else {
906                        decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), 0, isInline, isNoreturn );
907                } // if
[8f6f47d7]908                for ( DeclarationNode * cur = td->function.idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_next() ) ) {
[413ad05]909                        if ( cur->get_name() != "" ) {
910                                decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
911                        } // if
912                } // for
[8f6f47d7]913                buildList( td->function.oldDeclList, decl->get_oldDecls() );
[413ad05]914                return decl;
915        } else if ( td->kind == TypeData::Aggregate ) {
916                return buildAggregate( td );
917        } else if ( td->kind == TypeData::Enum ) {
918                return buildEnum( td );
919        } else if ( td->kind == TypeData::Symbolic ) {
920                return buildSymbolic( td, name, sc );
921        } else if ( td->kind == TypeData::Variable ) {
[28307be]922                assert( false );
[413ad05]923                return buildVariable( td );
924        } else {
925                return new ObjectDecl( name, sc, linkage, bitfieldWidth, typebuild( td ), init, std::list< Attribute * >(), isInline, isNoreturn );
926        } // if
927        return 0;
928} // buildDecl
929
930FunctionType * buildFunction( const TypeData * td ) {
931        assert( td->kind == TypeData::Function );
[8f6f47d7]932        bool hasEllipsis = td->function.params ? td->function.params->get_hasEllipsis() : true;
933        if ( ! td->function.params ) hasEllipsis = ! td->function.newStyle;
[413ad05]934        FunctionType * ft = new FunctionType( buildQualifiers( td ), hasEllipsis );
[8f6f47d7]935        buildList( td->function.params, ft->get_parameters() );
[413ad05]936        buildForall( td->forall, ft->get_forall() );
937        if ( td->base ) {
938                switch ( td->base->kind ) {
939                  case TypeData::Tuple:
[8f6f47d7]940                        buildList( td->base->tuple, ft->get_returnVals() );
[413ad05]941                        break;
942                  default:
943                        ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( buildDecl( td->base,  "", DeclarationNode::NoStorageClass, 0, false, false, LinkageSpec::Cforall ) ) );
944                } // switch
945        } else {
946                ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
947        } // if
948        return ft;
949} // buildFunction
[b87a5ed]950
951// Local Variables: //
952// tab-width: 4 //
953// mode: c++ //
954// compile-command: "make install" //
955// End: //
Note: See TracBrowser for help on using the repository browser.