source: src/Parser/TypeData.cc @ 413ad05

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 413ad05 was 413ad05, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

more refactoring of parser code

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