source: src/Parser/TypeData.cc@ bdc8591

Last change on this file since bdc8591 was 057608a, checked in by Andrew Beach <ajbeach@…>, 19 months ago

Parser clean-up: Removed an unused field, added a comment, fixed a memory leak and reformated a function.

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