source: src/Parser/TypeData.cc@ 9f4af04

Last change on this file since 9f4af04 was 6cef439, checked in by Andrew Beach <ajbeach@…>, 20 months ago

Return 'TypeData *' from some parse rules. Moved TypeData construction over to that file.

  • Property mode set to 100644
File size: 51.5 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 Feb 23 08:58:30 2024
13// Update Count : 734
14//
15
16#include "TypeData.h"
17
18#include <cassert> // for assert
19#include <ostream> // for operator<<, ostream, basic_ostream
20
21#include "AST/Decl.hpp" // for AggregateDecl, ObjectDecl, TypeDe...
22#include "AST/Attribute.hpp" // for Attribute
23#include "AST/Init.hpp" // for SingleInit, ListInit
24#include "AST/Print.hpp" // for print
25#include "Common/SemanticError.h" // for SemanticError
26#include "Common/utility.h" // for splice, spliceBegin
27#include "Common/Iterate.hpp" // for reverseIterate
28#include "Parser/ExpressionNode.h" // for ExpressionNode
29#include "Parser/StatementNode.h" // for StatementNode
30
31class Attribute;
32
33using namespace std;
34
35TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
36 switch ( kind ) {
37 case Unknown:
38 case Pointer:
39 case Reference:
40 case EnumConstant:
41 case GlobalScope:
42 case Basic:
43 // No unique data to initialize.
44 break;
45 case Array:
46 array.dimension = nullptr;
47 array.isVarLen = false;
48 array.isStatic = false;
49 break;
50 case Function:
51 function.params = nullptr;
52 function.idList = nullptr;
53 function.oldDeclList = nullptr;
54 function.body = nullptr;
55 function.withExprs = nullptr;
56 break;
57 case Enum:
58 enumeration.name = nullptr;
59 enumeration.constants = nullptr;
60 enumeration.body = false;
61 enumeration.anon = false;
62 break;
63 case Aggregate:
64 aggregate.kind = ast::AggregateDecl::NoAggregate;
65 aggregate.name = nullptr;
66 aggregate.params = nullptr;
67 aggregate.actuals = nullptr;
68 aggregate.fields = nullptr;
69 aggregate.body = false;
70 aggregate.tagged = false;
71 aggregate.parent = nullptr;
72 aggregate.anon = false;
73 break;
74 case AggregateInst:
75 aggInst.aggregate = nullptr;
76 aggInst.params = nullptr;
77 aggInst.hoistType = false;
78 break;
79 case Symbolic:
80 case SymbolicInst:
81 symbolic.name = nullptr;
82 symbolic.params = nullptr;
83 symbolic.actuals = nullptr;
84 symbolic.assertions = nullptr;
85 break;
86 case Tuple:
87 tuple = nullptr;
88 break;
89 case Typeof:
90 case Basetypeof:
91 typeexpr = nullptr;
92 break;
93 case Vtable:
94 case Builtin:
95 // No unique data to initialize.
96 break;
97 case Qualified:
98 qualified.parent = nullptr;
99 qualified.child = nullptr;
100 break;
101 } // switch
102} // TypeData::TypeData
103
104
105TypeData::~TypeData() {
106 delete base;
107 delete forall;
108
109 switch ( kind ) {
110 case Unknown:
111 case Pointer:
112 case Reference:
113 case EnumConstant:
114 case GlobalScope:
115 case Basic:
116 // No unique data to deconstruct.
117 break;
118 case Array:
119 delete array.dimension;
120 break;
121 case Function:
122 delete function.params;
123 delete function.idList;
124 delete function.oldDeclList;
125 delete function.body;
126 delete function.withExprs;
127 break;
128 case Aggregate:
129 delete aggregate.name;
130 delete aggregate.params;
131 delete aggregate.actuals;
132 delete aggregate.fields;
133 break;
134 case AggregateInst:
135 delete aggInst.aggregate;
136 delete aggInst.params;
137 break;
138 case Enum:
139 delete enumeration.name;
140 delete enumeration.constants;
141 break;
142 case Symbolic:
143 case SymbolicInst:
144 delete symbolic.name;
145 delete symbolic.params;
146 delete symbolic.actuals;
147 delete symbolic.assertions;
148 break;
149 case Tuple:
150 delete tuple;
151 break;
152 case Typeof:
153 case Basetypeof:
154 delete typeexpr;
155 break;
156 case Vtable:
157 case Builtin:
158 // No unique data to deconstruct.
159 break;
160 case Qualified:
161 delete qualified.parent;
162 delete qualified.child;
163 break;
164 } // switch
165} // TypeData::~TypeData
166
167
168TypeData * TypeData::clone() const {
169 TypeData * newtype = new TypeData( kind );
170 newtype->qualifiers = qualifiers;
171 newtype->base = maybeCopy( base );
172 newtype->forall = maybeCopy( forall );
173
174 switch ( kind ) {
175 case Unknown:
176 case EnumConstant:
177 case Pointer:
178 case Reference:
179 case GlobalScope:
180 // nothing else to copy
181 break;
182 case Basic:
183 newtype->basictype = basictype;
184 newtype->complextype = complextype;
185 newtype->signedness = signedness;
186 newtype->length = length;
187 break;
188 case Array:
189 newtype->array.dimension = maybeCopy( array.dimension );
190 newtype->array.isVarLen = array.isVarLen;
191 newtype->array.isStatic = array.isStatic;
192 break;
193 case Function:
194 newtype->function.params = maybeCopy( function.params );
195 newtype->function.idList = maybeCopy( function.idList );
196 newtype->function.oldDeclList = maybeCopy( function.oldDeclList );
197 newtype->function.body = maybeCopy( function.body );
198 newtype->function.withExprs = maybeCopy( function.withExprs );
199 break;
200 case Aggregate:
201 newtype->aggregate.kind = aggregate.kind;
202 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
203 newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;
204 newtype->aggregate.params = maybeCopy( aggregate.params );
205 newtype->aggregate.actuals = maybeCopy( aggregate.actuals );
206 newtype->aggregate.fields = maybeCopy( aggregate.fields );
207 newtype->aggregate.attributes = aggregate.attributes;
208 newtype->aggregate.body = aggregate.body;
209 newtype->aggregate.anon = aggregate.anon;
210 newtype->aggregate.tagged = aggregate.tagged;
211 break;
212 case AggregateInst:
213 newtype->aggInst.aggregate = maybeCopy( aggInst.aggregate );
214 newtype->aggInst.params = maybeCopy( aggInst.params );
215 newtype->aggInst.hoistType = aggInst.hoistType;
216 break;
217 case Enum:
218 newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
219 newtype->enumeration.constants = maybeCopy( enumeration.constants );
220 newtype->enumeration.body = enumeration.body;
221 newtype->enumeration.anon = enumeration.anon;
222 break;
223 case Symbolic:
224 case SymbolicInst:
225 newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr;
226 newtype->symbolic.params = maybeCopy( symbolic.params );
227 newtype->symbolic.actuals = maybeCopy( symbolic.actuals );
228 newtype->symbolic.assertions = maybeCopy( symbolic.assertions );
229 newtype->symbolic.isTypedef = symbolic.isTypedef;
230 break;
231 case Tuple:
232 newtype->tuple = maybeCopy( tuple );
233 break;
234 case Typeof:
235 case Basetypeof:
236 newtype->typeexpr = maybeCopy( typeexpr );
237 break;
238 case Vtable:
239 break;
240 case Builtin:
241 assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One );
242 newtype->builtintype = builtintype;
243 break;
244 case Qualified:
245 newtype->qualified.parent = maybeCopy( qualified.parent );
246 newtype->qualified.child = maybeCopy( qualified.child );
247 break;
248 } // switch
249 return newtype;
250} // TypeData::clone
251
252
253void TypeData::print( ostream &os, int indent ) const {
254 ast::print( os, qualifiers );
255
256 if ( forall ) {
257 os << "forall " << endl;
258 forall->printList( os, indent + 4 );
259 } // if
260
261 switch ( kind ) {
262 case Basic:
263 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
264 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
265 if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " ";
266 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
267 break;
268 case Pointer:
269 os << "pointer ";
270 if ( base ) {
271 os << "to ";
272 base->print( os, indent );
273 } // if
274 break;
275 case Reference:
276 os << "reference ";
277 if ( base ) {
278 os << "to ";
279 base->print( os, indent );
280 } // if
281 break;
282 case Array:
283 if ( array.isStatic ) {
284 os << "static ";
285 } // if
286 if ( array.dimension ) {
287 os << "array of ";
288 array.dimension->printOneLine( os, indent );
289 } else if ( array.isVarLen ) {
290 os << "variable-length array of ";
291 } else {
292 os << "open array of ";
293 } // if
294 if ( base ) {
295 base->print( os, indent );
296 } // if
297 break;
298 case Function:
299 os << "function" << endl;
300 if ( function.params ) {
301 os << string( indent + 2, ' ' ) << "with parameters " << endl;
302 function.params->printList( os, indent + 4 );
303 } else {
304 os << string( indent + 2, ' ' ) << "with no parameters" << endl;
305 } // if
306 if ( function.idList ) {
307 os << string( indent + 2, ' ' ) << "with old-style identifier list " << endl;
308 function.idList->printList( os, indent + 4 );
309 } // if
310 if ( function.oldDeclList ) {
311 os << string( indent + 2, ' ' ) << "with old-style declaration list " << endl;
312 function.oldDeclList->printList( os, indent + 4 );
313 } // if
314 os << string( indent + 2, ' ' ) << "returning ";
315 if ( base ) {
316 base->print( os, indent + 4 );
317 } else {
318 os << "nothing ";
319 } // if
320 os << endl;
321 if ( function.body ) {
322 os << string( indent + 2, ' ' ) << "with body " << endl;
323 function.body->printList( os, indent + 2 );
324 } // if
325 break;
326 case Aggregate:
327 os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
328 if ( aggregate.params ) {
329 os << string( indent + 2, ' ' ) << "with type parameters" << endl;
330 aggregate.params->printList( os, indent + 4 );
331 } // if
332 if ( aggregate.actuals ) {
333 os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl;
334 aggregate.actuals->printList( os, indent + 4 );
335 } // if
336 if ( aggregate.fields ) {
337 os << string( indent + 2, ' ' ) << "with members" << endl;
338 aggregate.fields->printList( os, indent + 4 );
339 } // if
340 if ( aggregate.body ) {
341 os << string( indent + 2, ' ' ) << "with body" << endl;
342 } // if
343 if ( ! aggregate.attributes.empty() ) {
344 os << string( indent + 2, ' ' ) << "with attributes" << endl;
345 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( aggregate.attributes ) ) {
346 os << string( indent + 4, ' ' );
347 ast::print( os, attr, indent + 2 );
348 } // for
349 } // if
350 break;
351 case AggregateInst:
352 if ( aggInst.aggregate ) {
353 os << "instance of " ;
354 aggInst.aggregate->print( os, indent );
355 } else {
356 os << "instance of an unspecified aggregate ";
357 } // if
358 if ( aggInst.params ) {
359 os << string( indent + 2, ' ' ) << "with parameters" << endl;
360 aggInst.params->printList( os, indent + 2 );
361 } // if
362 break;
363 case Enum:
364 os << "enumeration " << *enumeration.name << endl;;
365 if ( enumeration.constants ) {
366 os << "with constants" << endl;
367 enumeration.constants->printList( os, indent + 2 );
368 } // if
369 if ( enumeration.body ) {
370 os << string( indent + 2, ' ' ) << "with body" << endl;
371 } // if
372 if ( base ) {
373 os << "for ";
374 base->print( os, indent + 2 );
375 } // if
376 break;
377 case EnumConstant:
378 os << "enumeration constant ";
379 break;
380 case Symbolic:
381 if ( symbolic.isTypedef ) {
382 os << "typedef definition ";
383 } else {
384 os << "type definition ";
385 } // if
386 if ( symbolic.params ) {
387 os << endl << string( indent + 2, ' ' ) << "with parameters" << endl;
388 symbolic.params->printList( os, indent + 2 );
389 } // if
390 if ( symbolic.assertions ) {
391 os << endl << string( indent + 2, ' ' ) << "with assertions" << endl;
392 symbolic.assertions->printList( os, indent + 4 );
393 os << string( indent + 2, ' ' );
394 } // if
395 if ( base ) {
396 os << "for ";
397 base->print( os, indent + 2 );
398 } // if
399 break;
400 case SymbolicInst:
401 os << *symbolic.name;
402 if ( symbolic.actuals ) {
403 os << "(";
404 symbolic.actuals->printList( os, indent + 2 );
405 os << ")";
406 } // if
407 break;
408 case Tuple:
409 os << "tuple ";
410 if ( tuple ) {
411 os << "with members" << endl;
412 tuple->printList( os, indent + 2 );
413 } // if
414 break;
415 case Basetypeof:
416 os << "base-";
417 #if defined(__GNUC__) && __GNUC__ >= 7
418 __attribute__((fallthrough));
419 #endif
420 // FALL THROUGH
421 case Typeof:
422 os << "type-of expression ";
423 if ( typeexpr ) {
424 typeexpr->print( os, indent + 2 );
425 } // if
426 break;
427 case Vtable:
428 os << "vtable";
429 break;
430 case Builtin:
431 os << DeclarationNode::builtinTypeNames[builtintype];
432 break;
433 case GlobalScope:
434 break;
435 case Qualified:
436 qualified.parent->print( os );
437 os << ".";
438 qualified.child->print( os );
439 break;
440 case Unknown:
441 os << "entity of unknown type ";
442 break;
443 default:
444 os << "internal error: TypeData::print " << kind << endl;
445 assert( false );
446 } // switch
447} // TypeData::print
448
449const std::string * TypeData::leafName() const {
450 switch ( kind ) {
451 case Unknown:
452 case Pointer:
453 case Reference:
454 case EnumConstant:
455 case GlobalScope:
456 case Array:
457 case Basic:
458 case Function:
459 case AggregateInst:
460 case Tuple:
461 case Typeof:
462 case Basetypeof:
463 case Builtin:
464 case Vtable:
465 assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
466 break;
467 case Aggregate:
468 return aggregate.name;
469 case Enum:
470 return enumeration.name;
471 case Symbolic:
472 case SymbolicInst:
473 return symbolic.name;
474 case Qualified:
475 return qualified.child->leafName();
476 } // switch
477 assert(false);
478}
479
480TypeData * TypeData::getLastBase() {
481 TypeData * cur = this;
482 while ( cur->base ) cur = cur->base;
483 return cur;
484}
485
486void TypeData::setLastBase( TypeData * newBase ) {
487 getLastBase()->base = newBase;
488}
489
490
491TypeData * build_type_qualifier( ast::CV::Qualifiers tq ) {
492 TypeData * type = new TypeData;
493 type->qualifiers = tq;
494 return type;
495}
496
497TypeData * build_basic_type( DeclarationNode::BasicType basic ) {
498 TypeData * type = new TypeData( TypeData::Basic );
499 type->basictype = basic;
500 return type;
501}
502
503TypeData * build_complex_type( DeclarationNode::ComplexType complex ) {
504 TypeData * type = new TypeData( TypeData::Basic );
505 type->complextype = complex;
506 return type;
507}
508
509TypeData * build_signedness( DeclarationNode::Signedness signedness ) {
510 TypeData * type = new TypeData( TypeData::Basic );
511 type->signedness = signedness;
512 return type;
513}
514
515TypeData * build_builtin_type( DeclarationNode::BuiltinType bit ) {
516 TypeData * type = new TypeData( TypeData::Builtin );
517 type->builtintype = bit;
518 return type;
519}
520
521TypeData * build_length( DeclarationNode::Length length ) {
522 TypeData * type = new TypeData( TypeData::Basic );
523 type->length = length;
524 return type;
525}
526
527TypeData * build_forall( DeclarationNode * forall ) {
528 TypeData * type = new TypeData( TypeData::Unknown );
529 type->forall = forall;
530 return type;
531}
532
533TypeData * build_global_scope() {
534 return new TypeData( TypeData::GlobalScope );
535}
536
537TypeData * build_qualified_type( TypeData * parent, TypeData * child ) {
538 TypeData * type = new TypeData( TypeData::Qualified );
539 type->qualified.parent = parent;
540 type->qualified.child = child;
541 return type;
542}
543
544TypeData * build_typedef( const std::string * name ) {
545 TypeData * type = new TypeData( TypeData::SymbolicInst );
546 type->symbolic.name = name;
547 type->symbolic.isTypedef = true;
548 type->symbolic.actuals = nullptr;
549 return type;
550}
551
552TypeData * build_type_gen( const std::string * name, ExpressionNode * params ) {
553 TypeData * type = new TypeData( TypeData::SymbolicInst );
554 type->symbolic.name = name;
555 type->symbolic.isTypedef = false;
556 type->symbolic.actuals = params;
557 return type;
558}
559
560TypeData * build_vtable_type( TypeData * base ) {
561 TypeData * type = new TypeData( TypeData::Vtable );
562 type->base = base;
563 return type;
564}
565
566// Takes ownership of src.
567static void addQualifiersToType( TypeData * dst, TypeData * src ) {
568 if ( dst->base ) {
569 addQualifiersToType( dst->base, src );
570 } else if ( dst->kind == TypeData::Function ) {
571 dst->base = src;
572 src = nullptr;
573 } else {
574 dst->qualifiers |= src->qualifiers;
575 delete src;
576 } // if
577}
578
579// Takes ownership of all arguments, gives ownership of return value.
580TypeData * addQualifiers( TypeData * ltype, TypeData * rtype ) {
581 if ( ltype->forall ) {
582 if ( rtype->forall ) {
583 rtype->forall->set_last( ltype->forall );
584 } else if ( TypeData::Aggregate != rtype->kind ) {
585 rtype->forall = ltype->forall;
586 } else if ( rtype->aggregate.params ) {
587 rtype->aggregate.params->set_last( ltype->forall );
588 } else {
589 rtype->aggregate.params = ltype->forall;
590 }
591 ltype->forall = nullptr;
592 }
593
594 addQualifiersToType( rtype, ltype );
595 return rtype;
596}
597
598// Helper for addType and cloneBaseType.
599static void addTypeToType( TypeData *& dst, TypeData *& src ) {
600 if ( src->forall && dst->kind == TypeData::Function ) {
601 if ( dst->forall ) {
602 dst->forall->set_last( src->forall );
603 } else {
604 dst->forall = src->forall;
605 } // if
606 src->forall = nullptr;
607 } // if
608 if ( dst->base ) {
609 addTypeToType( dst->base, src );
610 return;
611 }
612 switch ( dst->kind ) {
613 case TypeData::Unknown:
614 src->qualifiers |= dst->qualifiers;
615 // LEAKS dst?
616 dst = src;
617 src = nullptr;
618 break;
619 case TypeData::Basic:
620 dst->qualifiers |= src->qualifiers;
621 if ( src->kind != TypeData::Unknown ) {
622 assert( src->kind == TypeData::Basic );
623
624 if ( dst->basictype == DeclarationNode::NoBasicType ) {
625 dst->basictype = src->basictype;
626 } else if ( src->basictype != DeclarationNode::NoBasicType ) {
627 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
628 DeclarationNode::basicTypeNames[ dst->basictype ],
629 DeclarationNode::basicTypeNames[ src->basictype ] );
630 }
631 if ( dst->complextype == DeclarationNode::NoComplexType ) {
632 dst->complextype = src->complextype;
633 } else if ( src->complextype != DeclarationNode::NoComplexType ) {
634 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
635 DeclarationNode::complexTypeNames[ src->complextype ],
636 DeclarationNode::complexTypeNames[ src->complextype ] );
637 }
638 if ( dst->signedness == DeclarationNode::NoSignedness ) {
639 dst->signedness = src->signedness;
640 } else if ( src->signedness != DeclarationNode::NoSignedness ) {
641 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
642 DeclarationNode::signednessNames[ dst->signedness ],
643 DeclarationNode::signednessNames[ src->signedness ] );
644 }
645 if ( dst->length == DeclarationNode::NoLength ) {
646 dst->length = src->length;
647 } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) {
648 dst->length = DeclarationNode::LongLong;
649 } else if ( src->length != DeclarationNode::NoLength ) {
650 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
651 DeclarationNode::lengthNames[ dst->length ],
652 DeclarationNode::lengthNames[ src->length ] );
653 }
654 } // if
655 break;
656 default:
657 switch ( src->kind ) {
658 case TypeData::Aggregate:
659 case TypeData::Enum:
660 dst->base = new TypeData( TypeData::AggregateInst );
661 dst->base->aggInst.aggregate = src;
662 if ( src->kind == TypeData::Aggregate ) {
663 dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
664 } // if
665 dst->base->qualifiers |= src->qualifiers;
666 src = nullptr;
667 break;
668 default:
669 if ( dst->forall ) {
670 dst->forall->set_last( src->forall );
671 } else {
672 dst->forall = src->forall;
673 } // if
674 src->forall = nullptr;
675 dst->base = src;
676 src = nullptr;
677 } // switch
678 } // switch
679}
680
681// Takes ownership of all arguments, gives ownership of return value.
682TypeData * addType( TypeData * ltype, TypeData * rtype, std::vector<ast::ptr<ast::Attribute>> & attributes ) {
683 if ( rtype ) {
684 addTypeToType( rtype, ltype );
685 return rtype;
686 } else {
687 if ( ltype->kind == TypeData::Aggregate || ltype->kind == TypeData::Enum ) {
688 // Hide type information aggregate instances.
689 rtype = new TypeData( TypeData::AggregateInst );
690 rtype->aggInst.aggregate = ltype;
691 rtype->aggInst.aggregate->aggregate.attributes.swap( attributes ); // change ownership
692 if ( ltype->kind == TypeData::Aggregate ) {
693 rtype->aggInst.hoistType = ltype->aggregate.body;
694 rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals );
695 } else {
696 rtype->aggInst.hoistType = ltype->enumeration.body;
697 } // if
698 rtype->qualifiers |= ltype->qualifiers;
699 } else {
700 rtype = ltype;
701 } // if
702 return rtype;
703 } // if
704}
705
706TypeData * addType( TypeData * ltype, TypeData * rtype ) {
707 std::vector<ast::ptr<ast::Attribute>> attributes;
708 return addType( ltype, rtype, attributes );
709}
710
711// Takes ownership of both arguments, gives ownership of return value.
712TypeData * cloneBaseType( TypeData * type, TypeData * other ) {
713 TypeData * newType = type->getLastBase()->clone();
714 if ( newType->kind == TypeData::AggregateInst ) {
715 // don't duplicate members
716 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
717 delete newType->aggInst.aggregate->enumeration.constants;
718 newType->aggInst.aggregate->enumeration.constants = nullptr;
719 newType->aggInst.aggregate->enumeration.body = false;
720 } else {
721 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
722 delete newType->aggInst.aggregate->aggregate.fields;
723 newType->aggInst.aggregate->aggregate.fields = nullptr;
724 newType->aggInst.aggregate->aggregate.body = false;
725 } // if
726 // don't hoist twice
727 newType->aggInst.hoistType = false;
728 } // if
729 newType->forall = maybeCopy( type->forall );
730
731 if ( other ) {
732 addTypeToType( other, newType );
733 delete newType;
734 return other;
735 } // if
736 return newType;
737}
738
739TypeData * makeNewBase( TypeData * type ) {
740 switch ( type->kind ) {
741 case TypeData::Aggregate:
742 case TypeData::Enum: {
743 TypeData * out = new TypeData( TypeData::AggregateInst );
744 out->aggInst.aggregate = type;
745 if ( TypeData::Aggregate == type->kind ) {
746 out->aggInst.params = maybeCopy( type->aggregate.actuals );
747 }
748 out->qualifiers |= type->qualifiers;
749 return out;
750 }
751 default:
752 return type;
753 } // switch
754}
755
756
757void buildForall(
758 const DeclarationNode * firstNode,
759 std::vector<ast::ptr<ast::TypeInstType>> &outputList ) {
760 {
761 std::vector<ast::ptr<ast::Type>> tmpList;
762 buildTypeList( firstNode, tmpList );
763 for ( auto tmp : tmpList ) {
764 outputList.emplace_back(
765 strict_dynamic_cast<const ast::TypeInstType *>(
766 tmp.release() ) );
767 }
768 }
769 auto n = firstNode;
770 for ( auto i = outputList.begin() ;
771 i != outputList.end() ;
772 ++i, n = n->next ) {
773 // Only the object type class adds additional assertions.
774 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
775 continue;
776 }
777
778 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
779 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
780 auto mutTypeDecl = ast::mutate( td );
781 const CodeLocation & location = mutTypeDecl->location;
782 *i = mutTypeDecl;
783
784 // add assertion parameters to `type' tyvars in reverse order
785 // add assignment operator: T * ?=?(T *, T)
786 newAssertions.push_back( new ast::FunctionDecl(
787 location,
788 "?=?",
789 {}, // forall
790 {}, // assertions
791 {
792 new ast::ObjectDecl(
793 location,
794 "",
795 new ast::ReferenceType( i->get() ),
796 (ast::Init *)nullptr,
797 ast::Storage::Classes(),
798 ast::Linkage::Cforall,
799 (ast::Expr *)nullptr
800 ),
801 new ast::ObjectDecl(
802 location,
803 "",
804 i->get(),
805 (ast::Init *)nullptr,
806 ast::Storage::Classes(),
807 ast::Linkage::Cforall,
808 (ast::Expr *)nullptr
809 ),
810 }, // params
811 {
812 new ast::ObjectDecl(
813 location,
814 "",
815 i->get(),
816 (ast::Init *)nullptr,
817 ast::Storage::Classes(),
818 ast::Linkage::Cforall,
819 (ast::Expr *)nullptr
820 ),
821 }, // returns
822 (ast::CompoundStmt *)nullptr,
823 ast::Storage::Classes(),
824 ast::Linkage::Cforall
825 ) );
826
827 // add default ctor: void ?{}(T *)
828 newAssertions.push_back( new ast::FunctionDecl(
829 location,
830 "?{}",
831 {}, // forall
832 {}, // assertions
833 {
834 new ast::ObjectDecl(
835 location,
836 "",
837 new ast::ReferenceType( i->get() ),
838 (ast::Init *)nullptr,
839 ast::Storage::Classes(),
840 ast::Linkage::Cforall,
841 (ast::Expr *)nullptr
842 ),
843 }, // params
844 {}, // returns
845 (ast::CompoundStmt *)nullptr,
846 ast::Storage::Classes(),
847 ast::Linkage::Cforall
848 ) );
849
850 // add copy ctor: void ?{}(T *, T)
851 newAssertions.push_back( new ast::FunctionDecl(
852 location,
853 "?{}",
854 {}, // forall
855 {}, // assertions
856 {
857 new ast::ObjectDecl(
858 location,
859 "",
860 new ast::ReferenceType( i->get() ),
861 (ast::Init *)nullptr,
862 ast::Storage::Classes(),
863 ast::Linkage::Cforall,
864 (ast::Expr *)nullptr
865 ),
866 new ast::ObjectDecl(
867 location,
868 "",
869 i->get(),
870 (ast::Init *)nullptr,
871 ast::Storage::Classes(),
872 ast::Linkage::Cforall,
873 (ast::Expr *)nullptr
874 ),
875 }, // params
876 {}, // returns
877 (ast::CompoundStmt *)nullptr,
878 ast::Storage::Classes(),
879 ast::Linkage::Cforall
880 ) );
881
882 // add dtor: void ^?{}(T *)
883 newAssertions.push_back( new ast::FunctionDecl(
884 location,
885 "^?{}",
886 {}, // forall
887 {}, // assertions
888 {
889 new ast::ObjectDecl(
890 location,
891 "",
892 new ast::ReferenceType( i->get() ),
893 (ast::Init *)nullptr,
894 ast::Storage::Classes(),
895 ast::Linkage::Cforall,
896 (ast::Expr *)nullptr
897 ),
898 }, // params
899 {}, // returns
900 (ast::CompoundStmt *)nullptr,
901 ast::Storage::Classes(),
902 ast::Linkage::Cforall
903 ) );
904
905 spliceBegin( mutTypeDecl->assertions, newAssertions );
906 } // for
907}
908
909
910void buildForall(
911 const DeclarationNode * firstNode,
912 std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
913 buildList( firstNode, outputForall );
914 auto n = firstNode;
915 for ( auto i = outputForall.begin() ;
916 i != outputForall.end() ;
917 ++i, n = n->next ) {
918 // Only the object type class adds additional assertions.
919 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
920 continue;
921 }
922
923 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
924 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
925 auto mutTypeDecl = ast::mutate( td );
926 const CodeLocation & location = mutTypeDecl->location;
927 *i = mutTypeDecl;
928
929 // add assertion parameters to `type' tyvars in reverse order
930 // add assignment operator: T * ?=?(T *, T)
931 newAssertions.push_back( new ast::FunctionDecl(
932 location,
933 "?=?",
934 {}, // forall
935 {}, // assertions
936 {
937 new ast::ObjectDecl(
938 location,
939 "",
940 new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
941 (ast::Init *)nullptr,
942 ast::Storage::Classes(),
943 ast::Linkage::Cforall,
944 (ast::Expr *)nullptr
945 ),
946 new ast::ObjectDecl(
947 location,
948 "",
949 new ast::TypeInstType( td->name, *i ),
950 (ast::Init *)nullptr,
951 ast::Storage::Classes(),
952 ast::Linkage::Cforall,
953 (ast::Expr *)nullptr
954 ),
955 }, // params
956 {
957 new ast::ObjectDecl(
958 location,
959 "",
960 new ast::TypeInstType( td->name, *i ),
961 (ast::Init *)nullptr,
962 ast::Storage::Classes(),
963 ast::Linkage::Cforall,
964 (ast::Expr *)nullptr
965 ),
966 }, // returns
967 (ast::CompoundStmt *)nullptr,
968 ast::Storage::Classes(),
969 ast::Linkage::Cforall
970 ) );
971
972 // add default ctor: void ?{}(T *)
973 newAssertions.push_back( new ast::FunctionDecl(
974 location,
975 "?{}",
976 {}, // forall
977 {}, // assertions
978 {
979 new ast::ObjectDecl(
980 location,
981 "",
982 new ast::ReferenceType(
983 new ast::TypeInstType( td->name, i->get() ) ),
984 (ast::Init *)nullptr,
985 ast::Storage::Classes(),
986 ast::Linkage::Cforall,
987 (ast::Expr *)nullptr
988 ),
989 }, // params
990 {}, // returns
991 (ast::CompoundStmt *)nullptr,
992 ast::Storage::Classes(),
993 ast::Linkage::Cforall
994 ) );
995
996 // add copy ctor: void ?{}(T *, T)
997 newAssertions.push_back( new ast::FunctionDecl(
998 location,
999 "?{}",
1000 {}, // forall
1001 {}, // assertions
1002 {
1003 new ast::ObjectDecl(
1004 location,
1005 "",
1006 new ast::ReferenceType(
1007 new ast::TypeInstType( td->name, *i ) ),
1008 (ast::Init *)nullptr,
1009 ast::Storage::Classes(),
1010 ast::Linkage::Cforall,
1011 (ast::Expr *)nullptr
1012 ),
1013 new ast::ObjectDecl(
1014 location,
1015 "",
1016 new ast::TypeInstType( td->name, *i ),
1017 (ast::Init *)nullptr,
1018 ast::Storage::Classes(),
1019 ast::Linkage::Cforall,
1020 (ast::Expr *)nullptr
1021 ),
1022 }, // params
1023 {}, // returns
1024 (ast::CompoundStmt *)nullptr,
1025 ast::Storage::Classes(),
1026 ast::Linkage::Cforall
1027 ) );
1028
1029 // add dtor: void ^?{}(T *)
1030 newAssertions.push_back( new ast::FunctionDecl(
1031 location,
1032 "^?{}",
1033 {}, // forall
1034 {}, // assertions
1035 {
1036 new ast::ObjectDecl(
1037 location,
1038 "",
1039 new ast::ReferenceType(
1040 new ast::TypeInstType( i->get() )
1041 ),
1042 (ast::Init *)nullptr,
1043 ast::Storage::Classes(),
1044 ast::Linkage::Cforall,
1045 (ast::Expr *)nullptr
1046 ),
1047 }, // params
1048 {}, // returns
1049 (ast::CompoundStmt *)nullptr,
1050 ast::Storage::Classes(),
1051 ast::Linkage::Cforall
1052 ) );
1053
1054 spliceBegin( mutTypeDecl->assertions, newAssertions );
1055 } // for
1056} // buildForall
1057
1058
1059ast::Type * typebuild( const TypeData * td ) {
1060 assert( td );
1061 switch ( td->kind ) {
1062 case TypeData::Unknown:
1063 // fill in implicit int
1064 return new ast::BasicType(
1065 ast::BasicType::SignedInt,
1066 buildQualifiers( td )
1067 );
1068 case TypeData::Basic:
1069 return buildBasicType( td );
1070 case TypeData::Pointer:
1071 return buildPointer( td );
1072 case TypeData::Array:
1073 return buildArray( td );
1074 case TypeData::Reference:
1075 return buildReference( td );
1076 case TypeData::Function:
1077 return buildFunctionType( td );
1078 case TypeData::AggregateInst:
1079 return buildAggInst( td );
1080 case TypeData::EnumConstant:
1081 return new ast::EnumInstType( "", buildQualifiers( td ) );
1082 case TypeData::SymbolicInst:
1083 return buildSymbolicInst( td );
1084 case TypeData::Tuple:
1085 return buildTuple( td );
1086 case TypeData::Typeof:
1087 case TypeData::Basetypeof:
1088 return buildTypeof( td );
1089 case TypeData::Vtable:
1090 return buildVtable( td );
1091 case TypeData::Builtin:
1092 switch ( td->builtintype ) {
1093 case DeclarationNode::Zero:
1094 return new ast::ZeroType();
1095 case DeclarationNode::One:
1096 return new ast::OneType();
1097 default:
1098 return new ast::VarArgsType( buildQualifiers( td ) );
1099 } // switch
1100 case TypeData::GlobalScope:
1101 return new ast::GlobalScopeType();
1102 case TypeData::Qualified:
1103 return new ast::QualifiedType(
1104 typebuild( td->qualified.parent ),
1105 typebuild( td->qualified.child ),
1106 buildQualifiers( td )
1107 );
1108 case TypeData::Symbolic:
1109 case TypeData::Enum:
1110 case TypeData::Aggregate:
1111 assert( false );
1112 } // switch
1113
1114 return nullptr;
1115} // typebuild
1116
1117
1118TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
1119 TypeData * ret = nullptr;
1120
1121 switch ( td->kind ) {
1122 case TypeData::Aggregate:
1123 if ( ! toplevel && td->aggregate.body ) {
1124 ret = td->clone();
1125 } // if
1126 break;
1127 case TypeData::Enum:
1128 if ( ! toplevel && td->enumeration.body ) {
1129 ret = td->clone();
1130 } // if
1131 break;
1132 case TypeData::AggregateInst:
1133 if ( td->aggInst.aggregate ) {
1134 ret = typeextractAggregate( td->aggInst.aggregate, false );
1135 } // if
1136 break;
1137 default:
1138 if ( td->base ) {
1139 ret = typeextractAggregate( td->base, false );
1140 } // if
1141 } // switch
1142 return ret;
1143} // typeextractAggregate
1144
1145
1146ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
1147 return td->qualifiers;
1148} // buildQualifiers
1149
1150
1151static string genTSError( string msg, DeclarationNode::BasicType basictype ) {
1152 SemanticError( yylloc, "invalid type specifier \"%s\" for type \"%s\".", msg.c_str(), DeclarationNode::basicTypeNames[basictype] );
1153} // genTSError
1154
1155ast::Type * buildBasicType( const TypeData * td ) {
1156 ast::BasicType::Kind ret;
1157
1158 switch ( td->basictype ) {
1159 case DeclarationNode::Void:
1160 if ( td->signedness != DeclarationNode::NoSignedness ) {
1161 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
1162 } // if
1163 if ( td->length != DeclarationNode::NoLength ) {
1164 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
1165 } // if
1166 return new ast::VoidType( buildQualifiers( td ) );
1167 break;
1168
1169 case DeclarationNode::Bool:
1170 if ( td->signedness != DeclarationNode::NoSignedness ) {
1171 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
1172 } // if
1173 if ( td->length != DeclarationNode::NoLength ) {
1174 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
1175 } // if
1176
1177 ret = ast::BasicType::Bool;
1178 break;
1179
1180 case DeclarationNode::Char:
1181 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
1182 // character types. The implementation shall define char to have the same range, representation, and behavior as
1183 // either signed char or unsigned char.
1184 static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };
1185
1186 if ( td->length != DeclarationNode::NoLength ) {
1187 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
1188 } // if
1189
1190 ret = chartype[ td->signedness ];
1191 break;
1192
1193 case DeclarationNode::Int:
1194 static ast::BasicType::Kind inttype[2][4] = {
1195 { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },
1196 { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },
1197 };
1198
1199 Integral: ;
1200 if ( td->signedness == DeclarationNode::NoSignedness ) {
1201 const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
1202 } // if
1203 ret = inttype[ td->signedness ][ td->length ];
1204 break;
1205
1206 case DeclarationNode::Int128:
1207 ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
1208 if ( td->length != DeclarationNode::NoLength ) {
1209 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
1210 } // if
1211 break;
1212
1213 case DeclarationNode::Float:
1214 case DeclarationNode::Double:
1215 case DeclarationNode::LongDouble: // not set until below
1216 case DeclarationNode::uuFloat80:
1217 case DeclarationNode::uuFloat128:
1218 case DeclarationNode::uFloat16:
1219 case DeclarationNode::uFloat32:
1220 case DeclarationNode::uFloat32x:
1221 case DeclarationNode::uFloat64:
1222 case DeclarationNode::uFloat64x:
1223 case DeclarationNode::uFloat128:
1224 case DeclarationNode::uFloat128x:
1225 static ast::BasicType::Kind floattype[2][12] = {
1226 { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, (ast::BasicType::Kind)-1, (ast::BasicType::Kind)-1, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex, },
1227 { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x, },
1228 };
1229
1230 FloatingPoint: ;
1231 if ( td->signedness != DeclarationNode::NoSignedness ) {
1232 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
1233 } // if
1234 if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
1235 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
1236 } // if
1237 if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) {
1238 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
1239 } // if
1240 if ( td->complextype == DeclarationNode::Imaginary ) {
1241 genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
1242 } // if
1243 if ( (td->basictype == DeclarationNode::uuFloat80 || td->basictype == DeclarationNode::uuFloat128) && td->complextype == DeclarationNode::Complex ) { // gcc unsupported
1244 genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
1245 } // if
1246 if ( td->length == DeclarationNode::Long ) {
1247 const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
1248 } // if
1249
1250 ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
1251 //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, DeclarationNode::Float, ret );
1252 break;
1253
1254 case DeclarationNode::NoBasicType:
1255 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
1256 if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
1257 const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
1258 goto FloatingPoint;
1259 } // if
1260
1261 const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
1262 goto Integral;
1263 default:
1264 assertf( false, "unknown basic type" );
1265 return nullptr;
1266 } // switch
1267
1268 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
1269 return bt;
1270} // buildBasicType
1271
1272
1273ast::PointerType * buildPointer( const TypeData * td ) {
1274 ast::PointerType * pt;
1275 if ( td->base ) {
1276 pt = new ast::PointerType(
1277 typebuild( td->base ),
1278 buildQualifiers( td )
1279 );
1280 } else {
1281 pt = new ast::PointerType(
1282 new ast::BasicType( ast::BasicType::SignedInt ),
1283 buildQualifiers( td )
1284 );
1285 } // if
1286 return pt;
1287} // buildPointer
1288
1289
1290ast::ArrayType * buildArray( const TypeData * td ) {
1291 ast::ArrayType * at;
1292 if ( td->base ) {
1293 at = new ast::ArrayType(
1294 typebuild( td->base ),
1295 maybeBuild( td->array.dimension ),
1296 td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1297 td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1298 buildQualifiers( td )
1299 );
1300 } else {
1301 at = new ast::ArrayType(
1302 new ast::BasicType( ast::BasicType::SignedInt ),
1303 maybeBuild( td->array.dimension ),
1304 td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1305 td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1306 buildQualifiers( td )
1307 );
1308 } // if
1309 return at;
1310} // buildArray
1311
1312
1313ast::ReferenceType * buildReference( const TypeData * td ) {
1314 ast::ReferenceType * rt;
1315 if ( td->base ) {
1316 rt = new ast::ReferenceType(
1317 typebuild( td->base ),
1318 buildQualifiers( td )
1319 );
1320 } else {
1321 rt = new ast::ReferenceType(
1322 new ast::BasicType( ast::BasicType::SignedInt ),
1323 buildQualifiers( td )
1324 );
1325 } // if
1326 return rt;
1327} // buildReference
1328
1329
1330ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
1331 assert( td->kind == TypeData::Aggregate );
1332 ast::AggregateDecl * at;
1333 switch ( td->aggregate.kind ) {
1334 case ast::AggregateDecl::Struct:
1335 case ast::AggregateDecl::Coroutine:
1336 case ast::AggregateDecl::Exception:
1337 case ast::AggregateDecl::Generator:
1338 case ast::AggregateDecl::Monitor:
1339 case ast::AggregateDecl::Thread:
1340 at = new ast::StructDecl( td->location,
1341 *td->aggregate.name,
1342 td->aggregate.kind,
1343 std::move( attributes ),
1344 linkage
1345 );
1346 buildForall( td->aggregate.params, at->params );
1347 break;
1348 case ast::AggregateDecl::Union:
1349 at = new ast::UnionDecl( td->location,
1350 *td->aggregate.name,
1351 std::move( attributes ),
1352 linkage
1353 );
1354 buildForall( td->aggregate.params, at->params );
1355 break;
1356 case ast::AggregateDecl::Trait:
1357 at = new ast::TraitDecl( td->location,
1358 *td->aggregate.name,
1359 std::move( attributes ),
1360 linkage
1361 );
1362 buildList( td->aggregate.params, at->params );
1363 break;
1364 default:
1365 assert( false );
1366 } // switch
1367
1368 buildList( td->aggregate.fields, at->members );
1369 at->set_body( td->aggregate.body );
1370
1371 return at;
1372} // buildAggregate
1373
1374
1375ast::BaseInstType * buildComAggInst(
1376 const TypeData * td,
1377 std::vector<ast::ptr<ast::Attribute>> && attributes,
1378 ast::Linkage::Spec linkage ) {
1379 switch ( td->kind ) {
1380 case TypeData::Enum:
1381 if ( td->enumeration.body ) {
1382 ast::EnumDecl * typedecl =
1383 buildEnum( td, std::move( attributes ), linkage );
1384 return new ast::EnumInstType(
1385 typedecl,
1386 buildQualifiers( td )
1387 );
1388 } else {
1389 return new ast::EnumInstType(
1390 *td->enumeration.name,
1391 buildQualifiers( td )
1392 );
1393 } // if
1394 break;
1395 case TypeData::Aggregate:
1396 if ( td->aggregate.body ) {
1397 ast::AggregateDecl * typedecl =
1398 buildAggregate( td, std::move( attributes ), linkage );
1399 switch ( td->aggregate.kind ) {
1400 case ast::AggregateDecl::Struct:
1401 case ast::AggregateDecl::Coroutine:
1402 case ast::AggregateDecl::Monitor:
1403 case ast::AggregateDecl::Thread:
1404 return new ast::StructInstType(
1405 strict_dynamic_cast<ast::StructDecl *>( typedecl ),
1406 buildQualifiers( td )
1407 );
1408 case ast::AggregateDecl::Union:
1409 return new ast::UnionInstType(
1410 strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
1411 buildQualifiers( td )
1412 );
1413 case ast::AggregateDecl::Trait:
1414 assert( false );
1415 break;
1416 default:
1417 assert( false );
1418 } // switch
1419 } else {
1420 switch ( td->aggregate.kind ) {
1421 case ast::AggregateDecl::Struct:
1422 case ast::AggregateDecl::Coroutine:
1423 case ast::AggregateDecl::Monitor:
1424 case ast::AggregateDecl::Thread:
1425 return new ast::StructInstType(
1426 *td->aggregate.name,
1427 buildQualifiers( td )
1428 );
1429 case ast::AggregateDecl::Union:
1430 return new ast::UnionInstType(
1431 *td->aggregate.name,
1432 buildQualifiers( td )
1433 );
1434 case ast::AggregateDecl::Trait:
1435 return new ast::TraitInstType(
1436 *td->aggregate.name,
1437 buildQualifiers( td )
1438 );
1439 default:
1440 assert( false );
1441 } // switch
1442 break;
1443 } // if
1444 break;
1445 default:
1446 assert( false );
1447 } // switch
1448 assert( false );
1449} // buildAggInst
1450
1451
1452ast::BaseInstType * buildAggInst( const TypeData * td ) {
1453 assert( td->kind == TypeData::AggregateInst );
1454
1455 ast::BaseInstType * ret = nullptr;
1456 TypeData * type = td->aggInst.aggregate;
1457 switch ( type->kind ) {
1458 case TypeData::Enum:
1459 return new ast::EnumInstType(
1460 *type->enumeration.name,
1461 buildQualifiers( type )
1462 );
1463 case TypeData::Aggregate:
1464 switch ( type->aggregate.kind ) {
1465 case ast::AggregateDecl::Struct:
1466 case ast::AggregateDecl::Coroutine:
1467 case ast::AggregateDecl::Monitor:
1468 case ast::AggregateDecl::Thread:
1469 ret = new ast::StructInstType(
1470 *type->aggregate.name,
1471 buildQualifiers( type )
1472 );
1473 break;
1474 case ast::AggregateDecl::Union:
1475 ret = new ast::UnionInstType(
1476 *type->aggregate.name,
1477 buildQualifiers( type )
1478 );
1479 break;
1480 case ast::AggregateDecl::Trait:
1481 ret = new ast::TraitInstType(
1482 *type->aggregate.name,
1483 buildQualifiers( type )
1484 );
1485 break;
1486 default:
1487 assert( false );
1488 } // switch
1489 break;
1490 default:
1491 assert( false );
1492 } // switch
1493
1494 ret->hoistType = td->aggInst.hoistType;
1495 buildList( td->aggInst.params, ret->params );
1496 return ret;
1497} // buildAggInst
1498
1499
1500ast::NamedTypeDecl * buildSymbolic(
1501 const TypeData * td,
1502 std::vector<ast::ptr<ast::Attribute>> attributes,
1503 const std::string & name,
1504 ast::Storage::Classes scs,
1505 ast::Linkage::Spec linkage ) {
1506 assert( td->kind == TypeData::Symbolic );
1507 ast::NamedTypeDecl * ret;
1508 assert( td->base );
1509 if ( td->symbolic.isTypedef ) {
1510 ret = new ast::TypedefDecl(
1511 td->location,
1512 name,
1513 scs,
1514 typebuild( td->base ),
1515 linkage
1516 );
1517 } else {
1518 ret = new ast::TypeDecl(
1519 td->location,
1520 name,
1521 scs,
1522 typebuild( td->base ),
1523 ast::TypeDecl::Dtype,
1524 true
1525 );
1526 } // if
1527 buildList( td->symbolic.assertions, ret->assertions );
1528 splice( ret->base.get_and_mutate()->attributes, attributes );
1529 return ret;
1530} // buildSymbolic
1531
1532
1533ast::EnumDecl * buildEnum(
1534 const TypeData * td,
1535 std::vector<ast::ptr<ast::Attribute>> && attributes,
1536 ast::Linkage::Spec linkage ) {
1537 assert( td->kind == TypeData::Enum );
1538 ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
1539 ast::EnumDecl * ret = new ast::EnumDecl(
1540 td->location,
1541 *td->enumeration.name,
1542 td->enumeration.typed,
1543 std::move( attributes ),
1544 linkage,
1545 baseType
1546 );
1547 buildList( td->enumeration.constants, ret->members );
1548 auto members = ret->members.begin();
1549 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
1550 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = cur->next, ++members ) {
1551 if ( cur->enumInLine ) {
1552 // Do Nothing
1553 } else if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
1554 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
1555 } else if ( cur->has_enumeratorValue() ) {
1556 ast::Decl * member = members->get_and_mutate();
1557 ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
1558 object->init = new ast::SingleInit(
1559 td->location,
1560 maybeMoveBuild( cur->consume_enumeratorValue() ),
1561 ast::NoConstruct
1562 );
1563 } else if ( !cur->initializer ) {
1564 if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
1565 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
1566 }
1567 }
1568 // else cur is a List Initializer and has been set as init in buildList()
1569 // if
1570 } // for
1571 ret->body = td->enumeration.body;
1572 return ret;
1573} // buildEnum
1574
1575
1576ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
1577 assert( td->kind == TypeData::SymbolicInst );
1578 ast::TypeInstType * ret = new ast::TypeInstType(
1579 *td->symbolic.name,
1580 ast::TypeDecl::Dtype,
1581 buildQualifiers( td )
1582 );
1583 buildList( td->symbolic.actuals, ret->params );
1584 return ret;
1585} // buildSymbolicInst
1586
1587
1588ast::TupleType * buildTuple( const TypeData * td ) {
1589 assert( td->kind == TypeData::Tuple );
1590 std::vector<ast::ptr<ast::Type>> types;
1591 buildTypeList( td->tuple, types );
1592 ast::TupleType * ret = new ast::TupleType(
1593 std::move( types ),
1594 buildQualifiers( td )
1595 );
1596 return ret;
1597} // buildTuple
1598
1599
1600ast::TypeofType * buildTypeof( const TypeData * td ) {
1601 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
1602 assert( td->typeexpr );
1603 return new ast::TypeofType(
1604 td->typeexpr->build(),
1605 td->kind == TypeData::Typeof
1606 ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
1607 buildQualifiers( td )
1608 );
1609} // buildTypeof
1610
1611
1612ast::VTableType * buildVtable( const TypeData * td ) {
1613 assert( td->base );
1614 return new ast::VTableType(
1615 typebuild( td->base ),
1616 buildQualifiers( td )
1617 );
1618} // buildVtable
1619
1620
1621ast::FunctionDecl * buildFunctionDecl(
1622 const TypeData * td,
1623 const string &name,
1624 ast::Storage::Classes scs,
1625 ast::Function::Specs funcSpec,
1626 ast::Linkage::Spec linkage,
1627 ast::Expr * asmName,
1628 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1629 assert( td->kind == TypeData::Function );
1630 // For some reason FunctionDecl takes a bool instead of an ArgumentFlag.
1631 bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
1632 ast::CV::Qualifiers cvq = buildQualifiers( td );
1633 std::vector<ast::ptr<ast::TypeDecl>> forall;
1634 std::vector<ast::ptr<ast::DeclWithType>> assertions;
1635 std::vector<ast::ptr<ast::DeclWithType>> params;
1636 std::vector<ast::ptr<ast::DeclWithType>> returns;
1637 buildList( td->function.params, params );
1638 buildForall( td->forall, forall );
1639 // Functions do not store their assertions there anymore.
1640 for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1641 auto mut = type_param.get_and_mutate();
1642 splice( assertions, mut->assertions );
1643 }
1644 if ( td->base ) {
1645 switch ( td->base->kind ) {
1646 case TypeData::Tuple:
1647 buildList( td->base->tuple, returns );
1648 break;
1649 default:
1650 returns.push_back( dynamic_cast<ast::DeclWithType *>(
1651 buildDecl(
1652 td->base,
1653 "",
1654 ast::Storage::Classes(),
1655 (ast::Expr *)nullptr, // bitfieldWidth
1656 ast::Function::Specs(),
1657 ast::Linkage::Cforall,
1658 (ast::Expr *)nullptr // asmName
1659 )
1660 ) );
1661 } // switch
1662 } else {
1663 returns.push_back( new ast::ObjectDecl(
1664 td->location,
1665 "",
1666 new ast::BasicType( ast::BasicType::SignedInt ),
1667 (ast::Init *)nullptr,
1668 ast::Storage::Classes(),
1669 ast::Linkage::Cforall
1670 ) );
1671 } // if
1672 ast::Stmt * stmt = maybeBuild( td->function.body );
1673 ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1674 ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1675 name,
1676 std::move( forall ),
1677 std::move( assertions ),
1678 std::move( params ),
1679 std::move( returns ),
1680 body,
1681 scs,
1682 linkage,
1683 std::move( attributes ),
1684 funcSpec,
1685 (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
1686 );
1687 buildList( td->function.withExprs, decl->withExprs );
1688 decl->asmName = asmName;
1689 // This may be redundant on a declaration.
1690 decl->type.get_and_mutate()->qualifiers = cvq;
1691 return decl;
1692} // buildFunctionDecl
1693
1694
1695ast::Decl * buildDecl(
1696 const TypeData * td,
1697 const string &name,
1698 ast::Storage::Classes scs,
1699 ast::Expr * bitfieldWidth,
1700 ast::Function::Specs funcSpec,
1701 ast::Linkage::Spec linkage,
1702 ast::Expr * asmName,
1703 ast::Init * init,
1704 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1705 if ( td->kind == TypeData::Function ) {
1706 if ( td->function.idList ) { // KR function ?
1707 buildKRFunction( td->function ); // transform into C11 function
1708 } // if
1709
1710 return buildFunctionDecl(
1711 td, name, scs, funcSpec, linkage,
1712 asmName, std::move( attributes ) );
1713 } else if ( td->kind == TypeData::Aggregate ) {
1714 return buildAggregate( td, std::move( attributes ), linkage );
1715 } else if ( td->kind == TypeData::Enum ) {
1716 return buildEnum( td, std::move( attributes ), linkage );
1717 } else if ( td->kind == TypeData::Symbolic ) {
1718 return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1719 } else {
1720 auto ret = new ast::ObjectDecl( td->location,
1721 name,
1722 typebuild( td ),
1723 init,
1724 scs,
1725 linkage,
1726 bitfieldWidth,
1727 std::move( attributes )
1728 );
1729 ret->asmName = asmName;
1730 return ret;
1731 } // if
1732 return nullptr;
1733} // buildDecl
1734
1735
1736ast::FunctionType * buildFunctionType( const TypeData * td ) {
1737 assert( td->kind == TypeData::Function );
1738 ast::FunctionType * ft = new ast::FunctionType(
1739 ( !td->function.params || td->function.params->hasEllipsis )
1740 ? ast::VariableArgs : ast::FixedArgs,
1741 buildQualifiers( td )
1742 );
1743 buildTypeList( td->function.params, ft->params );
1744 buildForall( td->forall, ft->forall );
1745 if ( td->base ) {
1746 switch ( td->base->kind ) {
1747 case TypeData::Tuple:
1748 buildTypeList( td->base->tuple, ft->returns );
1749 break;
1750 default:
1751 ft->returns.push_back( typebuild( td->base ) );
1752 break;
1753 } // switch
1754 } else {
1755 ft->returns.push_back(
1756 new ast::BasicType( ast::BasicType::SignedInt ) );
1757 } // if
1758 return ft;
1759} // buildFunctionType
1760
1761
1762// Transform KR routine declarations into C99 routine declarations:
1763//
1764// rtn( a, b, c ) int a, c; double b {} => int rtn( int a, double c, int b ) {}
1765//
1766// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1767// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1768// extra names are disallowed.
1769//
1770// Note, there is no KR routine-prototype syntax:
1771//
1772// rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1773// rtn(); // valid KR prototype
1774
1775void buildKRFunction( const TypeData::Function_t & function ) {
1776 assert( ! function.params );
1777 // loop over declaration first as it is easier to spot errors
1778 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) {
1779 // scan ALL parameter names for each declaration name to check for duplicates
1780 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1781 if ( *decl->name == *param->name ) {
1782 // type set => parameter name already transformed by a declaration names so there is a duplicate
1783 // declaration name attempting a second transformation
1784 if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1785 // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1786 // parameter name attempting a second transformation
1787 if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1788 param->type = decl->type; // set copy declaration type to parameter type
1789 decl->type = nullptr; // reset declaration type
1790 // Copy and reset attributes from declaration to parameter:
1791 splice( param->attributes, decl->attributes );
1792 } // if
1793 } // for
1794 // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1795 if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1796 } // for
1797
1798 // Parameter names without a declaration default to type int:
1799 //
1800 // rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1801
1802 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1803 if ( ! param->type ) { // generate type int for empty parameter type
1804 param->type = new TypeData( TypeData::Basic );
1805 param->type->basictype = DeclarationNode::Int;
1806 } // if
1807 } // for
1808
1809 function.params = function.idList; // newly modified idList becomes parameters
1810 function.idList = nullptr; // idList now empty
1811 delete function.oldDeclList; // deletes entire list
1812 function.oldDeclList = nullptr; // reset
1813} // buildKRFunction
1814
1815// Local Variables: //
1816// tab-width: 4 //
1817// mode: c++ //
1818// compile-command: "make install" //
1819// End: //
Note: See TracBrowser for help on using the repository browser.