source: src/Parser/TypeData.cc @ b1848a0

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since b1848a0 was 1d4580a, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

more refactoring of parser code

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