source: src/Parser/TypeData.cc@ 3f9a8d0

Last change on this file since 3f9a8d0 was 4eb3a7c5, checked in by Peter A. Buhr <pabuhr@…>, 19 months ago

first attempt at correct distribution of attributes for aggregates

  • Property mode set to 100644
File size: 43.5 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// TypeData.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
481void buildForall(
482 const DeclarationNode * firstNode,
483 std::vector<ast::ptr<ast::TypeInstType>> &outputList ) {
484 {
485 std::vector<ast::ptr<ast::Type>> tmpList;
486 buildTypeList( firstNode, tmpList );
487 for ( auto tmp : tmpList ) {
488 outputList.emplace_back(
489 strict_dynamic_cast<const ast::TypeInstType *>(
490 tmp.release() ) );
491 }
492 }
493 auto n = firstNode;
494 for ( auto i = outputList.begin() ;
495 i != outputList.end() ;
496 ++i, n = (DeclarationNode*)n->get_next() ) {
497 // Only the object type class adds additional assertions.
498 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
499 continue;
500 }
501
502 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
503 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
504 auto mutTypeDecl = ast::mutate( td );
505 const CodeLocation & location = mutTypeDecl->location;
506 *i = mutTypeDecl;
507
508 // add assertion parameters to `type' tyvars in reverse order
509 // add assignment operator: T * ?=?(T *, T)
510 newAssertions.push_back( new ast::FunctionDecl(
511 location,
512 "?=?",
513 {}, // forall
514 {}, // assertions
515 {
516 new ast::ObjectDecl(
517 location,
518 "",
519 new ast::ReferenceType( i->get() ),
520 (ast::Init *)nullptr,
521 ast::Storage::Classes(),
522 ast::Linkage::Cforall,
523 (ast::Expr *)nullptr
524 ),
525 new ast::ObjectDecl(
526 location,
527 "",
528 i->get(),
529 (ast::Init *)nullptr,
530 ast::Storage::Classes(),
531 ast::Linkage::Cforall,
532 (ast::Expr *)nullptr
533 ),
534 }, // params
535 {
536 new ast::ObjectDecl(
537 location,
538 "",
539 i->get(),
540 (ast::Init *)nullptr,
541 ast::Storage::Classes(),
542 ast::Linkage::Cforall,
543 (ast::Expr *)nullptr
544 ),
545 }, // returns
546 (ast::CompoundStmt *)nullptr,
547 ast::Storage::Classes(),
548 ast::Linkage::Cforall
549 ) );
550
551 // add default ctor: void ?{}(T *)
552 newAssertions.push_back( new ast::FunctionDecl(
553 location,
554 "?{}",
555 {}, // forall
556 {}, // assertions
557 {
558 new ast::ObjectDecl(
559 location,
560 "",
561 new ast::ReferenceType( i->get() ),
562 (ast::Init *)nullptr,
563 ast::Storage::Classes(),
564 ast::Linkage::Cforall,
565 (ast::Expr *)nullptr
566 ),
567 }, // params
568 {}, // returns
569 (ast::CompoundStmt *)nullptr,
570 ast::Storage::Classes(),
571 ast::Linkage::Cforall
572 ) );
573
574 // add copy ctor: void ?{}(T *, T)
575 newAssertions.push_back( new ast::FunctionDecl(
576 location,
577 "?{}",
578 {}, // forall
579 {}, // assertions
580 {
581 new ast::ObjectDecl(
582 location,
583 "",
584 new ast::ReferenceType( i->get() ),
585 (ast::Init *)nullptr,
586 ast::Storage::Classes(),
587 ast::Linkage::Cforall,
588 (ast::Expr *)nullptr
589 ),
590 new ast::ObjectDecl(
591 location,
592 "",
593 i->get(),
594 (ast::Init *)nullptr,
595 ast::Storage::Classes(),
596 ast::Linkage::Cforall,
597 (ast::Expr *)nullptr
598 ),
599 }, // params
600 {}, // returns
601 (ast::CompoundStmt *)nullptr,
602 ast::Storage::Classes(),
603 ast::Linkage::Cforall
604 ) );
605
606 // add dtor: void ^?{}(T *)
607 newAssertions.push_back( new ast::FunctionDecl(
608 location,
609 "^?{}",
610 {}, // forall
611 {}, // assertions
612 {
613 new ast::ObjectDecl(
614 location,
615 "",
616 new ast::ReferenceType( i->get() ),
617 (ast::Init *)nullptr,
618 ast::Storage::Classes(),
619 ast::Linkage::Cforall,
620 (ast::Expr *)nullptr
621 ),
622 }, // params
623 {}, // returns
624 (ast::CompoundStmt *)nullptr,
625 ast::Storage::Classes(),
626 ast::Linkage::Cforall
627 ) );
628
629 spliceBegin( mutTypeDecl->assertions, newAssertions );
630 } // for
631}
632
633
634void buildForall(
635 const DeclarationNode * firstNode,
636 std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
637 buildList( firstNode, outputForall );
638 auto n = firstNode;
639 for ( auto i = outputForall.begin() ;
640 i != outputForall.end() ;
641 ++i, n = (DeclarationNode*)n->get_next() ) {
642 // Only the object type class adds additional assertions.
643 if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
644 continue;
645 }
646
647 ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
648 std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
649 auto mutTypeDecl = ast::mutate( td );
650 const CodeLocation & location = mutTypeDecl->location;
651 *i = mutTypeDecl;
652
653 // add assertion parameters to `type' tyvars in reverse order
654 // add assignment operator: T * ?=?(T *, T)
655 newAssertions.push_back( new ast::FunctionDecl(
656 location,
657 "?=?",
658 {}, // forall
659 {}, // assertions
660 {
661 new ast::ObjectDecl(
662 location,
663 "",
664 new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
665 (ast::Init *)nullptr,
666 ast::Storage::Classes(),
667 ast::Linkage::Cforall,
668 (ast::Expr *)nullptr
669 ),
670 new ast::ObjectDecl(
671 location,
672 "",
673 new ast::TypeInstType( td->name, *i ),
674 (ast::Init *)nullptr,
675 ast::Storage::Classes(),
676 ast::Linkage::Cforall,
677 (ast::Expr *)nullptr
678 ),
679 }, // params
680 {
681 new ast::ObjectDecl(
682 location,
683 "",
684 new ast::TypeInstType( td->name, *i ),
685 (ast::Init *)nullptr,
686 ast::Storage::Classes(),
687 ast::Linkage::Cforall,
688 (ast::Expr *)nullptr
689 ),
690 }, // returns
691 (ast::CompoundStmt *)nullptr,
692 ast::Storage::Classes(),
693 ast::Linkage::Cforall
694 ) );
695
696 // add default ctor: void ?{}(T *)
697 newAssertions.push_back( new ast::FunctionDecl(
698 location,
699 "?{}",
700 {}, // forall
701 {}, // assertions
702 {
703 new ast::ObjectDecl(
704 location,
705 "",
706 new ast::ReferenceType(
707 new ast::TypeInstType( td->name, i->get() ) ),
708 (ast::Init *)nullptr,
709 ast::Storage::Classes(),
710 ast::Linkage::Cforall,
711 (ast::Expr *)nullptr
712 ),
713 }, // params
714 {}, // returns
715 (ast::CompoundStmt *)nullptr,
716 ast::Storage::Classes(),
717 ast::Linkage::Cforall
718 ) );
719
720 // add copy ctor: void ?{}(T *, T)
721 newAssertions.push_back( new ast::FunctionDecl(
722 location,
723 "?{}",
724 {}, // forall
725 {}, // assertions
726 {
727 new ast::ObjectDecl(
728 location,
729 "",
730 new ast::ReferenceType(
731 new ast::TypeInstType( td->name, *i ) ),
732 (ast::Init *)nullptr,
733 ast::Storage::Classes(),
734 ast::Linkage::Cforall,
735 (ast::Expr *)nullptr
736 ),
737 new ast::ObjectDecl(
738 location,
739 "",
740 new ast::TypeInstType( td->name, *i ),
741 (ast::Init *)nullptr,
742 ast::Storage::Classes(),
743 ast::Linkage::Cforall,
744 (ast::Expr *)nullptr
745 ),
746 }, // params
747 {}, // returns
748 (ast::CompoundStmt *)nullptr,
749 ast::Storage::Classes(),
750 ast::Linkage::Cforall
751 ) );
752
753 // add dtor: void ^?{}(T *)
754 newAssertions.push_back( new ast::FunctionDecl(
755 location,
756 "^?{}",
757 {}, // forall
758 {}, // assertions
759 {
760 new ast::ObjectDecl(
761 location,
762 "",
763 new ast::ReferenceType(
764 new ast::TypeInstType( i->get() )
765 ),
766 (ast::Init *)nullptr,
767 ast::Storage::Classes(),
768 ast::Linkage::Cforall,
769 (ast::Expr *)nullptr
770 ),
771 }, // params
772 {}, // returns
773 (ast::CompoundStmt *)nullptr,
774 ast::Storage::Classes(),
775 ast::Linkage::Cforall
776 ) );
777
778 spliceBegin( mutTypeDecl->assertions, newAssertions );
779 } // for
780} // buildForall
781
782
783ast::Type * typebuild( const TypeData * td ) {
784 assert( td );
785 switch ( td->kind ) {
786 case TypeData::Unknown:
787 // fill in implicit int
788 return new ast::BasicType(
789 ast::BasicType::SignedInt,
790 buildQualifiers( td )
791 );
792 case TypeData::Basic:
793 return buildBasicType( td );
794 case TypeData::Pointer:
795 return buildPointer( td );
796 case TypeData::Array:
797 return buildArray( td );
798 case TypeData::Reference:
799 return buildReference( td );
800 case TypeData::Function:
801 return buildFunctionType( td );
802 case TypeData::AggregateInst:
803 return buildAggInst( td );
804 case TypeData::EnumConstant:
805 return new ast::EnumInstType( "", buildQualifiers( td ) );
806 case TypeData::SymbolicInst:
807 return buildSymbolicInst( td );
808 case TypeData::Tuple:
809 return buildTuple( td );
810 case TypeData::Typeof:
811 case TypeData::Basetypeof:
812 return buildTypeof( td );
813 case TypeData::Vtable:
814 return buildVtable( td );
815 case TypeData::Builtin:
816 switch ( td->builtintype ) {
817 case DeclarationNode::Zero:
818 return new ast::ZeroType();
819 case DeclarationNode::One:
820 return new ast::OneType();
821 default:
822 return new ast::VarArgsType( buildQualifiers( td ) );
823 } // switch
824 case TypeData::GlobalScope:
825 return new ast::GlobalScopeType();
826 case TypeData::Qualified:
827 return new ast::QualifiedType(
828 typebuild( td->qualified.parent ),
829 typebuild( td->qualified.child ),
830 buildQualifiers( td )
831 );
832 case TypeData::Symbolic:
833 case TypeData::Enum:
834 case TypeData::Aggregate:
835 assert( false );
836 } // switch
837
838 return nullptr;
839} // typebuild
840
841
842TypeData * typeextractAggregate( const TypeData * td, bool toplevel ) {
843 TypeData * ret = nullptr;
844
845 switch ( td->kind ) {
846 case TypeData::Aggregate:
847 if ( ! toplevel && td->aggregate.body ) {
848 ret = td->clone();
849 } // if
850 break;
851 case TypeData::Enum:
852 if ( ! toplevel && td->enumeration.body ) {
853 ret = td->clone();
854 } // if
855 break;
856 case TypeData::AggregateInst:
857 if ( td->aggInst.aggregate ) {
858 ret = typeextractAggregate( td->aggInst.aggregate, false );
859 } // if
860 break;
861 default:
862 if ( td->base ) {
863 ret = typeextractAggregate( td->base, false );
864 } // if
865 } // switch
866 return ret;
867} // typeextractAggregate
868
869
870ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
871 return td->qualifiers;
872} // buildQualifiers
873
874
875static string genTSError( string msg, DeclarationNode::BasicType basictype ) {
876 SemanticError( yylloc, "invalid type specifier \"%s\" for type \"%s\".", msg.c_str(), DeclarationNode::basicTypeNames[basictype] );
877} // genTSError
878
879ast::Type * buildBasicType( const TypeData * td ) {
880 ast::BasicType::Kind ret;
881
882 switch ( td->basictype ) {
883 case DeclarationNode::Void:
884 if ( td->signedness != DeclarationNode::NoSignedness ) {
885 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
886 } // if
887 if ( td->length != DeclarationNode::NoLength ) {
888 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
889 } // if
890 return new ast::VoidType( buildQualifiers( td ) );
891 break;
892
893 case DeclarationNode::Bool:
894 if ( td->signedness != DeclarationNode::NoSignedness ) {
895 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
896 } // if
897 if ( td->length != DeclarationNode::NoLength ) {
898 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
899 } // if
900
901 ret = ast::BasicType::Bool;
902 break;
903
904 case DeclarationNode::Char:
905 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
906 // character types. The implementation shall define char to have the same range, representation, and behavior as
907 // either signed char or unsigned char.
908 static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };
909
910 if ( td->length != DeclarationNode::NoLength ) {
911 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
912 } // if
913
914 ret = chartype[ td->signedness ];
915 break;
916
917 case DeclarationNode::Int:
918 static ast::BasicType::Kind inttype[2][4] = {
919 { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },
920 { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },
921 };
922
923 Integral: ;
924 if ( td->signedness == DeclarationNode::NoSignedness ) {
925 const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
926 } // if
927 ret = inttype[ td->signedness ][ td->length ];
928 break;
929
930 case DeclarationNode::Int128:
931 ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
932 if ( td->length != DeclarationNode::NoLength ) {
933 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
934 } // if
935 break;
936
937 case DeclarationNode::Float:
938 case DeclarationNode::Double:
939 case DeclarationNode::LongDouble: // not set until below
940 case DeclarationNode::uuFloat80:
941 case DeclarationNode::uuFloat128:
942 case DeclarationNode::uFloat16:
943 case DeclarationNode::uFloat32:
944 case DeclarationNode::uFloat32x:
945 case DeclarationNode::uFloat64:
946 case DeclarationNode::uFloat64x:
947 case DeclarationNode::uFloat128:
948 case DeclarationNode::uFloat128x:
949 static ast::BasicType::Kind floattype[2][12] = {
950 { 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, },
951 { 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, },
952 };
953
954 FloatingPoint: ;
955 if ( td->signedness != DeclarationNode::NoSignedness ) {
956 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
957 } // if
958 if ( td->length == DeclarationNode::Short || td->length == DeclarationNode::LongLong ) {
959 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
960 } // if
961 if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) {
962 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
963 } // if
964 if ( td->complextype == DeclarationNode::Imaginary ) {
965 genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
966 } // if
967 if ( (td->basictype == DeclarationNode::uuFloat80 || td->basictype == DeclarationNode::uuFloat128) && td->complextype == DeclarationNode::Complex ) { // gcc unsupported
968 genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
969 } // if
970 if ( td->length == DeclarationNode::Long ) {
971 const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
972 } // if
973
974 ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
975 //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, DeclarationNode::Float, ret );
976 break;
977
978 case DeclarationNode::NoBasicType:
979 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
980 if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
981 const_cast<TypeData *>(td)->basictype = DeclarationNode::Double;
982 goto FloatingPoint;
983 } // if
984
985 const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
986 goto Integral;
987 default:
988 assertf( false, "unknown basic type" );
989 return nullptr;
990 } // switch
991
992 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
993 return bt;
994} // buildBasicType
995
996
997ast::PointerType * buildPointer( const TypeData * td ) {
998 ast::PointerType * pt;
999 if ( td->base ) {
1000 pt = new ast::PointerType(
1001 typebuild( td->base ),
1002 buildQualifiers( td )
1003 );
1004 } else {
1005 pt = new ast::PointerType(
1006 new ast::BasicType( ast::BasicType::SignedInt ),
1007 buildQualifiers( td )
1008 );
1009 } // if
1010 return pt;
1011} // buildPointer
1012
1013
1014ast::ArrayType * buildArray( const TypeData * td ) {
1015 ast::ArrayType * at;
1016 if ( td->base ) {
1017 at = new ast::ArrayType(
1018 typebuild( td->base ),
1019 maybeBuild( td->array.dimension ),
1020 td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1021 td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1022 buildQualifiers( td )
1023 );
1024 } else {
1025 at = new ast::ArrayType(
1026 new ast::BasicType( ast::BasicType::SignedInt ),
1027 maybeBuild( td->array.dimension ),
1028 td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
1029 td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
1030 buildQualifiers( td )
1031 );
1032 } // if
1033 return at;
1034} // buildArray
1035
1036
1037ast::ReferenceType * buildReference( const TypeData * td ) {
1038 ast::ReferenceType * rt;
1039 if ( td->base ) {
1040 rt = new ast::ReferenceType(
1041 typebuild( td->base ),
1042 buildQualifiers( td )
1043 );
1044 } else {
1045 rt = new ast::ReferenceType(
1046 new ast::BasicType( ast::BasicType::SignedInt ),
1047 buildQualifiers( td )
1048 );
1049 } // if
1050 return rt;
1051} // buildReference
1052
1053
1054ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
1055 assert( td->kind == TypeData::Aggregate );
1056 ast::AggregateDecl * at;
1057 switch ( td->aggregate.kind ) {
1058 case ast::AggregateDecl::Struct:
1059 case ast::AggregateDecl::Coroutine:
1060 case ast::AggregateDecl::Exception:
1061 case ast::AggregateDecl::Generator:
1062 case ast::AggregateDecl::Monitor:
1063 case ast::AggregateDecl::Thread:
1064 at = new ast::StructDecl( td->location,
1065 *td->aggregate.name,
1066 td->aggregate.kind,
1067 std::move( attributes ),
1068 linkage
1069 );
1070 buildForall( td->aggregate.params, at->params );
1071 break;
1072 case ast::AggregateDecl::Union:
1073 at = new ast::UnionDecl( td->location,
1074 *td->aggregate.name,
1075 std::move( attributes ),
1076 linkage
1077 );
1078 buildForall( td->aggregate.params, at->params );
1079 break;
1080 case ast::AggregateDecl::Trait:
1081 at = new ast::TraitDecl( td->location,
1082 *td->aggregate.name,
1083 std::move( attributes ),
1084 linkage
1085 );
1086 buildList( td->aggregate.params, at->params );
1087 break;
1088 default:
1089 assert( false );
1090 } // switch
1091
1092 buildList( td->aggregate.fields, at->members );
1093 at->set_body( td->aggregate.body );
1094
1095 return at;
1096} // buildAggregate
1097
1098
1099ast::BaseInstType * buildComAggInst(
1100 const TypeData * td,
1101 std::vector<ast::ptr<ast::Attribute>> && attributes,
1102 ast::Linkage::Spec linkage ) {
1103 switch ( td->kind ) {
1104 case TypeData::Enum:
1105 if ( td->enumeration.body ) {
1106 ast::EnumDecl * typedecl =
1107 buildEnum( td, std::move( attributes ), linkage );
1108 return new ast::EnumInstType(
1109 typedecl,
1110 buildQualifiers( td )
1111 );
1112 } else {
1113 return new ast::EnumInstType(
1114 *td->enumeration.name,
1115 buildQualifiers( td )
1116 );
1117 } // if
1118 break;
1119 case TypeData::Aggregate:
1120 if ( td->aggregate.body ) {
1121 ast::AggregateDecl * typedecl =
1122 buildAggregate( td, std::move( attributes ), linkage );
1123 switch ( td->aggregate.kind ) {
1124 case ast::AggregateDecl::Struct:
1125 case ast::AggregateDecl::Coroutine:
1126 case ast::AggregateDecl::Monitor:
1127 case ast::AggregateDecl::Thread:
1128 return new ast::StructInstType(
1129 strict_dynamic_cast<ast::StructDecl *>( typedecl ),
1130 buildQualifiers( td )
1131 );
1132 case ast::AggregateDecl::Union:
1133 return new ast::UnionInstType(
1134 strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
1135 buildQualifiers( td )
1136 );
1137 case ast::AggregateDecl::Trait:
1138 assert( false );
1139 break;
1140 default:
1141 assert( false );
1142 } // switch
1143 } else {
1144 switch ( td->aggregate.kind ) {
1145 case ast::AggregateDecl::Struct:
1146 case ast::AggregateDecl::Coroutine:
1147 case ast::AggregateDecl::Monitor:
1148 case ast::AggregateDecl::Thread:
1149 return new ast::StructInstType(
1150 *td->aggregate.name,
1151 buildQualifiers( td )
1152 );
1153 case ast::AggregateDecl::Union:
1154 return new ast::UnionInstType(
1155 *td->aggregate.name,
1156 buildQualifiers( td )
1157 );
1158 case ast::AggregateDecl::Trait:
1159 return new ast::TraitInstType(
1160 *td->aggregate.name,
1161 buildQualifiers( td )
1162 );
1163 default:
1164 assert( false );
1165 } // switch
1166 break;
1167 } // if
1168 break;
1169 default:
1170 assert( false );
1171 } // switch
1172 assert( false );
1173} // buildAggInst
1174
1175
1176ast::BaseInstType * buildAggInst( const TypeData * td ) {
1177 assert( td->kind == TypeData::AggregateInst );
1178
1179 ast::BaseInstType * ret = nullptr;
1180 TypeData * type = td->aggInst.aggregate;
1181 switch ( type->kind ) {
1182 case TypeData::Enum:
1183 return new ast::EnumInstType(
1184 *type->enumeration.name,
1185 buildQualifiers( type )
1186 );
1187 case TypeData::Aggregate:
1188 switch ( type->aggregate.kind ) {
1189 case ast::AggregateDecl::Struct:
1190 case ast::AggregateDecl::Coroutine:
1191 case ast::AggregateDecl::Monitor:
1192 case ast::AggregateDecl::Thread:
1193 ret = new ast::StructInstType(
1194 *type->aggregate.name,
1195 buildQualifiers( type )
1196 );
1197 break;
1198 case ast::AggregateDecl::Union:
1199 ret = new ast::UnionInstType(
1200 *type->aggregate.name,
1201 buildQualifiers( type )
1202 );
1203 break;
1204 case ast::AggregateDecl::Trait:
1205 ret = new ast::TraitInstType(
1206 *type->aggregate.name,
1207 buildQualifiers( type )
1208 );
1209 break;
1210 default:
1211 assert( false );
1212 } // switch
1213 break;
1214 default:
1215 assert( false );
1216 } // switch
1217
1218 ret->hoistType = td->aggInst.hoistType;
1219 buildList( td->aggInst.params, ret->params );
1220 return ret;
1221} // buildAggInst
1222
1223
1224ast::NamedTypeDecl * buildSymbolic(
1225 const TypeData * td,
1226 std::vector<ast::ptr<ast::Attribute>> attributes,
1227 const std::string & name,
1228 ast::Storage::Classes scs,
1229 ast::Linkage::Spec linkage ) {
1230 assert( td->kind == TypeData::Symbolic );
1231 ast::NamedTypeDecl * ret;
1232 assert( td->base );
1233 if ( td->symbolic.isTypedef ) {
1234 ret = new ast::TypedefDecl(
1235 td->location,
1236 name,
1237 scs,
1238 typebuild( td->base ),
1239 linkage
1240 );
1241 } else {
1242 ret = new ast::TypeDecl(
1243 td->location,
1244 name,
1245 scs,
1246 typebuild( td->base ),
1247 ast::TypeDecl::Dtype,
1248 true
1249 );
1250 } // if
1251 buildList( td->symbolic.assertions, ret->assertions );
1252 splice( ret->base.get_and_mutate()->attributes, attributes );
1253 return ret;
1254} // buildSymbolic
1255
1256
1257ast::EnumDecl * buildEnum(
1258 const TypeData * td,
1259 std::vector<ast::ptr<ast::Attribute>> && attributes,
1260 ast::Linkage::Spec linkage ) {
1261 assert( td->kind == TypeData::Enum );
1262 ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
1263 ast::EnumDecl * ret = new ast::EnumDecl(
1264 td->location,
1265 *td->enumeration.name,
1266 td->enumeration.typed,
1267 std::move( attributes ),
1268 linkage,
1269 baseType
1270 );
1271 buildList( td->enumeration.constants, ret->members );
1272 auto members = ret->members.begin();
1273 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
1274 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
1275 if ( cur->enumInLine ) {
1276 // Do Nothing
1277 } else if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
1278 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
1279 } else if ( cur->has_enumeratorValue() ) {
1280 ast::Decl * member = members->get_and_mutate();
1281 ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
1282 object->init = new ast::SingleInit(
1283 td->location,
1284 maybeMoveBuild( cur->consume_enumeratorValue() ),
1285 ast::NoConstruct
1286 );
1287 } else if ( !cur->initializer ) {
1288 if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
1289 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
1290 }
1291 }
1292 // else cur is a List Initializer and has been set as init in buildList()
1293 // if
1294 } // for
1295 ret->body = td->enumeration.body;
1296 return ret;
1297} // buildEnum
1298
1299
1300ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
1301 assert( td->kind == TypeData::SymbolicInst );
1302 ast::TypeInstType * ret = new ast::TypeInstType(
1303 *td->symbolic.name,
1304 ast::TypeDecl::Dtype,
1305 buildQualifiers( td )
1306 );
1307 buildList( td->symbolic.actuals, ret->params );
1308 return ret;
1309} // buildSymbolicInst
1310
1311
1312ast::TupleType * buildTuple( const TypeData * td ) {
1313 assert( td->kind == TypeData::Tuple );
1314 std::vector<ast::ptr<ast::Type>> types;
1315 buildTypeList( td->tuple, types );
1316 ast::TupleType * ret = new ast::TupleType(
1317 std::move( types ),
1318 buildQualifiers( td )
1319 );
1320 return ret;
1321} // buildTuple
1322
1323
1324ast::TypeofType * buildTypeof( const TypeData * td ) {
1325 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
1326 assert( td->typeexpr );
1327 return new ast::TypeofType(
1328 td->typeexpr->build(),
1329 td->kind == TypeData::Typeof
1330 ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
1331 buildQualifiers( td )
1332 );
1333} // buildTypeof
1334
1335
1336ast::VTableType * buildVtable( const TypeData * td ) {
1337 assert( td->base );
1338 return new ast::VTableType(
1339 typebuild( td->base ),
1340 buildQualifiers( td )
1341 );
1342} // buildVtable
1343
1344
1345ast::FunctionDecl * buildFunctionDecl(
1346 const TypeData * td,
1347 const string &name,
1348 ast::Storage::Classes scs,
1349 ast::Function::Specs funcSpec,
1350 ast::Linkage::Spec linkage,
1351 ast::Expr * asmName,
1352 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1353 assert( td->kind == TypeData::Function );
1354 // For some reason FunctionDecl takes a bool instead of an ArgumentFlag.
1355 bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
1356 ast::CV::Qualifiers cvq = buildQualifiers( td );
1357 std::vector<ast::ptr<ast::TypeDecl>> forall;
1358 std::vector<ast::ptr<ast::DeclWithType>> assertions;
1359 std::vector<ast::ptr<ast::DeclWithType>> params;
1360 std::vector<ast::ptr<ast::DeclWithType>> returns;
1361 buildList( td->function.params, params );
1362 buildForall( td->forall, forall );
1363 // Functions do not store their assertions there anymore.
1364 for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
1365 auto mut = type_param.get_and_mutate();
1366 splice( assertions, mut->assertions );
1367 }
1368 if ( td->base ) {
1369 switch ( td->base->kind ) {
1370 case TypeData::Tuple:
1371 buildList( td->base->tuple, returns );
1372 break;
1373 default:
1374 returns.push_back( dynamic_cast<ast::DeclWithType *>(
1375 buildDecl(
1376 td->base,
1377 "",
1378 ast::Storage::Classes(),
1379 (ast::Expr *)nullptr, // bitfieldWidth
1380 ast::Function::Specs(),
1381 ast::Linkage::Cforall,
1382 (ast::Expr *)nullptr // asmName
1383 )
1384 ) );
1385 } // switch
1386 } else {
1387 returns.push_back( new ast::ObjectDecl(
1388 td->location,
1389 "",
1390 new ast::BasicType( ast::BasicType::SignedInt ),
1391 (ast::Init *)nullptr,
1392 ast::Storage::Classes(),
1393 ast::Linkage::Cforall
1394 ) );
1395 } // if
1396 ast::Stmt * stmt = maybeBuild( td->function.body );
1397 ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
1398 ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
1399 name,
1400 std::move( forall ),
1401 std::move( assertions ),
1402 std::move( params ),
1403 std::move( returns ),
1404 body,
1405 scs,
1406 linkage,
1407 std::move( attributes ),
1408 funcSpec,
1409 (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
1410 );
1411 buildList( td->function.withExprs, decl->withExprs );
1412 decl->asmName = asmName;
1413 // This may be redundant on a declaration.
1414 decl->type.get_and_mutate()->qualifiers = cvq;
1415 return decl;
1416} // buildFunctionDecl
1417
1418
1419ast::Decl * buildDecl(
1420 const TypeData * td,
1421 const string &name,
1422 ast::Storage::Classes scs,
1423 ast::Expr * bitfieldWidth,
1424 ast::Function::Specs funcSpec,
1425 ast::Linkage::Spec linkage,
1426 ast::Expr * asmName,
1427 ast::Init * init,
1428 std::vector<ast::ptr<ast::Attribute>> && attributes ) {
1429 if ( td->kind == TypeData::Function ) {
1430 if ( td->function.idList ) { // KR function ?
1431 buildKRFunction( td->function ); // transform into C11 function
1432 } // if
1433
1434 return buildFunctionDecl(
1435 td, name, scs, funcSpec, linkage,
1436 asmName, std::move( attributes ) );
1437 } else if ( td->kind == TypeData::Aggregate ) {
1438 return buildAggregate( td, std::move( attributes ), linkage );
1439 } else if ( td->kind == TypeData::Enum ) {
1440 return buildEnum( td, std::move( attributes ), linkage );
1441 } else if ( td->kind == TypeData::Symbolic ) {
1442 return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
1443 } else {
1444 auto ret = new ast::ObjectDecl( td->location,
1445 name,
1446 typebuild( td ),
1447 init,
1448 scs,
1449 linkage,
1450 bitfieldWidth,
1451 std::move( attributes )
1452 );
1453 ret->asmName = asmName;
1454 return ret;
1455 } // if
1456 return nullptr;
1457} // buildDecl
1458
1459
1460ast::FunctionType * buildFunctionType( const TypeData * td ) {
1461 assert( td->kind == TypeData::Function );
1462 ast::FunctionType * ft = new ast::FunctionType(
1463 ( !td->function.params || td->function.params->hasEllipsis )
1464 ? ast::VariableArgs : ast::FixedArgs,
1465 buildQualifiers( td )
1466 );
1467 buildTypeList( td->function.params, ft->params );
1468 buildForall( td->forall, ft->forall );
1469 if ( td->base ) {
1470 switch ( td->base->kind ) {
1471 case TypeData::Tuple:
1472 buildTypeList( td->base->tuple, ft->returns );
1473 break;
1474 default:
1475 ft->returns.push_back( typebuild( td->base ) );
1476 break;
1477 } // switch
1478 } else {
1479 ft->returns.push_back(
1480 new ast::BasicType( ast::BasicType::SignedInt ) );
1481 } // if
1482 return ft;
1483} // buildFunctionType
1484
1485
1486// Transform KR routine declarations into C99 routine declarations:
1487//
1488// rtn( a, b, c ) int a, c; double b {} => int rtn( int a, double c, int b ) {}
1489//
1490// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
1491// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
1492// extra names are disallowed.
1493//
1494// Note, there is no KR routine-prototype syntax:
1495//
1496// rtn( a, b, c ) int a, c; double b; // invalid KR prototype
1497// rtn(); // valid KR prototype
1498
1499void buildKRFunction( const TypeData::Function_t & function ) {
1500 assert( ! function.params );
1501 // loop over declaration first as it is easier to spot errors
1502 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = dynamic_cast< DeclarationNode * >( decl->get_next() ) ) {
1503 // scan ALL parameter names for each declaration name to check for duplicates
1504 for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() ) ) {
1505 if ( *decl->name == *param->name ) {
1506 // type set => parameter name already transformed by a declaration names so there is a duplicate
1507 // declaration name attempting a second transformation
1508 if ( param->type ) SemanticError( param->location, "duplicate declaration name \"%s\".", param->name->c_str() );
1509 // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
1510 // parameter name attempting a second transformation
1511 if ( ! decl->type ) SemanticError( param->location, "duplicate parameter name \"%s\".", param->name->c_str() );
1512 param->type = decl->type; // set copy declaration type to parameter type
1513 decl->type = nullptr; // reset declaration type
1514 // Copy and reset attributes from declaration to parameter:
1515 splice( param->attributes, decl->attributes );
1516 } // if
1517 } // for
1518 // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
1519 if ( decl->type ) SemanticError( decl->location, "missing name in parameter list %s", decl->name->c_str() );
1520 } // for
1521
1522 // Parameter names without a declaration default to type int:
1523 //
1524 // rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
1525
1526 for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() ) ) {
1527 if ( ! param->type ) { // generate type int for empty parameter type
1528 param->type = new TypeData( TypeData::Basic );
1529 param->type->basictype = DeclarationNode::Int;
1530 } // if
1531 } // for
1532
1533 function.params = function.idList; // newly modified idList becomes parameters
1534 function.idList = nullptr; // idList now empty
1535 delete function.oldDeclList; // deletes entire list
1536 function.oldDeclList = nullptr; // reset
1537} // buildKRFunction
1538
1539// Local Variables: //
1540// tab-width: 4 //
1541// mode: c++ //
1542// compile-command: "make install" //
1543// End: //
Note: See TracBrowser for help on using the repository browser.