source: src/Parser/TypeData.cpp@ 9bb6c5f

Last change on this file since 9bb6c5f was db19e1d, checked in by Andrew Beach <ajbeach@…>, 13 months ago

Changed the interpritation of () to be no parameters instead of any parameters. This had a lot of little changes because of this and some nearby clean-up. This includes some changes, including changing some generated functions to be fixed-args instead of variable-args, stripping out the place holder void parameter earlier, but it still shows up earlier in some cases that examine the parser directly. Also had to update the function generation tools. Have only tested with one --arch. Hopefully this all works out.

  • Property mode set to 100644
File size: 49.2 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.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 {}, // forall
740 {}, // assertions
741 {
742 new ast::ObjectDecl(
743 location,
744 "",
745 new ast::ReferenceType( i->get() ),
746 (ast::Init *)nullptr,
747 ast::Storage::Classes(),
748 ast::Linkage::Cforall,
749 (ast::Expr *)nullptr
750 ),
751 new ast::ObjectDecl(
752 location,
753 "",
754 i->get(),
755 (ast::Init *)nullptr,
756 ast::Storage::Classes(),
757 ast::Linkage::Cforall,
758 (ast::Expr *)nullptr
759 ),
760 }, // params
761 {
762 new ast::ObjectDecl(
763 location,
764 "",
765 i->get(),
766 (ast::Init *)nullptr,
767 ast::Storage::Classes(),
768 ast::Linkage::Cforall,
769 (ast::Expr *)nullptr
770 ),
771 }, // returns
772 (ast::CompoundStmt *)nullptr,
773 ast::Storage::Classes(),
774 ast::Linkage::Cforall
775 ) );
776
777 // add default ctor: void ?{}(T *)
778 newAssertions.push_back( new ast::FunctionDecl(
779 location,
780 "?{}",
781 {}, // forall
782 {}, // assertions
783 {
784 new ast::ObjectDecl(
785 location,
786 "",
787 new ast::ReferenceType( i->get() ),
788 (ast::Init *)nullptr,
789 ast::Storage::Classes(),
790 ast::Linkage::Cforall,
791 (ast::Expr *)nullptr
792 ),
793 }, // params
794 {}, // returns
795 (ast::CompoundStmt *)nullptr,
796 ast::Storage::Classes(),
797 ast::Linkage::Cforall
798 ) );
799
800 // add copy ctor: void ?{}(T *, T)
801 newAssertions.push_back( new ast::FunctionDecl(
802 location,
803 "?{}",
804 {}, // forall
805 {}, // assertions
806 {
807 new ast::ObjectDecl(
808 location,
809 "",
810 new ast::ReferenceType( i->get() ),
811 (ast::Init *)nullptr,
812 ast::Storage::Classes(),
813 ast::Linkage::Cforall,
814 (ast::Expr *)nullptr
815 ),
816 new ast::ObjectDecl(
817 location,
818 "",
819 i->get(),
820 (ast::Init *)nullptr,
821 ast::Storage::Classes(),
822 ast::Linkage::Cforall,
823 (ast::Expr *)nullptr
824 ),
825 }, // params
826 {}, // returns
827 (ast::CompoundStmt *)nullptr,
828 ast::Storage::Classes(),
829 ast::Linkage::Cforall
830 ) );
831
832 // add dtor: void ^?{}(T *)
833 newAssertions.push_back( new ast::FunctionDecl(
834 location,
835 "^?{}",
836 {}, // forall
837 {}, // assertions
838 {
839 new ast::ObjectDecl(
840 location,
841 "",
842 new ast::ReferenceType( i->get() ),
843 (ast::Init *)nullptr,
844 ast::Storage::Classes(),
845 ast::Linkage::Cforall,
846 (ast::Expr *)nullptr
847 ),
848 }, // params
849 {}, // returns
850 (ast::CompoundStmt *)nullptr,
851 ast::Storage::Classes(),
852 ast::Linkage::Cforall
853 ) );
854
855 spliceBegin( mutTypeDecl->assertions, newAssertions );
856 } // for
857}
858
859
860void buildForall(
861 const DeclarationNode * firstNode,
862 std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
863 buildList( firstNode, outputForall );
864 auto n = firstNode;
865 for ( auto i = outputForall.begin() ;
866 i != outputForall.end() ;
867 ++i, n = n->next ) {
868 // Only the object type class adds additional assertions.
869 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
870 continue;
871 }
872
873 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
874 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
875 auto mutTypeDecl = ast::mutate( td );
876 const CodeLocation & location = mutTypeDecl->location;
877 *i = mutTypeDecl;
878
879 // add assertion parameters to `type' tyvars in reverse order
880 // add assignment operator: T * ?=?(T *, T)
881 newAssertions.push_back( new ast::FunctionDecl(
882 location,
883 "?=?",
884 {}, // forall
885 {}, // assertions
886 {
887 new ast::ObjectDecl(
888 location,
889 "",
890 new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
891 (ast::Init *)nullptr,
892 ast::Storage::Classes(),
893 ast::Linkage::Cforall,
894 (ast::Expr *)nullptr
895 ),
896 new ast::ObjectDecl(
897 location,
898 "",
899 new ast::TypeInstType( td->name, *i ),
900 (ast::Init *)nullptr,
901 ast::Storage::Classes(),
902 ast::Linkage::Cforall,
903 (ast::Expr *)nullptr
904 ),
905 }, // params
906 {
907 new ast::ObjectDecl(
908 location,
909 "",
910 new ast::TypeInstType( td->name, *i ),
911 (ast::Init *)nullptr,
912 ast::Storage::Classes(),
913 ast::Linkage::Cforall,
914 (ast::Expr *)nullptr
915 ),
916 }, // returns
917 (ast::CompoundStmt *)nullptr,
918 ast::Storage::Classes(),
919 ast::Linkage::Cforall
920 ) );
921
922 // add default ctor: void ?{}(T *)
923 newAssertions.push_back( new ast::FunctionDecl(
924 location,
925 "?{}",
926 {}, // forall
927 {}, // assertions
928 {
929 new ast::ObjectDecl(
930 location,
931 "",
932 new ast::ReferenceType(
933 new ast::TypeInstType( td->name, i->get() ) ),
934 (ast::Init *)nullptr,
935 ast::Storage::Classes(),
936 ast::Linkage::Cforall,
937 (ast::Expr *)nullptr
938 ),
939 }, // params
940 {}, // returns
941 (ast::CompoundStmt *)nullptr,
942 ast::Storage::Classes(),
943 ast::Linkage::Cforall
944 ) );
945
946 // add copy ctor: void ?{}(T *, T)
947 newAssertions.push_back( new ast::FunctionDecl(
948 location,
949 "?{}",
950 {}, // forall
951 {}, // assertions
952 {
953 new ast::ObjectDecl(
954 location,
955 "",
956 new ast::ReferenceType(
957 new ast::TypeInstType( td->name, *i ) ),
958 (ast::Init *)nullptr,
959 ast::Storage::Classes(),
960 ast::Linkage::Cforall,
961 (ast::Expr *)nullptr
962 ),
963 new ast::ObjectDecl(
964 location,
965 "",
966 new ast::TypeInstType( td->name, *i ),
967 (ast::Init *)nullptr,
968 ast::Storage::Classes(),
969 ast::Linkage::Cforall,
970 (ast::Expr *)nullptr
971 ),
972 }, // params
973 {}, // returns
974 (ast::CompoundStmt *)nullptr,
975 ast::Storage::Classes(),
976 ast::Linkage::Cforall
977 ) );
978
979 // add dtor: void ^?{}(T *)
980 newAssertions.push_back( new ast::FunctionDecl(
981 location,
982 "^?{}",
983 {}, // forall
984 {}, // assertions
985 {
986 new ast::ObjectDecl(
987 location,
988 "",
989 new ast::ReferenceType(
990 new ast::TypeInstType( i->get() )
991 ),
992 (ast::Init *)nullptr,
993 ast::Storage::Classes(),
994 ast::Linkage::Cforall,
995 (ast::Expr *)nullptr
996 ),
997 }, // params
998 {}, // returns
999 (ast::CompoundStmt *)nullptr,
1000 ast::Storage::Classes(),
1001 ast::Linkage::Cforall
1002 ) );
1003
1004 spliceBegin( mutTypeDecl->assertions, newAssertions );
1005 } // for
1006} // buildForall
1007
1008
1009ast::Type * typebuild( const TypeData * td ) {
1010 assert( td );
1011 switch ( td->kind ) {
1012 case TypeData::Unknown:
1013 // fill in implicit int
1014 return new ast::BasicType(
1015 ast::BasicKind::SignedInt,
1016 buildQualifiers( td )
1017 );
1018 case TypeData::Basic:
1019 return buildBasicType( td );
1020 case TypeData::Pointer:
1021 return buildPointer( td );
1022 case TypeData::Array:
1023 return buildArray( td );
1024 case TypeData::Reference:
1025 return buildReference( td );
1026 case TypeData::Function:
1027 return buildFunctionType( td );
1028 case TypeData::AggregateInst:
1029 return buildAggInst( td );
1030 case TypeData::EnumConstant:
1031 return new ast::EnumInstType( "", buildQualifiers( td ) );
1032 case TypeData::SymbolicInst:
1033 return buildSymbolicInst( td );
1034 case TypeData::Tuple:
1035 return buildTuple( td );
1036 case TypeData::Typeof:
1037 case TypeData::Basetypeof:
1038 return buildTypeof( td );
1039 case TypeData::Vtable:
1040 return buildVtable( td );
1041 case TypeData::Builtin:
1042 switch ( td->builtintype ) {
1043 case TypeData::Zero:
1044 return new ast::ZeroType();
1045 case TypeData::One:
1046 return new ast::OneType();
1047 default:
1048 return new ast::VarArgsType( buildQualifiers( td ) );
1049 } // switch
1050 case TypeData::GlobalScope:
1051 return new ast::GlobalScopeType();
1052 case TypeData::Qualified:
1053 return new ast::QualifiedType(
1054 typebuild( td->qualified.parent ),
1055 typebuild( td->qualified.child ),
1056 buildQualifiers( td )
1057 );
1058 case TypeData::Symbolic:
1059 case TypeData::Aggregate:
1060 assert( false );
1061 } // switch
1062
1063 return nullptr;
1064} // typebuild
1065
1066
1067TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
1068 TypeData * ret = nullptr;
1069
1070 switch ( td->kind ) {
1071 case TypeData::Aggregate:
1072 if ( ! toplevel && td->aggregate.body ) {
1073 ret = td->clone();
1074 } // if
1075 break;
1076 case TypeData::AggregateInst:
1077 if ( td->aggInst.aggregate ) {
1078 ret = typeextractAggregate( td->aggInst.aggregate, false );
1079 } // if
1080 break;
1081 default:
1082 if ( td->base ) {
1083 ret = typeextractAggregate( td->base, false );
1084 } // if
1085 } // switch
1086 return ret;
1087} // typeextractAggregate
1088
1089
1090ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
1091 return td->qualifiers;
1092} // buildQualifiers
1093
1094
1095static string genTSError( string msg, TypeData::BasicType basictype ) {
1096 SemanticError( yylloc, "invalid type specifier \"%s\" for type \"%s\".", msg.c_str(), TypeData::basicTypeNames[basictype] );
1097} // genTSError
1098
1099ast::Type * buildBasicType( const TypeData * td ) {
1100 ast::BasicKind ret;
1101
1102 switch ( td->basictype ) {
1103 case TypeData::Void:
1104 if ( td->signedness != TypeData::NoSignedness ) {
1105 genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1106 } // if
1107 if ( td->length != TypeData::NoLength ) {
1108 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1109 } // if
1110 return new ast::VoidType( buildQualifiers( td ) );
1111 break;
1112
1113 case TypeData::Bool:
1114 if ( td->signedness != TypeData::NoSignedness ) {
1115 genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1116 } // if
1117 if ( td->length != TypeData::NoLength ) {
1118 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1119 } // if
1120
1121 ret = ast::BasicKind::Bool;
1122 break;
1123
1124 case TypeData::Char:
1125 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
1126 // character types. The implementation shall define char to have the same range, representation, and behavior as
1127 // either signed char or unsigned char.
1128 static ast::BasicKind chartype[] = { ast::BasicKind::SignedChar, ast::BasicKind::UnsignedChar, ast::BasicKind::Char };
1129
1130 if ( td->length != TypeData::NoLength ) {
1131 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1132 } // if
1133
1134 ret = chartype[ td->signedness ];
1135 break;
1136
1137 case TypeData::Int:
1138 static ast::BasicKind inttype[2][4] = {
1139 { ast::BasicKind::ShortSignedInt, ast::BasicKind::LongSignedInt, ast::BasicKind::LongLongSignedInt, ast::BasicKind::SignedInt },
1140 { ast::BasicKind::ShortUnsignedInt, ast::BasicKind::LongUnsignedInt, ast::BasicKind::LongLongUnsignedInt, ast::BasicKind::UnsignedInt },
1141 };
1142
1143 Integral: ;
1144 if ( td->signedness == TypeData::NoSignedness ) {
1145 const_cast<TypeData *>(td)->signedness = TypeData::Signed;
1146 } // if
1147 ret = inttype[ td->signedness ][ td->length ];
1148 break;
1149
1150 case TypeData::Int128:
1151 ret = td->signedness == TypeData::Unsigned ? ast::BasicKind::UnsignedInt128 : ast::BasicKind::SignedInt128;
1152 if ( td->length != TypeData::NoLength ) {
1153 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1154 } // if
1155 break;
1156
1157 case TypeData::Float:
1158 case TypeData::Double:
1159 case TypeData::LongDouble: // not set until below
1160 case TypeData::uuFloat80:
1161 case TypeData::uuFloat128:
1162 case TypeData::uFloat16:
1163 case TypeData::uFloat32:
1164 case TypeData::uFloat32x:
1165 case TypeData::uFloat64:
1166 case TypeData::uFloat64x:
1167 case TypeData::uFloat128:
1168 case TypeData::uFloat128x:
1169 static ast::BasicKind floattype[2][12] = {
1170 { 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, },
1171 { 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, },
1172 };
1173
1174 FloatingPoint: ;
1175 if ( td->signedness != TypeData::NoSignedness ) {
1176 genTSError( TypeData::signednessNames[ td->signedness ], td->basictype );
1177 } // if
1178 if ( td->length == TypeData::Short || td->length == TypeData::LongLong ) {
1179 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1180 } // if
1181 if ( td->basictype != TypeData::Double && td->length == TypeData::Long ) {
1182 genTSError( TypeData::lengthNames[ td->length ], td->basictype );
1183 } // if
1184 if ( td->complextype == TypeData::Imaginary ) {
1185 genTSError( TypeData::complexTypeNames[ td->complextype ], td->basictype );
1186 } // if
1187 if ( (td->basictype == TypeData::uuFloat80 || td->basictype == TypeData::uuFloat128) && td->complextype == TypeData::Complex ) { // gcc unsupported
1188 genTSError( TypeData::complexTypeNames[ td->complextype ], td->basictype );
1189 } // if
1190 if ( td->length == TypeData::Long ) {
1191 const_cast<TypeData *>(td)->basictype = TypeData::LongDouble;
1192 } // if
1193
1194 ret = floattype[ td->complextype ][ td->basictype - TypeData::Float ];
1195 //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, TypeData::Float, ret );
1196 break;
1197
1198 case TypeData::NoBasicType:
1199 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
1200 if ( td->complextype == TypeData::Complex || td->complextype == TypeData::Imaginary ) {
1201 const_cast<TypeData *>(td)->basictype = TypeData::Double;
1202 goto FloatingPoint;
1203 } // if
1204
1205 const_cast<TypeData *>(td)->basictype = TypeData::Int;
1206 goto Integral;
1207 default:
1208 assertf( false, "unknown basic type" );
1209 return nullptr;
1210 } // switch
1211
1212 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
1213 return bt;
1214} // buildBasicType
1215
1216
1217static ast::Type * buildDefaultType( const TypeData * td ) {
1218 return ( td ) ? typebuild( td ) : new ast::BasicType( ast::BasicKind::SignedInt );
1219} // buildDefaultType
1220
1221
1222ast::PointerType * buildPointer( const TypeData * td ) {
1223 return new ast::PointerType(
1224 buildDefaultType( td->base ),
1225 buildQualifiers( td )
1226 );
1227} // buildPointer
1228
1229
1230ast::ArrayType * buildArray( const TypeData * td ) {
1231 return new ast::ArrayType(
1232 buildDefaultType( td->base ),
1233 maybeBuild( td->array.dimension ),
1234 td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1235 td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1236 buildQualifiers( td )
1237 );
1238} // buildArray
1239
1240
1241ast::ReferenceType * buildReference( const TypeData * td ) {
1242 return new ast::ReferenceType(
1243 buildDefaultType( td->base ),
1244 buildQualifiers( td )
1245 );
1246} // buildReference
1247
1248
1249ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
1250 assert( td->kind == TypeData::Aggregate );
1251 ast::AggregateDecl * at;
1252 switch ( td->aggregate.kind ) {
1253 case ast::AggregateDecl::Struct:
1254 case ast::AggregateDecl::Coroutine:
1255 case ast::AggregateDecl::Exception:
1256 case ast::AggregateDecl::Generator:
1257 case ast::AggregateDecl::Monitor:
1258 case ast::AggregateDecl::Thread:
1259 at = new ast::StructDecl( td->location,
1260 *td->aggregate.name,
1261 td->aggregate.kind,
1262 std::move( attributes ),
1263 linkage
1264 );
1265 buildForall( td->aggregate.params, at->params );
1266 break;
1267 case ast::AggregateDecl::Union:
1268 at = new ast::UnionDecl( td->location,
1269 *td->aggregate.name,
1270 std::move( attributes ),
1271 linkage
1272 );
1273 buildForall( td->aggregate.params, at->params );
1274 break;
1275 case ast::AggregateDecl::Enum:
1276 return buildEnum( td, std::move( attributes ), linkage );
1277 case ast::AggregateDecl::Trait:
1278 at = new ast::TraitDecl( td->location,
1279 *td->aggregate.name,
1280 std::move( attributes ),
1281 linkage
1282 );
1283 buildList( td->aggregate.params, at->params );
1284 break;
1285 default:
1286 assert( false );
1287 } // switch
1288
1289 buildList( td->aggregate.fields, at->members );
1290 at->set_body( td->aggregate.body );
1291
1292 return at;
1293} // buildAggregate
1294
1295
1296ast::BaseInstType * buildComAggInst(
1297 const TypeData * td,
1298 std::vector<ast::ptr<ast::Attribute>> && attributes,
1299 ast::Linkage::Spec linkage ) {
1300 switch ( td->kind ) {
1301 case TypeData::Aggregate:
1302 if ( td->aggregate.body ) {
1303 ast::AggregateDecl * typedecl =
1304 buildAggregate( td, std::move( attributes ), linkage );
1305 switch ( td->aggregate.kind ) {
1306 case ast::AggregateDecl::Struct:
1307 case ast::AggregateDecl::Coroutine:
1308 case ast::AggregateDecl::Monitor:
1309 case ast::AggregateDecl::Thread:
1310 return new ast::StructInstType(
1311 strict_dynamic_cast<ast::StructDecl *>( typedecl ),
1312 buildQualifiers( td )
1313 );
1314 case ast::AggregateDecl::Union:
1315 return new ast::UnionInstType(
1316 strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
1317 buildQualifiers( td )
1318 );
1319 case ast::AggregateDecl::Enum:
1320 return new ast::EnumInstType(
1321 strict_dynamic_cast<ast::EnumDecl *>( typedecl ),
1322 buildQualifiers( td )
1323 );
1324 case ast::AggregateDecl::Trait:
1325 assert( false );
1326 break;
1327 default:
1328 assert( false );
1329 } // switch
1330 } else {
1331 switch ( td->aggregate.kind ) {
1332 case ast::AggregateDecl::Struct:
1333 case ast::AggregateDecl::Coroutine:
1334 case ast::AggregateDecl::Monitor:
1335 case ast::AggregateDecl::Thread:
1336 return new ast::StructInstType(
1337 *td->aggregate.name,
1338 buildQualifiers( td )
1339 );
1340 case ast::AggregateDecl::Union:
1341 return new ast::UnionInstType(
1342 *td->aggregate.name,
1343 buildQualifiers( td )
1344 );
1345 case ast::AggregateDecl::Enum:
1346 return new ast::EnumInstType(
1347 *td->aggregate.name,
1348 buildQualifiers( td )
1349 );
1350 case ast::AggregateDecl::Trait:
1351 return new ast::TraitInstType(
1352 *td->aggregate.name,
1353 buildQualifiers( td )
1354 );
1355 default:
1356 assert( false );
1357 } // switch
1358 break;
1359 } // if
1360 break;
1361 default:
1362 assert( false );
1363 } // switch
1364 assert( false );
1365} // buildAggInst
1366
1367
1368ast::BaseInstType * buildAggInst( const TypeData * td ) {
1369 assert( td->kind == TypeData::AggregateInst );
1370
1371 ast::BaseInstType * ret = nullptr;
1372 TypeData * type = td->aggInst.aggregate;
1373 switch ( type->kind ) {
1374 case TypeData::Aggregate:
1375 switch ( type->aggregate.kind ) {
1376 case ast::AggregateDecl::Struct:
1377 case ast::AggregateDecl::Coroutine:
1378 case ast::AggregateDecl::Monitor:
1379 case ast::AggregateDecl::Thread:
1380 ret = new ast::StructInstType(
1381 *type->aggregate.name,
1382 buildQualifiers( type )
1383 );
1384 break;
1385 case ast::AggregateDecl::Union:
1386 ret = new ast::UnionInstType(
1387 *type->aggregate.name,
1388 buildQualifiers( type )
1389 );
1390 break;
1391 case ast::AggregateDecl::Enum:
1392 ret = new ast::EnumInstType(
1393 *type->aggregate.name,
1394 buildQualifiers( type )
1395 );
1396 break;
1397 case ast::AggregateDecl::Trait:
1398 ret = new ast::TraitInstType(
1399 *type->aggregate.name,
1400 buildQualifiers( type )
1401 );
1402 break;
1403 default:
1404 assert( false );
1405 } // switch
1406 break;
1407 default:
1408 assert( false );
1409 } // switch
1410
1411 ret->hoistType = td->aggInst.hoistType;
1412 buildList( td->aggInst.params, ret->params );
1413 return ret;
1414} // buildAggInst
1415
1416
1417ast::NamedTypeDecl * buildSymbolic(
1418 const TypeData * td,
1419 std::vector<ast::ptr<ast::Attribute>> attributes,
1420 const std::string & name,
1421 ast::Storage::Classes scs,
1422 ast::Linkage::Spec linkage ) {
1423 assert( td->kind == TypeData::Symbolic );
1424 ast::NamedTypeDecl * ret;
1425 assert( td->base );
1426 if ( td->symbolic.isTypedef ) {
1427 ret = new ast::TypedefDecl(
1428 td->location,
1429 name,
1430 scs,
1431 typebuild( td->base ),
1432 linkage
1433 );
1434 } else {
1435 ret = new ast::TypeDecl(
1436 td->location,
1437 name,
1438 scs,
1439 typebuild( td->base ),
1440 ast::TypeDecl::Dtype,
1441 true
1442 );
1443 } // if
1444 buildList( td->symbolic.assertions, ret->assertions );
1445 splice( ret->base.get_and_mutate()->attributes, attributes );
1446 return ret;
1447} // buildSymbolic
1448
1449
1450ast::EnumDecl * buildEnum(
1451 const TypeData * td,
1452 std::vector<ast::ptr<ast::Attribute>> && attributes,
1453 ast::Linkage::Spec linkage ) {
1454 assert( td->kind == TypeData::Aggregate );
1455 assert( td->aggregate.kind == ast::AggregateDecl::Enum );
1456 ast::ptr<ast::Type> baseType = td->base ? typebuild(td->base) : nullptr;
1457
1458 ast::EnumDecl * ret = new ast::EnumDecl(
1459 td->location,
1460 *td->aggregate.name,
1461 td->aggregate.isCfa,
1462 std::move( attributes ),
1463 linkage,
1464 baseType
1465 );
1466 buildList( td->aggregate.fields, ret->members );
1467 auto members = ret->members.begin();
1468 ret->hide = td->aggregate.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
1469 for ( const DeclarationNode * cur = td->aggregate.fields ; cur != nullptr ; cur = cur->next, ++members ) {
1470 if (cur->enumInLine) continue;
1471 ast::Decl * member = members->get_and_mutate();
1472 ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
1473 object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
1474 if ( ret->isOpaque() && cur->has_enumeratorValue() ) {
1475 SemanticError( td->location, "Opague cannot have an explicit initializer value." );
1476 } else if ( cur->has_enumeratorValue() ) {
1477 ast::Expr * initValue;
1478 if (ret->isCfa && ret->base) {
1479 initValue = new ast::CastExpr( cur->enumeratorValue->location, maybeMoveBuild( cur->consume_enumeratorValue() ), ret->base );
1480 } else {
1481 initValue = maybeMoveBuild( cur->consume_enumeratorValue() );
1482 }
1483 object->init = new ast::SingleInit(
1484 td->location,
1485 initValue,
1486 ast::NoConstruct
1487 );
1488 }
1489 // else cur is a List Initializer and has been set as init in buildList()
1490 // if
1491 } // for
1492 ret->body = td->aggregate.body;
1493 return ret;
1494} // buildEnum
1495
1496
1497ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
1498 assert( td->kind == TypeData::SymbolicInst );
1499 ast::TypeInstType * ret = new ast::TypeInstType(
1500 *td->symbolic.name,
1501 ast::TypeDecl::Dtype,
1502 buildQualifiers( td )
1503 );
1504 buildList( td->symbolic.actuals, ret->params );
1505 return ret;
1506} // buildSymbolicInst
1507
1508
1509ast::TupleType * buildTuple( const TypeData * td ) {
1510 assert( td->kind == TypeData::Tuple );
1511 std::vector<ast::ptr<ast::Type>> types;
1512 buildTypeList( td->tuple, types );
1513 ast::TupleType * ret = new ast::TupleType(
1514 std::move( types ),
1515 buildQualifiers( td )
1516 );
1517 return ret;
1518} // buildTuple
1519
1520
1521ast::TypeofType * buildTypeof( const TypeData * td ) {
1522 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
1523 assert( td->typeexpr );
1524 return new ast::TypeofType(
1525 td->typeexpr->build(),
1526 td->kind == TypeData::Typeof
1527 ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
1528 buildQualifiers( td )
1529 );
1530} // buildTypeof
1531
1532
1533ast::VTableType * buildVtable( const TypeData * td ) {
1534 assert( td->base );
1535 return new ast::VTableType(
1536 typebuild( td->base ),
1537 buildQualifiers( td )
1538 );
1539} // buildVtable
1540
1541
1542// The argument flag (is/is not var-args) of a computed property.
1543static ast::ArgumentFlag buildArgumentFlag( const TypeData * td ) {
1544 assert( td->kind == TypeData::Function );
1545 bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
1546 return (isVarArgs) ? ast::VariableArgs : ast::FixedArgs;
1547}
1548
1549
1550// Wrapper to convert the void parameter into the empty explicit list.
1551static void buildParamList( DeclarationNode * decl,
1552 std::vector<ast::ptr<ast::DeclWithType>> & params ) {
1553 buildList( decl, params );
1554 if ( 1 == params.size() && params[0]->get_type()->isVoid() ) {
1555 params.pop_back();
1556 }
1557}
1558
1559
1560ast::FunctionDecl * buildFunctionDecl(
1561 const TypeData * td,
1562 const string &name,
1563 ast::Storage::Classes scs,
1564 ast::Function::Specs funcSpec,
1565 ast::Linkage::Spec linkage,
1566 ast::Expr * asmName,
1567 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1568 assert( td->kind == TypeData::Function );
1569 ast::CV::Qualifiers cvq = buildQualifiers( td );
1570 std::vector<ast::ptr<ast::TypeDecl>> forall;
1571 std::vector<ast::ptr<ast::DeclWithType>> assertions;
1572 std::vector<ast::ptr<ast::DeclWithType>> params;
1573 std::vector<ast::ptr<ast::DeclWithType>> returns;
1574 buildParamList( td->function.params, params );
1575 buildForall( td->forall, forall );
1576 // Functions do not store their assertions there anymore.
1577 for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1578 auto mut = type_param.get_and_mutate();
1579 splice( assertions, mut->assertions );
1580 }
1581 if ( td->base ) {
1582 switch ( td->base->kind ) {
1583 case TypeData::Tuple:
1584 buildList( td->base->tuple, returns );
1585 break;
1586 default:
1587 returns.push_back( dynamic_cast<ast::DeclWithType *>(
1588 buildDecl(
1589 td->base,
1590 "",
1591 ast::Storage::Classes(),
1592 (ast::Expr *)nullptr, // bitfieldWidth
1593 ast::Function::Specs(),
1594 ast::Linkage::Cforall,
1595 (ast::Expr *)nullptr // asmName
1596 )
1597 ) );
1598 } // switch
1599 } else {
1600 returns.push_back( new ast::ObjectDecl(
1601 td->location,
1602 "",
1603 new ast::BasicType( ast::BasicKind::SignedInt ),
1604 (ast::Init *)nullptr,
1605 ast::Storage::Classes(),
1606 ast::Linkage::Cforall
1607 ) );
1608 } // if
1609 ast::Stmt * stmt = maybeBuild( td->function.body );
1610 ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1611 ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1612 name,
1613 std::move( forall ),
1614 std::move( assertions ),
1615 std::move( params ),
1616 std::move( returns ),
1617 body,
1618 scs,
1619 linkage,
1620 std::move( attributes ),
1621 funcSpec,
1622 buildArgumentFlag( td )
1623 );
1624 buildList( td->function.withExprs, decl->withExprs );
1625 decl->asmName = asmName;
1626 // This may be redundant on a declaration.
1627 decl->type.get_and_mutate()->qualifiers = cvq;
1628 return decl;
1629} // buildFunctionDecl
1630
1631
1632ast::Decl * buildDecl(
1633 const TypeData * td,
1634 const string &name,
1635 ast::Storage::Classes scs,
1636 ast::Expr * bitfieldWidth,
1637 ast::Function::Specs funcSpec,
1638 ast::Linkage::Spec linkage,
1639 ast::Expr * asmName,
1640 ast::Init * init,
1641 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1642 if ( td->kind == TypeData::Function ) {
1643 if ( td->function.idList ) { // KR function ?
1644 buildKRFunction( td->function ); // transform into C11 function
1645 } // if
1646
1647 return buildFunctionDecl(
1648 td, name, scs, funcSpec, linkage,
1649 asmName, std::move( attributes ) );
1650 } else if ( td->kind == TypeData::Aggregate ) {
1651 return buildAggregate( td, std::move( attributes ), linkage );
1652 } else if ( td->kind == TypeData::Symbolic ) {
1653 return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1654 } else {
1655 auto ret = new ast::ObjectDecl( td->location,
1656 name,
1657 typebuild( td ),
1658 init,
1659 scs,
1660 linkage,
1661 bitfieldWidth,
1662 std::move( attributes )
1663 );
1664 ret->asmName = asmName;
1665 return ret;
1666 } // if
1667 return nullptr;
1668} // buildDecl
1669
1670
1671ast::FunctionType * buildFunctionType( const TypeData * td ) {
1672 assert( td->kind == TypeData::Function );
1673 ast::FunctionType * ft = new ast::FunctionType(
1674 buildArgumentFlag( td ),
1675 buildQualifiers( td )
1676 );
1677 buildTypeList( td->function.params, ft->params );
1678 buildForall( td->forall, ft->forall );
1679 if ( td->base ) {
1680 switch ( td->base->kind ) {
1681 case TypeData::Tuple:
1682 buildTypeList( td->base->tuple, ft->returns );
1683 break;
1684 default:
1685 ft->returns.push_back( typebuild( td->base ) );
1686 break;
1687 } // switch
1688 } else {
1689 ft->returns.push_back(
1690 new ast::BasicType( ast::BasicKind::SignedInt ) );
1691 } // if
1692 return ft;
1693} // buildFunctionType
1694
1695
1696// Transform KR routine declarations into C99 routine declarations:
1697//
1698// rtn( a, b, c ) int a, c; double b {} => int rtn( int a, double c, int b ) {}
1699//
1700// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1701// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1702// extra names are disallowed.
1703//
1704// Note, there is no KR routine-prototype syntax:
1705//
1706// rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1707// rtn(); // valid KR prototype
1708
1709void buildKRFunction( const TypeData::Function_t & function ) {
1710 assert( ! function.params );
1711 // loop over declaration first as it is easier to spot errors
1712 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) {
1713 // scan ALL parameter names for each declaration name to check for duplicates
1714 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1715 if ( *decl->name == *param->name ) {
1716 // type set => parameter name already transformed by a declaration names so there is a duplicate
1717 // declaration name attempting a second transformation
1718 if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1719 // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1720 // parameter name attempting a second transformation
1721 if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1722 param->type = decl->type; // set copy declaration type to parameter type
1723 decl->type = nullptr; // reset declaration type
1724 // Copy and reset attributes from declaration to parameter:
1725 splice( param->attributes, decl->attributes );
1726 } // if
1727 } // for
1728 // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1729 if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1730 } // for
1731
1732 // Parameter names without a declaration default to type int:
1733 //
1734 // rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1735
1736 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) {
1737 if ( ! param->type ) { // generate type int for empty parameter type
1738 param->type = new TypeData( TypeData::Basic );
1739 param->type->basictype = TypeData::Int;
1740 } // if
1741 } // for
1742
1743 function.params = function.idList; // newly modified idList becomes parameters
1744 function.idList = nullptr; // idList now empty
1745 delete function.oldDeclList; // deletes entire list
1746 function.oldDeclList = nullptr; // reset
1747} // buildKRFunction
1748
1749// Local Variables: //
1750// tab-width: 4 //
1751// mode: c++ //
1752// compile-command: "make install" //
1753// End: //
Note: See TracBrowser for help on using the repository browser.