source: src/Parser/TypeData.cc @ de62360d

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newstringwith_gc
Last change on this file since de62360d was de62360d, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

fix computed goto, fixed -std=, implicit typedefs for enum and aggregates, add _Noreturn _Thread_local

  • Property mode set to 100644
File size: 26.6 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 : Thu Jun 18 22:06:23 2015
13// Update Count     : 21
14//
15
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
26TypeData::TypeData( Kind k ) : kind( k ), base( 0 ), forall( 0 ) {
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;
55                aggregate->members = 0;
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;
91        } // switch
92}
93
94TypeData::~TypeData() {
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;
121                delete aggregate->members;
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;
157        } // switch
158}
159
160TypeData *TypeData::clone() const {
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 );
192                newtype->aggregate->members = maybeClone( aggregate->members );
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;
227        } // switch
228        return newtype;
229}
230
231void TypeData::print( std::ostream &os, int indent ) const {
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;
239                forall->printList( os, indent+4 );
240        } // if
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 );
251                } // if
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 ";
263                } // if
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 ";
271                } // if
272                if ( base ) {
273                        base->print( os, indent );
274                } // if
275                break;
276          case Function:
277                os << "function" << endl;
278                if ( function->params ) {
279                        os << string( indent+2, ' ' ) << "with parameters " << endl;
280                        function->params->printList( os, indent+4 );
281                } else {
282                        os << string( indent+2, ' ' ) << "with no parameters " << endl;
283                } // if
284                if ( function->idList ) {
285                        os << string( indent+2, ' ' ) << "with old-style identifier list " << endl;
286                        function->idList->printList( os, indent+4 );
287                } // if
288                if ( function->oldDeclList ) {
289                        os << string( indent+2, ' ' ) << "with old-style declaration list " << endl;
290                        function->oldDeclList->printList( os, indent+4 );
291                } // if
292                os << string( indent+2, ' ' ) << "returning ";
293                if ( base ) {
294                        base->print( os, indent+4 );
295                } else {
296                        os << "nothing ";
297                } // if
298                os << endl;
299                if ( function->hasBody ) {
300                        os << string( indent+2, ' ' ) << "with body " << endl;
301                } // if
302                if ( function->body ) {
303                        function->body->printList( os, indent+2 );
304                } // if
305                break;
306          case Aggregate:
307                os << DeclarationNode::aggregateName[ aggregate->kind ] << ' ' << aggregate->name << endl;
308                if ( aggregate->params ) {
309                        os << string( indent+2, ' ' ) << "with type parameters " << endl;
310                        aggregate->params->printList( os, indent+4 );
311                } // if
312                if ( aggregate->actuals ) {
313                        os << string( indent+2, ' ' ) << "instantiated with actual parameters " << endl;
314                        aggregate->actuals->printList( os, indent+4 );
315                } // if
316                if ( aggregate->members ) {
317                        os << string( indent+2, ' ' ) << "with members " << endl;
318                        aggregate->members->printList( os, indent+4 );
319///     } else {
320///       os << string( indent+2, ' ' ) << "with no members " << endl;
321                } // if
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 ";
329                } // if
330                if ( aggInst->params ) {
331                        os << string( indent+2, ' ' ) << "with parameters " << endl;
332                        aggInst->params->printList( os, indent+2 );
333                } // if
334                break;
335          case Enum:
336                os << "enumeration ";
337                if ( enumeration->constants ) {
338                        os << "with constants" << endl;
339                        enumeration->constants->printList( os, indent+2 );
340                } // if
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 );
347                } // if
348                break;
349          case Symbolic:
350                if ( symbolic->isTypedef ) {
351                        os << "typedef definition ";
352                } else {
353                        os << "type definition ";
354                } // if
355                if ( symbolic->params ) {
356                        os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
357                        symbolic->params->printList( os, indent + 2 );
358                } // if
359                if ( symbolic->assertions ) {
360                        os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
361                        symbolic->assertions->printList( os, indent + 4 );
362                        os << string( indent+2, ' ' );
363                } // if
364                if ( base ) {
365                        os << "for ";
366                        base->print( os, indent + 2 );
367                } // if
368                break;
369          case Variable:
370                os << DeclarationNode::typeClassName[ variable->tyClass ] << " variable ";
371                if ( variable->assertions ) {
372                        os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
373                        variable->assertions->printList( os, indent + 4 );
374                        os << string( indent+2, ' ' );
375                } // if
376                break;
377          case Tuple:
378                os << "tuple ";
379                if ( tuple->members ) {
380                        os << "with members " << endl;
381                        tuple->members->printList( os, indent + 2 );
382                } // if
383                break;
384          case Typeof:
385                os << "type-of expression ";
386                if ( typeexpr->expr ) {
387                        typeexpr->expr->print( os, indent + 2 );
388                } // if
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 );
394                } // if
395                if ( attr->type ) {
396                        attr->type->print( os, indent + 2 );
397                } // if
398                break;
399        } // switch
400}
401
402TypeData *TypeData::extractAggregate( bool toplevel ) const {
403        TypeData *ret = 0;
404
405        switch ( kind ) {
406          case Aggregate:
407                if ( ! toplevel && aggregate->members ) {
408                        ret = clone();
409                        ret->qualifiers.clear();
410                } // if
411                break;
412          case Enum:
413                if ( ! toplevel && enumeration->constants ) {
414                        ret = clone();
415                        ret->qualifiers.clear();
416                } // if
417                break;
418          case AggregateInst:
419                if ( aggInst->aggregate ) {
420                        ret = aggInst->aggregate->extractAggregate( false );
421                } // if
422                break;
423          default:
424                if ( base ) {
425                        ret = base->extractAggregate( false );
426                } // if
427        } // switch
428        return ret;
429}
430
431void buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList ) {
432        buildList( firstNode, outputList );
433        for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
434                if ( (*i)->get_kind() == TypeDecl::Any ) {
435                        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
436                        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 ) );
437                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
438                        assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
439                        (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
440                } // if
441        } // for
442}
443
444Declaration *TypeData::buildDecl( std::string name, DeclarationNode::StorageClass sc, Expression *bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Type linkage, Initializer *init ) const {
445        if ( kind == TypeData::Function ) {
446                FunctionDecl *decl;
447                if ( function->hasBody ) {
448                        if ( function->body ) {
449                                Statement *stmt = function->body->build();
450                                CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt );
451                                assert( body );
452                                decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline, isNoreturn );
453                        } else {
454                                // std::list<Label> ls;
455                                decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list<Label>() ), isInline, isNoreturn );
456                        } // if
457                } else {
458                        decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline, isNoreturn );
459                } // if
460                for ( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_link() ) ) {
461                        if ( cur->get_name() != "" ) {
462                                decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
463                        } // if
464                } // for
465                buildList( function->oldDeclList, decl->get_oldDecls() );
466                return decl;
467        } else if ( kind == TypeData::Aggregate ) {
468                return buildAggregate();
469        } else if ( kind == TypeData::Enum ) {
470                return buildEnum();
471        } else if ( kind == TypeData::Symbolic ) {
472                return buildSymbolic( name, sc );
473        } else if ( kind == TypeData::Variable ) {
474                return buildVariable();
475        } else {
476                if ( isInline || isNoreturn ) {
477                        throw SemanticError( "invalid inline or _Noreturn specification in declaration of ", this );
478                } else {
479                        return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init );
480                } // if
481        } // if
482        return 0;
483}
484
485Type *TypeData::build() const {
486        switch ( kind ) {
487          case Unknown:
488                // fill in implicit int
489                return new BasicType( buildQualifiers(), BasicType::SignedInt );
490          case Basic:
491                return buildBasicType();
492          case Pointer:
493                return buildPointer();
494          case Array:
495                return buildArray();
496          case Function:
497                return buildFunction();
498          case AggregateInst:
499                return buildAggInst();
500          case EnumConstant:
501                // the name gets filled in later -- by SymTab::Validate
502                return new EnumInstType( buildQualifiers(), "" );
503          case SymbolicInst:
504                return buildSymbolicInst();;
505          case Tuple:
506                return buildTuple();
507          case Typeof:
508                return buildTypeof();
509          case Attr:
510                return buildAttr();
511          case Symbolic:
512          case Enum:
513          case Aggregate:
514          case Variable:
515                assert( false );
516        } // switch
517
518        return 0;
519}
520
521Type::Qualifiers TypeData::buildQualifiers() const {
522        Type::Qualifiers q;
523        for ( std::list< DeclarationNode::Qualifier >::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i ) {
524                switch ( *i ) {
525                  case DeclarationNode::Const:
526                        q.isConst = true;
527                        break;
528                  case DeclarationNode::Volatile:
529                        q.isVolatile = true;
530                        break;
531                  case DeclarationNode::Restrict:
532                        q.isRestrict = true;
533                        break;
534                  case DeclarationNode::Lvalue:
535                        q.isLvalue = true;
536                        break;
537                  case DeclarationNode::Atomic:
538                        q.isAtomic = true;
539                        break;
540                  case DeclarationNode::Attribute:
541                        q.isAttribute = true;
542                        break;
543                } // switch
544        } // for
545        return q;
546}
547
548Type *TypeData::buildBasicType() const {
549        static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
550                                                                                           BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
551                                                                                           BasicType::DoubleImaginary };
552        bool init = false;
553        bool sawDouble = false;
554        bool sawSigned = false;
555        BasicType::Kind ret;
556
557        for ( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) {
558                if ( ! init ) {
559                        init = true;
560                        if ( *i == DeclarationNode::Void ) {
561                                if ( basic->typeSpec.size() != 1 || ! basic->modifiers.empty() ) {
562                                        throw SemanticError( "invalid type specifier \"void\" in type: ", this );
563                                } else {
564                                        return new VoidType( buildQualifiers() );
565                                } // if
566                        } else {
567                                ret = kindMap[ *i ];
568                        } // if
569                } else {
570                        switch ( *i ) {
571                          case DeclarationNode::Float:
572                                if ( sawDouble ) {
573                                        throw SemanticError( "invalid type specifier \"float\" in type: ", this );
574                                } else {
575                                        switch ( ret ) {
576                                          case BasicType::DoubleComplex:
577                                                ret = BasicType::FloatComplex;
578                                                break;
579                                          case BasicType::DoubleImaginary:
580                                                ret = BasicType::FloatImaginary;
581                                                break;
582                                          default:
583                                                throw SemanticError( "invalid type specifier \"float\" in type: ", this );
584                                        } // switch
585                                } // if
586                                break;
587                          case DeclarationNode::Double:
588                                if ( sawDouble ) {
589                                        throw SemanticError( "duplicate type specifier \"double\" in type: ", this );
590                                } else {
591                                        switch ( ret ) {
592                                          case BasicType::DoubleComplex:
593                                          case BasicType::DoubleImaginary:
594                                                break;
595                                          default:
596                                                throw SemanticError( "invalid type specifier \"double\" in type: ", this );
597                                        } // switch
598                                } // if
599                                break;
600                          case DeclarationNode::Complex:
601                                switch ( ret ) {
602                                  case BasicType::Float:
603                                        ret = BasicType::FloatComplex;
604                                        break;
605                                  case BasicType::Double:
606                                        ret = BasicType::DoubleComplex;
607                                        break;
608                                  default:
609                                        throw SemanticError( "invalid type specifier \"_Complex\" in type: ", this );
610                                } // switch
611                                break;
612                          case DeclarationNode::Imaginary:
613                                switch ( ret ) {
614                                  case BasicType::Float:
615                                        ret = BasicType::FloatImaginary;
616                                        break;
617                                  case BasicType::Double:
618                                        ret = BasicType::DoubleImaginary;
619                                        break;
620                                  default:
621                                        throw SemanticError( "invalid type specifier \"_Imaginary\" in type: ", this );
622                                } // switch
623                                break;
624                          default:
625                                throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type: ", this );
626                        } // switch
627                } // if
628                if ( *i == DeclarationNode::Double ) {
629                        sawDouble = true;
630                } // if
631        } // for
632
633        for ( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) {
634                switch ( *i ) {
635                  case DeclarationNode::Long:
636                        if ( ! init ) {
637                                init = true;
638                                ret = BasicType::LongSignedInt;
639                        } else {
640                                switch ( ret ) {
641                                  case BasicType::SignedInt:
642                                        ret = BasicType::LongSignedInt;
643                                        break;
644                                  case BasicType::UnsignedInt:
645                                        ret = BasicType::LongUnsignedInt;
646                                        break;
647                                  case BasicType::LongSignedInt:
648                                        ret = BasicType::LongLongSignedInt;
649                                        break;
650                                  case BasicType::LongUnsignedInt:
651                                        ret = BasicType::LongLongUnsignedInt;
652                                        break;
653                                  case BasicType::Double:
654                                        ret = BasicType::LongDouble;
655                                        break;
656                                  case BasicType::DoubleComplex:
657                                        ret = BasicType::LongDoubleComplex;
658                                        break;
659                                  case BasicType::DoubleImaginary:
660                                        ret = BasicType::LongDoubleImaginary;
661                                        break;
662                                  default:
663                                        throw SemanticError( "invalid type modifier \"long\" in type: ", this );
664                                } // switch
665                        } // if
666                        break;
667                  case DeclarationNode::Short:
668                        if ( ! init ) {
669                                init = true;
670                                ret = BasicType::ShortSignedInt;
671                        } else {
672                                switch ( ret ) {
673                                  case BasicType::SignedInt:
674                                        ret = BasicType::ShortSignedInt;
675                                        break;
676                                  case BasicType::UnsignedInt:
677                                        ret = BasicType::ShortUnsignedInt;
678                                        break;
679                                  default:
680                                        throw SemanticError( "invalid type modifier \"short\" in type: ", this );
681                                } // switch
682                        } // if
683                        break;
684                  case DeclarationNode::Signed:
685                        if ( ! init ) {
686                                init = true;
687                                ret = BasicType::SignedInt;
688                        } else if ( sawSigned ) {
689                                throw SemanticError( "duplicate type modifer \"signed\" in type: ", this );
690                        } else {
691                                switch ( ret ) {
692                                  case BasicType::LongLongSignedInt:
693                                        ret = BasicType::LongLongUnsignedInt;
694                                        break;
695                                  case BasicType::LongSignedInt:
696                                        ret = BasicType::LongUnsignedInt;
697                                        break;
698                                  case BasicType::SignedInt:
699                                  case BasicType::ShortSignedInt:
700                                        break;
701                                  case BasicType::Char:
702                                        ret = BasicType::SignedChar;
703                                        break;
704                                  default:
705                                        throw SemanticError( "invalid type modifer \"signed\" in type: ", this );
706                                } // switch
707                        } // if
708                        break;
709                  case DeclarationNode::Unsigned:
710                        if ( ! init ) {
711                                init = true;
712                                ret = BasicType::UnsignedInt;
713                        } else if ( sawSigned ) {
714                                throw SemanticError( "invalid type modifer \"unsigned\" in type: ", this );
715                        } else {
716                                switch ( ret ) {
717                                  case BasicType::LongLongSignedInt:
718                                        ret = BasicType::LongLongUnsignedInt;
719                                        break;
720                                  case BasicType::LongSignedInt:
721                                        ret = BasicType::LongUnsignedInt;
722                                        break;
723                                  case BasicType::SignedInt:
724                                        ret = BasicType::UnsignedInt;
725                                        break;
726                                  case BasicType::ShortSignedInt:
727                                        ret = BasicType::ShortUnsignedInt;
728                                        break;
729                                  case BasicType::Char:
730                                        ret = BasicType::UnsignedChar;
731                                        break;
732                                  default:
733                                        throw SemanticError( "invalid type modifer \"unsigned\" in type: ", this );
734                                } // switch
735                        } // if
736                        break;
737                } // switch
738
739                if ( *i == DeclarationNode::Signed ) {
740                        sawSigned = true;
741                } // if
742        } // for
743
744        BasicType *bt;
745        if ( ! init ) {
746                bt = new BasicType( buildQualifiers(), BasicType::SignedInt );
747        } else {
748                bt = new BasicType( buildQualifiers(), ret );
749        } // if
750        buildForall( forall, bt->get_forall() );
751        return bt;
752}
753
754
755PointerType *TypeData::buildPointer() const {
756        PointerType *pt;
757        if ( base ) {
758                pt = new PointerType( buildQualifiers(), base->build() );
759        } else {
760                pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
761        } // if
762        buildForall( forall, pt->get_forall() );
763        return pt;
764}
765
766ArrayType *TypeData::buildArray() const {
767        ArrayType *at;
768        if ( base ) {
769                at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ),
770                                                        array->isVarLen, array->isStatic );
771        } else {
772                at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
773                                                        maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic );
774        } // if
775        buildForall( forall, at->get_forall() );
776        return at;
777}
778
779FunctionType *TypeData::buildFunction() const {
780        assert( kind == Function );
781        bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true;
782        if ( ! function->params ) hasEllipsis = ! function->newStyle;
783        FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis );
784        buildList( function->params, ft->get_parameters() );
785        buildForall( forall, ft->get_forall() );
786        if ( base ) {
787                switch ( base->kind ) {
788                  case Tuple:
789                        buildList( base->tuple->members, ft->get_returnVals() );
790                        break;
791                  default:
792                        ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", DeclarationNode::NoStorageClass, 0, false, false, LinkageSpec::Cforall ) ) );
793                } // switch
794        } else {
795                ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
796        } // if
797        return ft;
798}
799
800AggregateDecl *TypeData::buildAggregate() const {
801        assert( kind == Aggregate );
802        AggregateDecl *at;
803        switch ( aggregate->kind ) {
804          case DeclarationNode::Struct:
805                at = new StructDecl( aggregate->name );
806                break;
807          case DeclarationNode::Union:
808                at = new UnionDecl( aggregate->name );
809                break;
810          case DeclarationNode::Context:
811                at = new ContextDecl( aggregate->name );
812                break;
813          default:
814                assert( false );
815        } // switch
816        buildList( aggregate->params, at->get_parameters() );
817        buildList( aggregate->members, at->get_members() );
818
819        return at;
820}
821
822/// namespace {
823/// Type*
824/// makeType( Declaration* decl )
825/// {
826///   if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
827///     return dwt->get_type()->clone();
828///   } else {
829///     return 0;
830///   }
831/// }
832/// }
833
834ReferenceToType *TypeData::buildAggInst() const {
835        assert( kind == AggregateInst );
836
837        ReferenceToType *ret;
838        if ( aggInst->aggregate->kind == Enum ) {
839                ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name );
840        } else {
841                assert( aggInst->aggregate->kind == Aggregate );
842                switch ( aggInst->aggregate->aggregate->kind ) {
843                  case DeclarationNode::Struct:
844                        ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
845                        break;
846                  case DeclarationNode::Union:
847                        ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
848                        break;
849                  case DeclarationNode::Context:
850                        ret = new ContextInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
851                        break;
852                  default:
853                        assert( false );
854                } // switch
855        } // if
856        buildList( aggInst->params, ret->get_parameters() );
857        buildForall( forall, ret->get_forall() );
858        return ret;
859}
860
861NamedTypeDecl *TypeData::buildSymbolic( const std::string &name, DeclarationNode::StorageClass sc ) const {
862        assert( kind == Symbolic );
863        NamedTypeDecl *ret;
864        if ( symbolic->isTypedef ) {
865                ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) );
866        } else {
867                ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any );
868        } // if
869        buildList( symbolic->params, ret->get_parameters() );
870        buildList( symbolic->assertions, ret->get_assertions() );
871        return ret;
872}
873
874TypeDecl *TypeData::buildVariable() const {
875        assert( kind == Variable );
876        static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
877
878        TypeDecl *ret = new TypeDecl( variable->name, DeclarationNode::NoStorageClass, 0, kindMap[ variable->tyClass ] );
879        buildList( variable->assertions, ret->get_assertions() );
880        return ret;
881}
882
883EnumDecl *TypeData::buildEnum() const {
884        assert( kind == Enum );
885        EnumDecl *ret = new EnumDecl( enumeration->name );
886        buildList( enumeration->constants, ret->get_members() );
887        return ret;
888}
889
890TypeInstType *TypeData::buildSymbolicInst() const {
891        assert( kind == SymbolicInst );
892        TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name, false );
893        buildList( symbolic->actuals, ret->get_parameters() );
894        buildForall( forall, ret->get_forall() );
895        return ret;
896}
897
898TupleType *TypeData::buildTuple() const {
899        assert( kind == Tuple );
900        TupleType *ret = new TupleType( buildQualifiers() );
901        buildTypeList( tuple->members, ret->get_types() );
902        buildForall( forall, ret->get_forall() );
903        return ret;
904}
905
906TypeofType *TypeData::buildTypeof() const {
907        assert( kind == Typeof );
908        assert( typeexpr );
909        assert( typeexpr->expr );
910        TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() );
911        return ret;
912}
913
914AttrType *TypeData::buildAttr() const {
915        assert( kind == Attr );
916        assert( attr );
917        AttrType *ret;
918        if ( attr->expr ) {
919                ret = new AttrType( buildQualifiers(), attr->name, attr->expr->build() );
920        } else {
921                assert( attr->type );
922                ret = new AttrType( buildQualifiers(), attr->name, attr->type->buildType() );
923        } // if
924        return ret;
925}
926
927// Local Variables: //
928// tab-width: 4 //
929// mode: c++ //
930// compile-command: "make install" //
931// End: //
Note: See TracBrowser for help on using the repository browser.