source: src/Parser/TypeData.cc @ 2f0a0678

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 2f0a0678 was 6926a6d, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

fixes for gcc-7/8

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