source: src/Parser/TypeData.cc@ ddcfb88

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

more refactoring of parser code

  • Property mode set to 100644
File size: 30.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 : Mon Aug 29 22:31:53 2016
13// Update Count : 277
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->basic.typeSpec = basic.typeSpec;
181 newtype->basic.modifiers = basic.modifiers;
182 break;
183 case Array:
184 newtype->array.dimension = maybeClone( array.dimension );
185 newtype->array.isVarLen = array.isVarLen;
186 newtype->array.isStatic = array.isStatic;
187 break;
188 case Function:
189 newtype->function.params = maybeClone( function.params );
190 newtype->function.idList = maybeClone( function.idList );
191 newtype->function.oldDeclList = maybeClone( function.oldDeclList );
192 newtype->function.body = maybeClone( function.body );
193 newtype->function.hasBody = function.hasBody;
194 newtype->function.newStyle = function.newStyle;
195 break;
196 case Aggregate:
197 newtype->aggregate.params = maybeClone( aggregate.params );
198 newtype->aggregate.actuals = maybeClone( aggregate.actuals );
199 newtype->aggregate.fields = maybeClone( aggregate.fields );
200 newtype->aggregate.name = aggregate.name;
201 newtype->aggregate.kind = aggregate.kind;
202 newtype->aggregate.body = aggregate.body;
203 break;
204 case AggregateInst:
205 newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
206 newtype->aggInst.params = maybeClone( aggInst.params );
207 break;
208 case Enum:
209 newtype->enumeration.name = enumeration.name;
210 newtype->enumeration.constants = maybeClone( enumeration.constants );
211 break;
212 case Symbolic:
213 case SymbolicInst:
214 newtype->symbolic.params = maybeClone( symbolic.params );
215 newtype->symbolic.actuals = maybeClone( symbolic.actuals );
216 newtype->symbolic.assertions = maybeClone( symbolic.assertions );
217 newtype->symbolic.isTypedef = symbolic.isTypedef;
218 newtype->symbolic.name = symbolic.name;
219 break;
220 case Variable:
221 assert( false );
222 // newtype->variable.assertions = maybeClone( variable.assertions );
223 // newtype->variable.name = variable.name;
224 // newtype->variable.tyClass = variable.tyClass;
225 break;
226 case Tuple:
227 newtype->tuple = maybeClone( tuple );
228 break;
229 case Typeof:
230 newtype->typeexpr = maybeClone( typeexpr );
231 break;
232 case Attr:
233 assert( false );
234 // newtype->attr.expr = maybeClone( attr.expr );
235 // newtype->attr.type = maybeClone( attr.type );
236 break;
237 case Builtin:
238 assert( false );
239 // newtype->builtin = builtin;
240 break;
241 } // switch
242 return newtype;
243} // TypeData::clone
244
245void TypeData::print( std::ostream &os, int indent ) const {
246 using std::endl;
247 using std::string;
248
249 for ( int i = 0; i < DeclarationNode::NoOfQualifier; i += 1 ) {
250 if ( qualifiers[i] ) os << DeclarationNode::qualifierName[ i ] << ' ';
251 } // for
252
253 if ( forall ) {
254 os << "forall " << endl;
255 forall->printList( os, indent + 4 );
256 } // if
257
258 switch ( kind ) {
259 case Unknown:
260 os << "entity of unknown type ";
261 break;
262 case Pointer:
263 os << "pointer ";
264 if ( base ) {
265 os << "to ";
266 base->print( os, indent );
267 } // if
268 break;
269 case EnumConstant:
270 os << "enumeration constant ";
271 break;
272 case Basic:
273 printEnums( basic.modifiers.begin(), basic.modifiers.end(), DeclarationNode::modifierName, os );
274 printEnums( basic.typeSpec.begin(), basic.typeSpec.end(), DeclarationNode::basicTypeName, os );
275 break;
276 case Array:
277 if ( array.isStatic ) {
278 os << "static ";
279 } // if
280 if ( array.dimension ) {
281 os << "array of ";
282 array.dimension->printOneLine( os, indent );
283 } else if ( array.isVarLen ) {
284 os << "variable-length array of ";
285 } else {
286 os << "open array of ";
287 } // if
288 if ( base ) {
289 base->print( os, indent );
290 } // if
291 break;
292 case Function:
293 os << "function" << endl;
294 if ( function.params ) {
295 os << string( indent + 2, ' ' ) << "with parameters " << endl;
296 function.params->printList( os, indent + 4 );
297 } else {
298 os << string( indent + 2, ' ' ) << "with no parameters " << endl;
299 } // if
300 if ( function.idList ) {
301 os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
302 function.idList->printList( os, indent + 4 );
303 } // if
304 if ( function.oldDeclList ) {
305 os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
306 function.oldDeclList->printList( os, indent + 4 );
307 } // if
308 os << string( indent + 2, ' ' ) << "returning ";
309 if ( base ) {
310 base->print( os, indent + 4 );
311 } else {
312 os << "nothing ";
313 } // if
314 os << endl;
315 if ( function.hasBody ) {
316 os << string( indent + 2, ' ' ) << "with body " << endl;
317 } // if
318 if ( function.body ) {
319 function.body->printList( os, indent + 2 );
320 } // if
321 break;
322 case Aggregate:
323 os << DeclarationNode::aggregateName[ aggregate.kind ] << ' ' << aggregate.name << endl;
324 if ( aggregate.params ) {
325 os << string( indent + 2, ' ' ) << "with type parameters " << endl;
326 aggregate.params->printList( os, indent + 4 );
327 } // if
328 if ( aggregate.actuals ) {
329 os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
330 aggregate.actuals->printList( os, indent + 4 );
331 } // if
332 if ( aggregate.fields ) {
333 os << string( indent + 2, ' ' ) << "with members " << endl;
334 aggregate.fields->printList( os, indent + 4 );
335 } // if
336 if ( aggregate.body ) {
337 os << string( indent + 2, ' ' ) << " with body " << endl;
338 } // if
339 break;
340 case AggregateInst:
341 if ( aggInst.aggregate ) {
342 os << "instance of " ;
343 aggInst.aggregate->print( os, indent );
344 } else {
345 os << "instance of an unspecified aggregate ";
346 } // if
347 if ( aggInst.params ) {
348 os << string( indent + 2, ' ' ) << "with parameters " << endl;
349 aggInst.params->printList( os, indent + 2 );
350 } // if
351 break;
352 case Enum:
353 os << "enumeration ";
354 if ( enumeration.constants ) {
355 os << "with constants" << endl;
356 enumeration.constants->printList( os, indent + 2 );
357 } // if
358 break;
359 case SymbolicInst:
360 os << "instance of type " << symbolic.name;
361 if ( symbolic.actuals ) {
362 os << " with parameters" << endl;
363 symbolic.actuals->printList( os, indent + 2 );
364 } // if
365 break;
366 case Symbolic:
367 if ( symbolic.isTypedef ) {
368 os << "typedef definition ";
369 } else {
370 os << "type definition ";
371 } // if
372 if ( symbolic.params ) {
373 os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
374 symbolic.params->printList( os, indent + 2 );
375 } // if
376 if ( symbolic.assertions ) {
377 os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
378 symbolic.assertions->printList( os, indent + 4 );
379 os << string( indent + 2, ' ' );
380 } // if
381 if ( base ) {
382 os << "for ";
383 base->print( os, indent + 2 );
384 } // if
385 break;
386 case Variable:
387 // os << DeclarationNode::typeClassName[ variable.tyClass ] << " variable ";
388 // if ( variable.assertions ) {
389 // os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
390 // variable.assertions->printList( os, indent + 4 );
391 // os << string( indent + 2, ' ' );
392 // } // if
393 break;
394 case Tuple:
395 os << "tuple ";
396 if ( tuple ) {
397 os << "with members " << endl;
398 tuple->printList( os, indent + 2 );
399 } // if
400 break;
401 case Typeof:
402 os << "type-of expression ";
403 if ( typeexpr ) {
404 typeexpr->print( os, indent + 2 );
405 } // if
406 break;
407 case Attr:
408 // os << "attribute type decl " << attr.name << " applied to ";
409 // if ( attr.expr ) {
410 // attr.expr->print( os, indent + 2 );
411 // } // if
412 // if ( attr.type ) {
413 // attr.type->print( os, indent + 2 );
414 // } // if
415 break;
416 case Builtin:
417 os << "gcc builtin type";
418 break;
419 default:
420 os << "internal error: TypeData::print " << kind << endl;
421 assert( false );
422 } // switch
423} // TypeData::print
424
425void buildForall( const DeclarationNode * firstNode, std::list< TypeDecl* > &outputList ) {
426 buildList( firstNode, outputList );
427 for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
428 if ( (*i)->get_kind() == TypeDecl::Any ) {
429 // add assertion parameters to `type' tyvars in reverse order
430 // add dtor: void ^?{}(T *)
431 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
432 dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
433 (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
434
435 // add copy ctor: void ?{}(T *, T)
436 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
437 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
438 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
439 (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
440
441 // add default ctor: void ?{}(T *)
442 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
443 ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
444 (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
445
446 // add assignment operator: T * ?=?(T *, T)
447 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
448 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
449 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
450 assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
451 (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
452 } // if
453 } // for
454}
455
456Type * typebuild( const TypeData * td ) {
457 assert( td );
458 switch ( td->kind ) {
459 case TypeData::Unknown:
460 // fill in implicit int
461 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
462 case TypeData::Basic:
463 return buildBasicType( td );
464 case TypeData::Pointer:
465 return buildPointer( td );
466 case TypeData::Array:
467 return buildArray( td );
468 case TypeData::Function:
469 return buildFunction( td );
470 case TypeData::AggregateInst:
471 return buildAggInst( td );
472 case TypeData::EnumConstant:
473 // the name gets filled in later -- by SymTab::Validate
474 return new EnumInstType( buildQualifiers( td ), "" );
475 case TypeData::SymbolicInst:
476 return buildSymbolicInst( td );;
477 case TypeData::Tuple:
478 return buildTuple( td );
479 case TypeData::Typeof:
480 return buildTypeof( td );
481 case TypeData::Builtin:
482 return new VarArgsType( buildQualifiers( td ) );
483 case TypeData::Attr:
484 assert( false );
485 return buildAttr( td );
486 case TypeData::Symbolic:
487 case TypeData::Enum:
488 case TypeData::Aggregate:
489 case TypeData::Variable:
490 assert( false );
491 } // switch
492 return 0;
493} // typebuild
494
495TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
496 TypeData * ret = 0;
497
498 switch ( td->kind ) {
499 case TypeData::Aggregate:
500 if ( ! toplevel && td->aggregate.fields ) {
501 ret = td->clone();
502 } // if
503 break;
504 case TypeData::Enum:
505 if ( ! toplevel && td->enumeration.constants ) {
506 ret = td->clone();
507 } // if
508 break;
509 case TypeData::AggregateInst:
510 if ( td->aggInst.aggregate ) {
511 ret = typeextractAggregate( td->aggInst.aggregate, false );
512 } // if
513 break;
514 default:
515 if ( td->base ) {
516 ret = typeextractAggregate( td->base, false );
517 } // if
518 } // switch
519 return ret;
520} // typeextractAggregate
521
522Type::Qualifiers buildQualifiers( const TypeData * td ) {
523 Type::Qualifiers q;
524 q.isConst = td->qualifiers[ DeclarationNode::Const ];
525 q.isVolatile = td->qualifiers[ DeclarationNode::Volatile ];
526 q.isRestrict = td->qualifiers[ DeclarationNode::Restrict ];
527 q.isLvalue = td->qualifiers[ DeclarationNode::Lvalue ];
528 q.isAtomic = td->qualifiers[ DeclarationNode::Atomic ];;
529 return q;
530} // buildQualifiers
531
532Type * buildBasicType( const TypeData * td ) {
533 static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
534 BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
535 BasicType::DoubleImaginary };
536 bool init = false;
537 bool sawDouble = false;
538 bool sawSigned = false;
539 BasicType::Kind ret;
540
541 for ( std::list< DeclarationNode::BasicType >::const_iterator i = td->basic.typeSpec.begin(); i != td->basic.typeSpec.end(); ++i ) {
542 if ( ! init ) {
543 init = true;
544 if ( *i == DeclarationNode::Void ) {
545 if ( td->basic.typeSpec.size() != 1 || ! td->basic.modifiers.empty() ) {
546 throw SemanticError( "invalid type specifier \"void\" in type: ", td );
547 } else {
548 return new VoidType( buildQualifiers( td ) );
549 } // if
550 } else {
551 ret = kindMap[ *i ];
552 } // if
553 } else {
554 switch ( *i ) {
555 case DeclarationNode::Float:
556 if ( sawDouble ) {
557 throw SemanticError( "invalid type specifier \"float\" in type: ", td );
558 } else {
559 switch ( ret ) {
560 case BasicType::DoubleComplex:
561 ret = BasicType::FloatComplex;
562 break;
563 case BasicType::DoubleImaginary:
564 ret = BasicType::FloatImaginary;
565 break;
566 default:
567 throw SemanticError( "invalid type specifier \"float\" in type: ", td );
568 } // switch
569 } // if
570 break;
571 case DeclarationNode::Double:
572 if ( sawDouble ) {
573 throw SemanticError( "duplicate type specifier \"double\" in type: ", td );
574 } else {
575 switch ( ret ) {
576 case BasicType::DoubleComplex:
577 case BasicType::DoubleImaginary:
578 break;
579 default:
580 throw SemanticError( "invalid type specifier \"double\" in type: ", td );
581 } // switch
582 } // if
583 break;
584 case DeclarationNode::Complex:
585 switch ( ret ) {
586 case BasicType::Float:
587 ret = BasicType::FloatComplex;
588 break;
589 case BasicType::Double:
590 ret = BasicType::DoubleComplex;
591 break;
592 default:
593 throw SemanticError( "invalid type specifier \"_Complex\" in type: ", td );
594 } // switch
595 break;
596 case DeclarationNode::Imaginary:
597 switch ( ret ) {
598 case BasicType::Float:
599 ret = BasicType::FloatImaginary;
600 break;
601 case BasicType::Double:
602 ret = BasicType::DoubleImaginary;
603 break;
604 default:
605 throw SemanticError( "invalid type specifier \"_Imaginary\" in type: ", td );
606 } // switch
607 break;
608 default:
609 throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type: ", td );
610 } // switch
611 } // if
612 if ( *i == DeclarationNode::Double ) {
613 sawDouble = true;
614 } // if
615 } // for
616
617 for ( std::list< DeclarationNode::Modifier >::const_iterator i = td->basic.modifiers.begin(); i != td->basic.modifiers.end(); ++i ) {
618 switch ( *i ) {
619 case DeclarationNode::Long:
620 if ( ! init ) {
621 init = true;
622 ret = BasicType::LongSignedInt;
623 } else {
624 switch ( ret ) {
625 case BasicType::SignedInt:
626 ret = BasicType::LongSignedInt;
627 break;
628 case BasicType::UnsignedInt:
629 ret = BasicType::LongUnsignedInt;
630 break;
631 case BasicType::LongSignedInt:
632 ret = BasicType::LongLongSignedInt;
633 break;
634 case BasicType::LongUnsignedInt:
635 ret = BasicType::LongLongUnsignedInt;
636 break;
637 case BasicType::Double:
638 ret = BasicType::LongDouble;
639 break;
640 case BasicType::DoubleComplex:
641 ret = BasicType::LongDoubleComplex;
642 break;
643 case BasicType::DoubleImaginary:
644 ret = BasicType::LongDoubleImaginary;
645 break;
646 default:
647 throw SemanticError( "invalid type modifier \"long\" in type: ", td );
648 } // switch
649 } // if
650 break;
651 case DeclarationNode::Short:
652 if ( ! init ) {
653 init = true;
654 ret = BasicType::ShortSignedInt;
655 } else {
656 switch ( ret ) {
657 case BasicType::SignedInt:
658 ret = BasicType::ShortSignedInt;
659 break;
660 case BasicType::UnsignedInt:
661 ret = BasicType::ShortUnsignedInt;
662 break;
663 default:
664 throw SemanticError( "invalid type modifier \"short\" in type: ", td );
665 } // switch
666 } // if
667 break;
668 case DeclarationNode::Signed:
669 if ( ! init ) {
670 init = true;
671 ret = BasicType::SignedInt;
672 } else if ( sawSigned ) {
673 throw SemanticError( "duplicate type modifer \"signed\" in type: ", td );
674 } else {
675 switch ( ret ) {
676 case BasicType::LongLongSignedInt:
677 ret = BasicType::LongLongUnsignedInt;
678 break;
679 case BasicType::LongSignedInt:
680 ret = BasicType::LongUnsignedInt;
681 break;
682 case BasicType::SignedInt:
683 case BasicType::ShortSignedInt:
684 break;
685 case BasicType::Char:
686 ret = BasicType::SignedChar;
687 break;
688 default:
689 throw SemanticError( "invalid type modifer \"signed\" in type: ", td );
690 } // switch
691 } // if
692 break;
693 case DeclarationNode::Unsigned:
694 if ( ! init ) {
695 init = true;
696 ret = BasicType::UnsignedInt;
697 } else if ( sawSigned ) {
698 throw SemanticError( "invalid type modifer \"unsigned\" in type: ", td );
699 } else {
700 switch ( ret ) {
701 case BasicType::LongLongSignedInt:
702 ret = BasicType::LongLongUnsignedInt;
703 break;
704 case BasicType::LongSignedInt:
705 ret = BasicType::LongUnsignedInt;
706 break;
707 case BasicType::SignedInt:
708 ret = BasicType::UnsignedInt;
709 break;
710 case BasicType::ShortSignedInt:
711 ret = BasicType::ShortUnsignedInt;
712 break;
713 case BasicType::Char:
714 ret = BasicType::UnsignedChar;
715 break;
716 default:
717 throw SemanticError( "invalid type modifer \"unsigned\" in type: ", td );
718 } // switch
719 } // if
720 break;
721 } // switch
722
723 if ( *i == DeclarationNode::Signed ) {
724 sawSigned = true;
725 } // if
726 } // for
727
728 BasicType * bt;
729 if ( ! init ) {
730 bt = new BasicType( buildQualifiers( td ), BasicType::SignedInt );
731 } else {
732 bt = new BasicType( buildQualifiers( td ), ret );
733 } // if
734 buildForall( td->forall, bt->get_forall() );
735 return bt;
736} // buildBasicType
737
738PointerType * buildPointer( const TypeData * td ) {
739 PointerType * pt;
740 if ( td->base ) {
741 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
742 } else {
743 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
744 } // if
745 buildForall( td->forall, pt->get_forall() );
746 return pt;
747} // buildPointer
748
749ArrayType * buildArray( const TypeData * td ) {
750 ArrayType * at;
751 if ( td->base ) {
752 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
753 td->array.isVarLen, td->array.isStatic );
754 } else {
755 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
756 maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
757 } // if
758 buildForall( td->forall, at->get_forall() );
759 return at;
760} // buildPointer
761
762AggregateDecl * buildAggregate( const TypeData * td ) {
763 assert( td->kind == TypeData::Aggregate );
764 AggregateDecl * at;
765 switch ( td->aggregate.kind ) {
766 case DeclarationNode::Struct:
767 at = new StructDecl( td->aggregate.name );
768 buildForall( td->aggregate.params, at->get_parameters() );
769 break;
770 case DeclarationNode::Union:
771 at = new UnionDecl( td->aggregate.name );
772 buildForall( td->aggregate.params, at->get_parameters() );
773 break;
774 case DeclarationNode::Trait:
775 at = new TraitDecl( td->aggregate.name );
776 buildList( td->aggregate.params, at->get_parameters() );
777 break;
778 default:
779 assert( false );
780 } // switch
781
782 buildList( td->aggregate.fields, at->get_members() );
783 at->set_body( td->aggregate.body );
784
785 return at;
786} // buildAggregate
787
788ReferenceToType * buildAggInst( const TypeData * td ) {
789 assert( td->kind == TypeData::AggregateInst );
790
791 ReferenceToType * ret;
792 if ( td->aggInst.aggregate->kind == TypeData::Enum ) {
793 ret = new EnumInstType( buildQualifiers( td ), td->aggInst.aggregate->enumeration.name );
794 } else {
795 assert( td->aggInst.aggregate->kind == TypeData::Aggregate );
796 switch ( td->aggInst.aggregate->aggregate.kind ) {
797 case DeclarationNode::Struct:
798 ret = new StructInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
799 break;
800 case DeclarationNode::Union:
801 ret = new UnionInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
802 break;
803 case DeclarationNode::Trait:
804 ret = new TraitInstType( buildQualifiers( td ), td->aggInst.aggregate->aggregate.name );
805 break;
806 default:
807 assert( false );
808 } // switch
809 } // if
810 buildList( td->aggInst.params, ret->get_parameters() );
811 buildForall( td->forall, ret->get_forall() );
812 return ret;
813} // buildAggInst
814
815NamedTypeDecl * buildSymbolic( const TypeData * td, const std::string & name, DeclarationNode::StorageClass sc ) {
816 assert( td->kind == TypeData::Symbolic );
817 NamedTypeDecl * ret;
818 assert( td->base );
819 if ( td->symbolic.isTypedef ) {
820 ret = new TypedefDecl( name, sc, typebuild( td->base ) );
821 } else {
822 ret = new TypeDecl( name, sc, typebuild( td->base ), TypeDecl::Any );
823 } // if
824 buildList( td->symbolic.params, ret->get_parameters() );
825 buildList( td->symbolic.assertions, ret->get_assertions() );
826 return ret;
827} // buildSymbolic
828
829TypeDecl * buildVariable( const TypeData * td ) {
830 assert( false );
831 return nullptr;
832 // assert( td->kind == TypeData::Variable );
833 // static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
834
835 // TypeDecl * ret = new TypeDecl( td->variable.name, DeclarationNode::NoStorageClass, 0, kindMap[ td->variable.tyClass ] );
836 // buildList( td->variable.assertions, ret->get_assertions() );
837 // return ret;
838} // buildSymbolic
839
840EnumDecl * buildEnum( const TypeData * td ) {
841 assert( td->kind == TypeData::Enum );
842 EnumDecl * ret = new EnumDecl( td->enumeration.name );
843 buildList( td->enumeration.constants, ret->get_members() );
844 std::list< Declaration * >::iterator members = ret->get_members().begin();
845 for ( const DeclarationNode * cur = td->enumeration. constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
846 if ( cur->has_enumeratorValue() ) {
847 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
848 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), std::list< Expression * >() ) );
849 } // if
850 } // for
851 return ret;
852} // buildEnum
853
854TypeInstType * buildSymbolicInst( const TypeData * td ) {
855 assert( td->kind == TypeData::SymbolicInst );
856 TypeInstType * ret = new TypeInstType( buildQualifiers( td ), td->symbolic.name, false );
857 buildList( td->symbolic.actuals, ret->get_parameters() );
858 buildForall( td->forall, ret->get_forall() );
859 return ret;
860} // buildSymbolicInst
861
862TupleType * buildTuple( const TypeData * td ) {
863 assert( td->kind == TypeData::Tuple );
864 TupleType * ret = new TupleType( buildQualifiers( td ) );
865 buildTypeList( td->tuple, ret->get_types() );
866 buildForall( td->forall, ret->get_forall() );
867 return ret;
868} // buildTuple
869
870TypeofType * buildTypeof( const TypeData * td ) {
871 assert( td->kind == TypeData::Typeof );
872 assert( td->typeexpr );
873 // assert( td->typeexpr->expr );
874 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
875} // buildTypeof
876
877AttrType * buildAttr( const TypeData * td ) {
878 assert( false );
879 return nullptr;
880 // assert( td->kind == TypeData::Attr );
881 // // assert( td->attr );
882 // AttrType * ret;
883 // if ( td->attr.expr ) {
884 // ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.expr->build() );
885 // } else {
886 // assert( td->attr.type );
887 // ret = new AttrType( buildQualifiers( td ), td->attr.name, td->attr.type->buildType() );
888 // } // if
889 // return ret;
890} // buildAttr
891
892Declaration * buildDecl( const TypeData * td, std::string name, DeclarationNode::StorageClass sc, Expression * bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Spec linkage, Initializer * init ) {
893 if ( td->kind == TypeData::Function ) {
894 FunctionDecl * decl;
895 if ( td->function.hasBody ) {
896 if ( td->function.body ) {
897 Statement * stmt = td->function.body->build();
898 CompoundStmt * body = dynamic_cast< CompoundStmt* >( stmt );
899 assert( body );
900 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), body, isInline, isNoreturn );
901 } else {
902 // std::list< Label > ls;
903 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), new CompoundStmt( std::list< Label >() ), isInline, isNoreturn );
904 } // if
905 } else {
906 decl = new FunctionDecl( name, sc, linkage, buildFunction( td ), 0, isInline, isNoreturn );
907 } // if
908 for ( DeclarationNode * cur = td->function.idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_next() ) ) {
909 if ( cur->get_name() != "" ) {
910 decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
911 } // if
912 } // for
913 buildList( td->function.oldDeclList, decl->get_oldDecls() );
914 return decl;
915 } else if ( td->kind == TypeData::Aggregate ) {
916 return buildAggregate( td );
917 } else if ( td->kind == TypeData::Enum ) {
918 return buildEnum( td );
919 } else if ( td->kind == TypeData::Symbolic ) {
920 return buildSymbolic( td, name, sc );
921 } else if ( td->kind == TypeData::Variable ) {
922 assert( false );
923 return buildVariable( td );
924 } else {
925 return new ObjectDecl( name, sc, linkage, bitfieldWidth, typebuild( td ), init, std::list< Attribute * >(), isInline, isNoreturn );
926 } // if
927 return 0;
928} // buildDecl
929
930FunctionType * buildFunction( const TypeData * td ) {
931 assert( td->kind == TypeData::Function );
932 bool hasEllipsis = td->function.params ? td->function.params->get_hasEllipsis() : true;
933 if ( ! td->function.params ) hasEllipsis = ! td->function.newStyle;
934 FunctionType * ft = new FunctionType( buildQualifiers( td ), hasEllipsis );
935 buildList( td->function.params, ft->get_parameters() );
936 buildForall( td->forall, ft->get_forall() );
937 if ( td->base ) {
938 switch ( td->base->kind ) {
939 case TypeData::Tuple:
940 buildList( td->base->tuple, ft->get_returnVals() );
941 break;
942 default:
943 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( buildDecl( td->base, "", DeclarationNode::NoStorageClass, 0, false, false, LinkageSpec::Cforall ) ) );
944 } // switch
945 } else {
946 ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
947 } // if
948 return ft;
949} // buildFunction
950
951// Local Variables: //
952// tab-width: 4 //
953// mode: c++ //
954// compile-command: "make install" //
955// End: //
Note: See TracBrowser for help on using the repository browser.