source: src/Parser/TypeData.cc@ 46fa473

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum with_gc
Last change on this file since 46fa473 was d15a45d, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add missing initializers for TypeData::Aggregate_t members

  • 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 : 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.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.