source: src/Parser/TypeData.cc@ cff1143

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since cff1143 was 721f17a, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

fix OT_LABELADDRESS warning, parse genric types

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