source: src/Parser/TypeData.cc@ b8cb388

Last change on this file since b8cb388 was 67467a3, checked in by Andrew Beach <ajbeach@…>, 19 months ago

Fused TypeData::Enum and TypeData::Aggregate, an enumeration is a kind of aggregate after all. There will always be some unused fields in Aggregate_t (but less in TypeData overall) but the code is almost always simpler.

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