source: src/Parser/TypeData.cc@ f4e01f1

ADT
Last change on this file since f4e01f1 was 561354f, checked in by JiadaL <j82liang@…>, 2 years ago

Save progress

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