source: src/Parser/TypeData.cc@ 783dfd6

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 resolv-new with_gc
Last change on this file since 783dfd6 was ca1a547, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

fixed missing body in enumeration, removed hashBody function flag, only generate sue prototype if body

  • Property mode set to 100644
File size: 29.6 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 Feb 23 16:26:39 2017
13// Update Count : 477
14//
15
16#include <cassert>
17#include <algorithm>
18#include <iterator>
19#include "Common/utility.h"
20#include "TypeData.h"
21#include "SynTree/Type.h"
22#include "SynTree/Declaration.h"
23#include "SynTree/Expression.h"
24#include "SynTree/Statement.h"
25#include "SynTree/Initializer.h"
26using namespace std;
27
28TypeData::TypeData( Kind k ) : kind( k ), base( nullptr ), forall( nullptr ) {
29 switch ( kind ) {
30 case Unknown:
31 case Pointer:
32 case EnumConstant:
33 // nothing else to initialize
34 break;
35 case Basic:
36 // basic = new Basic_t;
37 break;
38 case Array:
39 // array = new Array_t;
40 array.dimension = nullptr;
41 array.isVarLen = false;
42 array.isStatic = false;
43 break;
44 case Function:
45 // function = new Function_t;
46 function.params = nullptr;
47 function.idList = nullptr;
48 function.oldDeclList = nullptr;
49 function.body = nullptr;
50 function.newStyle = false;
51 break;
52 case Aggregate:
53 // aggregate = new Aggregate_t;
54 aggregate.name = nullptr;
55 aggregate.params = nullptr;
56 aggregate.actuals = nullptr;
57 aggregate.fields = nullptr;
58 aggregate.body = false;
59 break;
60 case AggregateInst:
61 // aggInst = new AggInst_t;
62 aggInst.aggregate = nullptr;
63 aggInst.params = nullptr;
64 break;
65 case Enum:
66 // enumeration = new Enumeration_t;
67 enumeration.name = nullptr;
68 enumeration.constants = nullptr;
69 enumeration.body = false;
70 break;
71 case Symbolic:
72 case SymbolicInst:
73 // symbolic = new Symbolic_t;
74 symbolic.name = nullptr;
75 symbolic.params = nullptr;
76 symbolic.actuals = nullptr;
77 symbolic.assertions = nullptr;
78 break;
79 case Tuple:
80 // tuple = new Tuple_t;
81 tuple = nullptr;
82 break;
83 case Typeof:
84 // typeexpr = new Typeof_t;
85 typeexpr = nullptr;
86 break;
87 case Builtin:
88 // builtin = new Builtin_t;
89 break;
90 } // switch
91} // TypeData::TypeData
92
93TypeData::~TypeData() {
94 delete base;
95 delete forall;
96
97 switch ( kind ) {
98 case Unknown:
99 case Pointer:
100 case EnumConstant:
101 // nothing to destroy
102 break;
103 case Basic:
104 // delete basic;
105 break;
106 case Array:
107 delete array.dimension;
108 // delete array;
109 break;
110 case Function:
111 delete function.params;
112 delete function.idList;
113 delete function.oldDeclList;
114 delete function.body;
115 // delete function;
116 break;
117 case Aggregate:
118 delete aggregate.name;
119 delete aggregate.params;
120 delete aggregate.actuals;
121 delete aggregate.fields;
122 // delete aggregate;
123 break;
124 case AggregateInst:
125 delete aggInst.aggregate;
126 delete aggInst.params;
127 // delete aggInst;
128 break;
129 case Enum:
130 delete enumeration.name;
131 delete enumeration.constants;
132 // delete enumeration;
133 break;
134 case Symbolic:
135 case SymbolicInst:
136 delete symbolic.name;
137 delete symbolic.params;
138 delete symbolic.actuals;
139 delete symbolic.assertions;
140 // delete symbolic;
141 break;
142 case Tuple:
143 // delete tuple->members;
144 delete tuple;
145 break;
146 case Typeof:
147 // delete typeexpr->expr;
148 delete typeexpr;
149 break;
150 case Builtin:
151 // delete builtin;
152 break;
153 } // switch
154} // TypeData::~TypeData
155
156TypeData * TypeData::clone() const {
157 TypeData * newtype = new TypeData( kind );
158 newtype->qualifiers = qualifiers;
159 newtype->base = maybeClone( base );
160 newtype->forall = maybeClone( forall );
161
162 switch ( kind ) {
163 case Unknown:
164 case EnumConstant:
165 case Pointer:
166 // nothing else to copy
167 break;
168 case Basic:
169 newtype->basictype = basictype;
170 newtype->complextype = complextype;
171 newtype->signedness = signedness;
172 newtype->length = length;
173 break;
174 case Array:
175 newtype->array.dimension = maybeClone( array.dimension );
176 newtype->array.isVarLen = array.isVarLen;
177 newtype->array.isStatic = array.isStatic;
178 break;
179 case Function:
180 newtype->function.params = maybeClone( function.params );
181 newtype->function.idList = maybeClone( function.idList );
182 newtype->function.oldDeclList = maybeClone( function.oldDeclList );
183 newtype->function.body = maybeClone( function.body );
184 newtype->function.newStyle = function.newStyle;
185 break;
186 case Aggregate:
187 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
188 newtype->aggregate.params = maybeClone( aggregate.params );
189 newtype->aggregate.actuals = maybeClone( aggregate.actuals );
190 newtype->aggregate.fields = maybeClone( aggregate.fields );
191 newtype->aggregate.kind = aggregate.kind;
192 newtype->aggregate.body = aggregate.body;
193 break;
194 case AggregateInst:
195 newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
196 newtype->aggInst.params = maybeClone( aggInst.params );
197 break;
198 case Enum:
199 newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
200 newtype->enumeration.constants = maybeClone( enumeration.constants );
201 newtype->enumeration.body = enumeration.body;
202 break;
203 case Symbolic:
204 case SymbolicInst:
205 newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr;
206 newtype->symbolic.params = maybeClone( symbolic.params );
207 newtype->symbolic.actuals = maybeClone( symbolic.actuals );
208 newtype->symbolic.assertions = maybeClone( symbolic.assertions );
209 newtype->symbolic.isTypedef = symbolic.isTypedef;
210 break;
211 case Tuple:
212 newtype->tuple = maybeClone( tuple );
213 break;
214 case Typeof:
215 newtype->typeexpr = maybeClone( typeexpr );
216 break;
217 case Builtin:
218 assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One );
219 newtype->builtintype = builtintype;
220 break;
221 } // switch
222 return newtype;
223} // TypeData::clone
224
225void TypeData::print( ostream &os, int indent ) const {
226 for ( int i = 0; i < DeclarationNode::NoQualifier; i += 1 ) {
227 if ( qualifiers[i] ) os << DeclarationNode::qualifierName[ i ] << ' ';
228 } // for
229
230 if ( forall ) {
231 os << "forall " << endl;
232 forall->printList( os, indent + 4 );
233 } // if
234
235 switch ( kind ) {
236 case Unknown:
237 os << "entity of unknown type ";
238 break;
239 case Pointer:
240 os << "pointer ";
241 if ( base ) {
242 os << "to ";
243 base->print( os, indent );
244 } // if
245 break;
246 case EnumConstant:
247 os << "enumeration constant ";
248 break;
249 case Basic:
250 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessName[ signedness ] << " ";
251 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthName[ length ] << " ";
252 assert( basictype != DeclarationNode::NoBasicType );
253 os << DeclarationNode::basicTypeName[ basictype ] << " ";
254 if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeName[ complextype ] << " ";
255 break;
256 case Array:
257 if ( array.isStatic ) {
258 os << "static ";
259 } // if
260 if ( array.dimension ) {
261 os << "array of ";
262 array.dimension->printOneLine( os, indent );
263 } else if ( array.isVarLen ) {
264 os << "variable-length array of ";
265 } else {
266 os << "open array of ";
267 } // if
268 if ( base ) {
269 base->print( os, indent );
270 } // if
271 break;
272 case Function:
273 os << "function" << endl;
274 if ( function.params ) {
275 os << string( indent + 2, ' ' ) << "with parameters " << endl;
276 function.params->printList( os, indent + 4 );
277 } else {
278 os << string( indent + 2, ' ' ) << "with no parameters " << endl;
279 } // if
280 if ( function.idList ) {
281 os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
282 function.idList->printList( os, indent + 4 );
283 } // if
284 if ( function.oldDeclList ) {
285 os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
286 function.oldDeclList->printList( os, indent + 4 );
287 } // if
288 os << string( indent + 2, ' ' ) << "returning ";
289 if ( base ) {
290 base->print( os, indent + 4 );
291 } else {
292 os << "nothing ";
293 } // if
294 os << endl;
295 if ( function.body ) {
296 os << string( indent + 2, ' ' ) << "with body " << endl;
297 function.body->printList( os, indent + 2 );
298 } // if
299 break;
300 case Aggregate:
301 os << DeclarationNode::aggregateName[ aggregate.kind ] << ' ' << *aggregate.name << endl;
302 if ( aggregate.params ) {
303 os << string( indent + 2, ' ' ) << "with type parameters " << endl;
304 aggregate.params->printList( os, indent + 4 );
305 } // if
306 if ( aggregate.actuals ) {
307 os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
308 aggregate.actuals->printList( os, indent + 4 );
309 } // if
310 if ( aggregate.fields ) {
311 os << string( indent + 2, ' ' ) << "with members " << endl;
312 aggregate.fields->printList( os, indent + 4 );
313 } // if
314 if ( aggregate.body ) {
315 os << string( indent + 2, ' ' ) << " with body " << endl;
316 } // if
317 break;
318 case AggregateInst:
319 if ( aggInst.aggregate ) {
320 os << "instance of " ;
321 aggInst.aggregate->print( os, indent );
322 } else {
323 os << "instance of an unspecified aggregate ";
324 } // if
325 if ( aggInst.params ) {
326 os << string( indent + 2, ' ' ) << "with parameters " << endl;
327 aggInst.params->printList( os, indent + 2 );
328 } // if
329 break;
330 case Enum:
331 os << "enumeration ";
332 if ( enumeration.constants ) {
333 os << "with constants" << endl;
334 enumeration.constants->printList( os, indent + 2 );
335 } // if
336 if ( enumeration.body ) {
337 os << string( indent + 2, ' ' ) << " with body " << endl;
338 } // if
339 break;
340 case SymbolicInst:
341 os << "instance of type " << *symbolic.name;
342 if ( symbolic.actuals ) {
343 os << " with parameters" << endl;
344 symbolic.actuals->printList( os, indent + 2 );
345 } // if
346 break;
347 case Symbolic:
348 if ( symbolic.isTypedef ) {
349 os << "typedef definition ";
350 } else {
351 os << "type definition ";
352 } // if
353 if ( symbolic.params ) {
354 os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
355 symbolic.params->printList( os, indent + 2 );
356 } // if
357 if ( symbolic.assertions ) {
358 os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
359 symbolic.assertions->printList( os, indent + 4 );
360 os << string( indent + 2, ' ' );
361 } // if
362 if ( base ) {
363 os << "for ";
364 base->print( os, indent + 2 );
365 } // if
366 break;
367 case Tuple:
368 os << "tuple ";
369 if ( tuple ) {
370 os << "with members " << endl;
371 tuple->printList( os, indent + 2 );
372 } // if
373 break;
374 case Typeof:
375 os << "type-of expression ";
376 if ( typeexpr ) {
377 typeexpr->print( os, indent + 2 );
378 } // if
379 break;
380 case Builtin:
381 os << "gcc builtin type";
382 break;
383 default:
384 os << "internal error: TypeData::print " << kind << endl;
385 assert( false );
386 } // switch
387} // TypeData::print
388
389template< typename ForallList >
390void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
391 buildList( firstNode, outputList );
392 for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
393 TypeDecl * td = static_cast<TypeDecl*>(*i);
394 if ( td->get_kind() == TypeDecl::Any ) {
395 // add assertion parameters to `type' tyvars in reverse order
396 // add dtor: void ^?{}(T *)
397 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
398 dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
399 td->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, nullptr, false, false ) );
400
401 // add copy ctor: void ?{}(T *, T)
402 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
403 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
404 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
405 td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, nullptr, false, false ) );
406
407 // add default ctor: void ?{}(T *)
408 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
409 ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
410 td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, nullptr, false, false ) );
411
412 // add assignment operator: T * ?=?(T *, T)
413 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
414 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
415 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
416 assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
417 td->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, nullptr, false, false ) );
418 } // if
419 } // for
420}
421
422Type * typebuild( const TypeData * td ) {
423 assert( td );
424 switch ( td->kind ) {
425 case TypeData::Unknown:
426 // fill in implicit int
427 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
428 case TypeData::Basic:
429 return buildBasicType( td );
430 case TypeData::Pointer:
431 return buildPointer( td );
432 case TypeData::Array:
433 return buildArray( td );
434 case TypeData::Function:
435 return buildFunction( td );
436 case TypeData::AggregateInst:
437 return buildAggInst( td );
438 case TypeData::EnumConstant:
439 // the name gets filled in later -- by SymTab::Validate
440 return new EnumInstType( buildQualifiers( td ), "" );
441 case TypeData::SymbolicInst:
442 return buildSymbolicInst( td );;
443 case TypeData::Tuple:
444 return buildTuple( td );
445 case TypeData::Typeof:
446 return buildTypeof( td );
447 case TypeData::Builtin:
448 if(td->builtintype == DeclarationNode::Zero) {
449 return new ZeroType( emptyQualifiers );
450 }
451 else if(td->builtintype == DeclarationNode::One) {
452 return new OneType( emptyQualifiers );
453 }
454 else {
455 return new VarArgsType( buildQualifiers( td ) );
456 }
457 case TypeData::Symbolic:
458 case TypeData::Enum:
459 case TypeData::Aggregate:
460 assert( false );
461 } // switch
462 return nullptr;
463} // typebuild
464
465TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
466 TypeData * ret = nullptr;
467
468 switch ( td->kind ) {
469 case TypeData::Aggregate:
470 if ( ! toplevel && td->aggregate.fields ) {
471 ret = td->clone();
472 } // if
473 break;
474 case TypeData::Enum:
475 if ( ! toplevel && td->enumeration.constants ) {
476 ret = td->clone();
477 } // if
478 break;
479 case TypeData::AggregateInst:
480 if ( td->aggInst.aggregate ) {
481 ret = typeextractAggregate( td->aggInst.aggregate, false );
482 } // if
483 break;
484 default:
485 if ( td->base ) {
486 ret = typeextractAggregate( td->base, false );
487 } // if
488 } // switch
489 return ret;
490} // typeextractAggregate
491
492Type::Qualifiers buildQualifiers( const TypeData * td ) {
493 Type::Qualifiers q;
494 q.isConst = td->qualifiers[ DeclarationNode::Const ];
495 q.isVolatile = td->qualifiers[ DeclarationNode::Volatile ];
496 q.isRestrict = td->qualifiers[ DeclarationNode::Restrict ];
497 q.isLvalue = td->qualifiers[ DeclarationNode::Lvalue ];
498 q.isAtomic = td->qualifiers[ DeclarationNode::Atomic ];;
499 return q;
500} // buildQualifiers
501
502Type * buildBasicType( const TypeData * td ) {
503 BasicType::Kind ret;
504
505 switch ( td->basictype ) {
506 case DeclarationNode::Void:
507 if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) {
508 throw SemanticError( "invalid type specifier \"void\" in type: ", td );
509 } // if
510
511 return new VoidType( buildQualifiers( td ) );
512 break;
513
514 case DeclarationNode::Bool:
515 if ( td->signedness != DeclarationNode::NoSignedness ) {
516 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td );
517 } // if
518 if ( td->length != DeclarationNode::NoLength ) {
519 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
520 } // if
521
522 ret = BasicType::Bool;
523 break;
524
525 case DeclarationNode::Char:
526 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
527 // character types. The implementation shall define char to have the same range, representation, and behavior as
528 // either signed char or unsigned char.
529 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
530
531 if ( td->length != DeclarationNode::NoLength ) {
532 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
533 } // if
534
535 ret = chartype[ td->signedness ];
536 break;
537
538 case DeclarationNode::Int:
539 static BasicType::Kind inttype[2][4] = {
540 { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
541 { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
542 };
543
544 Integral: ;
545 if ( td->signedness == DeclarationNode::NoSignedness ) {
546 const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
547 } // if
548 ret = inttype[ td->signedness ][ td->length ];
549 break;
550
551 case DeclarationNode::Float:
552 case DeclarationNode::Double:
553 case DeclarationNode::LongDouble: // not set until below
554 static BasicType::Kind floattype[3][3] = {
555 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
556 { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
557 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
558 };
559
560 FloatingPoint: ;
561 if ( td->signedness != DeclarationNode::NoSignedness ) {
562 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td );
563 } // if
564 if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
565 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
566 } // if
567 if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) {
568 throw SemanticError( "invalid type specifier \"long\" in type: ", td );
569 } // if
570 if ( td->length == DeclarationNode::Long ) {
571 const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
572 } // if
573
574 ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
575 break;
576
577 case DeclarationNode::NoBasicType:
578 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
579 if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
580 const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
581 goto FloatingPoint;
582 } // if
583
584 const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
585 goto Integral;
586 default:
587 assert(false);
588 return nullptr;
589 } // switch
590
591 BasicType * bt = new BasicType( buildQualifiers( td ), ret );
592 buildForall( td->forall, bt->get_forall() );
593 return bt;
594} // buildBasicType
595
596PointerType * buildPointer( const TypeData * td ) {
597 PointerType * pt;
598 if ( td->base ) {
599 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
600 } else {
601 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
602 } // if
603 buildForall( td->forall, pt->get_forall() );
604 return pt;
605} // buildPointer
606
607ArrayType * buildArray( const TypeData * td ) {
608 ArrayType * at;
609 if ( td->base ) {
610 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
611 td->array.isVarLen, td->array.isStatic );
612 } else {
613 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
614 maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
615 } // if
616 buildForall( td->forall, at->get_forall() );
617 return at;
618} // buildPointer
619
620AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes ) {
621 assert( td->kind == TypeData::Aggregate );
622 AggregateDecl * at;
623 switch ( td->aggregate.kind ) {
624 case DeclarationNode::Struct:
625 at = new StructDecl( *td->aggregate.name, attributes );
626 buildForall( td->aggregate.params, at->get_parameters() );
627 break;
628 case DeclarationNode::Union:
629 at = new UnionDecl( *td->aggregate.name, attributes );
630 buildForall( td->aggregate.params, at->get_parameters() );
631 break;
632 case DeclarationNode::Trait:
633 at = new TraitDecl( *td->aggregate.name, attributes );
634 buildList( td->aggregate.params, at->get_parameters() );
635 break;
636 default:
637 assert( false );
638 } // switch
639
640 buildList( td->aggregate.fields, at->get_members() );
641 at->set_body( td->aggregate.body );
642
643 return at;
644} // buildAggregate
645
646ReferenceToType * buildAggInst( const TypeData * td ) {
647 assert( td->kind == TypeData::AggregateInst );
648
649 ReferenceToType * ret;
650 if ( td->aggInst.aggregate->kind == TypeData::Enum ) {
651 ret = new EnumInstType( buildQualifiers( td ), *td->aggInst.aggregate->enumeration.name );
652 } else {
653 assert( td->aggInst.aggregate->kind == TypeData::Aggregate );
654 switch ( td->aggInst.aggregate->aggregate.kind ) {
655 case DeclarationNode::Struct:
656 assert( td->aggInst.aggregate->aggregate.name );
657 ret = new StructInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
658 break;
659 case DeclarationNode::Union:
660 ret = new UnionInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
661 break;
662 case DeclarationNode::Trait:
663 ret = new TraitInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
664 break;
665 default:
666 assert( false );
667 } // switch
668 } // if
669 buildList( td->aggInst.params, ret->get_parameters() );
670 buildForall( td->forall, ret->get_forall() );
671 return ret;
672} // buildAggInst
673
674NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, DeclarationNode::StorageClass sc ) {
675 assert( td->kind == TypeData::Symbolic );
676 NamedTypeDecl * ret;
677 assert( td->base );
678 if ( td->symbolic.isTypedef ) {
679 ret = new TypedefDecl( name, sc, typebuild( td->base ) );
680 } else {
681 ret = new TypeDecl( name, sc, typebuild( td->base ), TypeDecl::Any );
682 } // if
683 buildList( td->symbolic.params, ret->get_parameters() );
684 buildList( td->symbolic.assertions, ret->get_assertions() );
685 return ret;
686} // buildSymbolic
687
688EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes ) {
689 assert( td->kind == TypeData::Enum );
690 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes );
691 buildList( td->enumeration.constants, ret->get_members() );
692 list< Declaration * >::iterator members = ret->get_members().begin();
693 for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
694 if ( cur->has_enumeratorValue() ) {
695 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
696 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), list< Expression * >() ) );
697 } // if
698 } // for
699 ret->set_body( td->enumeration.body );
700 return ret;
701} // buildEnum
702
703TypeInstType * buildSymbolicInst( const TypeData * td ) {
704 assert( td->kind == TypeData::SymbolicInst );
705 TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
706 buildList( td->symbolic.actuals, ret->get_parameters() );
707 buildForall( td->forall, ret->get_forall() );
708 return ret;
709} // buildSymbolicInst
710
711TupleType * buildTuple( const TypeData * td ) {
712 assert( td->kind == TypeData::Tuple );
713 TupleType * ret = new TupleType( buildQualifiers( td ) );
714 buildTypeList( td->tuple, ret->get_types() );
715 buildForall( td->forall, ret->get_forall() );
716 return ret;
717} // buildTuple
718
719TypeofType * buildTypeof( const TypeData * td ) {
720 assert( td->kind == TypeData::Typeof );
721 assert( td->typeexpr );
722 // assert( td->typeexpr->expr );
723 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
724} // buildTypeof
725
726Declaration * buildDecl( const TypeData * td, const string &name, DeclarationNode::StorageClass sc, Expression * bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Spec linkage, ConstantExpr *asmName, Initializer * init, std::list< Attribute * > attributes ) {
727 if ( td->kind == TypeData::Function ) {
728 if ( td->function.idList ) { // KR function ?
729 buildKRFunction( td->function ); // transform into C11 function
730 } // if
731
732 FunctionDecl * decl;
733 Statement * stmt = maybeBuild<Statement>( td->function.body );
734 CompoundStmt * body = dynamic_cast< CompoundStmt* >( stmt );
735 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), body, isInline, isNoreturn, attributes );
736 return decl->set_asmName( asmName );
737 } else if ( td->kind == TypeData::Aggregate ) {
738 return buildAggregate( td, attributes );
739 } else if ( td->kind == TypeData::Enum ) {
740 return buildEnum( td, attributes );
741 } else if ( td->kind == TypeData::Symbolic ) {
742 return buildSymbolic( td, name, sc );
743 } else {
744 return (new ObjectDecl( name, sc, linkage, bitfieldWidth, typebuild( td ), init, attributes, isInline, isNoreturn ))->set_asmName( asmName );
745 } // if
746 return nullptr;
747} // buildDecl
748
749FunctionType * buildFunction( const TypeData * td ) {
750 assert( td->kind == TypeData::Function );
751 bool hasEllipsis = td->function.params ? td->function.params->get_hasEllipsis() : true;
752 if ( ! td->function.params ) hasEllipsis = ! td->function.newStyle;
753 FunctionType * ft = new FunctionType( buildQualifiers( td ), hasEllipsis );
754 buildList( td->function.params, ft->get_parameters() );
755 buildForall( td->forall, ft->get_forall() );
756 if ( td->base ) {
757 switch ( td->base->kind ) {
758 case TypeData::Tuple:
759 buildList( td->base->tuple, ft->get_returnVals() );
760 break;
761 default:
762 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( buildDecl( td->base, "", DeclarationNode::NoStorageClass, nullptr, false, false, LinkageSpec::Cforall, nullptr ) ) );
763 } // switch
764 } else {
765 ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
766 } // if
767 return ft;
768} // buildFunction
769
770// Transform KR routine declarations into C99 routine declarations:
771//
772// rtn( a, b, c ) int a, c; double b {} => int rtn( int a, double c, int b ) {}
773//
774// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
775// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
776// extra names are disallowed.
777//
778// Note, there is no KR routine-prototype syntax:
779//
780// rtn( a, b, c ) int a, c; double b; // invalid KR prototype
781// rtn(); // valid KR prototype
782
783void buildKRFunction( const TypeData::Function_t & function ) {
784 assert( ! function.params );
785 // loop over declaration first as it is easier to spot errors
786 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = dynamic_cast< DeclarationNode * >( decl->get_next() ) ) {
787 // scan ALL parameter names for each declaration name to check for duplicates
788 for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode* >( param->get_next() ) ) {
789 if ( *decl->name == *param->name ) {
790 // type set => parameter name already transformed by a declaration names so there is a duplicate
791 // declaration name attempting a second transformation
792 if ( param->type ) throw SemanticError( string( "duplicate declaration name " ) + *param->name );
793 // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
794 // parameter name attempting a second transformation
795 if ( ! decl->type ) throw SemanticError( string( "duplicate parameter name " ) + *param->name );
796 param->type = decl->type; // set copy declaration type to parameter type
797 decl->type = nullptr; // reset declaration type
798 param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter
799 } // if
800 } // for
801 // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
802 if ( decl->type ) throw SemanticError( string( "missing name in parameter list " ) + *decl->name );
803 } // for
804
805 // Parameter names without a declaration default to type int:
806 //
807 // rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
808
809 for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode* >( param->get_next() ) ) {
810 if ( ! param->type ) { // generate type int for empty parameter type
811 param->type = new TypeData( TypeData::Basic );
812 param->type->basictype = DeclarationNode::Int;
813 } // if
814 } // for
815
816 function.params = function.idList; // newly modified idList becomes parameters
817 function.idList = nullptr; // idList now empty
818 delete function.oldDeclList; // deletes entire list
819 function.oldDeclList = nullptr; // reset
820} // buildKRFunction
821
822// Local Variables: //
823// tab-width: 4 //
824// mode: c++ //
825// compile-command: "make install" //
826// End: //
Note: See TracBrowser for help on using the repository browser.