source: src/Parser/TypeData.cc @ 6d43cc57

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumwith_gc
Last change on this file since 6d43cc57 was 2ee0076, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

temporarily remove check for _Complex with float80/128

  • Property mode set to 100644
File size: 34.0 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 : Wed Jun  6 17:40:33 2018
13// Update Count     : 604
14//
15
16#include <cassert>                 // for assert
17#include <ostream>                 // for operator<<, ostream, basic_ostream
18
19#include "Common/SemanticError.h"  // for SemanticError
20#include "Common/utility.h"        // for maybeClone, maybeBuild, maybeMoveB...
21#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
22#include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, FunctionDecl
23#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
24#include "SynTree/Initializer.h"   // for SingleInit, Initializer (ptr only)
25#include "SynTree/Statement.h"     // for CompoundStmt, Statement
26#include "SynTree/Type.h"          // for BasicType, Type, Type::ForallList
27#include "TypeData.h"
28
29class Attribute;
30
31using namespace std;
32
33TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
34        switch ( kind ) {
35          case Unknown:
36          case Pointer:
37          case Reference:
38          case EnumConstant:
39                // nothing else to initialize
40                break;
41          case Basic:
42                // basic = new Basic_t;
43                break;
44          case Array:
45                // array = new Array_t;
46                array.dimension = nullptr;
47                array.isVarLen = false;
48                array.isStatic = false;
49                break;
50          case Function:
51                // function = new Function_t;
52                function.params = nullptr;
53                function.idList = nullptr;
54                function.oldDeclList = nullptr;
55                function.body = nullptr;
56                function.withExprs = nullptr;
57                break;
58                // Enum is an Aggregate, so both structures are initialized together.
59          case Enum:
60                // enumeration = new Enumeration_t;
61                enumeration.name = nullptr;
62                enumeration.constants = nullptr;
63                enumeration.body = false;
64                break;
65          case Aggregate:
66                // aggregate = new Aggregate_t;
67                aggregate.kind = DeclarationNode::NoAggregate;
68                aggregate.name = nullptr;
69                aggregate.params = nullptr;
70                aggregate.actuals = nullptr;
71                aggregate.fields = nullptr;
72                aggregate.body = false;
73                aggregate.tagged = false;
74                aggregate.parent = nullptr;
75                break;
76          case AggregateInst:
77                // aggInst = new AggInst_t;
78                aggInst.aggregate = nullptr;
79                aggInst.params = nullptr;
80                aggInst.hoistType = false;;
81                break;
82          case Symbolic:
83          case SymbolicInst:
84                // symbolic = new Symbolic_t;
85                symbolic.name = nullptr;
86                symbolic.params = nullptr;
87                symbolic.actuals = nullptr;
88                symbolic.assertions = nullptr;
89                break;
90          case Tuple:
91                // tuple = new Tuple_t;
92                tuple = nullptr;
93                break;
94          case Typeof:
95                // typeexpr = new Typeof_t;
96                typeexpr = nullptr;
97                break;
98          case Builtin:
99                // builtin = new Builtin_t;
100                break;
101        } // switch
102} // TypeData::TypeData
103
104
105TypeData::~TypeData() {
106        delete base;
107        delete forall;
108
109        switch ( kind ) {
110          case Unknown:
111          case Pointer:
112          case Reference:
113          case EnumConstant:
114                // nothing to destroy
115                break;
116          case Basic:
117                // delete basic;
118                break;
119          case Array:
120                delete array.dimension;
121                // delete array;
122                break;
123          case Function:
124                delete function.params;
125                delete function.idList;
126                delete function.oldDeclList;
127                delete function.body;
128                delete function.withExprs;
129                // delete function;
130                break;
131          case Aggregate:
132                delete aggregate.name;
133                delete aggregate.params;
134                delete aggregate.actuals;
135                delete aggregate.fields;
136                // delete aggregate;
137                break;
138          case AggregateInst:
139                delete aggInst.aggregate;
140                delete aggInst.params;
141                // delete aggInst;
142                break;
143          case Enum:
144                delete enumeration.name;
145                delete enumeration.constants;
146                // delete enumeration;
147                break;
148          case Symbolic:
149          case SymbolicInst:
150                delete symbolic.name;
151                delete symbolic.params;
152                delete symbolic.actuals;
153                delete symbolic.assertions;
154                // delete symbolic;
155                break;
156          case Tuple:
157                // delete tuple->members;
158                delete tuple;
159                break;
160          case Typeof:
161                // delete typeexpr->expr;
162                delete typeexpr;
163                break;
164          case Builtin:
165                // delete builtin;
166                break;
167        } // switch
168} // TypeData::~TypeData
169
170
171TypeData * TypeData::clone() const {
172        TypeData * newtype = new TypeData( kind );
173        newtype->qualifiers = qualifiers;
174        newtype->base = maybeClone( base );
175        newtype->forall = maybeClone( forall );
176
177        switch ( kind ) {
178          case Unknown:
179          case EnumConstant:
180          case Pointer:
181          case Reference:
182                // nothing else to copy
183                break;
184          case Basic:
185                newtype->basictype = basictype;
186                newtype->complextype = complextype;
187                newtype->signedness = signedness;
188                newtype->length = length;
189                break;
190          case Array:
191                newtype->array.dimension = maybeClone( array.dimension );
192                newtype->array.isVarLen = array.isVarLen;
193                newtype->array.isStatic = array.isStatic;
194                break;
195          case Function:
196                newtype->function.params = maybeClone( function.params );
197                newtype->function.idList = maybeClone( function.idList );
198                newtype->function.oldDeclList = maybeClone( function.oldDeclList );
199                newtype->function.body = maybeClone( function.body );
200                newtype->function.withExprs = maybeClone( function.withExprs );
201                break;
202          case Aggregate:
203                newtype->aggregate.kind = aggregate.kind;
204                newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
205                newtype->aggregate.params = maybeClone( aggregate.params );
206                newtype->aggregate.actuals = maybeClone( aggregate.actuals );
207                newtype->aggregate.fields = maybeClone( aggregate.fields );
208                newtype->aggregate.body = aggregate.body;
209                newtype->aggregate.tagged = aggregate.tagged;
210                newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;
211                break;
212          case AggregateInst:
213                newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
214                newtype->aggInst.params = maybeClone( aggInst.params );
215                newtype->aggInst.hoistType = aggInst.hoistType;
216                break;
217          case Enum:
218                newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
219                newtype->enumeration.constants = maybeClone( enumeration.constants );
220                newtype->enumeration.body = enumeration.body;
221                break;
222          case Symbolic:
223          case SymbolicInst:
224                newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr;
225                newtype->symbolic.params = maybeClone( symbolic.params );
226                newtype->symbolic.actuals = maybeClone( symbolic.actuals );
227                newtype->symbolic.assertions = maybeClone( symbolic.assertions );
228                newtype->symbolic.isTypedef = symbolic.isTypedef;
229                break;
230          case Tuple:
231                newtype->tuple = maybeClone( tuple );
232                break;
233          case Typeof:
234                newtype->typeexpr = maybeClone( typeexpr );
235                break;
236          case Builtin:
237                assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One );
238                newtype->builtintype = builtintype;
239                break;
240        } // switch
241        return newtype;
242} // TypeData::clone
243
244
245void TypeData::print( ostream &os, int indent ) const {
246        for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
247                if ( qualifiers[i] ) os << Type::QualifiersNames[ 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                if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
271                if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
272                assert( basictype != DeclarationNode::NoBasicType );
273                os << DeclarationNode::basicTypeNames[ basictype ] << " ";
274                if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " ";
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.body ) {
316                        os << string( indent + 2, ' ' ) << "with body " << endl;
317                        function.body->printList( os, indent + 2 );
318                } // if
319                break;
320          case Aggregate:
321                os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl;
322                if ( aggregate.params ) {
323                        os << string( indent + 2, ' ' ) << "with type parameters " << endl;
324                        aggregate.params->printList( os, indent + 4 );
325                } // if
326                if ( aggregate.actuals ) {
327                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
328                        aggregate.actuals->printList( os, indent + 4 );
329                } // if
330                if ( aggregate.fields ) {
331                        os << string( indent + 2, ' ' ) << "with members " << endl;
332                        aggregate.fields->printList( os, indent + 4 );
333                } // if
334                if ( aggregate.body ) {
335                        os << string( indent + 2, ' ' ) << " with body " << endl;
336                } // if
337                break;
338          case AggregateInst:
339                if ( aggInst.aggregate ) {
340                        os << "instance of " ;
341                        aggInst.aggregate->print( os, indent );
342                } else {
343                        os << "instance of an unspecified aggregate ";
344                } // if
345                if ( aggInst.params ) {
346                        os << string( indent + 2, ' ' ) << "with parameters " << endl;
347                        aggInst.params->printList( os, indent + 2 );
348                } // if
349                break;
350          case Enum:
351                os << "enumeration ";
352                if ( enumeration.constants ) {
353                        os << "with constants" << endl;
354                        enumeration.constants->printList( os, indent + 2 );
355                } // if
356                if ( enumeration.body ) {
357                        os << string( indent + 2, ' ' ) << " with body " << endl;
358                } // if
359                break;
360          case SymbolicInst:
361                os << "instance of type " << *symbolic.name;
362                if ( symbolic.actuals ) {
363                        os << " with parameters" << endl;
364                        symbolic.actuals->printList( os, indent + 2 );
365                } // if
366                break;
367          case Symbolic:
368                if ( symbolic.isTypedef ) {
369                        os << "typedef definition ";
370                } else {
371                        os << "type definition ";
372                } // if
373                if ( symbolic.params ) {
374                        os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
375                        symbolic.params->printList( os, indent + 2 );
376                } // if
377                if ( symbolic.assertions ) {
378                        os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
379                        symbolic.assertions->printList( os, indent + 4 );
380                        os << string( indent + 2, ' ' );
381                } // if
382                if ( base ) {
383                        os << "for ";
384                        base->print( os, indent + 2 );
385                } // if
386                break;
387          case Tuple:
388                os << "tuple ";
389                if ( tuple ) {
390                        os << "with members " << endl;
391                        tuple->printList( os, indent + 2 );
392                } // if
393                break;
394          case Typeof:
395                os << "type-of expression ";
396                if ( typeexpr ) {
397                        typeexpr->print( os, indent + 2 );
398                } // if
399                break;
400          case Builtin:
401                os << DeclarationNode::builtinTypeNames[builtintype];
402                break;
403          default:
404                os << "internal error: TypeData::print " << kind << endl;
405                assert( false );
406        } // switch
407} // TypeData::print
408
409
410template< typename ForallList >
411void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
412        buildList( firstNode, outputList );
413        auto n = firstNode;
414        for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) {
415                TypeDecl * td = static_cast<TypeDecl *>(*i);
416                if ( n->variable.tyClass == DeclarationNode::Otype ) {
417                        // add assertion parameters to `type' tyvars in reverse order
418                        // add dtor:  void ^?{}(T *)
419                        FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
420                        dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
421                        td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) );
422
423                        // add copy ctor:  void ?{}(T *, T)
424                        FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
425                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
426                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
427                        td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) );
428
429                        // add default ctor:  void ?{}(T *)
430                        FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
431                        ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
432                        td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) );
433
434                        // add assignment operator:  T * ?=?(T *, T)
435                        FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
436                        assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
437                        assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
438                        assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
439                        td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) );
440                } // if
441        } // for
442} // buildForall
443
444
445Type * typebuild( const TypeData * td ) {
446        assert( td );
447        switch ( td->kind ) {
448          case TypeData::Unknown:
449                // fill in implicit int
450                return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
451          case TypeData::Basic:
452                return buildBasicType( td );
453          case TypeData::Pointer:
454                return buildPointer( td );
455          case TypeData::Array:
456                return buildArray( td );
457          case TypeData::Reference:
458                return buildReference( td );
459          case TypeData::Function:
460                return buildFunction( td );
461          case TypeData::AggregateInst:
462                return buildAggInst( td );
463          case TypeData::EnumConstant:
464                // the name gets filled in later -- by SymTab::Validate
465                return new EnumInstType( buildQualifiers( td ), "" );
466          case TypeData::SymbolicInst:
467                return buildSymbolicInst( td );;
468          case TypeData::Tuple:
469                return buildTuple( td );
470          case TypeData::Typeof:
471                return buildTypeof( td );
472          case TypeData::Builtin:
473                if(td->builtintype == DeclarationNode::Zero) {
474                        return new ZeroType( noQualifiers );
475                }
476                else if(td->builtintype == DeclarationNode::One) {
477                        return new OneType( noQualifiers );
478                }
479                else {
480                        return new VarArgsType( buildQualifiers( td ) );
481                }
482          case TypeData::Symbolic:
483          case TypeData::Enum:
484          case TypeData::Aggregate:
485                assert( false );
486        } // switch
487        return nullptr;
488} // typebuild
489
490
491TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
492        TypeData * ret = nullptr;
493
494        switch ( td->kind ) {
495          case TypeData::Aggregate:
496                if ( ! toplevel && td->aggregate.body ) {
497                        ret = td->clone();
498                } // if
499                break;
500          case TypeData::Enum:
501                if ( ! toplevel && td->enumeration.body ) {
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
518
519Type::Qualifiers buildQualifiers( const TypeData * td ) {
520        return td->qualifiers;
521} // buildQualifiers
522
523
524static string genTSError( string msg, DeclarationNode::BasicType basictype ) {
525        SemanticError( yylloc, string( "invalid type specifier \"" ) + msg + "\" for type \"" + DeclarationNode::basicTypeNames[basictype] + "\"." );
526} // genTSError
527
528Type * buildBasicType( const TypeData * td ) {
529        BasicType::Kind ret;
530
531        switch ( td->basictype ) {
532          case DeclarationNode::Void:
533                if ( td->signedness != DeclarationNode::NoSignedness ) {
534                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
535                } // if
536                if ( td->length != DeclarationNode::NoLength ) {
537                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
538                } // if
539                return new VoidType( buildQualifiers( td ) );
540                break;
541
542          case DeclarationNode::Bool:
543                if ( td->signedness != DeclarationNode::NoSignedness ) {
544                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
545                } // if
546                if ( td->length != DeclarationNode::NoLength ) {
547                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
548                } // if
549
550                ret = BasicType::Bool;
551                break;
552
553          case DeclarationNode::Char:
554                // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
555                // character types. The implementation shall define char to have the same range, representation, and behavior as
556                // either signed char or unsigned char.
557                static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
558
559                if ( td->length != DeclarationNode::NoLength ) {
560                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
561                } // if
562
563                ret = chartype[ td->signedness ];
564                break;
565
566          case DeclarationNode::Int:
567                static BasicType::Kind inttype[2][4] = {
568                        { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
569                        { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
570                };
571
572          Integral: ;
573                if ( td->signedness == DeclarationNode::NoSignedness ) {
574                        const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
575                } // if
576                ret = inttype[ td->signedness ][ td->length ];
577                break;
578
579          case DeclarationNode::Int128:
580                ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
581                if ( td->length != DeclarationNode::NoLength ) {
582                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
583                } // if
584                break;
585
586          case DeclarationNode::Float:
587          case DeclarationNode::Float80:
588          case DeclarationNode::Float128:
589          case DeclarationNode::Double:
590          case DeclarationNode::LongDouble:                                     // not set until below
591                static BasicType::Kind floattype[3][3] = {
592                        { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
593                        { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
594                        { BasicType::Float, BasicType::Double, BasicType::LongDouble },
595                };
596
597          FloatingPoint: ;
598                if ( td->signedness != DeclarationNode::NoSignedness ) {
599                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
600                } // if
601                if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
602                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
603                } // if
604                if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) {
605                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
606                } // if
607                if ( td->length == DeclarationNode::Long ) {
608                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
609                } // if
610
611                if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
612                        // if ( td->complextype != DeclarationNode::NoComplexType ) {
613                        //      genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
614                        // }
615                        if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
616                        else ret = BasicType::Float128;
617                        break;
618                }
619
620                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
621                break;
622
623          case DeclarationNode::NoBasicType:
624                // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
625                if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
626                        const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
627                        goto FloatingPoint;
628                } // if
629
630                const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
631                goto Integral;
632          default:
633                assertf( false, "unknown basic type" );
634                return nullptr;
635        } // switch
636
637        BasicType * bt = new BasicType( buildQualifiers( td ), ret );
638        buildForall( td->forall, bt->get_forall() );
639        return bt;
640} // buildBasicType
641
642
643PointerType * buildPointer( const TypeData * td ) {
644        PointerType * pt;
645        if ( td->base ) {
646                pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
647        } else {
648                pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
649        } // if
650        buildForall( td->forall, pt->get_forall() );
651        return pt;
652} // buildPointer
653
654
655ArrayType * buildArray( const TypeData * td ) {
656        ArrayType * at;
657        if ( td->base ) {
658                at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
659                                                        td->array.isVarLen, td->array.isStatic );
660        } else {
661                at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
662                                                        maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
663        } // if
664        buildForall( td->forall, at->get_forall() );
665        return at;
666} // buildArray
667
668
669ReferenceType * buildReference( const TypeData * td ) {
670        ReferenceType * rt;
671        if ( td->base ) {
672                rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) );
673        } else {
674                rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
675        } // if
676        buildForall( td->forall, rt->get_forall() );
677        return rt;
678} // buildReference
679
680
681AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
682        assert( td->kind == TypeData::Aggregate );
683        AggregateDecl * at;
684        switch ( td->aggregate.kind ) {
685          case DeclarationNode::Struct:
686          case DeclarationNode::Coroutine:
687          case DeclarationNode::Monitor:
688          case DeclarationNode::Thread:
689                at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
690                buildForall( td->aggregate.params, at->get_parameters() );
691                break;
692          case DeclarationNode::Union:
693                at = new UnionDecl( *td->aggregate.name, attributes, linkage );
694                buildForall( td->aggregate.params, at->get_parameters() );
695                break;
696          case DeclarationNode::Trait:
697                at = new TraitDecl( *td->aggregate.name, attributes, linkage );
698                buildList( td->aggregate.params, at->get_parameters() );
699                break;
700          default:
701                assert( false );
702        } // switch
703
704        buildList( td->aggregate.fields, at->get_members() );
705        at->set_body( td->aggregate.body );
706
707        return at;
708} // buildAggregate
709
710
711ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
712        switch ( type->kind ) {
713          case TypeData::Enum: {
714                  if ( type->enumeration.body ) {
715                          EnumDecl * typedecl = buildEnum( type, attributes, linkage );
716                          return new EnumInstType( buildQualifiers( type ), typedecl );
717                  } else {
718                          return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
719                  } // if
720          }
721          case TypeData::Aggregate: {
722                  ReferenceToType * ret;
723                  if ( type->aggregate.body ) {
724                          AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
725                          switch ( type->aggregate.kind ) {
726                                case DeclarationNode::Struct:
727                                case DeclarationNode::Coroutine:
728                                case DeclarationNode::Monitor:
729                                case DeclarationNode::Thread:
730                                  ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
731                                  break;
732                                case DeclarationNode::Union:
733                                  ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
734                                  break;
735                                case DeclarationNode::Trait:
736                                  assert( false );
737                                  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
738                                  break;
739                                default:
740                                  assert( false );
741                          } // switch
742                  } else {
743                          switch ( type->aggregate.kind ) {
744                                case DeclarationNode::Struct:
745                                case DeclarationNode::Coroutine:
746                                case DeclarationNode::Monitor:
747                                case DeclarationNode::Thread:
748                                  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
749                                  break;
750                                case DeclarationNode::Union:
751                                  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
752                                  break;
753                                case DeclarationNode::Trait:
754                                  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
755                                  break;
756                                default:
757                                  assert( false );
758                          } // switch
759                  } // if
760                  return ret;
761          }
762          default:
763                assert( false );
764        } // switch
765} // buildAggInst
766
767
768ReferenceToType * buildAggInst( const TypeData * td ) {
769        assert( td->kind == TypeData::AggregateInst );
770
771        // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() );
772        ReferenceToType * ret = nullptr;
773        TypeData * type = td->aggInst.aggregate;
774        switch ( type->kind ) {
775          case TypeData::Enum: {
776                  return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
777          }
778          case TypeData::Aggregate: {
779                  switch ( type->aggregate.kind ) {
780                        case DeclarationNode::Struct:
781                        case DeclarationNode::Coroutine:
782                        case DeclarationNode::Monitor:
783                        case DeclarationNode::Thread:
784                          ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
785                          break;
786                        case DeclarationNode::Union:
787                          ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
788                          break;
789                        case DeclarationNode::Trait:
790                          ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
791                          break;
792                        default:
793                          assert( false );
794                  } // switch
795          }
796          break;
797          default:
798                assert( false );
799        } // switch
800
801        ret->set_hoistType( td->aggInst.hoistType );
802        buildList( td->aggInst.params, ret->get_parameters() );
803        buildForall( td->forall, ret->get_forall() );
804        return ret;
805} // buildAggInst
806
807
808NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
809        assert( td->kind == TypeData::Symbolic );
810        NamedTypeDecl * ret;
811        assert( td->base );
812        if ( td->symbolic.isTypedef ) {
813                ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage );
814        } else {
815                ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true );
816        } // if
817        buildList( td->symbolic.params, ret->get_parameters() );
818        buildList( td->symbolic.assertions, ret->get_assertions() );
819        ret->base->attributes.splice( ret->base->attributes.end(), attributes );
820        return ret;
821} // buildSymbolic
822
823
824EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
825        assert( td->kind == TypeData::Enum );
826        EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage );
827        buildList( td->enumeration.constants, ret->get_members() );
828        list< Declaration * >::iterator members = ret->get_members().begin();
829        for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
830                if ( cur->has_enumeratorValue() ) {
831                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
832                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
833                } // if
834        } // for
835        ret->set_body( td->enumeration.body );
836        return ret;
837} // buildEnum
838
839
840TypeInstType * buildSymbolicInst( const TypeData * td ) {
841        assert( td->kind == TypeData::SymbolicInst );
842        TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
843        buildList( td->symbolic.actuals, ret->get_parameters() );
844        buildForall( td->forall, ret->get_forall() );
845        return ret;
846} // buildSymbolicInst
847
848
849TupleType * buildTuple( const TypeData * td ) {
850        assert( td->kind == TypeData::Tuple );
851        std::list< Type * > types;
852        buildTypeList( td->tuple, types );
853        TupleType * ret = new TupleType( buildQualifiers( td ), types );
854        buildForall( td->forall, ret->get_forall() );
855        return ret;
856} // buildTuple
857
858
859TypeofType * buildTypeof( const TypeData * td ) {
860        assert( td->kind == TypeData::Typeof );
861        assert( td->typeexpr );
862        // assert( td->typeexpr->expr );
863        return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
864} // buildTypeof
865
866
867Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
868        if ( td->kind == TypeData::Function ) {
869                if ( td->function.idList ) {                                    // KR function ?
870                        buildKRFunction( td->function );                        // transform into C11 function
871                } // if
872
873                FunctionDecl * decl;
874                Statement * stmt = maybeBuild<Statement>( td->function.body );
875                CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
876                decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
877                buildList( td->function.withExprs, decl->withExprs );
878                return decl->set_asmName( asmName );
879        } else if ( td->kind == TypeData::Aggregate ) {
880                return buildAggregate( td, attributes, linkage );
881        } else if ( td->kind == TypeData::Enum ) {
882                return buildEnum( td, attributes, linkage );
883        } else if ( td->kind == TypeData::Symbolic ) {
884                return buildSymbolic( td, attributes, name, scs, linkage );
885        } else {
886                return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName );
887        } // if
888        return nullptr;
889} // buildDecl
890
891
892FunctionType * buildFunction( const TypeData * td ) {
893        assert( td->kind == TypeData::Function );
894        FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
895        buildList( td->function.params, ft->get_parameters() );
896        buildForall( td->forall, ft->get_forall() );
897        if ( td->base ) {
898                switch ( td->base->kind ) {
899                  case TypeData::Tuple:
900                        buildList( td->base->tuple, ft->get_returnVals() );
901                        break;
902                  default:
903                        ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) );
904                } // switch
905        } else {
906                ft->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
907        } // if
908        return ft;
909} // buildFunction
910
911
912// Transform KR routine declarations into C99 routine declarations:
913//
914//    rtn( a, b, c ) int a, c; double b {}  =>  int rtn( int a, double c, int b ) {}
915//
916// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
917// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
918// extra names are disallowed.
919//
920// Note, there is no KR routine-prototype syntax:
921//
922//    rtn( a, b, c ) int a, c; double b; // invalid KR prototype
923//    rtn(); // valid KR prototype
924
925void buildKRFunction( const TypeData::Function_t & function ) {
926        assert( ! function.params );
927        // loop over declaration first as it is easier to spot errors
928        for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = dynamic_cast< DeclarationNode * >( decl->get_next() ) ) {
929                // scan ALL parameter names for each declaration name to check for duplicates
930                for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() ) ) {
931                        if ( *decl->name == *param->name ) {
932                                // type set => parameter name already transformed by a declaration names so there is a duplicate
933                                // declaration name attempting a second transformation
934                                if ( param->type ) SemanticError( param->location, string( "duplicate declaration name " ) + *param->name );
935                                // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
936                                // parameter name attempting a second transformation
937                                if ( ! decl->type ) SemanticError( param->location, string( "duplicate parameter name " ) + *param->name );
938                                param->type = decl->type;                               // set copy declaration type to parameter type
939                                decl->type = nullptr;                                   // reset declaration type
940                                param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter
941                        } // if
942                } // for
943                // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
944                if ( decl->type ) SemanticError( decl->location, string( "missing name in parameter list " ) + *decl->name );
945        } // for
946
947        // Parameter names without a declaration default to type int:
948        //
949        //    rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
950
951        for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() ) ) {
952                if ( ! param->type ) {                                                  // generate type int for empty parameter type
953                        param->type = new TypeData( TypeData::Basic );
954                        param->type->basictype = DeclarationNode::Int;
955                } // if
956        } // for
957
958        function.params = function.idList;                                      // newly modified idList becomes parameters
959        function.idList = nullptr;                                                      // idList now empty
960        delete function.oldDeclList;                                            // deletes entire list
961        function.oldDeclList = nullptr;                                         // reset
962} // buildKRFunction
963
964// Local Variables: //
965// tab-width: 4 //
966// mode: c++ //
967// compile-command: "make install" //
968// End: //
Note: See TracBrowser for help on using the repository browser.