source: src/Parser/TypeData.cpp@ 3eb5f993

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