source: src/Parser/TypeData.cc@ 06601401

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

Moved a field and functions from DeclarationNode to TypeData. Trying to make the line between them cleaner.

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