source: src/Parser/TypeData.cc@ d066c5b

Last change on this file since d066c5b was bf050c5, checked in by Andrew Beach <ajbeach@…>, 21 months ago

Removed unused field from TypeData.

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