source: src/Parser/TypeData.cc@ 65660bd

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 65660bd was 8c49c0e, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

decouple code that uses Type's forall list from std::list in preparation for trying to replace with a managed list

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