source: src/Parser/TypeData.cc@ f31cb3e

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 f31cb3e was c0aa336, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

third attempt at gcc attributes

  • Property mode set to 100644
File size: 27.2 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 : Fri Jan 27 15:28:56 2017
13// Update Count : 428
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.hasBody = false;
51 function.newStyle = false;
52 break;
53 case Aggregate:
54 // aggregate = new Aggregate_t;
55 aggregate.name = nullptr;
56 aggregate.params = nullptr;
57 aggregate.actuals = nullptr;
58 aggregate.fields = nullptr;
59 aggregate.body = false;
60 break;
61 case AggregateInst:
62 // aggInst = new AggInst_t;
63 aggInst.aggregate = nullptr;
64 aggInst.params = nullptr;
65 break;
66 case Enum:
67 // enumeration = new Enumeration_t;
68 enumeration.name = nullptr;
69 enumeration.constants = nullptr;
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.hasBody = function.hasBody;
185 newtype->function.newStyle = function.newStyle;
186 break;
187 case Aggregate:
188 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
189 newtype->aggregate.params = maybeClone( aggregate.params );
190 newtype->aggregate.actuals = maybeClone( aggregate.actuals );
191 newtype->aggregate.fields = maybeClone( aggregate.fields );
192 newtype->aggregate.kind = aggregate.kind;
193 newtype->aggregate.body = aggregate.body;
194 break;
195 case AggregateInst:
196 newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
197 newtype->aggInst.params = maybeClone( aggInst.params );
198 break;
199 case Enum:
200 newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
201 newtype->enumeration.constants = maybeClone( enumeration.constants );
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.hasBody ) {
296 os << string( indent + 2, ' ' ) << "with body " << endl;
297 } // if
298 if ( function.body ) {
299 function.body->printList( os, indent + 2 );
300 } // if
301 break;
302 case Aggregate:
303 os << DeclarationNode::aggregateName[ aggregate.kind ] << ' ' << *aggregate.name << endl;
304 if ( aggregate.params ) {
305 os << string( indent + 2, ' ' ) << "with type parameters " << endl;
306 aggregate.params->printList( os, indent + 4 );
307 } // if
308 if ( aggregate.actuals ) {
309 os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
310 aggregate.actuals->printList( os, indent + 4 );
311 } // if
312 if ( aggregate.fields ) {
313 os << string( indent + 2, ' ' ) << "with members " << endl;
314 aggregate.fields->printList( os, indent + 4 );
315 } // if
316 if ( aggregate.body ) {
317 os << string( indent + 2, ' ' ) << " with body " << endl;
318 } // if
319 break;
320 case AggregateInst:
321 if ( aggInst.aggregate ) {
322 os << "instance of " ;
323 aggInst.aggregate->print( os, indent );
324 } else {
325 os << "instance of an unspecified aggregate ";
326 } // if
327 if ( aggInst.params ) {
328 os << string( indent + 2, ' ' ) << "with parameters " << endl;
329 aggInst.params->printList( os, indent + 2 );
330 } // if
331 break;
332 case Enum:
333 os << "enumeration ";
334 if ( enumeration.constants ) {
335 os << "with constants" << endl;
336 enumeration.constants->printList( os, indent + 2 );
337 } // if
338 break;
339 case SymbolicInst:
340 os << "instance of type " << *symbolic.name;
341 if ( symbolic.actuals ) {
342 os << " with parameters" << endl;
343 symbolic.actuals->printList( os, indent + 2 );
344 } // if
345 break;
346 case Symbolic:
347 if ( symbolic.isTypedef ) {
348 os << "typedef definition ";
349 } else {
350 os << "type definition ";
351 } // if
352 if ( symbolic.params ) {
353 os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
354 symbolic.params->printList( os, indent + 2 );
355 } // if
356 if ( symbolic.assertions ) {
357 os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
358 symbolic.assertions->printList( os, indent + 4 );
359 os << string( indent + 2, ' ' );
360 } // if
361 if ( base ) {
362 os << "for ";
363 base->print( os, indent + 2 );
364 } // if
365 break;
366 case Tuple:
367 os << "tuple ";
368 if ( tuple ) {
369 os << "with members " << endl;
370 tuple->printList( os, indent + 2 );
371 } // if
372 break;
373 case Typeof:
374 os << "type-of expression ";
375 if ( typeexpr ) {
376 typeexpr->print( os, indent + 2 );
377 } // if
378 break;
379 case Builtin:
380 os << "gcc builtin type";
381 break;
382 default:
383 os << "internal error: TypeData::print " << kind << endl;
384 assert( false );
385 } // switch
386} // TypeData::print
387
388template< typename ForallList >
389void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
390 buildList( firstNode, outputList );
391 for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
392 TypeDecl * td = static_cast<TypeDecl*>(*i);
393 if ( td->get_kind() == TypeDecl::Any ) {
394 // add assertion parameters to `type' tyvars in reverse order
395 // add dtor: void ^?{}(T *)
396 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
397 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 ) );
398 td->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, nullptr, false, false ) );
399
400 // add copy ctor: void ?{}(T *, T)
401 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
402 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 ) );
403 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
404 td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, nullptr, false, false ) );
405
406 // add default ctor: void ?{}(T *)
407 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
408 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 ) );
409 td->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, nullptr, false, false ) );
410
411 // add assignment operator: T * ?=?(T *, T)
412 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
413 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 ) );
414 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
415 assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
416 td->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, nullptr, false, false ) );
417 } // if
418 } // for
419}
420
421Type * typebuild( const TypeData * td ) {
422 assert( td );
423 switch ( td->kind ) {
424 case TypeData::Unknown:
425 // fill in implicit int
426 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
427 case TypeData::Basic:
428 return buildBasicType( td );
429 case TypeData::Pointer:
430 return buildPointer( td );
431 case TypeData::Array:
432 return buildArray( td );
433 case TypeData::Function:
434 return buildFunction( td );
435 case TypeData::AggregateInst:
436 return buildAggInst( td );
437 case TypeData::EnumConstant:
438 // the name gets filled in later -- by SymTab::Validate
439 return new EnumInstType( buildQualifiers( td ), "" );
440 case TypeData::SymbolicInst:
441 return buildSymbolicInst( td );;
442 case TypeData::Tuple:
443 return buildTuple( td );
444 case TypeData::Typeof:
445 return buildTypeof( td );
446 case TypeData::Builtin:
447 if(td->builtintype == DeclarationNode::Zero) {
448 return new ZeroType( emptyQualifiers );
449 }
450 else if(td->builtintype == DeclarationNode::One) {
451 return new OneType( emptyQualifiers );
452 }
453 else {
454 return new VarArgsType( buildQualifiers( td ) );
455 }
456 case TypeData::Symbolic:
457 case TypeData::Enum:
458 case TypeData::Aggregate:
459 assert( false );
460 } // switch
461 return nullptr;
462} // typebuild
463
464TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
465 TypeData * ret = nullptr;
466
467 switch ( td->kind ) {
468 case TypeData::Aggregate:
469 if ( ! toplevel && td->aggregate.fields ) {
470 ret = td->clone();
471 } // if
472 break;
473 case TypeData::Enum:
474 if ( ! toplevel && td->enumeration.constants ) {
475 ret = td->clone();
476 } // if
477 break;
478 case TypeData::AggregateInst:
479 if ( td->aggInst.aggregate ) {
480 ret = typeextractAggregate( td->aggInst.aggregate, false );
481 } // if
482 break;
483 default:
484 if ( td->base ) {
485 ret = typeextractAggregate( td->base, false );
486 } // if
487 } // switch
488 return ret;
489} // typeextractAggregate
490
491Type::Qualifiers buildQualifiers( const TypeData * td ) {
492 Type::Qualifiers q;
493 q.isConst = td->qualifiers[ DeclarationNode::Const ];
494 q.isVolatile = td->qualifiers[ DeclarationNode::Volatile ];
495 q.isRestrict = td->qualifiers[ DeclarationNode::Restrict ];
496 q.isLvalue = td->qualifiers[ DeclarationNode::Lvalue ];
497 q.isAtomic = td->qualifiers[ DeclarationNode::Atomic ];;
498 return q;
499} // buildQualifiers
500
501Type * buildBasicType( const TypeData * td ) {
502 BasicType::Kind ret;
503
504 switch ( td->basictype ) {
505 case DeclarationNode::Void:
506 if ( td->signedness != DeclarationNode::NoSignedness && td->length != DeclarationNode::NoLength ) {
507 throw SemanticError( "invalid type specifier \"void\" in type: ", td );
508 } // if
509
510 return new VoidType( buildQualifiers( td ) );
511 break;
512
513 case DeclarationNode::Bool:
514 if ( td->signedness != DeclarationNode::NoSignedness ) {
515 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td );
516 } // if
517 if ( td->length != DeclarationNode::NoLength ) {
518 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
519 } // if
520
521 ret = BasicType::Bool;
522 break;
523
524 case DeclarationNode::Char:
525 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
526 // character types. The implementation shall define char to have the same range, representation, and behavior as
527 // either signed char or unsigned char.
528 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
529
530 if ( td->length != DeclarationNode::NoLength ) {
531 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
532 } // if
533
534 ret = chartype[ td->signedness ];
535 break;
536
537 case DeclarationNode::Int:
538 static BasicType::Kind inttype[2][4] = {
539 { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
540 { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
541 };
542
543 Integral: ;
544 if ( td->signedness == DeclarationNode::NoSignedness ) {
545 const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
546 } // if
547 ret = inttype[ td->signedness ][ td->length ];
548 break;
549
550 case DeclarationNode::Float:
551 case DeclarationNode::Double:
552 case DeclarationNode::LongDouble: // not set until below
553 static BasicType::Kind floattype[3][3] = {
554 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
555 { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
556 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
557 };
558
559 FloatingPoint: ;
560 if ( td->signedness != DeclarationNode::NoSignedness ) {
561 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::signednessName[ td->signedness ] + " in type: ", td );
562 } // if
563 if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
564 throw SemanticError( string( "invalid type specifier " ) + DeclarationNode::lengthName[ td->length ] + " in type: ", td );
565 } // if
566 if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) {
567 throw SemanticError( "invalid type specifier \"long\" in type: ", td );
568 } // if
569 if ( td->length == DeclarationNode::Long ) {
570 const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
571 } // if
572
573 ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
574 break;
575
576 case DeclarationNode::NoBasicType:
577 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
578 if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
579 const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
580 goto FloatingPoint;
581 } // if
582
583 const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
584 goto Integral;
585 default:
586 assert(false);
587 return nullptr;
588 } // switch
589
590 BasicType * bt = new BasicType( buildQualifiers( td ), ret );
591 buildForall( td->forall, bt->get_forall() );
592 return bt;
593} // buildBasicType
594
595PointerType * buildPointer( const TypeData * td ) {
596 PointerType * pt;
597 if ( td->base ) {
598 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
599 } else {
600 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
601 } // if
602 buildForall( td->forall, pt->get_forall() );
603 return pt;
604} // buildPointer
605
606ArrayType * buildArray( const TypeData * td ) {
607 ArrayType * at;
608 if ( td->base ) {
609 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
610 td->array.isVarLen, td->array.isStatic );
611 } else {
612 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
613 maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
614 } // if
615 buildForall( td->forall, at->get_forall() );
616 return at;
617} // buildPointer
618
619AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes ) {
620 assert( td->kind == TypeData::Aggregate );
621 AggregateDecl * at;
622 switch ( td->aggregate.kind ) {
623 case DeclarationNode::Struct:
624 at = new StructDecl( *td->aggregate.name, attributes );
625 buildForall( td->aggregate.params, at->get_parameters() );
626 break;
627 case DeclarationNode::Union:
628 at = new UnionDecl( *td->aggregate.name, attributes );
629 buildForall( td->aggregate.params, at->get_parameters() );
630 break;
631 case DeclarationNode::Trait:
632 at = new TraitDecl( *td->aggregate.name, attributes );
633 buildList( td->aggregate.params, at->get_parameters() );
634 break;
635 default:
636 assert( false );
637 } // switch
638
639 buildList( td->aggregate.fields, at->get_members() );
640 at->set_body( td->aggregate.body );
641
642 return at;
643} // buildAggregate
644
645ReferenceToType * buildAggInst( const TypeData * td ) {
646 assert( td->kind == TypeData::AggregateInst );
647
648 ReferenceToType * ret;
649 if ( td->aggInst.aggregate->kind == TypeData::Enum ) {
650 ret = new EnumInstType( buildQualifiers( td ), *td->aggInst.aggregate->enumeration.name );
651 } else {
652 assert( td->aggInst.aggregate->kind == TypeData::Aggregate );
653 switch ( td->aggInst.aggregate->aggregate.kind ) {
654 case DeclarationNode::Struct:
655 assert( td->aggInst.aggregate->aggregate.name );
656 ret = new StructInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
657 break;
658 case DeclarationNode::Union:
659 ret = new UnionInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
660 break;
661 case DeclarationNode::Trait:
662 ret = new TraitInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
663 break;
664 default:
665 assert( false );
666 } // switch
667 } // if
668 buildList( td->aggInst.params, ret->get_parameters() );
669 buildForall( td->forall, ret->get_forall() );
670 return ret;
671} // buildAggInst
672
673NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, DeclarationNode::StorageClass sc ) {
674 assert( td->kind == TypeData::Symbolic );
675 NamedTypeDecl * ret;
676 assert( td->base );
677 if ( td->symbolic.isTypedef ) {
678 ret = new TypedefDecl( name, sc, typebuild( td->base ) );
679 } else {
680 ret = new TypeDecl( name, sc, typebuild( td->base ), TypeDecl::Any );
681 } // if
682 buildList( td->symbolic.params, ret->get_parameters() );
683 buildList( td->symbolic.assertions, ret->get_assertions() );
684 return ret;
685} // buildSymbolic
686
687EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes ) {
688 assert( td->kind == TypeData::Enum );
689 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes );
690 buildList( td->enumeration.constants, ret->get_members() );
691 list< Declaration * >::iterator members = ret->get_members().begin();
692 for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
693 if ( cur->has_enumeratorValue() ) {
694 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
695 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), list< Expression * >() ) );
696 } // if
697 } // for
698 return ret;
699} // buildEnum
700
701TypeInstType * buildSymbolicInst( const TypeData * td ) {
702 assert( td->kind == TypeData::SymbolicInst );
703 TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
704 buildList( td->symbolic.actuals, ret->get_parameters() );
705 buildForall( td->forall, ret->get_forall() );
706 return ret;
707} // buildSymbolicInst
708
709TupleType * buildTuple( const TypeData * td ) {
710 assert( td->kind == TypeData::Tuple );
711 TupleType * ret = new TupleType( buildQualifiers( td ) );
712 buildTypeList( td->tuple, ret->get_types() );
713 buildForall( td->forall, ret->get_forall() );
714 return ret;
715} // buildTuple
716
717TypeofType * buildTypeof( const TypeData * td ) {
718 assert( td->kind == TypeData::Typeof );
719 assert( td->typeexpr );
720 // assert( td->typeexpr->expr );
721 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
722} // buildTypeof
723
724Declaration * 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 ) {
725 if ( td->kind == TypeData::Function ) {
726 FunctionDecl * decl;
727 if ( td->function.hasBody ) {
728 if ( td->function.body ) {
729 Statement * stmt = td->function.body->build();
730 CompoundStmt * body = dynamic_cast< CompoundStmt* >( stmt );
731 assert( body );
732 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), body, isInline, isNoreturn, attributes );
733 } else {
734 // list< Label > ls;
735 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), new CompoundStmt( list< Label >() ), isInline, isNoreturn, attributes );
736 } // if
737 } else {
738 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), nullptr, isInline, isNoreturn, attributes );
739 } // if
740 for ( DeclarationNode * cur = td->function.idList; cur != nullptr; cur = dynamic_cast< DeclarationNode* >( cur->get_next() ) ) {
741 if ( cur->name ) {
742 decl->get_oldIdents().insert( decl->get_oldIdents().end(), *cur->name );
743 } // if
744 } // for
745 buildList( td->function.oldDeclList, decl->get_oldDecls() );
746 return decl->set_asmName( asmName );
747 } else if ( td->kind == TypeData::Aggregate ) {
748 return buildAggregate( td, attributes );
749 } else if ( td->kind == TypeData::Enum ) {
750 return buildEnum( td, attributes );
751 } else if ( td->kind == TypeData::Symbolic ) {
752 return buildSymbolic( td, name, sc );
753 } else {
754 return (new ObjectDecl( name, sc, linkage, bitfieldWidth, typebuild( td ), init, attributes, isInline, isNoreturn ))->set_asmName( asmName );
755 } // if
756 return nullptr;
757} // buildDecl
758
759FunctionType * buildFunction( const TypeData * td ) {
760 assert( td->kind == TypeData::Function );
761 bool hasEllipsis = td->function.params ? td->function.params->get_hasEllipsis() : true;
762 if ( ! td->function.params ) hasEllipsis = ! td->function.newStyle;
763 FunctionType * ft = new FunctionType( buildQualifiers( td ), hasEllipsis );
764 buildList( td->function.params, ft->get_parameters() );
765 buildForall( td->forall, ft->get_forall() );
766 if ( td->base ) {
767 switch ( td->base->kind ) {
768 case TypeData::Tuple:
769 buildList( td->base->tuple, ft->get_returnVals() );
770 break;
771 default:
772 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( buildDecl( td->base, "", DeclarationNode::NoStorageClass, nullptr, false, false, LinkageSpec::Cforall, nullptr ) ) );
773 } // switch
774 } else {
775 ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
776 } // if
777 return ft;
778} // buildFunction
779
780// Local Variables: //
781// tab-width: 4 //
782// mode: c++ //
783// compile-command: "make install" //
784// End: //
Note: See TracBrowser for help on using the repository browser.