source: src/Parser/TypeData.cc @ 28307be

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