source: src/Parser/TypeData.cc @ f1e012b

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

added intrinsic ctor/dtors to prelude, modified MakeLibCfa? to build prelude ctor/dtors, added ctor/dtor to polymorphic object type constraints, rudimentary fallback on initializer nodes if chosen ctor is intrinsic, remove intrinsic destructor statements to reduce output pollution

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