source: src/Parser/TypeData.cc@ c14cff1

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 with_gc
Last change on this file since c14cff1 was a9a259c, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

autogenerate union ctor/dtors, autogenerate struct copy ctor, temporarily allow explicit calls to autogenerated ctors, add copy ctor to type constraints

  • 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 : Rob Schluntz
12// Last Modified On : Thu Jan 14 10:43:42 2016
13// Update Count : 36
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
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 default:
400 os << "internal error: TypeData::print " << kind << endl;
401 assert( false );
402 } // switch
403}
404
405TypeData *TypeData::extractAggregate( bool toplevel ) const {
406 TypeData *ret = 0;
407
408 switch ( kind ) {
409 case Aggregate:
410 if ( ! toplevel && aggregate->fields ) {
411 ret = clone();
412 ret->qualifiers.clear();
413 } // if
414 break;
415 case Enum:
416 if ( ! toplevel && enumeration->constants ) {
417 ret = clone();
418 ret->qualifiers.clear();
419 } // if
420 break;
421 case AggregateInst:
422 if ( aggInst->aggregate ) {
423 ret = aggInst->aggregate->extractAggregate( false );
424 } // if
425 break;
426 default:
427 if ( base ) {
428 ret = base->extractAggregate( false );
429 } // if
430 } // switch
431 return ret;
432}
433
434void buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList ) {
435 buildList( firstNode, outputList );
436 for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
437 if ( (*i)->get_kind() == TypeDecl::Any ) {
438 // add assertion parameters to `type' tyvars
439 // add assignment operator: T * ?=?(T *, T)
440 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
441 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 ) );
442 assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
443 assignType->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
444 (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
445
446 // add default ctor: void ?{}(T *)
447 FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
448 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 ) );
449 (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
450
451 // add copy ctor: void ?{}(T *, T)
452 FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false );
453 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 ) );
454 copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
455 (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
456
457 // add dtor: void ^?{}(T *)
458 FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false );
459 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 ) );
460 (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
461 } // if
462 } // for
463}
464
465Declaration *TypeData::buildDecl( std::string name, DeclarationNode::StorageClass sc, Expression *bitfieldWidth, bool isInline, bool isNoreturn, LinkageSpec::Type linkage, Initializer *init ) const {
466 if ( kind == TypeData::Function ) {
467 FunctionDecl *decl;
468 if ( function->hasBody ) {
469 if ( function->body ) {
470 Statement *stmt = function->body->build();
471 CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt );
472 assert( body );
473 decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline, isNoreturn );
474 } else {
475 // std::list<Label> ls;
476 decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list<Label>() ), isInline, isNoreturn );
477 } // if
478 } else {
479 decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline, isNoreturn );
480 } // if
481 for ( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_link() ) ) {
482 if ( cur->get_name() != "" ) {
483 decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
484 } // if
485 } // for
486 buildList( function->oldDeclList, decl->get_oldDecls() );
487 return decl;
488 } else if ( kind == TypeData::Aggregate ) {
489 return buildAggregate();
490 } else if ( kind == TypeData::Enum ) {
491 return buildEnum();
492 } else if ( kind == TypeData::Symbolic ) {
493 return buildSymbolic( name, sc );
494 } else if ( kind == TypeData::Variable ) {
495 return buildVariable();
496 } else {
497 return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init, isInline, isNoreturn );
498 } // if
499 return 0;
500}
501
502Type *TypeData::build() const {
503 switch ( kind ) {
504 case Unknown:
505 // fill in implicit int
506 return new BasicType( buildQualifiers(), BasicType::SignedInt );
507 case Basic:
508 return buildBasicType();
509 case Pointer:
510 return buildPointer();
511 case Array:
512 return buildArray();
513 case Function:
514 return buildFunction();
515 case AggregateInst:
516 return buildAggInst();
517 case EnumConstant:
518 // the name gets filled in later -- by SymTab::Validate
519 return new EnumInstType( buildQualifiers(), "" );
520 case SymbolicInst:
521 return buildSymbolicInst();;
522 case Tuple:
523 return buildTuple();
524 case Typeof:
525 return buildTypeof();
526 case Attr:
527 return buildAttr();
528 case Symbolic:
529 case Enum:
530 case Aggregate:
531 case Variable:
532 assert( false );
533 } // switch
534 return 0;
535}
536
537Type::Qualifiers TypeData::buildQualifiers() const {
538 Type::Qualifiers q;
539 for ( std::list< DeclarationNode::Qualifier >::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i ) {
540 switch ( *i ) {
541 case DeclarationNode::Const:
542 q.isConst = true;
543 break;
544 case DeclarationNode::Volatile:
545 q.isVolatile = true;
546 break;
547 case DeclarationNode::Restrict:
548 q.isRestrict = true;
549 break;
550 case DeclarationNode::Lvalue:
551 q.isLvalue = true;
552 break;
553 case DeclarationNode::Atomic:
554 q.isAtomic = true;
555 break;
556 } // switch
557 } // for
558 return q;
559}
560
561Type *TypeData::buildBasicType() const {
562 static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
563 BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
564 BasicType::DoubleImaginary };
565 bool init = false;
566 bool sawDouble = false;
567 bool sawSigned = false;
568 BasicType::Kind ret;
569
570 for ( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) {
571 if ( ! init ) {
572 init = true;
573 if ( *i == DeclarationNode::Void ) {
574 if ( basic->typeSpec.size() != 1 || ! basic->modifiers.empty() ) {
575 throw SemanticError( "invalid type specifier \"void\" in type: ", this );
576 } else {
577 return new VoidType( buildQualifiers() );
578 } // if
579 } else {
580 ret = kindMap[ *i ];
581 } // if
582 } else {
583 switch ( *i ) {
584 case DeclarationNode::Float:
585 if ( sawDouble ) {
586 throw SemanticError( "invalid type specifier \"float\" in type: ", this );
587 } else {
588 switch ( ret ) {
589 case BasicType::DoubleComplex:
590 ret = BasicType::FloatComplex;
591 break;
592 case BasicType::DoubleImaginary:
593 ret = BasicType::FloatImaginary;
594 break;
595 default:
596 throw SemanticError( "invalid type specifier \"float\" in type: ", this );
597 } // switch
598 } // if
599 break;
600 case DeclarationNode::Double:
601 if ( sawDouble ) {
602 throw SemanticError( "duplicate type specifier \"double\" in type: ", this );
603 } else {
604 switch ( ret ) {
605 case BasicType::DoubleComplex:
606 case BasicType::DoubleImaginary:
607 break;
608 default:
609 throw SemanticError( "invalid type specifier \"double\" in type: ", this );
610 } // switch
611 } // if
612 break;
613 case DeclarationNode::Complex:
614 switch ( ret ) {
615 case BasicType::Float:
616 ret = BasicType::FloatComplex;
617 break;
618 case BasicType::Double:
619 ret = BasicType::DoubleComplex;
620 break;
621 default:
622 throw SemanticError( "invalid type specifier \"_Complex\" in type: ", this );
623 } // switch
624 break;
625 case DeclarationNode::Imaginary:
626 switch ( ret ) {
627 case BasicType::Float:
628 ret = BasicType::FloatImaginary;
629 break;
630 case BasicType::Double:
631 ret = BasicType::DoubleImaginary;
632 break;
633 default:
634 throw SemanticError( "invalid type specifier \"_Imaginary\" in type: ", this );
635 } // switch
636 break;
637 default:
638 throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type: ", this );
639 } // switch
640 } // if
641 if ( *i == DeclarationNode::Double ) {
642 sawDouble = true;
643 } // if
644 } // for
645
646 for ( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) {
647 switch ( *i ) {
648 case DeclarationNode::Long:
649 if ( ! init ) {
650 init = true;
651 ret = BasicType::LongSignedInt;
652 } else {
653 switch ( ret ) {
654 case BasicType::SignedInt:
655 ret = BasicType::LongSignedInt;
656 break;
657 case BasicType::UnsignedInt:
658 ret = BasicType::LongUnsignedInt;
659 break;
660 case BasicType::LongSignedInt:
661 ret = BasicType::LongLongSignedInt;
662 break;
663 case BasicType::LongUnsignedInt:
664 ret = BasicType::LongLongUnsignedInt;
665 break;
666 case BasicType::Double:
667 ret = BasicType::LongDouble;
668 break;
669 case BasicType::DoubleComplex:
670 ret = BasicType::LongDoubleComplex;
671 break;
672 case BasicType::DoubleImaginary:
673 ret = BasicType::LongDoubleImaginary;
674 break;
675 default:
676 throw SemanticError( "invalid type modifier \"long\" in type: ", this );
677 } // switch
678 } // if
679 break;
680 case DeclarationNode::Short:
681 if ( ! init ) {
682 init = true;
683 ret = BasicType::ShortSignedInt;
684 } else {
685 switch ( ret ) {
686 case BasicType::SignedInt:
687 ret = BasicType::ShortSignedInt;
688 break;
689 case BasicType::UnsignedInt:
690 ret = BasicType::ShortUnsignedInt;
691 break;
692 default:
693 throw SemanticError( "invalid type modifier \"short\" in type: ", this );
694 } // switch
695 } // if
696 break;
697 case DeclarationNode::Signed:
698 if ( ! init ) {
699 init = true;
700 ret = BasicType::SignedInt;
701 } else if ( sawSigned ) {
702 throw SemanticError( "duplicate type modifer \"signed\" in type: ", this );
703 } else {
704 switch ( ret ) {
705 case BasicType::LongLongSignedInt:
706 ret = BasicType::LongLongUnsignedInt;
707 break;
708 case BasicType::LongSignedInt:
709 ret = BasicType::LongUnsignedInt;
710 break;
711 case BasicType::SignedInt:
712 case BasicType::ShortSignedInt:
713 break;
714 case BasicType::Char:
715 ret = BasicType::SignedChar;
716 break;
717 default:
718 throw SemanticError( "invalid type modifer \"signed\" in type: ", this );
719 } // switch
720 } // if
721 break;
722 case DeclarationNode::Unsigned:
723 if ( ! init ) {
724 init = true;
725 ret = BasicType::UnsignedInt;
726 } else if ( sawSigned ) {
727 throw SemanticError( "invalid type modifer \"unsigned\" in type: ", this );
728 } else {
729 switch ( ret ) {
730 case BasicType::LongLongSignedInt:
731 ret = BasicType::LongLongUnsignedInt;
732 break;
733 case BasicType::LongSignedInt:
734 ret = BasicType::LongUnsignedInt;
735 break;
736 case BasicType::SignedInt:
737 ret = BasicType::UnsignedInt;
738 break;
739 case BasicType::ShortSignedInt:
740 ret = BasicType::ShortUnsignedInt;
741 break;
742 case BasicType::Char:
743 ret = BasicType::UnsignedChar;
744 break;
745 default:
746 throw SemanticError( "invalid type modifer \"unsigned\" in type: ", this );
747 } // switch
748 } // if
749 break;
750 } // switch
751
752 if ( *i == DeclarationNode::Signed ) {
753 sawSigned = true;
754 } // if
755 } // for
756
757 BasicType *bt;
758 if ( ! init ) {
759 bt = new BasicType( buildQualifiers(), BasicType::SignedInt );
760 } else {
761 bt = new BasicType( buildQualifiers(), ret );
762 } // if
763 buildForall( forall, bt->get_forall() );
764 return bt;
765}
766
767
768PointerType *TypeData::buildPointer() const {
769 PointerType *pt;
770 if ( base ) {
771 pt = new PointerType( buildQualifiers(), base->build() );
772 } else {
773 pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
774 } // if
775 buildForall( forall, pt->get_forall() );
776 return pt;
777}
778
779ArrayType *TypeData::buildArray() const {
780 ArrayType *at;
781 if ( base ) {
782 at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ),
783 array->isVarLen, array->isStatic );
784 } else {
785 at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
786 maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic );
787 } // if
788 buildForall( forall, at->get_forall() );
789 return at;
790}
791
792FunctionType *TypeData::buildFunction() const {
793 assert( kind == Function );
794 bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true;
795 if ( ! function->params ) hasEllipsis = ! function->newStyle;
796 FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis );
797 buildList( function->params, ft->get_parameters() );
798 buildForall( forall, ft->get_forall() );
799 if ( base ) {
800 switch ( base->kind ) {
801 case Tuple:
802 buildList( base->tuple->members, ft->get_returnVals() );
803 break;
804 default:
805 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", DeclarationNode::NoStorageClass, 0, false, false, LinkageSpec::Cforall ) ) );
806 } // switch
807 } else {
808 ft->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
809 } // if
810 return ft;
811}
812
813AggregateDecl *TypeData::buildAggregate() const {
814 assert( kind == Aggregate );
815 AggregateDecl *at;
816 switch ( aggregate->kind ) {
817 case DeclarationNode::Struct:
818 at = new StructDecl( aggregate->name );
819 buildForall( aggregate->params, at->get_parameters() );
820 break;
821 case DeclarationNode::Union:
822 at = new UnionDecl( aggregate->name );
823 buildForall( aggregate->params, at->get_parameters() );
824 break;
825 case DeclarationNode::Context:
826 at = new ContextDecl( aggregate->name );
827 buildList( aggregate->params, at->get_parameters() );
828 break;
829 default:
830 assert( false );
831 } // switch
832// buildList( aggregate->params, at->get_parameters() );
833 buildList( aggregate->fields, at->get_members() );
834
835 return at;
836}
837
838/// namespace {
839/// Type*
840/// makeType( Declaration* decl )
841/// {
842/// if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
843/// return dwt->get_type()->clone();
844/// } else {
845/// return 0;
846/// }
847/// }
848/// }
849
850ReferenceToType *TypeData::buildAggInst() const {
851 assert( kind == AggregateInst );
852
853 ReferenceToType *ret;
854 if ( aggInst->aggregate->kind == Enum ) {
855 ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name );
856 } else {
857 assert( aggInst->aggregate->kind == Aggregate );
858 switch ( aggInst->aggregate->aggregate->kind ) {
859 case DeclarationNode::Struct:
860 ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
861 break;
862 case DeclarationNode::Union:
863 ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
864 break;
865 case DeclarationNode::Context:
866 ret = new ContextInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
867 break;
868 default:
869 assert( false );
870 } // switch
871 } // if
872 buildList( aggInst->params, ret->get_parameters() );
873 buildForall( forall, ret->get_forall() );
874 return ret;
875}
876
877NamedTypeDecl *TypeData::buildSymbolic( const std::string &name, DeclarationNode::StorageClass sc ) const {
878 assert( kind == Symbolic );
879 NamedTypeDecl *ret;
880 if ( symbolic->isTypedef ) {
881 ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) );
882 } else {
883 ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any );
884 } // if
885 buildList( symbolic->params, ret->get_parameters() );
886 buildList( symbolic->assertions, ret->get_assertions() );
887 return ret;
888}
889
890TypeDecl *TypeData::buildVariable() const {
891 assert( kind == Variable );
892 static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
893
894 TypeDecl *ret = new TypeDecl( variable->name, DeclarationNode::NoStorageClass, 0, kindMap[ variable->tyClass ] );
895 buildList( variable->assertions, ret->get_assertions() );
896 return ret;
897}
898
899EnumDecl *TypeData::buildEnum() const {
900 assert( kind == Enum );
901 EnumDecl *ret = new EnumDecl( enumeration->name );
902 buildList( enumeration->constants, ret->get_members() );
903 return ret;
904}
905
906TypeInstType *TypeData::buildSymbolicInst() const {
907 assert( kind == SymbolicInst );
908 TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name, false );
909 buildList( symbolic->actuals, ret->get_parameters() );
910 buildForall( forall, ret->get_forall() );
911 return ret;
912}
913
914TupleType *TypeData::buildTuple() const {
915 assert( kind == Tuple );
916 TupleType *ret = new TupleType( buildQualifiers() );
917 buildTypeList( tuple->members, ret->get_types() );
918 buildForall( forall, ret->get_forall() );
919 return ret;
920}
921
922TypeofType *TypeData::buildTypeof() const {
923 assert( kind == Typeof );
924 assert( typeexpr );
925 assert( typeexpr->expr );
926 TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() );
927 return ret;
928}
929
930AttrType *TypeData::buildAttr() const {
931 assert( kind == Attr );
932 assert( attr );
933 AttrType *ret;
934 if ( attr->expr ) {
935 ret = new AttrType( buildQualifiers(), attr->name, attr->expr->build() );
936 } else {
937 assert( attr->type );
938 ret = new AttrType( buildQualifiers(), attr->name, attr->type->buildType() );
939 } // if
940 return ret;
941}
942
943// Local Variables: //
944// tab-width: 4 //
945// mode: c++ //
946// compile-command: "make install" //
947// End: //
Note: See TracBrowser for help on using the repository browser.