source: src/Parser/TypeData.cc@ a885357

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

Moved the DeclarationNode enums over to TypeData where they are actually used.

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