source: src/Parser/TypeData.cc@ fb4dc28

ADT ast-experimental
Last change on this file since fb4dc28 was c468150, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Split up ParseNode.h so that headers match implementation. May have a bit less to include total because of it.

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