source: src/Parser/TypeData.cc@ cb98d9d

Last change on this file since cb98d9d was 1cfe640, checked in by Andrew Beach <ajbeach@…>, 18 months ago

One more bit of clean-up, improving some names.

  • Property mode set to 100644
File size: 48.7 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
477// Wrap an aggregate up in an instance. Takes and gives ownership.
478static TypeData * makeInstance( TypeData * type ) {
479 assert( TypeData::Aggregate == type->kind );
480 TypeData * out = new TypeData( TypeData::AggregateInst );
481 out->aggInst.aggregate = type;
482 out->aggInst.params = maybeCopy( type->aggregate.actuals );
483 out->aggInst.hoistType = type->aggregate.body;
484 out->qualifiers |= type->qualifiers;
485 return out;
486}
487
488
489TypeData * build_type_qualifier( ast::CV::Qualifiers tq ) {
490 TypeData * type = new TypeData;
491 type->qualifiers = tq;
492 return type;
493}
494
495TypeData * build_basic_type( TypeData::BasicType basic ) {
496 TypeData * type = new TypeData( TypeData::Basic );
497 type->basictype = basic;
498 return type;
499}
500
501TypeData * build_complex_type( TypeData::ComplexType complex ) {
502 TypeData * type = new TypeData( TypeData::Basic );
503 type->complextype = complex;
504 return type;
505}
506
507TypeData * build_signedness( TypeData::Signedness signedness ) {
508 TypeData * type = new TypeData( TypeData::Basic );
509 type->signedness = signedness;
510 return type;
511}
512
513TypeData * build_builtin_type( TypeData::BuiltinType bit ) {
514 TypeData * type = new TypeData( TypeData::Builtin );
515 type->builtintype = bit;
516 return type;
517}
518
519TypeData * build_length( TypeData::Length length ) {
520 TypeData * type = new TypeData( TypeData::Basic );
521 type->length = length;
522 return type;
523}
524
525TypeData * build_forall( DeclarationNode * forall ) {
526 TypeData * type = new TypeData( TypeData::Unknown );
527 type->forall = forall;
528 return type;
529}
530
531TypeData * build_global_scope() {
532 return new TypeData( TypeData::GlobalScope );
533}
534
535TypeData * build_qualified_type( TypeData * parent, TypeData * child ) {
536 TypeData * type = new TypeData( TypeData::Qualified );
537 type->qualified.parent = parent;
538 type->qualified.child = child;
539 return type;
540}
541
542TypeData * build_typedef( const std::string * name ) {
543 TypeData * type = new TypeData( TypeData::SymbolicInst );
544 type->symbolic.name = name;
545 type->symbolic.isTypedef = true;
546 type->symbolic.actuals = nullptr;
547 return type;
548}
549
550TypeData * build_type_gen( const std::string * name, ExpressionNode * params ) {
551 TypeData * type = new TypeData( TypeData::SymbolicInst );
552 type->symbolic.name = name;
553 type->symbolic.isTypedef = false;
554 type->symbolic.actuals = params;
555 return type;
556}
557
558TypeData * build_vtable_type( TypeData * base ) {
559 TypeData * type = new TypeData( TypeData::Vtable );
560 type->base = base;
561 return type;
562}
563
564// Takes ownership of src.
565static void addQualifiersToType( TypeData * dst, TypeData * src ) {
566 if ( dst->base ) {
567 addQualifiersToType( dst->base, src );
568 } else if ( dst->kind == TypeData::Function ) {
569 dst->base = src;
570 src = nullptr;
571 } else {
572 dst->qualifiers |= src->qualifiers;
573 delete src;
574 } // if
575}
576
577// Takes ownership of all arguments, gives ownership of return value.
578TypeData * addQualifiers( TypeData * dst, TypeData * src ) {
579 if ( src->forall ) {
580 if ( dst->forall || TypeData::Aggregate != dst->kind ) {
581 extend( dst->forall, src->forall );
582 } else {
583 extend( dst->aggregate.params, src->forall );
584 }
585 src->forall = nullptr;
586 }
587
588 addQualifiersToType( dst, src );
589 return dst;
590}
591
592// Helper for addType and cloneBaseType.
593static void addTypeToType( TypeData *& dst, TypeData *& src ) {
594 if ( src->forall && dst->kind == TypeData::Function ) {
595 extend( dst->forall, src->forall );
596 src->forall = nullptr;
597 } // if
598 if ( dst->base ) {
599 addTypeToType( dst->base, src );
600 return;
601 }
602 switch ( dst->kind ) {
603 case TypeData::Unknown:
604 src->qualifiers |= dst->qualifiers;
605 // LEAKS dst?
606 dst = src;
607 src = nullptr;
608 break;
609 case TypeData::Basic:
610 dst->qualifiers |= src->qualifiers;
611 if ( src->kind != TypeData::Unknown ) {
612 assert( src->kind == TypeData::Basic );
613
614 if ( dst->basictype == TypeData::NoBasicType ) {
615 dst->basictype = src->basictype;
616 } else if ( src->basictype != TypeData::NoBasicType ) {
617 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
618 TypeData::basicTypeNames[ dst->basictype ],
619 TypeData::basicTypeNames[ src->basictype ] );
620 }
621 if ( dst->complextype == TypeData::NoComplexType ) {
622 dst->complextype = src->complextype;
623 } else if ( src->complextype != TypeData::NoComplexType ) {
624 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
625 TypeData::complexTypeNames[ src->complextype ],
626 TypeData::complexTypeNames[ src->complextype ] );
627 }
628 if ( dst->signedness == TypeData::NoSignedness ) {
629 dst->signedness = src->signedness;
630 } else if ( src->signedness != TypeData::NoSignedness ) {
631 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
632 TypeData::signednessNames[ dst->signedness ],
633 TypeData::signednessNames[ src->signedness ] );
634 }
635 if ( dst->length == TypeData::NoLength ) {
636 dst->length = src->length;
637 } else if ( dst->length == TypeData::Long && src->length == TypeData::Long ) {
638 dst->length = TypeData::LongLong;
639 } else if ( src->length != TypeData::NoLength ) {
640 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
641 TypeData::lengthNames[ dst->length ],
642 TypeData::lengthNames[ src->length ] );
643 }
644 } // if
645 break;
646 default:
647 if ( TypeData::Aggregate == src->kind ) {
648 dst->base = makeInstance( src );
649 } else {
650 extend( dst->forall, src->forall );
651 src->forall = nullptr;
652 dst->base = src;
653 }
654 src = nullptr;
655 } // switch
656}
657
658// Takes ownership of all arguments, gives ownership of return value.
659TypeData * addType( TypeData * dst, TypeData * src, std::vector<ast::ptr<ast::Attribute>> & attributes ) {
660 if ( dst ) {
661 addTypeToType( dst, src );
662 } else if ( src->kind == TypeData::Aggregate ) {
663 // Hide type information aggregate instances.
664 dst = makeInstance( src );
665 dst->aggInst.aggregate->aggregate.attributes.swap( attributes );
666 } else {
667 dst = src;
668 } // if
669 return dst;
670}
671
672TypeData * addType( TypeData * dst, TypeData * src ) {
673 std::vector<ast::ptr<ast::Attribute>> attributes;
674 return addType( dst, src, attributes );
675}
676
677// Takes ownership of both arguments, gives ownership of return value.
678TypeData * cloneBaseType( TypeData * type, TypeData * other ) {
679 TypeData * newType = type->getLastBase()->clone();
680 if ( newType->kind == TypeData::AggregateInst ) {
681 // don't duplicate members
682 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
683 delete newType->aggInst.aggregate->aggregate.fields;
684 newType->aggInst.aggregate->aggregate.fields = nullptr;
685 newType->aggInst.aggregate->aggregate.body = false;
686 // don't hoist twice
687 newType->aggInst.hoistType = false;
688 } // if
689 newType->forall = maybeCopy( type->forall );
690
691 if ( other ) {
692 addTypeToType( other, newType );
693 delete newType;
694 return other;
695 } // if
696 return newType;
697}
698
699TypeData * makeNewBase( TypeData * type ) {
700 return ( TypeData::Aggregate == type->kind ) ? makeInstance( type ) : type;
701}
702
703
704void buildForall(
705 const DeclarationNode * firstNode,
706 std::vector<ast::ptr<ast::TypeInstType>> &outputList ) {
707 {
708 std::vector<ast::ptr<ast::Type>> tmpList;
709 buildTypeList( firstNode, tmpList );
710 for ( auto tmp : tmpList ) {
711 outputList.emplace_back(
712 strict_dynamic_cast<const ast::TypeInstType *>(
713 tmp.release() ) );
714 }
715 }
716 auto n = firstNode;
717 for ( auto i = outputList.begin() ;
718 i != outputList.end() ;
719 ++i, n = n->next ) {
720 // Only the object type class adds additional assertions.
721 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
722 continue;
723 }
724
725 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
726 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
727 auto mutTypeDecl = ast::mutate( td );
728 const CodeLocation & location = mutTypeDecl->location;
729 *i = mutTypeDecl;
730
731 // add assertion parameters to `type' tyvars in reverse order
732 // add assignment operator: T * ?=?(T *, T)
733 newAssertions.push_back( new ast::FunctionDecl(
734 location,
735 "?=?",
736 {}, // forall
737 {}, // assertions
738 {
739 new ast::ObjectDecl(
740 location,
741 "",
742 new ast::ReferenceType( i->get() ),
743 (ast::Init *)nullptr,
744 ast::Storage::Classes(),
745 ast::Linkage::Cforall,
746 (ast::Expr *)nullptr
747 ),
748 new ast::ObjectDecl(
749 location,
750 "",
751 i->get(),
752 (ast::Init *)nullptr,
753 ast::Storage::Classes(),
754 ast::Linkage::Cforall,
755 (ast::Expr *)nullptr
756 ),
757 }, // params
758 {
759 new ast::ObjectDecl(
760 location,
761 "",
762 i->get(),
763 (ast::Init *)nullptr,
764 ast::Storage::Classes(),
765 ast::Linkage::Cforall,
766 (ast::Expr *)nullptr
767 ),
768 }, // returns
769 (ast::CompoundStmt *)nullptr,
770 ast::Storage::Classes(),
771 ast::Linkage::Cforall
772 ) );
773
774 // add default ctor: void ?{}(T *)
775 newAssertions.push_back( new ast::FunctionDecl(
776 location,
777 "?{}",
778 {}, // forall
779 {}, // assertions
780 {
781 new ast::ObjectDecl(
782 location,
783 "",
784 new ast::ReferenceType( i->get() ),
785 (ast::Init *)nullptr,
786 ast::Storage::Classes(),
787 ast::Linkage::Cforall,
788 (ast::Expr *)nullptr
789 ),
790 }, // params
791 {}, // returns
792 (ast::CompoundStmt *)nullptr,
793 ast::Storage::Classes(),
794 ast::Linkage::Cforall
795 ) );
796
797 // add copy ctor: void ?{}(T *, T)
798 newAssertions.push_back( new ast::FunctionDecl(
799 location,
800 "?{}",
801 {}, // forall
802 {}, // assertions
803 {
804 new ast::ObjectDecl(
805 location,
806 "",
807 new ast::ReferenceType( i->get() ),
808 (ast::Init *)nullptr,
809 ast::Storage::Classes(),
810 ast::Linkage::Cforall,
811 (ast::Expr *)nullptr
812 ),
813 new ast::ObjectDecl(
814 location,
815 "",
816 i->get(),
817 (ast::Init *)nullptr,
818 ast::Storage::Classes(),
819 ast::Linkage::Cforall,
820 (ast::Expr *)nullptr
821 ),
822 }, // params
823 {}, // returns
824 (ast::CompoundStmt *)nullptr,
825 ast::Storage::Classes(),
826 ast::Linkage::Cforall
827 ) );
828
829 // add dtor: void ^?{}(T *)
830 newAssertions.push_back( new ast::FunctionDecl(
831 location,
832 "^?{}",
833 {}, // forall
834 {}, // assertions
835 {
836 new ast::ObjectDecl(
837 location,
838 "",
839 new ast::ReferenceType( i->get() ),
840 (ast::Init *)nullptr,
841 ast::Storage::Classes(),
842 ast::Linkage::Cforall,
843 (ast::Expr *)nullptr
844 ),
845 }, // params
846 {}, // returns
847 (ast::CompoundStmt *)nullptr,
848 ast::Storage::Classes(),
849 ast::Linkage::Cforall
850 ) );
851
852 spliceBegin( mutTypeDecl->assertions, newAssertions );
853 } // for
854}
855
856
857void buildForall(
858 const DeclarationNode * firstNode,
859 std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
860 buildList( firstNode, outputForall );
861 auto n = firstNode;
862 for ( auto i = outputForall.begin() ;
863 i != outputForall.end() ;
864 ++i, n = n->next ) {
865 // Only the object type class adds additional assertions.
866 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
867 continue;
868 }
869
870 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
871 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
872 auto mutTypeDecl = ast::mutate( td );
873 const CodeLocation & location = mutTypeDecl->location;
874 *i = mutTypeDecl;
875
876 // add assertion parameters to `type' tyvars in reverse order
877 // add assignment operator: T * ?=?(T *, T)
878 newAssertions.push_back( new ast::FunctionDecl(
879 location,
880 "?=?",
881 {}, // forall
882 {}, // assertions
883 {
884 new ast::ObjectDecl(
885 location,
886 "",
887 new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
888 (ast::Init *)nullptr,
889 ast::Storage::Classes(),
890 ast::Linkage::Cforall,
891 (ast::Expr *)nullptr
892 ),
893 new ast::ObjectDecl(
894 location,
895 "",
896 new ast::TypeInstType( td->name, *i ),
897 (ast::Init *)nullptr,
898 ast::Storage::Classes(),
899 ast::Linkage::Cforall,
900 (ast::Expr *)nullptr
901 ),
902 }, // params
903 {
904 new ast::ObjectDecl(
905 location,
906 "",
907 new ast::TypeInstType( td->name, *i ),
908 (ast::Init *)nullptr,
909 ast::Storage::Classes(),
910 ast::Linkage::Cforall,
911 (ast::Expr *)nullptr
912 ),
913 }, // returns
914 (ast::CompoundStmt *)nullptr,
915 ast::Storage::Classes(),
916 ast::Linkage::Cforall
917 ) );
918
919 // add default ctor: void ?{}(T *)
920 newAssertions.push_back( new ast::FunctionDecl(
921 location,
922 "?{}",
923 {}, // forall
924 {}, // assertions
925 {
926 new ast::ObjectDecl(
927 location,
928 "",
929 new ast::ReferenceType(
930 new ast::TypeInstType( td->name, i->get() ) ),
931 (ast::Init *)nullptr,
932 ast::Storage::Classes(),
933 ast::Linkage::Cforall,
934 (ast::Expr *)nullptr
935 ),
936 }, // params
937 {}, // returns
938 (ast::CompoundStmt *)nullptr,
939 ast::Storage::Classes(),
940 ast::Linkage::Cforall
941 ) );
942
943 // add copy ctor: void ?{}(T *, T)
944 newAssertions.push_back( new ast::FunctionDecl(
945 location,
946 "?{}",
947 {}, // forall
948 {}, // assertions
949 {
950 new ast::ObjectDecl(
951 location,
952 "",
953 new ast::ReferenceType(
954 new ast::TypeInstType( td->name, *i ) ),
955 (ast::Init *)nullptr,
956 ast::Storage::Classes(),
957 ast::Linkage::Cforall,
958 (ast::Expr *)nullptr
959 ),
960 new ast::ObjectDecl(
961 location,
962 "",
963 new ast::TypeInstType( td->name, *i ),
964 (ast::Init *)nullptr,
965 ast::Storage::Classes(),
966 ast::Linkage::Cforall,
967 (ast::Expr *)nullptr
968 ),
969 }, // params
970 {}, // returns
971 (ast::CompoundStmt *)nullptr,
972 ast::Storage::Classes(),
973 ast::Linkage::Cforall
974 ) );
975
976 // add dtor: void ^?{}(T *)
977 newAssertions.push_back( new ast::FunctionDecl(
978 location,
979 "^?{}",
980 {}, // forall
981 {}, // assertions
982 {
983 new ast::ObjectDecl(
984 location,
985 "",
986 new ast::ReferenceType(
987 new ast::TypeInstType( i->get() )
988 ),
989 (ast::Init *)nullptr,
990 ast::Storage::Classes(),
991 ast::Linkage::Cforall,
992 (ast::Expr *)nullptr
993 ),
994 }, // params
995 {}, // returns
996 (ast::CompoundStmt *)nullptr,
997 ast::Storage::Classes(),
998 ast::Linkage::Cforall
999 ) );
1000
1001 spliceBegin( mutTypeDecl->assertions, newAssertions );
1002 } // for
1003} // buildForall
1004
1005
1006ast::Type * typebuild( const TypeData * td ) {
1007 assert( td );
1008 switch ( td->kind ) {
1009 case TypeData::Unknown:
1010 // fill in implicit int
1011 return new ast::BasicType(
1012 ast::BasicType::SignedInt,
1013 buildQualifiers( td )
1014 );
1015 case TypeData::Basic:
1016 return buildBasicType( td );
1017 case TypeData::Pointer:
1018 return buildPointer( td );
1019 case TypeData::Array:
1020 return buildArray( td );
1021 case TypeData::Reference:
1022 return buildReference( td );
1023 case TypeData::Function:
1024 return buildFunctionType( td );
1025 case TypeData::AggregateInst:
1026 return buildAggInst( td );
1027 case TypeData::EnumConstant:
1028 return new ast::EnumInstType( "", buildQualifiers( td ) );
1029 case TypeData::SymbolicInst:
1030 return buildSymbolicInst( td );
1031 case TypeData::Tuple:
1032 return buildTuple( td );
1033 case TypeData::Typeof:
1034 case TypeData::Basetypeof:
1035 return buildTypeof( td );
1036 case TypeData::Vtable:
1037 return buildVtable( td );
1038 case TypeData::Builtin:
1039 switch ( td->builtintype ) {
1040 case TypeData::Zero:
1041 return new ast::ZeroType();
1042 case TypeData::One:
1043 return new ast::OneType();
1044 default:
1045 return new ast::VarArgsType( buildQualifiers( td ) );
1046 } // switch
1047 case TypeData::GlobalScope:
1048 return new ast::GlobalScopeType();
1049 case TypeData::Qualified:
1050 return new ast::QualifiedType(
1051 typebuild( td->qualified.parent ),
1052 typebuild( td->qualified.child ),
1053 buildQualifiers( td )
1054 );
1055 case TypeData::Symbolic:
1056 case TypeData::Aggregate:
1057 assert( false );
1058 } // switch
1059
1060 return nullptr;
1061} // typebuild
1062
1063
1064TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
1065 TypeData * ret = nullptr;
1066
1067 switch ( td->kind ) {
1068 case TypeData::Aggregate:
1069 if ( ! toplevel && td->aggregate.body ) {
1070 ret = td->clone();
1071 } // if
1072 break;
1073 case TypeData::AggregateInst:
1074 if ( td->aggInst.aggregate ) {
1075 ret = typeextractAggregate( td->aggInst.aggregate, false );
1076 } // if
1077 break;
1078 default:
1079 if ( td->base ) {
1080 ret = typeextractAggregate( td->base, false );
1081 } // if
1082 } // switch
1083 return ret;
1084} // typeextractAggregate
1085
1086
1087ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
1088 return td->qualifiers;
1089} // buildQualifiers
1090
1091
1092static string genTSError( string msg, TypeData::BasicType basictype ) {
1093 SemanticError( yylloc, "invalid type specifier \"%s\" for type \"%s\".", msg.c_str(), TypeData::basicTypeNames[basictype] );
1094} // genTSError
1095
1096ast::Type * buildBasicType( const TypeData * td ) {
1097 ast::BasicType::Kind ret;
1098
1099 switch ( td->basictype ) {
1100 case TypeData::Void:
1101 if ( td->signedness != TypeData::NoSignedness ) {
1102 genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1103 } // if
1104 if ( td->length != TypeData::NoLength ) {
1105 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1106 } // if
1107 return new ast::VoidType( buildQualifiers( td ) );
1108 break;
1109
1110 case TypeData::Bool:
1111 if ( td->signedness != TypeData::NoSignedness ) {
1112 genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1113 } // if
1114 if ( td->length != TypeData::NoLength ) {
1115 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1116 } // if
1117
1118 ret = ast::BasicType::Bool;
1119 break;
1120
1121 case TypeData::Char:
1122 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
1123 // character types. The implementation shall define char to have the same range, representation, and behavior as
1124 // either signed char or unsigned char.
1125 static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };
1126
1127 if ( td->length != TypeData::NoLength ) {
1128 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1129 } // if
1130
1131 ret = chartype[ td->signedness ];
1132 break;
1133
1134 case TypeData::Int:
1135 static ast::BasicType::Kind inttype[2][4] = {
1136 { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },
1137 { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },
1138 };
1139
1140 Integral: ;
1141 if ( td->signedness == TypeData::NoSignedness ) {
1142 const_cast<TypeData *>(td)->signedness = TypeData::Signed;
1143 } // if
1144 ret = inttype[ td->signedness ][ td->length ];
1145 break;
1146
1147 case TypeData::Int128:
1148 ret = td->signedness == TypeData::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
1149 if ( td->length != TypeData::NoLength ) {
1150 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1151 } // if
1152 break;
1153
1154 case TypeData::Float:
1155 case TypeData::Double:
1156 case TypeData::LongDouble: // not set until below
1157 case TypeData::uuFloat80:
1158 case TypeData::uuFloat128:
1159 case TypeData::uFloat16:
1160 case TypeData::uFloat32:
1161 case TypeData::uFloat32x:
1162 case TypeData::uFloat64:
1163 case TypeData::uFloat64x:
1164 case TypeData::uFloat128:
1165 case TypeData::uFloat128x:
1166 static ast::BasicType::Kind floattype[2][12] = {
1167 { 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, },
1168 { 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, },
1169 };
1170
1171 FloatingPoint: ;
1172 if ( td->signedness != TypeData::NoSignedness ) {
1173 genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1174 } // if
1175 if ( td->length == TypeData::Short || td->length == TypeData::LongLong ) {
1176 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1177 } // if
1178 if ( td->basictype != TypeData::Double && td->length == TypeData::Long ) {
1179 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1180 } // if
1181 if ( td->complextype == TypeData::Imaginary ) {
1182 genTSError( TypeData::complexTypeNames[ td->complextype ], td->basictype );
1183 } // if
1184 if ( (td->basictype == TypeData::uuFloat80 || td->basictype == TypeData::uuFloat128) && td->complextype == TypeData::Complex ) { // gcc unsupported
1185 genTSError( TypeData::complexTypeNames[ td->complextype ], td->basictype );
1186 } // if
1187 if ( td->length == TypeData::Long ) {
1188 const_cast<TypeData *>(td)->basictype = TypeData::LongDouble;
1189 } // if
1190
1191 ret = floattype[ td->complextype ][ td->basictype - TypeData::Float ];
1192 //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, TypeData::Float, ret );
1193 break;
1194
1195 case TypeData::NoBasicType:
1196 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
1197 if ( td->complextype == TypeData::Complex || td->complextype == TypeData::Imaginary ) {
1198 const_cast<TypeData *>(td)->basictype = TypeData::Double;
1199 goto FloatingPoint;
1200 } // if
1201
1202 const_cast<TypeData *>(td)->basictype = TypeData::Int;
1203 goto Integral;
1204 default:
1205 assertf( false, "unknown basic type" );
1206 return nullptr;
1207 } // switch
1208
1209 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
1210 return bt;
1211} // buildBasicType
1212
1213
1214static ast::Type * buildDefaultType( const TypeData * td ) {
1215 return ( td ) ? typebuild( td ) : new ast::BasicType( ast::BasicType::SignedInt );
1216} // buildDefaultType
1217
1218
1219ast::PointerType * buildPointer( const TypeData * td ) {
1220 return new ast::PointerType(
1221 buildDefaultType( td->base ),
1222 buildQualifiers( td )
1223 );
1224} // buildPointer
1225
1226
1227ast::ArrayType * buildArray( const TypeData * td ) {
1228 return new ast::ArrayType(
1229 buildDefaultType( td->base ),
1230 maybeBuild( td->array.dimension ),
1231 td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1232 td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1233 buildQualifiers( td )
1234 );
1235} // buildArray
1236
1237
1238ast::ReferenceType * buildReference( const TypeData * td ) {
1239 return new ast::ReferenceType(
1240 buildDefaultType( td->base ),
1241 buildQualifiers( td )
1242 );
1243} // buildReference
1244
1245
1246ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
1247 assert( td->kind == TypeData::Aggregate );
1248 ast::AggregateDecl * at;
1249 switch ( td->aggregate.kind ) {
1250 case ast::AggregateDecl::Struct:
1251 case ast::AggregateDecl::Coroutine:
1252 case ast::AggregateDecl::Exception:
1253 case ast::AggregateDecl::Generator:
1254 case ast::AggregateDecl::Monitor:
1255 case ast::AggregateDecl::Thread:
1256 at = new ast::StructDecl( td->location,
1257 *td->aggregate.name,
1258 td->aggregate.kind,
1259 std::move( attributes ),
1260 linkage
1261 );
1262 buildForall( td->aggregate.params, at->params );
1263 break;
1264 case ast::AggregateDecl::Union:
1265 at = new ast::UnionDecl( td->location,
1266 *td->aggregate.name,
1267 std::move( attributes ),
1268 linkage
1269 );
1270 buildForall( td->aggregate.params, at->params );
1271 break;
1272 case ast::AggregateDecl::Enum:
1273 return buildEnum( td, std::move( attributes ), linkage );
1274 case ast::AggregateDecl::Trait:
1275 at = new ast::TraitDecl( td->location,
1276 *td->aggregate.name,
1277 std::move( attributes ),
1278 linkage
1279 );
1280 buildList( td->aggregate.params, at->params );
1281 break;
1282 default:
1283 assert( false );
1284 } // switch
1285
1286 buildList( td->aggregate.fields, at->members );
1287 at->set_body( td->aggregate.body );
1288
1289 return at;
1290} // buildAggregate
1291
1292
1293ast::BaseInstType * buildComAggInst(
1294 const TypeData * td,
1295 std::vector<ast::ptr<ast::Attribute>> && attributes,
1296 ast::Linkage::Spec linkage ) {
1297 switch ( td->kind ) {
1298 case TypeData::Aggregate:
1299 if ( td->aggregate.body ) {
1300 ast::AggregateDecl * typedecl =
1301 buildAggregate( td, std::move( attributes ), linkage );
1302 switch ( td->aggregate.kind ) {
1303 case ast::AggregateDecl::Struct:
1304 case ast::AggregateDecl::Coroutine:
1305 case ast::AggregateDecl::Monitor:
1306 case ast::AggregateDecl::Thread:
1307 return new ast::StructInstType(
1308 strict_dynamic_cast<ast::StructDecl *>( typedecl ),
1309 buildQualifiers( td )
1310 );
1311 case ast::AggregateDecl::Union:
1312 return new ast::UnionInstType(
1313 strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
1314 buildQualifiers( td )
1315 );
1316 case ast::AggregateDecl::Enum:
1317 return new ast::EnumInstType(
1318 strict_dynamic_cast<ast::EnumDecl *>( typedecl ),
1319 buildQualifiers( td )
1320 );
1321 case ast::AggregateDecl::Trait:
1322 assert( false );
1323 break;
1324 default:
1325 assert( false );
1326 } // switch
1327 } else {
1328 switch ( td->aggregate.kind ) {
1329 case ast::AggregateDecl::Struct:
1330 case ast::AggregateDecl::Coroutine:
1331 case ast::AggregateDecl::Monitor:
1332 case ast::AggregateDecl::Thread:
1333 return new ast::StructInstType(
1334 *td->aggregate.name,
1335 buildQualifiers( td )
1336 );
1337 case ast::AggregateDecl::Union:
1338 return new ast::UnionInstType(
1339 *td->aggregate.name,
1340 buildQualifiers( td )
1341 );
1342 case ast::AggregateDecl::Enum:
1343 return new ast::EnumInstType(
1344 *td->aggregate.name,
1345 buildQualifiers( td )
1346 );
1347 case ast::AggregateDecl::Trait:
1348 return new ast::TraitInstType(
1349 *td->aggregate.name,
1350 buildQualifiers( td )
1351 );
1352 default:
1353 assert( false );
1354 } // switch
1355 break;
1356 } // if
1357 break;
1358 default:
1359 assert( false );
1360 } // switch
1361 assert( false );
1362} // buildAggInst
1363
1364
1365ast::BaseInstType * buildAggInst( const TypeData * td ) {
1366 assert( td->kind == TypeData::AggregateInst );
1367
1368 ast::BaseInstType * ret = nullptr;
1369 TypeData * type = td->aggInst.aggregate;
1370 switch ( type->kind ) {
1371 case TypeData::Aggregate:
1372 switch ( type->aggregate.kind ) {
1373 case ast::AggregateDecl::Struct:
1374 case ast::AggregateDecl::Coroutine:
1375 case ast::AggregateDecl::Monitor:
1376 case ast::AggregateDecl::Thread:
1377 ret = new ast::StructInstType(
1378 *type->aggregate.name,
1379 buildQualifiers( type )
1380 );
1381 break;
1382 case ast::AggregateDecl::Union:
1383 ret = new ast::UnionInstType(
1384 *type->aggregate.name,
1385 buildQualifiers( type )
1386 );
1387 break;
1388 case ast::AggregateDecl::Enum:
1389 ret = new ast::EnumInstType(
1390 *type->aggregate.name,
1391 buildQualifiers( type )
1392 );
1393 break;
1394 case ast::AggregateDecl::Trait:
1395 ret = new ast::TraitInstType(
1396 *type->aggregate.name,
1397 buildQualifiers( type )
1398 );
1399 break;
1400 default:
1401 assert( false );
1402 } // switch
1403 break;
1404 default:
1405 assert( false );
1406 } // switch
1407
1408 ret->hoistType = td->aggInst.hoistType;
1409 buildList( td->aggInst.params, ret->params );
1410 return ret;
1411} // buildAggInst
1412
1413
1414ast::NamedTypeDecl * buildSymbolic(
1415 const TypeData * td,
1416 std::vector<ast::ptr<ast::Attribute>> attributes,
1417 const std::string & name,
1418 ast::Storage::Classes scs,
1419 ast::Linkage::Spec linkage ) {
1420 assert( td->kind == TypeData::Symbolic );
1421 ast::NamedTypeDecl * ret;
1422 assert( td->base );
1423 if ( td->symbolic.isTypedef ) {
1424 ret = new ast::TypedefDecl(
1425 td->location,
1426 name,
1427 scs,
1428 typebuild( td->base ),
1429 linkage
1430 );
1431 } else {
1432 ret = new ast::TypeDecl(
1433 td->location,
1434 name,
1435 scs,
1436 typebuild( td->base ),
1437 ast::TypeDecl::Dtype,
1438 true
1439 );
1440 } // if
1441 buildList( td->symbolic.assertions, ret->assertions );
1442 splice( ret->base.get_and_mutate()->attributes, attributes );
1443 return ret;
1444} // buildSymbolic
1445
1446
1447ast::EnumDecl * buildEnum(
1448 const TypeData * td,
1449 std::vector<ast::ptr<ast::Attribute>> && attributes,
1450 ast::Linkage::Spec linkage ) {
1451 assert( td->kind == TypeData::Aggregate );
1452 assert( td->aggregate.kind == ast::AggregateDecl::Enum );
1453 ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
1454 ast::EnumDecl * ret = new ast::EnumDecl(
1455 td->location,
1456 *td->aggregate.name,
1457 td->aggregate.typed,
1458 std::move( attributes ),
1459 linkage,
1460 baseType
1461 );
1462 buildList( td->aggregate.fields, ret->members );
1463 auto members = ret->members.begin();
1464 ret->hide = td->aggregate.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
1465 for ( const DeclarationNode * cur = td->aggregate.fields ; cur != nullptr ; cur = cur->next, ++members ) {
1466 if ( cur->enumInLine ) {
1467 // Do Nothing
1468 } else if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
1469 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
1470 } else if ( cur->has_enumeratorValue() ) {
1471 ast::Decl * member = members->get_and_mutate();
1472 ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
1473 object->init = new ast::SingleInit(
1474 td->location,
1475 maybeMoveBuild( cur->consume_enumeratorValue() ),
1476 ast::NoConstruct
1477 );
1478 } else if ( !cur->initializer ) {
1479 if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
1480 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
1481 }
1482 }
1483 // else cur is a List Initializer and has been set as init in buildList()
1484 // if
1485 } // for
1486 ret->body = td->aggregate.body;
1487 return ret;
1488} // buildEnum
1489
1490
1491ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
1492 assert( td->kind == TypeData::SymbolicInst );
1493 ast::TypeInstType * ret = new ast::TypeInstType(
1494 *td->symbolic.name,
1495 ast::TypeDecl::Dtype,
1496 buildQualifiers( td )
1497 );
1498 buildList( td->symbolic.actuals, ret->params );
1499 return ret;
1500} // buildSymbolicInst
1501
1502
1503ast::TupleType * buildTuple( const TypeData * td ) {
1504 assert( td->kind == TypeData::Tuple );
1505 std::vector<ast::ptr<ast::Type>> types;
1506 buildTypeList( td->tuple, types );
1507 ast::TupleType * ret = new ast::TupleType(
1508 std::move( types ),
1509 buildQualifiers( td )
1510 );
1511 return ret;
1512} // buildTuple
1513
1514
1515ast::TypeofType * buildTypeof( const TypeData * td ) {
1516 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
1517 assert( td->typeexpr );
1518 return new ast::TypeofType(
1519 td->typeexpr->build(),
1520 td->kind == TypeData::Typeof
1521 ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
1522 buildQualifiers( td )
1523 );
1524} // buildTypeof
1525
1526
1527ast::VTableType * buildVtable( const TypeData * td ) {
1528 assert( td->base );
1529 return new ast::VTableType(
1530 typebuild( td->base ),
1531 buildQualifiers( td )
1532 );
1533} // buildVtable
1534
1535
1536ast::FunctionDecl * buildFunctionDecl(
1537 const TypeData * td,
1538 const string &name,
1539 ast::Storage::Classes scs,
1540 ast::Function::Specs funcSpec,
1541 ast::Linkage::Spec linkage,
1542 ast::Expr * asmName,
1543 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1544 assert( td->kind == TypeData::Function );
1545 // For some reason FunctionDecl takes a bool instead of an ArgumentFlag.
1546 bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
1547 ast::CV::Qualifiers cvq = buildQualifiers( td );
1548 std::vector<ast::ptr<ast::TypeDecl>> forall;
1549 std::vector<ast::ptr<ast::DeclWithType>> assertions;
1550 std::vector<ast::ptr<ast::DeclWithType>> params;
1551 std::vector<ast::ptr<ast::DeclWithType>> returns;
1552 buildList( td->function.params, params );
1553 buildForall( td->forall, forall );
1554 // Functions do not store their assertions there anymore.
1555 for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1556 auto mut = type_param.get_and_mutate();
1557 splice( assertions, mut->assertions );
1558 }
1559 if ( td->base ) {
1560 switch ( td->base->kind ) {
1561 case TypeData::Tuple:
1562 buildList( td->base->tuple, returns );
1563 break;
1564 default:
1565 returns.push_back( dynamic_cast<ast::DeclWithType *>(
1566 buildDecl(
1567 td->base,
1568 "",
1569 ast::Storage::Classes(),
1570 (ast::Expr *)nullptr, // bitfieldWidth
1571 ast::Function::Specs(),
1572 ast::Linkage::Cforall,
1573 (ast::Expr *)nullptr // asmName
1574 )
1575 ) );
1576 } // switch
1577 } else {
1578 returns.push_back( new ast::ObjectDecl(
1579 td->location,
1580 "",
1581 new ast::BasicType( ast::BasicType::SignedInt ),
1582 (ast::Init *)nullptr,
1583 ast::Storage::Classes(),
1584 ast::Linkage::Cforall
1585 ) );
1586 } // if
1587 ast::Stmt * stmt = maybeBuild( td->function.body );
1588 ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1589 ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1590 name,
1591 std::move( forall ),
1592 std::move( assertions ),
1593 std::move( params ),
1594 std::move( returns ),
1595 body,
1596 scs,
1597 linkage,
1598 std::move( attributes ),
1599 funcSpec,
1600 (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
1601 );
1602 buildList( td->function.withExprs, decl->withExprs );
1603 decl->asmName = asmName;
1604 // This may be redundant on a declaration.
1605 decl->type.get_and_mutate()->qualifiers = cvq;
1606 return decl;
1607} // buildFunctionDecl
1608
1609
1610ast::Decl * buildDecl(
1611 const TypeData * td,
1612 const string &name,
1613 ast::Storage::Classes scs,
1614 ast::Expr * bitfieldWidth,
1615 ast::Function::Specs funcSpec,
1616 ast::Linkage::Spec linkage,
1617 ast::Expr * asmName,
1618 ast::Init * init,
1619 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1620 if ( td->kind == TypeData::Function ) {
1621 if ( td->function.idList ) { // KR function ?
1622 buildKRFunction( td->function ); // transform into C11 function
1623 } // if
1624
1625 return buildFunctionDecl(
1626 td, name, scs, funcSpec, linkage,
1627 asmName, std::move( attributes ) );
1628 } else if ( td->kind == TypeData::Aggregate ) {
1629 return buildAggregate( td, std::move( attributes ), linkage );
1630 } else if ( td->kind == TypeData::Symbolic ) {
1631 return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1632 } else {
1633 auto ret = new ast::ObjectDecl( td->location,
1634 name,
1635 typebuild( td ),
1636 init,
1637 scs,
1638 linkage,
1639 bitfieldWidth,
1640 std::move( attributes )
1641 );
1642 ret->asmName = asmName;
1643 return ret;
1644 } // if
1645 return nullptr;
1646} // buildDecl
1647
1648
1649ast::FunctionType * buildFunctionType( const TypeData * td ) {
1650 assert( td->kind == TypeData::Function );
1651 ast::FunctionType * ft = new ast::FunctionType(
1652 ( !td->function.params || td->function.params->hasEllipsis )
1653 ? ast::VariableArgs : ast::FixedArgs,
1654 buildQualifiers( td )
1655 );
1656 buildTypeList( td->function.params, ft->params );
1657 buildForall( td->forall, ft->forall );
1658 if ( td->base ) {
1659 switch ( td->base->kind ) {
1660 case TypeData::Tuple:
1661 buildTypeList( td->base->tuple, ft->returns );
1662 break;
1663 default:
1664 ft->returns.push_back( typebuild( td->base ) );
1665 break;
1666 } // switch
1667 } else {
1668 ft->returns.push_back(
1669 new ast::BasicType( ast::BasicType::SignedInt ) );
1670 } // if
1671 return ft;
1672} // buildFunctionType
1673
1674
1675// Transform KR routine declarations into C99 routine declarations:
1676//
1677// rtn( a, b, c ) int a, c; double b {} => int rtn( int a, double c, int b ) {}
1678//
1679// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1680// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1681// extra names are disallowed.
1682//
1683// Note, there is no KR routine-prototype syntax:
1684//
1685// rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1686// rtn(); // valid KR prototype
1687
1688void buildKRFunction( const TypeData::Function_t & function ) {
1689 assert( ! function.params );
1690 // loop over declaration first as it is easier to spot errors
1691 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) {
1692 // scan ALL parameter names for each declaration name to check for duplicates
1693 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1694 if ( *decl->name == *param->name ) {
1695 // type set => parameter name already transformed by a declaration names so there is a duplicate
1696 // declaration name attempting a second transformation
1697 if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1698 // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1699 // parameter name attempting a second transformation
1700 if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1701 param->type = decl->type; // set copy declaration type to parameter type
1702 decl->type = nullptr; // reset declaration type
1703 // Copy and reset attributes from declaration to parameter:
1704 splice( param->attributes, decl->attributes );
1705 } // if
1706 } // for
1707 // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1708 if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1709 } // for
1710
1711 // Parameter names without a declaration default to type int:
1712 //
1713 // rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1714
1715 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1716 if ( ! param->type ) { // generate type int for empty parameter type
1717 param->type = new TypeData( TypeData::Basic );
1718 param->type->basictype = TypeData::Int;
1719 } // if
1720 } // for
1721
1722 function.params = function.idList; // newly modified idList becomes parameters
1723 function.idList = nullptr; // idList now empty
1724 delete function.oldDeclList; // deletes entire list
1725 function.oldDeclList = nullptr; // reset
1726} // buildKRFunction
1727
1728// Local Variables: //
1729// tab-width: 4 //
1730// mode: c++ //
1731// compile-command: "make install" //
1732// End: //
Note: See TracBrowser for help on using the repository browser.