source: src/Parser/TypeData.cpp@ ef05cf0

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

Moved over some clean-up I did in various attempted fixes. InitDepthChecker has a very rare error case that has now been removed.

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