Changeset 24d6572 for src/Parser
- Timestamp:
- Jun 12, 2023, 2:45:32 PM (2 years ago)
- Branches:
- ast-experimental, master
- Children:
- 62d62db
- Parents:
- 34b4268 (diff), 251ce80 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/Parser
- Files:
-
- 6 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
r34b4268 r24d6572 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Aug 8 17:07:00 202213 // Update Count : 1 18511 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Apr 20 11:46:00 2023 13 // Update Count : 1393 14 14 // 15 16 #include "DeclarationNode.h" 15 17 16 18 #include <cassert> // for assert, assertf, strict_dynamic_cast … … 21 23 #include <string> // for string, operator+, allocator, char... 22 24 25 #include "AST/Attribute.hpp" // for Attribute 26 #include "AST/Copy.hpp" // for shallowCopy 27 #include "AST/Decl.hpp" // for Decl 28 #include "AST/Expr.hpp" // for Expr 29 #include "AST/Print.hpp" // for print 30 #include "AST/Stmt.hpp" // for AsmStmt, DirectiveStmt 31 #include "AST/StorageClasses.hpp" // for Storage::Class 32 #include "AST/Type.hpp" // for Type 33 #include "Common/CodeLocation.h" // for CodeLocation 34 #include "Common/Iterate.hpp" // for reverseIterate 23 35 #include "Common/SemanticError.h" // for SemanticError 24 36 #include "Common/UniqueName.h" // for UniqueName 25 #include "Common/utility.h" // for maybeClone, maybeBuild, CodeLocation 26 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 27 #include "SynTree/LinkageSpec.h" // for Spec, linkageName, Cforall 28 #include "SynTree/Attribute.h" // for Attribute 29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration 30 #include "SynTree/Expression.h" // for Expression, ConstantExpr 31 #include "SynTree/Statement.h" // for AsmStmt 32 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Type::... 37 #include "Common/utility.h" // for maybeClone 38 #include "Parser/ExpressionNode.h" // for ExpressionNode 39 #include "Parser/InitializerNode.h"// for InitializerNode 40 #include "Parser/StatementNode.h" // for StatementNode 33 41 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 34 42 #include "TypedefTable.h" // for TypedefTable … … 41 49 42 50 // These must harmonize with the corresponding DeclarationNode enumerations. 43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128", 44 "float", "double", "long double", "float80", "float128", 45 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" }; 46 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message 47 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; 48 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" }; 49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" }; 51 const char * DeclarationNode::basicTypeNames[] = { 52 "void", "_Bool", "char", "int", "int128", 53 "float", "double", "long double", "float80", "float128", 54 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" 55 }; 56 const char * DeclarationNode::complexTypeNames[] = { 57 "_Complex", "NoComplexTypeNames", "_Imaginary" 58 }; // Imaginary unsupported => parse, but make invisible and print error message 59 const char * DeclarationNode::signednessNames[] = { 60 "signed", "unsigned", "NoSignednessNames" 61 }; 62 const char * DeclarationNode::lengthNames[] = { 63 "short", "long", "long long", "NoLengthNames" 64 }; 65 const char * DeclarationNode::builtinTypeNames[] = { 66 "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" 67 }; 50 68 51 69 UniqueName DeclarationNode::anonymous( "__anonymous" ); 52 70 53 extern LinkageSpec::Spec linkage; // defined in parser.yy71 extern ast::Linkage::Spec linkage; // defined in parser.yy 54 72 55 73 DeclarationNode::DeclarationNode() : … … 57 75 58 76 // variable.name = nullptr; 59 variable.tyClass = TypeDecl::NUMBER_OF_KINDS;77 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS; 60 78 variable.assertions = nullptr; 61 79 variable.initializer = nullptr; 62 80 63 // attr.name = nullptr;64 attr.expr = nullptr;65 attr.type = nullptr;66 67 81 assert.condition = nullptr; 68 82 assert.message = nullptr; … … 70 84 71 85 DeclarationNode::~DeclarationNode() { 72 // delete attr.name;73 delete attr.expr;74 delete attr.type;75 76 86 // delete variable.name; 77 87 delete variable.assertions; 78 88 delete variable.initializer; 79 89 80 // 90 // delete type; 81 91 delete bitfieldWidth; 82 92 … … 103 113 newnode->hasEllipsis = hasEllipsis; 104 114 newnode->linkage = linkage; 105 newnode->asmName = maybeC lone( asmName );106 cloneAll( attributes, newnode->attributes );115 newnode->asmName = maybeCopy( asmName ); 116 newnode->attributes = attributes; 107 117 newnode->initializer = maybeClone( initializer ); 108 118 newnode->extension = extension; … … 115 125 newnode->variable.initializer = maybeClone( variable.initializer ); 116 126 117 // newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr;118 newnode->attr.expr = maybeClone( attr.expr );119 newnode->attr.type = maybeClone( attr.type );120 121 127 newnode->assert.condition = maybeClone( assert.condition ); 122 newnode->assert.message = maybeC lone( assert.message );128 newnode->assert.message = maybeCopy( assert.message ); 123 129 return newnode; 124 130 } // DeclarationNode::clone … … 130 136 } // if 131 137 132 if ( linkage != LinkageSpec::Cforall ) {133 os << LinkageSpec::name( linkage ) << " ";134 } // if 135 136 storageClasses.print( os );137 funcSpecs.print( os );138 if ( linkage != ast::Linkage::Cforall ) { 139 os << ast::Linkage::name( linkage ) << " "; 140 } // if 141 142 ast::print( os, storageClasses ); 143 ast::print( os, funcSpecs ); 138 144 139 145 if ( type ) { … … 154 160 } // if 155 161 156 for ( Attribute * attr: reverseIterate( attributes ) ) { 157 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str(); 158 } // for 162 if ( ! attributes.empty() ) { 163 os << string( indent + 2, ' ' ) << "with attributes " << endl; 164 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) { 165 os << string( indent + 4, ' ' ) << attr->name.c_str() << endl; 166 } // for 167 } // if 159 168 160 169 os << endl; … … 168 177 } 169 178 170 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {179 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) { 171 180 DeclarationNode * newnode = new DeclarationNode; 172 181 newnode->storageClasses = sc; … … 174 183 } // DeclarationNode::newStorageClass 175 184 176 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {185 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) { 177 186 DeclarationNode * newnode = new DeclarationNode; 178 187 newnode->funcSpecs = fs; … … 180 189 } // DeclarationNode::newFuncSpecifier 181 190 182 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {191 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) { 183 192 DeclarationNode * newnode = new DeclarationNode; 184 193 newnode->type = new TypeData(); … … 240 249 } 241 250 242 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {251 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 243 252 DeclarationNode * newnode = new DeclarationNode; 244 253 newnode->type = new TypeData( TypeData::Aggregate ); 245 254 newnode->type->aggregate.kind = kind; 246 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 255 newnode->type->aggregate.anon = name == nullptr; 256 newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 247 257 newnode->type->aggregate.actuals = actuals; 248 258 newnode->type->aggregate.fields = fields; … … 250 260 newnode->type->aggregate.tagged = false; 251 261 newnode->type->aggregate.parent = nullptr; 252 newnode->type->aggregate.anon = name == nullptr;253 262 return newnode; 254 263 } // DeclarationNode::newAggregate … … 257 266 DeclarationNode * newnode = new DeclarationNode; 258 267 newnode->type = new TypeData( TypeData::Enum ); 259 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 268 newnode->type->enumeration.anon = name == nullptr; 269 newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 260 270 newnode->type->enumeration.constants = constants; 261 271 newnode->type->enumeration.body = body; 262 newnode->type->enumeration.anon = name == nullptr;263 272 newnode->type->enumeration.typed = typed; 264 273 newnode->type->enumeration.hiding = hiding; 265 if ( base && base->type ) {274 if ( base && base->type ) { 266 275 newnode->type->base = base->type; 267 276 } // if … … 269 278 return newnode; 270 279 } // DeclarationNode::newEnum 271 272 273 280 274 281 DeclarationNode * DeclarationNode::newName( const string * name ) { … … 323 330 } // DeclarationNode::newFromTypeGen 324 331 325 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {332 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) { 326 333 DeclarationNode * newnode = newName( name ); 327 334 newnode->type = nullptr; … … 335 342 newnode->type = new TypeData( TypeData::Aggregate ); 336 343 newnode->type->aggregate.name = name; 337 newnode->type->aggregate.kind = AggregateDecl::Trait;344 newnode->type->aggregate.kind = ast::AggregateDecl::Trait; 338 345 newnode->type->aggregate.params = params; 339 346 newnode->type->aggregate.fields = asserts; … … 345 352 newnode->type = new TypeData( TypeData::AggregateInst ); 346 353 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate ); 347 newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;354 newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait; 348 355 newnode->type->aggInst.aggregate->aggregate.name = name; 349 356 newnode->type->aggInst.params = params; … … 380 387 newnode->type->array.dimension = size; 381 388 newnode->type->array.isStatic = isStatic; 382 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType< ConstantExpr *>() ) {389 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) { 383 390 newnode->type->array.isVarLen = false; 384 391 } else { … … 450 457 DeclarationNode * newnode = new DeclarationNode; 451 458 newnode->type = nullptr; 452 std:: list< Expression *> exprs;459 std::vector<ast::ptr<ast::Expr>> exprs; 453 460 buildList( expr, exprs ); 454 newnode->attributes.push_back( new Attribute( *name, exprs ) ); 461 newnode->attributes.push_back( 462 new ast::Attribute( *name, std::move( exprs ) ) ); 455 463 delete name; 456 464 return newnode; … … 469 477 } 470 478 471 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression* message ) {479 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) { 472 480 DeclarationNode * newnode = new DeclarationNode; 473 481 newnode->assert.condition = condition; … … 476 484 } 477 485 478 479 void appendError( string & dst, const string & src ) { 486 static void appendError( string & dst, const string & src ) { 480 487 if ( src.empty() ) return; 481 488 if ( dst.empty() ) { dst = src; return; } … … 484 491 485 492 void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) { 486 const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 487 488 if ( (qsrc & qdst).any() ) { // duplicates ? 489 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates 490 if ( qsrc[i] && qdst[i] ) { 491 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] ); 492 } // if 493 } // for 493 const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 494 const ast::CV::Qualifiers duplicates = qsrc & qdst; 495 496 if ( duplicates.any() ) { 497 std::stringstream str; 498 str << "duplicate "; 499 ast::print( str, duplicates ); 500 str << "qualifier(s)"; 501 appendError( error, str.str() ); 494 502 } // for 495 503 } // DeclarationNode::checkQualifiers 496 504 497 505 void DeclarationNode::checkSpecifiers( DeclarationNode * src ) { 498 if ( (funcSpecs & src->funcSpecs).any() ) { // duplicates ? 499 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates 500 if ( funcSpecs[i] && src->funcSpecs[i] ) { 501 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] ); 502 } // if 503 } // for 504 } // if 505 506 if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ? 507 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ? 508 for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates 509 if ( storageClasses[i] && src->storageClasses[i] ) { 510 appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] ); 511 } // if 512 } // for 513 // src is the new item being added and has a single bit 514 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ? 515 appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] + 516 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] ); 517 src->storageClasses.reset(); // FIX to preserve invariant of one basic storage specifier 518 } // if 506 ast::Function::Specs fsDups = funcSpecs & src->funcSpecs; 507 if ( fsDups.any() ) { 508 std::stringstream str; 509 str << "duplicate "; 510 ast::print( str, fsDups ); 511 str << "function specifier(s)"; 512 appendError( error, str.str() ); 513 } // if 514 515 // Skip if everything is unset. 516 if ( storageClasses.any() && src->storageClasses.any() ) { 517 ast::Storage::Classes dups = storageClasses & src->storageClasses; 518 // Check for duplicates. 519 if ( dups.any() ) { 520 std::stringstream str; 521 str << "duplicate "; 522 ast::print( str, dups ); 523 str << "storage class(es)"; 524 appendError( error, str.str() ); 525 // Check for conflicts. 526 } else if ( !src->storageClasses.is_threadlocal_any() ) { 527 std::stringstream str; 528 str << "conflicting "; 529 ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) ); 530 str << "& "; 531 ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) ); 532 str << "storage classes"; 533 appendError( error, str.str() ); 534 // FIX to preserve invariant of one basic storage specifier 535 src->storageClasses.reset(); 536 } 519 537 } // if 520 538 … … 526 544 storageClasses |= q->storageClasses; 527 545 528 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 529 attributes.push_front( attr->clone() ); 530 } // for 546 std::vector<ast::ptr<ast::Attribute>> tmp; 547 tmp.reserve( q->attributes.size() ); 548 for ( auto const & attr : q->attributes ) { 549 tmp.emplace_back( ast::shallowCopy( attr.get() ) ); 550 } 551 spliceBegin( attributes, tmp ); 552 531 553 return this; 532 554 } // DeclarationNode::copySpecifiers … … 576 598 577 599 checkQualifiers( type, q->type ); 578 if ( (builtin == Zero || builtin == One) && q->type->qualifiers. val != 0&& error.length() == 0 ) {579 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )],builtinTypeNames[builtin] );600 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) { 601 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] ); 580 602 } // if 581 603 addQualifiersToType( q->type, type ); … … 598 620 } else { 599 621 switch ( dst->kind ) { 600 622 case TypeData::Unknown: 601 623 src->qualifiers |= dst->qualifiers; 602 624 dst = src; 603 625 src = nullptr; 604 626 break; 605 627 case TypeData::Basic: 606 628 dst->qualifiers |= src->qualifiers; 607 629 if ( src->kind != TypeData::Unknown ) { … … 631 653 } // if 632 654 break; 633 655 default: 634 656 switch ( src->kind ) { 635 636 657 case TypeData::Aggregate: 658 case TypeData::Enum: 637 659 dst->base = new TypeData( TypeData::AggregateInst ); 638 660 dst->base->aggInst.aggregate = src; … … 643 665 src = nullptr; 644 666 break; 645 667 default: 646 668 if ( dst->forall ) { 647 669 dst->forall->appendList( src->forall ); … … 714 736 715 737 DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) { 716 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {717 718 719 720 721 722 738 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 739 if ( variable.assertions ) { 740 variable.assertions->appendList( assertions ); 741 } else { 742 variable.assertions = assertions; 743 } // if 744 return this; 723 745 } // if 724 746 725 747 assert( type ); 726 748 switch ( type->kind ) { 727 749 case TypeData::Symbolic: 728 750 if ( type->symbolic.assertions ) { 729 751 type->symbolic.assertions->appendList( assertions ); … … 732 754 } // if 733 755 break; 734 756 default: 735 757 assert( false ); 736 758 } // switch … … 796 818 DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) { 797 819 if ( a ) { 798 for ( Attribute *attr: reverseIterate( a->attributes ) ) { 799 attributes.push_front( attr ); 800 } // for 820 spliceBegin( attributes, a->attributes ); 801 821 a->attributes.clear(); 802 822 } // if … … 831 851 if ( type ) { 832 852 switch ( type->kind ) { 833 834 853 case TypeData::Aggregate: 854 case TypeData::Enum: 835 855 p->type->base = new TypeData( TypeData::AggregateInst ); 836 856 p->type->base->aggInst.aggregate = type; … … 841 861 break; 842 862 843 863 default: 844 864 p->type->base = type; 845 865 } // switch … … 863 883 864 884 DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) { 865 885 if ( ! a ) return this; 866 886 assert( a->type->kind == TypeData::Array ); 867 887 TypeData * lastArray = findLast( a->type ); 868 888 if ( type ) { 869 889 switch ( type->kind ) { 870 871 890 case TypeData::Aggregate: 891 case TypeData::Enum: 872 892 lastArray->base = new TypeData( TypeData::AggregateInst ); 873 893 lastArray->base->aggInst.aggregate = type; … … 877 897 lastArray->base->qualifiers |= type->qualifiers; 878 898 break; 879 899 default: 880 900 lastArray->base = type; 881 901 } // switch … … 919 939 920 940 DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) { 921 assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );941 assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." ); 922 942 variable.initializer = init; 923 943 return this; … … 983 1003 } 984 1004 985 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 1005 // If a typedef wraps an anonymous declaration, name the inner declaration 1006 // so it has a consistent name across translation units. 1007 static void nameTypedefedDecl( 1008 DeclarationNode * innerDecl, 1009 const DeclarationNode * outerDecl ) { 1010 TypeData * outer = outerDecl->type; 1011 assert( outer ); 1012 // First make sure this is a typedef: 1013 if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) { 1014 return; 1015 } 1016 TypeData * inner = innerDecl->type; 1017 assert( inner ); 1018 // Always clear any CVs associated with the aggregate: 1019 inner->qualifiers.reset(); 1020 // Handle anonymous aggregates: typedef struct { int i; } foo 1021 if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) { 1022 delete inner->aggregate.name; 1023 inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name ); 1024 inner->aggregate.anon = false; 1025 assert( outer->base ); 1026 delete outer->base->aggInst.aggregate->aggregate.name; 1027 outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name ); 1028 outer->base->aggInst.aggregate->aggregate.anon = false; 1029 outer->base->aggInst.aggregate->qualifiers.reset(); 1030 // Handle anonymous enumeration: typedef enum { A, B, C } foo 1031 } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) { 1032 delete inner->enumeration.name; 1033 inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name ); 1034 inner->enumeration.anon = false; 1035 assert( outer->base ); 1036 delete outer->base->aggInst.aggregate->enumeration.name; 1037 outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name ); 1038 outer->base->aggInst.aggregate->enumeration.anon = false; 1039 // No qualifiers.reset() here. 1040 } 1041 } 1042 1043 // This code handles a special issue with the attribute transparent_union. 1044 // 1045 // typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union )) 1046 // 1047 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are 1048 // aligned. However, the attribute transparent_union must be moved from the typedef_name to 1049 // alias union U. Currently, this is the only know attribute that must be moved from typedef to 1050 // alias. 1051 static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) { 1052 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) { 1053 // Is the typedef alias a union aggregate? 1054 if ( nullptr == unionDecl ) return; 1055 1056 // If typedef is an alias for a union, then its alias type was hoisted above and remembered. 1057 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) { 1058 auto instType = ast::mutate( unionInstType ); 1059 // Remove all transparent_union attributes from typedef and move to alias union. 1060 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { 1061 assert( *attr ); 1062 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) { 1063 unionDecl->attributes.emplace_back( attr->release() ); 1064 attr = instType->attributes.erase( attr ); 1065 } else { 1066 attr++; 1067 } 1068 } 1069 typedefDecl->base = instType; 1070 } 1071 } 1072 } 1073 1074 // Get the non-anonymous name of the instance type of the declaration, 1075 // if one exists. 1076 static const std::string * getInstTypeOfName( ast::Decl * decl ) { 1077 if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1078 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) { 1079 if ( aggr->name.find("anonymous") == std::string::npos ) { 1080 return &aggr->name; 1081 } 1082 } 1083 } 1084 return nullptr; 1085 } 1086 1087 void buildList( DeclarationNode * firstNode, 1088 std::vector<ast::ptr<ast::Decl>> & outputList ) { 986 1089 SemanticErrorException errors; 987 std::back_insert_iterator< std::list< Declaration * >> out( outputList );988 989 for ( const DeclarationNode * cur = firstNode ; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next()) ) {1090 std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList ); 1091 1092 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) { 990 1093 try { 991 bool extracted = false; 992 bool anon = false; 1094 bool extracted_named = false; 1095 ast::UnionDecl * unionDecl = nullptr; 1096 993 1097 if ( DeclarationNode * extr = cur->extractAggregate() ) { 994 // handle the case where a structure declaration is contained within an object or type declaration 995 Declaration * decl = extr->build(); 996 if ( decl ) { 997 // hoist the structure declaration 998 decl->location = cur->location; 999 * out++ = decl; 1098 assert( cur->type ); 1099 nameTypedefedDecl( extr, cur ); 1100 1101 if ( ast::Decl * decl = extr->build() ) { 1102 // Remember the declaration if it is a union aggregate ? 1103 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 1104 1105 *out++ = decl; 1000 1106 1001 1107 // need to remember the cases where a declaration contains an anonymous aggregate definition 1002 extracted = true;1003 1108 assert( extr->type ); 1004 1109 if ( extr->type->kind == TypeData::Aggregate ) { 1005 anon = extr->type->aggregate.anon; 1110 // typedef struct { int A } B is the only case? 1111 extracted_named = !extr->type->aggregate.anon; 1006 1112 } else if ( extr->type->kind == TypeData::Enum ) { 1007 // xxx - is it useful to have an implicit anonymous enum member? 1008 anon = extr->type->enumeration.anon; 1113 // typedef enum { A } B is the only case? 1114 extracted_named = !extr->type->enumeration.anon; 1115 } else { 1116 extracted_named = true; 1009 1117 } 1010 1118 } // if … … 1012 1120 } // if 1013 1121 1014 Declaration * decl = cur->build(); 1015 if ( decl ) { 1016 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.: 1017 // struct S { 1018 // struct T { int x; }; // no anonymous member 1019 // struct { int y; }; // anonymous member 1020 // struct T; // anonymous member 1021 // }; 1022 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 1023 if ( decl->name == "" ) { 1024 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) { 1025 if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) { 1026 if ( aggr->name.find("anonymous") == std::string::npos ) { 1027 if ( ! cur->get_inLine() ) { 1028 // temporary: warn about anonymous member declarations of named types, since 1029 // this conflicts with the syntax for the forward declaration of an anonymous type 1030 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() ); 1031 } // if 1032 } // if 1033 } // if 1034 } // if 1035 } // if 1036 decl->location = cur->location; 1037 *out++ = decl; 1122 if ( ast::Decl * decl = cur->build() ) { 1123 moveUnionAttribute( decl, unionDecl ); 1124 1125 if ( "" == decl->name && !cur->get_inLine() ) { 1126 // Don't include anonymous declaration for named aggregates, 1127 // but do include them for anonymous aggregates, e.g.: 1128 // struct S { 1129 // struct T { int x; }; // no anonymous member 1130 // struct { int y; }; // anonymous member 1131 // struct T; // anonymous member 1132 // }; 1133 if ( extracted_named ) { 1134 continue; 1135 } 1136 1137 if ( auto name = getInstTypeOfName( decl ) ) { 1138 // Temporary: warn about anonymous member declarations of named types, since 1139 // this conflicts with the syntax for the forward declaration of an anonymous type. 1140 SemanticWarning( cur->location, Warning::AggrForwardDecl, name->c_str() ); 1141 } 1038 1142 } // if 1143 *out++ = decl; 1039 1144 } // if 1040 } catch ( SemanticErrorException & e ) {1145 } catch ( SemanticErrorException & e ) { 1041 1146 errors.append( e ); 1042 1147 } // try … … 1049 1154 1050 1155 // currently only builds assertions, function parameters, and return values 1051 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType *> & outputList ) {1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) { 1052 1157 SemanticErrorException errors; 1053 std::back_insert_iterator< std::list< DeclarationWithType * >> out( outputList );1054 1055 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next()) ) {1158 std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList ); 1159 1160 for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) { 1056 1161 try { 1057 Declaration* decl = cur->build();1058 assert ( decl);1059 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {1162 ast::Decl * decl = cur->build(); 1163 assertf( decl, "buildList: build for ast::DeclWithType." ); 1164 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1060 1165 dwt->location = cur->location; 1061 1166 *out++ = dwt; 1062 } else if ( StructDecl * agg = dynamic_cast< StructDecl *>( decl ) ) {1167 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) { 1063 1168 // e.g., int foo(struct S) {} 1064 StructInstType * inst = new StructInstType( Type::Qualifiers(),agg->name );1065 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr);1066 obj->l ocation = cur->location;1169 auto inst = new ast::StructInstType( agg->name ); 1170 auto obj = new ast::ObjectDecl( cur->location, "", inst ); 1171 obj->linkage = linkage; 1067 1172 *out++ = obj; 1068 1173 delete agg; 1069 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl *>( decl ) ) {1174 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) { 1070 1175 // e.g., int foo(union U) {} 1071 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name ); 1072 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1073 obj->location = cur->location; 1176 auto inst = new ast::UnionInstType( agg->name ); 1177 auto obj = new ast::ObjectDecl( cur->location, 1178 "", inst, nullptr, ast::Storage::Classes(), 1179 linkage ); 1074 1180 *out++ = obj; 1075 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl *>( decl ) ) {1181 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) { 1076 1182 // e.g., int foo(enum E) {} 1077 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name ); 1078 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1079 obj->location = cur->location; 1183 auto inst = new ast::EnumInstType( agg->name ); 1184 auto obj = new ast::ObjectDecl( cur->location, 1185 "", 1186 inst, 1187 nullptr, 1188 ast::Storage::Classes(), 1189 linkage 1190 ); 1080 1191 *out++ = obj; 1192 } else { 1193 assertf( false, "buildList: Could not convert to ast::DeclWithType." ); 1081 1194 } // if 1082 } catch ( SemanticErrorException & e ) {1195 } catch ( SemanticErrorException & e ) { 1083 1196 errors.append( e ); 1084 1197 } // try … … 1090 1203 } // buildList 1091 1204 1092 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1205 void buildTypeList( const DeclarationNode * firstNode, 1206 std::vector<ast::ptr<ast::Type>> & outputList ) { 1093 1207 SemanticErrorException errors; 1094 std::back_insert_iterator< std::list< Type * > > out( outputList ); 1095 const DeclarationNode * cur = firstNode; 1096 1097 while ( cur ) { 1208 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList ); 1209 1210 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) { 1098 1211 try { 1099 1212 * out++ = cur->buildType(); 1100 } catch ( SemanticErrorException & e ) {1213 } catch ( SemanticErrorException & e ) { 1101 1214 errors.append( e ); 1102 1215 } // try 1103 cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); 1104 } // while 1216 } // for 1105 1217 1106 1218 if ( ! errors.isEmpty() ) { … … 1109 1221 } // buildTypeList 1110 1222 1111 Declaration* DeclarationNode::build() const {1223 ast::Decl * DeclarationNode::build() const { 1112 1224 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1113 1225 1114 1226 if ( asmStmt ) { 1115 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) ); 1227 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() ); 1228 return new ast::AsmDecl( stmt->location, stmt ); 1116 1229 } // if 1117 1230 if ( directiveStmt ) { 1118 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) ); 1119 } // if 1120 1121 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 1231 auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() ); 1232 return new ast::DirectiveDecl( stmt->location, stmt ); 1233 } // if 1234 1235 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 1122 1236 // otype is internally converted to dtype + otype parameters 1123 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype,TypeDecl::Dimension };1124 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );1237 static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension }; 1238 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." ); 1125 1239 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." ); 1126 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr ); 1127 buildList( variable.assertions, ret->get_assertions() ); 1240 ast::TypeDecl * ret = new ast::TypeDecl( location, 1241 *name, 1242 ast::Storage::Classes(), 1243 (ast::Type *)nullptr, 1244 kindMap[ variable.tyClass ], 1245 variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype, 1246 variable.initializer ? variable.initializer->buildType() : nullptr 1247 ); 1248 buildList( variable.assertions, ret->assertions ); 1128 1249 return ret; 1129 1250 } // if … … 1147 1268 } // if 1148 1269 bool isDelete = initializer && initializer->get_isDelete(); 1149 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1270 ast::Decl * decl = buildDecl( 1271 type, 1272 name ? *name : string( "" ), 1273 storageClasses, 1274 maybeBuild( bitfieldWidth ), 1275 funcSpecs, 1276 linkage, 1277 asmName, 1278 isDelete ? nullptr : maybeBuild( initializer ), 1279 copy( attributes ) 1280 )->set_extension( extension ); 1150 1281 if ( isDelete ) { 1151 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );1282 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl ); 1152 1283 dwt->isDeleted = true; 1153 1284 } … … 1156 1287 1157 1288 if ( assert.condition ) { 1158 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 1289 auto cond = maybeBuild( assert.condition ); 1290 auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) ); 1291 return new ast::StaticAssertDecl( location, cond, msg ); 1159 1292 } 1160 1293 … … 1167 1300 } // if 1168 1301 if ( enumInLine ) { 1169 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1302 return new ast::InlineMemberDecl( location, 1303 *name, (ast::Type*)nullptr, storageClasses, linkage ); 1170 1304 } // if 1171 1305 assertf( name, "ObjectDecl must a have name\n" ); 1172 return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension ); 1173 } 1174 1175 Type * DeclarationNode::buildType() const { 1306 auto ret = new ast::ObjectDecl( location, 1307 *name, 1308 (ast::Type*)nullptr, 1309 maybeBuild( initializer ), 1310 storageClasses, 1311 linkage, 1312 maybeBuild( bitfieldWidth ) 1313 ); 1314 ret->asmName = asmName; 1315 ret->extension = extension; 1316 return ret; 1317 } 1318 1319 ast::Type * DeclarationNode::buildType() const { 1176 1320 assert( type ); 1177 1321 1178 if ( attr.expr ) {1179 return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes );1180 } else if ( attr.type ) {1181 return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes );1182 } // if1183 1184 1322 switch ( type->kind ) { 1185 case TypeData::Enum: 1186 case TypeData::Aggregate: { 1187 ReferenceToType * ret = buildComAggInst( type, attributes, linkage ); 1188 buildList( type->aggregate.actuals, ret->get_parameters() ); 1189 return ret; 1190 } 1191 case TypeData::Symbolic: { 1192 TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes ); 1193 buildList( type->symbolic.actuals, ret->get_parameters() ); 1194 return ret; 1195 } 1196 default: 1197 Type * simpletypes = typebuild( type ); 1198 simpletypes->get_attributes() = attributes; // copy because member is const 1323 case TypeData::Enum: 1324 case TypeData::Aggregate: { 1325 ast::BaseInstType * ret = 1326 buildComAggInst( type, copy( attributes ), linkage ); 1327 buildList( type->aggregate.actuals, ret->params ); 1328 return ret; 1329 } 1330 case TypeData::Symbolic: { 1331 ast::TypeInstType * ret = new ast::TypeInstType( 1332 *type->symbolic.name, 1333 // This is just a default, the true value is not known yet. 1334 ast::TypeDecl::Dtype, 1335 buildQualifiers( type ), 1336 copy( attributes ) ); 1337 buildList( type->symbolic.actuals, ret->params ); 1338 return ret; 1339 } 1340 default: 1341 ast::Type * simpletypes = typebuild( type ); 1342 // copy because member is const 1343 simpletypes->attributes = attributes; 1199 1344 return simpletypes; 1200 1345 } // switch -
src/Parser/ExpressionNode.cc
r34b4268 r24d6572 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 13:17:07 2015 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 7 09:18:56 2021 13 // Update Count : 1077 14 // 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 11:07:00 2023 13 // Update Count : 1083 14 // 15 16 #include "ExpressionNode.h" 15 17 16 18 #include <cassert> // for assert … … 21 23 #include <string> // for string, operator+, operator== 22 24 25 #include "AST/Expr.hpp" // for NameExpr 26 #include "AST/Type.hpp" // for BaseType, SueInstType 23 27 #include "Common/SemanticError.h" // for SemanticError 24 28 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 25 #include "ParseNode.h" // for ExpressionNode, maybeMoveBuildType 26 #include "SynTree/Constant.h" // for Constant 27 #include "SynTree/Declaration.h" // for EnumDecl, StructDecl, UnionDecl 28 #include "SynTree/Expression.h" // for Expression, ConstantExpr, NameExpr 29 #include "SynTree/Statement.h" // for CompoundStmt, Statement 30 #include "SynTree/Type.h" // for BasicType, Type, Type::Qualifiers 29 #include "DeclarationNode.h" // for DeclarationNode 30 #include "InitializerNode.h" // for InitializerNode 31 31 #include "parserutility.h" // for notZeroExpr 32 33 class Initializer;34 32 35 33 using namespace std; … … 48 46 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 49 47 // type. 50 51 extern const Type::Qualifiers noQualifiers; // no qualifiers on constants52 48 53 49 // static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } … … 71 67 size_t end = str.length() - 1; 72 68 if ( posn == end ) { type = 3; return; } // no length after 'l' => long 73 69 74 70 string::size_type next = posn + 1; // advance to length 75 71 if ( str[next] == '3' ) { // 32 … … 122 118 if ( str[i] == '1' ) v |= 1; 123 119 i += 1; 124 120 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 125 121 v <<= 1; 126 122 } // for 127 123 } // scanbin 128 124 129 Expression * build_constantInteger( string & str ) { 130 static const BasicType::Kind kind[2][6] = { 125 ast::Expr * build_constantInteger( 126 const CodeLocation & location, string & str ) { 127 static const ast::BasicType::Kind kind[2][6] = { 131 128 // short (h) must be before char (hh) because shorter type has the longer suffix 132 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */BasicType::LongLongSignedInt, },133 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */BasicType::LongLongUnsignedInt, },129 { ast::BasicType::ShortSignedInt, ast::BasicType::SignedChar, ast::BasicType::SignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ ast::BasicType::LongLongSignedInt, }, 130 { ast::BasicType::ShortUnsignedInt, ast::BasicType::UnsignedChar, ast::BasicType::UnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ ast::BasicType::LongLongUnsignedInt, }, 134 131 }; 135 132 … … 141 138 string str2( "0x0" ); 142 139 unsigned long long int v, v2 = 0; // converted integral value 143 Expression* ret, * ret2;140 ast::Expr * ret, * ret2; 144 141 145 142 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 … … 149 146 // special constants 150 147 if ( str == "0" ) { 151 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ));148 ret = new ast::ConstantExpr( location, new ast::ZeroType(), str, 0 ); 152 149 goto CLEANUP; 153 150 } // if 154 151 if ( str == "1" ) { 155 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ));152 ret = new ast::ConstantExpr( location, new ast::OneType(), str, 1 ); 156 153 goto CLEANUP; 157 154 } // if 158 159 string::size_type posn;160 155 161 156 // 'u' can appear before or after length suffix … … 166 161 } else { 167 162 // At least one digit in integer constant, so safe to backup while looking for suffix. 168 169 posn = str.find_last_of( "pP" ); // pointer value 170 if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; } 171 172 posn = str.find_last_of( "zZ" ); // size_t 173 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 174 175 posn = str.rfind( "hh" ); // char 176 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 177 178 posn = str.rfind( "HH" ); // char 179 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 180 181 posn = str.find_last_of( "hH" ); // short 182 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 183 184 posn = str.find_last_of( "nN" ); // int (natural number) 185 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 186 187 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 188 189 lnthSuffix( str, type, ltype ); // must be after check for "ll" 190 FINI: ; 163 // This declaration and the comma expressions in the conditions mimic 164 // the declare and check pattern allowed in later compiler versions. 165 // (Only some early compilers/C++ standards do not support it.) 166 string::size_type posn; 167 // pointer value 168 if ( posn = str.find_last_of( "pP" ), posn != string::npos ) { 169 ltype = 5; str.erase( posn, 1 ); 170 // size_t 171 } else if ( posn = str.find_last_of( "zZ" ), posn != string::npos ) { 172 Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); 173 // signed char 174 } else if ( posn = str.rfind( "hh" ), posn != string::npos ) { 175 type = 1; str.erase( posn, 2 ); 176 // signed char 177 } else if ( posn = str.rfind( "HH" ), posn != string::npos ) { 178 type = 1; str.erase( posn, 2 ); 179 // short 180 } else if ( posn = str.find_last_of( "hH" ), posn != string::npos ) { 181 type = 0; str.erase( posn, 1 ); 182 // int (natural number) 183 } else if ( posn = str.find_last_of( "nN" ), posn != string::npos ) { 184 type = 2; str.erase( posn, 1 ); 185 } else if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { 186 type = 4; 187 } else { 188 lnthSuffix( str, type, ltype ); 189 } // if 191 190 } // if 192 191 … … 196 195 if ( type == 5 ) SemanticError( yylloc, "int128 constant is not supported on this target " + str ); 197 196 #endif // ! __SIZEOF_INT128__ 198 197 199 198 if ( str[0] == '0' ) { // radix character ? 200 199 dec = false; … … 206 205 unsigned int len = str.length(); 207 206 if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str ); 208 if ( len <= (2 + 16) ) goto FHEX1; // hex digits < 2^64 209 str2 = "0x" + str.substr( len - 16 ); 210 sscanf( (char *)str2.c_str(), "%llx", &v2 ); 211 str = str.substr( 0, len - 16 ); 212 FHEX1: ; 207 // hex digits < 2^64 208 if ( len > (2 + 16) ) { 209 str2 = "0x" + str.substr( len - 16 ); 210 sscanf( (char *)str2.c_str(), "%llx", &v2 ); 211 str = str.substr( 0, len - 16 ); 212 } // if 213 213 sscanf( (char *)str.c_str(), "%llx", &v ); 214 214 #endif // __SIZEOF_INT128__ … … 301 301 302 302 // Constant type is correct for overload resolving. 303 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) ); 303 ret = new ast::ConstantExpr( location, 304 new ast::BasicType( kind[Unsigned][type] ), str, v ); 304 305 if ( Unsigned && type < 2 ) { // hh or h, less than int ? 305 306 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 306 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 307 ret = new ast::CastExpr( location, 308 ret, 309 new ast::BasicType( kind[Unsigned][type] ), 310 ast::ExplicitCast ); 307 311 } else if ( ltype != -1 ) { // explicit length ? 308 312 if ( ltype == 6 ) { // int128, (int128)constant 309 // ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 310 ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) ); 311 ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 312 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) ); 313 ret2 = new ast::ConstantExpr( location, 314 new ast::BasicType( ast::BasicType::LongLongSignedInt ), 315 str2, 316 v2 ); 317 ret = build_compoundLiteral( location, 318 DeclarationNode::newBasicType( 319 DeclarationNode::Int128 320 )->addType( 321 DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 322 new InitializerNode( 323 (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) 324 ); 313 325 } else { // explicit length, (length_type)constant 314 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); 326 ret = new ast::CastExpr( location, 327 ret, 328 new ast::TypeInstType( lnthsInt[Unsigned][ltype], ast::TypeDecl::Dtype ), 329 ast::ExplicitCast ); 315 330 if ( ltype == 5 ) { // pointer, intptr( (uintptr_t)constant ) 316 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) ); 331 ret = build_func( location, 332 new ExpressionNode( 333 build_varref( location, new string( "intptr" ) ) ), 334 new ExpressionNode( ret ) ); 317 335 } // if 318 336 } // if … … 358 376 359 377 360 Expression * build_constantFloat( string & str ) { 361 static const BasicType::Kind kind[2][12] = { 362 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x }, 363 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex }, 378 ast::Expr * build_constantFloat( 379 const CodeLocation & location, string & str ) { 380 static const ast::BasicType::Kind kind[2][12] = { 381 { 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 }, 382 { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex }, 364 383 }; 365 384 … … 398 417 399 418 assert( 0 <= type && type < 12 ); 400 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) ); 401 if ( explnth ) { // explicit length ? 402 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false ); 419 ast::Expr * ret = new ast::ConstantExpr( location, 420 new ast::BasicType( kind[complx][type] ), 421 str, 422 v ); 423 // explicit length ? 424 if ( explnth ) { 425 ret = new ast::CastExpr( location, 426 ret, 427 new ast::BasicType( kind[complx][type] ), 428 ast::ExplicitCast ); 403 429 } // if 404 430 … … 415 441 } // sepString 416 442 417 Expression * build_constantChar(string & str ) {443 ast::Expr * build_constantChar( const CodeLocation & location, string & str ) { 418 444 string units; // units 419 445 sepString( str, units, '\'' ); // separate constant from units 420 446 421 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) ); 447 ast::Expr * ret = new ast::ConstantExpr( location, 448 new ast::BasicType( ast::BasicType::Char ), 449 str, 450 (unsigned long long int)(unsigned char)str[1] ); 422 451 if ( units.length() != 0 ) { 423 ret = new UntypedExpr( new NameExpr( units ), { ret } ); 452 ret = new ast::UntypedExpr( location, 453 new ast::NameExpr( location, units ), 454 { ret } ); 424 455 } // if 425 456 … … 428 459 } // build_constantChar 429 460 430 Expression * build_constantStr( string & str ) { 461 ast::Expr * build_constantStr( 462 const CodeLocation & location, 463 string & str ) { 431 464 assert( str.length() > 0 ); 432 465 string units; // units 433 466 sepString( str, units, '"' ); // separate constant from units 434 467 435 Type * strtype;468 ast::Type * strtype; 436 469 switch ( str[0] ) { // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1 437 470 case 'u': 438 471 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char 439 472 // lookup type of associated typedef 440 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );473 strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype ); 441 474 break; 442 443 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );475 case 'U': 476 strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype ); 444 477 break; 445 446 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );478 case 'L': 479 strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype ); 447 480 break; 448 449 450 strtype = new BasicType( Type::Qualifiers( ),BasicType::Char );481 Default: // char default string type 482 default: 483 strtype = new ast::BasicType( ast::BasicType::Char ); 451 484 } // switch 452 ArrayType * at = new ArrayType( noQualifiers, strtype, 453 new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"' 454 false, false ); 455 Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) ); 485 ast::ArrayType * at = new ast::ArrayType( 486 strtype, 487 // Length is adjusted: +1 for '\0' and -2 for '"' 488 ast::ConstantExpr::from_ulong( location, str.size() + 1 - 2 ), 489 ast::FixedLen, 490 ast::DynamicDim ); 491 ast::Expr * ret = new ast::ConstantExpr( location, at, str, std::nullopt ); 456 492 if ( units.length() != 0 ) { 457 ret = new UntypedExpr( new NameExpr( units ), { ret } ); 493 ret = new ast::UntypedExpr( location, 494 new ast::NameExpr( location, units ), 495 { ret } ); 458 496 } // if 459 497 … … 462 500 } // build_constantStr 463 501 464 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) { 502 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( 503 const CodeLocation & location, const string & str ) { 465 504 if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str ); 466 Expression * ret = build_constantInteger( *new string( str.substr(1) ) ); 505 ast::Expr * ret = build_constantInteger( location, 506 *new string( str.substr(1) ) ); 467 507 delete &str; 468 508 return ret; 469 509 } // build_field_name_FLOATING_FRACTIONconstant 470 510 471 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) { 511 ast::Expr * build_field_name_FLOATING_DECIMALconstant( 512 const CodeLocation & location, const string & str ) { 472 513 if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str ); 473 Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) ); 514 ast::Expr * ret = build_constantInteger( 515 location, *new string( str.substr( 0, str.size()-1 ) ) ); 474 516 delete &str; 475 517 return ret; 476 518 } // build_field_name_FLOATING_DECIMALconstant 477 519 478 Expression * build_field_name_FLOATINGconstant( const string & str ) { 520 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location, 521 const string & str ) { 479 522 // str is of the form A.B -> separate at the . and return member expression 480 523 int a, b; … … 482 525 stringstream ss( str ); 483 526 ss >> a >> dot >> b; 484 UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) ); 527 auto ret = new ast::UntypedMemberExpr( location, 528 ast::ConstantExpr::from_int( location, b ), 529 ast::ConstantExpr::from_int( location, a ) 530 ); 485 531 delete &str; 486 532 return ret; 487 533 } // build_field_name_FLOATINGconstant 488 534 489 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) { 490 if ( fracts ) { 491 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) { 492 memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) ); 493 return memberExpr; 494 } else { 495 return new UntypedMemberExpr( fracts, fieldName ); 496 } // if 497 } // if 498 return fieldName; 535 ast::Expr * make_field_name_fraction_constants( const CodeLocation & location, 536 ast::Expr * fieldName, 537 ast::Expr * fracts ) { 538 if ( nullptr == fracts ) { 539 return fieldName; 540 } else if ( auto memberExpr = dynamic_cast<ast::UntypedMemberExpr *>( fracts ) ) { 541 memberExpr->member = make_field_name_fraction_constants( location, 542 fieldName, 543 ast::mutate( memberExpr->aggregate.get() ) ); 544 return memberExpr; 545 } else { 546 return new ast::UntypedMemberExpr( location, fracts, fieldName ); 547 } // if 499 548 } // make_field_name_fraction_constants 500 549 501 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) { 502 return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) ); 550 ast::Expr * build_field_name_fraction_constants( const CodeLocation & location, 551 ast::Expr * fieldName, 552 ExpressionNode * fracts ) { 553 return make_field_name_fraction_constants( location, fieldName, maybeMoveBuild( fracts ) ); 503 554 } // build_field_name_fraction_constants 504 555 505 NameExpr * build_varref( const string * name ) { 506 NameExpr * expr = new NameExpr( *name ); 556 ast::NameExpr * build_varref( const CodeLocation & location, 557 const string * name ) { 558 ast::NameExpr * expr = new ast::NameExpr( location, *name ); 507 559 delete name; 508 560 return expr; 509 561 } // build_varref 510 562 511 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) { 512 Declaration * newDecl = maybeBuild< Declaration >(decl_node); 513 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { 514 const Type * t = newDeclWithType->get_type(); 515 if ( t ) { 516 if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) { 517 newDecl= new EnumDecl( typeInst->name ); 563 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location, 564 const DeclarationNode * decl_node, 565 const ast::NameExpr * name ) { 566 ast::Decl * newDecl = maybeBuild( decl_node ); 567 if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) { 568 if ( const ast::Type * t = newDeclWithType->get_type() ) { 569 if ( auto typeInst = dynamic_cast<const ast::TypeInstType *>( t ) ) { 570 newDecl = new ast::EnumDecl( location, typeInst->name ); 518 571 } 519 572 } 520 573 } 521 return new QualifiedNameExpr(newDecl, name->name );574 return new ast::QualifiedNameExpr( location, newDecl, name->name ); 522 575 } 523 576 524 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) { 525 EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node ); 526 return new QualifiedNameExpr( newDecl, name->name ); 577 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location, 578 const ast::EnumDecl * decl, 579 const ast::NameExpr * name ) { 580 return new ast::QualifiedNameExpr( location, decl, name->name ); 527 581 } 528 582 529 DimensionExpr * build_dimensionref( const string * name ) { 530 DimensionExpr * expr = new DimensionExpr( *name ); 583 ast::DimensionExpr * build_dimensionref( const CodeLocation & location, 584 const string * name ) { 585 ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name ); 531 586 delete name; 532 587 return expr; … … 544 599 }; // OperName 545 600 546 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node, CastExpr::CastKind kind ) { 547 Type * targetType = maybeMoveBuildType( decl_node ); 548 if ( dynamic_cast< VoidType * >( targetType ) ) { 601 ast::Expr * build_cast( const CodeLocation & location, 602 DeclarationNode * decl_node, 603 ExpressionNode * expr_node, 604 ast::CastExpr::CastKind kind ) { 605 ast::Type * targetType = maybeMoveBuildType( decl_node ); 606 if ( dynamic_cast<ast::VoidType *>( targetType ) ) { 549 607 delete targetType; 550 return new CastExpr( maybeMoveBuild< Expression >(expr_node), false, kind ); 608 return new ast::CastExpr( location, 609 maybeMoveBuild( expr_node ), 610 ast::ExplicitCast, kind ); 551 611 } else { 552 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType, false, kind ); 612 return new ast::CastExpr( location, 613 maybeMoveBuild( expr_node ), 614 targetType, 615 ast::ExplicitCast, kind ); 553 616 } // if 554 617 } // build_cast 555 618 556 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) { 557 return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target ); 619 ast::Expr * build_keyword_cast( const CodeLocation & location, 620 ast::AggregateDecl::Aggregate target, 621 ExpressionNode * expr_node ) { 622 return new ast::KeywordCastExpr( location, 623 maybeMoveBuild( expr_node ), 624 target 625 ); 558 626 } 559 627 560 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) { 561 return new VirtualCastExpr( maybeMoveBuild< Expression >( expr_node ), maybeMoveBuildType( decl_node ) ); 628 ast::Expr * build_virtual_cast( const CodeLocation & location, 629 DeclarationNode * decl_node, 630 ExpressionNode * expr_node ) { 631 return new ast::VirtualCastExpr( location, 632 maybeMoveBuild( expr_node ), 633 maybeMoveBuildType( decl_node ) 634 ); 562 635 } // build_virtual_cast 563 636 564 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) { 565 return new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) ); 637 ast::Expr * build_fieldSel( const CodeLocation & location, 638 ExpressionNode * expr_node, 639 ast::Expr * member ) { 640 return new ast::UntypedMemberExpr( location, 641 member, 642 maybeMoveBuild( expr_node ) 643 ); 566 644 } // build_fieldSel 567 645 568 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) { 569 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 646 ast::Expr * build_pfieldSel( const CodeLocation & location, 647 ExpressionNode * expr_node, 648 ast::Expr * member ) { 649 auto deref = new ast::UntypedExpr( location, 650 new ast::NameExpr( location, "*?" ) 651 ); 570 652 deref->location = expr_node->location; 571 deref-> get_args().push_back( maybeMoveBuild< Expression >(expr_node) );572 UntypedMemberExpr * ret = new UntypedMemberExpr(member, deref );653 deref->args.push_back( maybeMoveBuild( expr_node ) ); 654 auto ret = new ast::UntypedMemberExpr( location, member, deref ); 573 655 return ret; 574 656 } // build_pfieldSel 575 657 576 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) { 577 Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() ); 658 ast::Expr * build_offsetOf( const CodeLocation & location, 659 DeclarationNode * decl_node, 660 ast::NameExpr * member ) { 661 ast::Expr * ret = new ast::UntypedOffsetofExpr( location, 662 maybeMoveBuildType( decl_node ), 663 member->name 664 ); 665 ret->result = new ast::BasicType( ast::BasicType::LongUnsignedInt ); 578 666 delete member; 579 667 return ret; 580 668 } // build_offsetOf 581 669 582 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) { 583 return new LogicalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), notZeroExpr( maybeMoveBuild< Expression >(expr_node2) ), kind ); 670 ast::Expr * build_and_or( const CodeLocation & location, 671 ExpressionNode * expr_node1, 672 ExpressionNode * expr_node2, 673 ast::LogicalFlag flag ) { 674 return new ast::LogicalExpr( location, 675 notZeroExpr( maybeMoveBuild( expr_node1 ) ), 676 notZeroExpr( maybeMoveBuild( expr_node2 ) ), 677 flag 678 ); 584 679 } // build_and_or 585 680 586 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) { 587 list< Expression * > args; 588 args.push_back( maybeMoveBuild< Expression >(expr_node) ); 589 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 681 ast::Expr * build_unary_val( const CodeLocation & location, 682 OperKinds op, 683 ExpressionNode * expr_node ) { 684 std::vector<ast::ptr<ast::Expr>> args; 685 args.push_back( maybeMoveBuild( expr_node ) ); 686 return new ast::UntypedExpr( location, 687 new ast::NameExpr( location, OperName[ (int)op ] ), 688 std::move( args ) 689 ); 590 690 } // build_unary_val 591 691 592 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) { 593 list< Expression * > args;594 args.push_back( maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.595 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );596 } // build_unary_ptr 597 598 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 599 list< Expression * > args;600 args.push_back( maybeMoveBuild< Expression >(expr_node1) );601 args.push_back( maybeMoveBuild< Expression >(expr_node2) );602 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args);692 ast::Expr * build_binary_val( const CodeLocation & location, 693 OperKinds op, 694 ExpressionNode * expr_node1, 695 ExpressionNode * expr_node2 ) { 696 std::vector<ast::ptr<ast::Expr>> args; 697 args.push_back( maybeMoveBuild( expr_node1 ) ); 698 args.push_back( maybeMoveBuild( expr_node2 ) ); 699 return new ast::UntypedExpr( location, 700 new ast::NameExpr( location, OperName[ (int)op ] ), 701 std::move( args ) 702 ); 603 703 } // build_binary_val 604 704 605 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 606 list< Expression * > args;607 args.push_back( maybeMoveBuild< Expression >(expr_node1) );608 args.push_back( maybeMoveBuild< Expression >(expr_node2) );609 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );610 } // build_binary_ptr 611 612 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) { 613 return new ConditionalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), maybeMoveBuild< Expression >(expr_node2), maybeMoveBuild< Expression >(expr_node3));705 ast::Expr * build_cond( const CodeLocation & location, 706 ExpressionNode * expr_node1, 707 ExpressionNode * expr_node2, 708 ExpressionNode * expr_node3 ) { 709 return new ast::ConditionalExpr( location, 710 notZeroExpr( maybeMoveBuild( expr_node1 ) ), 711 maybeMoveBuild( expr_node2 ), 712 maybeMoveBuild( expr_node3 ) 713 ); 614 714 } // build_cond 615 715 616 Expression * build_tuple( ExpressionNode * expr_node ) { 617 list< Expression * > exprs; 716 ast::Expr * build_tuple( const CodeLocation & location, 717 ExpressionNode * expr_node ) { 718 std::vector<ast::ptr<ast::Expr>> exprs; 618 719 buildMoveList( expr_node, exprs ); 619 return new UntypedTupleExpr( exprs );;720 return new ast::UntypedTupleExpr( location, std::move( exprs ) ); 620 721 } // build_tuple 621 722 622 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) { 623 list< Expression * > args; 723 ast::Expr * build_func( const CodeLocation & location, 724 ExpressionNode * function, 725 ExpressionNode * expr_node ) { 726 std::vector<ast::ptr<ast::Expr>> args; 624 727 buildMoveList( expr_node, args ); 625 return new UntypedExpr( maybeMoveBuild< Expression >(function), args ); 728 return new ast::UntypedExpr( location, 729 maybeMoveBuild( function ), 730 std::move( args ) 731 ); 626 732 } // build_func 627 733 628 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) { 629 Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type 630 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type 631 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild< Initializer >(kids) ); 734 ast::Expr * build_compoundLiteral( const CodeLocation & location, 735 DeclarationNode * decl_node, 736 InitializerNode * kids ) { 737 // compound literal type 738 ast::Decl * newDecl = maybeBuild( decl_node ); 739 // non-sue compound-literal type 740 if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) { 741 return new ast::CompoundLiteralExpr( location, 742 newDeclWithType->get_type(), 743 maybeMoveBuild( kids ) ); 632 744 // these types do not have associated type information 633 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) { 634 if ( newDeclStructDecl->has_body() ) { 635 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild< Initializer >(kids) ); 745 } else if ( auto newDeclStructDecl = dynamic_cast<ast::StructDecl *>( newDecl ) ) { 746 if ( newDeclStructDecl->body ) { 747 return new ast::CompoundLiteralExpr( location, 748 new ast::StructInstType( newDeclStructDecl ), 749 maybeMoveBuild( kids ) ); 636 750 } else { 637 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild< Initializer >(kids) ); 638 } // if 639 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) { 640 if ( newDeclUnionDecl->has_body() ) { 641 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild< Initializer >(kids) ); 751 return new ast::CompoundLiteralExpr( location, 752 new ast::StructInstType( newDeclStructDecl->name ), 753 maybeMoveBuild( kids ) ); 754 } // if 755 } else if ( auto newDeclUnionDecl = dynamic_cast<ast::UnionDecl *>( newDecl ) ) { 756 if ( newDeclUnionDecl->body ) { 757 return new ast::CompoundLiteralExpr( location, 758 new ast::UnionInstType( newDeclUnionDecl ), 759 maybeMoveBuild( kids ) ); 642 760 } else { 643 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild< Initializer >(kids) ); 644 } // if 645 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) { 646 if ( newDeclEnumDecl->has_body() ) { 647 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild< Initializer >(kids) ); 761 return new ast::CompoundLiteralExpr( location, 762 new ast::UnionInstType( newDeclUnionDecl->name ), 763 maybeMoveBuild( kids ) ); 764 } // if 765 } else if ( auto newDeclEnumDecl = dynamic_cast<ast::EnumDecl *>( newDecl ) ) { 766 if ( newDeclEnumDecl->body ) { 767 return new ast::CompoundLiteralExpr( location, 768 new ast::EnumInstType( newDeclEnumDecl ), 769 maybeMoveBuild( kids ) ); 648 770 } else { 649 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild< Initializer >(kids) ); 771 return new ast::CompoundLiteralExpr( location, 772 new ast::EnumInstType( newDeclEnumDecl->name ), 773 maybeMoveBuild( kids ) ); 650 774 } // if 651 775 } else { … … 656 780 // Local Variables: // 657 781 // tab-width: 4 // 658 // mode: c++ //659 // compile-command: "make install" //660 782 // End: // -
src/Parser/InitializerNode.cc
r34b4268 r24d6572 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:20:24 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 28 23:27:20 201713 // Update Count : 2 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 11:18:00 2023 13 // Update Count : 27 14 14 // 15 16 #include "InitializerNode.h" 15 17 16 18 #include <iostream> // for operator<<, ostream, basic_ostream … … 18 20 #include <string> // for operator<<, string 19 21 22 #include "AST/Expr.hpp" // for Expr 23 #include "AST/Init.hpp" // for Designator, Init, ListInit, Sing... 24 #include "Common/SemanticError.h" // for SemanticError 25 #include "Common/utility.h" // for maybeBuild 26 #include "ExpressionNode.h" // for ExpressionNode 27 #include "DeclarationNode.h" // for buildList 28 20 29 using namespace std; 21 30 22 #include "Common/SemanticError.h" // for SemanticError 23 #include "Common/utility.h" // for maybeBuild 24 #include "ParseNode.h" // for InitializerNode, ExpressionNode 25 #include "SynTree/Expression.h" // for Expression 26 #include "SynTree/Initializer.h" // for Initializer, ListInit, SingleInit 31 static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) { 32 return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct; 33 } 27 34 28 35 InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des ) … … 33 40 if ( kids ) 34 41 set_last( nullptr ); 35 } // InitializerNode::InitializerNode 42 } // InitializerNode::InitializerNode 36 43 37 44 InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des ) … … 85 92 } // InitializerNode::printOneLine 86 93 87 Initializer* InitializerNode::build() const {94 ast::Init * InitializerNode::build() const { 88 95 assertf( ! isDelete, "Should not build delete stmt InitializerNode" ); 89 96 if ( aggregate ) { 90 97 // steal designators from children 91 std:: list< Designation *> designlist;98 std::vector<ast::ptr<ast::Designation>> designlist; 92 99 InitializerNode * child = next_init(); 93 for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) { 94 std::list< Expression * > desList; 95 buildList< Expression, ExpressionNode >( child->designator, desList ); 96 designlist.push_back( new Designation( desList ) ); 100 for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) { 101 std::deque<ast::ptr<ast::Expr>> desList; 102 buildList( child->designator, desList ); 103 designlist.push_back( 104 new ast::Designation( location, std::move( desList ) ) ); 97 105 } // for 98 std::list< Initializer * > initlist; 99 buildList< Initializer, InitializerNode >( next_init(), initlist ); 100 return new ListInit( initlist, designlist, maybeConstructed ); 101 } else { 102 if ( get_expression() ) { 103 assertf( get_expression()->expr, "The expression of initializer must have value" ); 104 return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed ); 105 } // if 106 std::vector<ast::ptr<ast::Init>> initlist; 107 buildList( next_init(), initlist ); 108 return new ast::ListInit( location, 109 std::move( initlist ), 110 std::move( designlist ), 111 toConstructFlag( maybeConstructed ) 112 ); 113 } else if ( get_expression() ) { 114 assertf( get_expression()->expr, "The expression of initializer must have value" ); 115 return new ast::SingleInit( location, 116 maybeBuild( get_expression() ), 117 toConstructFlag( maybeConstructed ) 118 ); 106 119 } // if 107 120 return nullptr; -
src/Parser/ParseNode.h
r34b4268 r24d6572 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:28:16 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Nov 2 21:27:07 202213 // Update Count : 9 3911 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Apr 3 17:55:00 2023 13 // Update Count : 942 14 14 // 15 15 … … 24 24 #include <string> // for string 25 25 26 #include "AST/Expr.hpp" // for Expr, NameExpr LogicalFlag 27 #include "AST/Fwd.hpp" // for ptr, Decl, DeclWithType, 28 #include "AST/Stmt.hpp" // for Stmt 26 29 #include "Common/CodeLocation.h" // for CodeLocation 27 30 #include "Common/SemanticError.h" // for SemanticError 28 31 #include "Common/UniqueName.h" // for UniqueName 29 #include "Common/utility.h" // for maybeClone, maybeBuild 30 #include "SynTree/LinkageSpec.h" // for Spec 31 #include "SynTree/Declaration.h" // for Aggregate 32 #include "SynTree/Expression.h" // for Expression, ConstantExpr (ptr only) 33 #include "SynTree/Label.h" // for Label 34 #include "SynTree/Statement.h" // for Statement, BranchStmt, BranchStmt:... 35 #include "SynTree/Type.h" // for Type, Type::FuncSpecifiers, Type::... 32 #include "Common/utility.h" // for maybeClone 33 #include "Parser/parserutility.h" // for maybeBuild, maybeCopy 36 34 37 35 class Attribute; … … 40 38 class DeclarationWithType; 41 39 class Initializer; 40 class InitializerNode; 42 41 class ExpressionNode; 43 42 struct StatementNode; … … 82 81 }; // ParseNode 83 82 84 //##############################################################################85 86 class InitializerNode : public ParseNode {87 public:88 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );89 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );90 InitializerNode( bool isDelete );91 ~InitializerNode();92 virtual InitializerNode * clone() const { assert( false ); return nullptr; }93 94 ExpressionNode * get_expression() const { return expr; }95 96 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }97 ExpressionNode * get_designators() const { return designator; }98 99 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }100 bool get_maybeConstructed() const { return maybeConstructed; }101 102 bool get_isDelete() const { return isDelete; }103 104 InitializerNode * next_init() const { return kids; }105 106 void print( std::ostream & os, int indent = 0 ) const;107 void printOneLine( std::ostream & ) const;108 109 virtual Initializer * build() const;110 private:111 ExpressionNode * expr;112 bool aggregate;113 ExpressionNode * designator; // may be list114 InitializerNode * kids;115 bool maybeConstructed;116 bool isDelete;117 }; // InitializerNode118 119 //##############################################################################120 121 class ExpressionNode final : public ParseNode {122 public:123 ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}124 virtual ~ExpressionNode() {}125 virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }126 127 bool get_extension() const { return extension; }128 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }129 130 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {131 os << expr.get();132 }133 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}134 135 template<typename T>136 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }137 138 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }139 140 std::unique_ptr<Expression> expr; // public because of lifetime implications141 private:142 bool extension = false;143 }; // ExpressionNode144 145 template< typename T >146 struct maybeBuild_t< Expression, T > {147 static inline Expression * doit( const T * orig ) {148 if ( orig ) {149 Expression * p = orig->build();150 p->set_extension( orig->get_extension() );151 p->location = orig->location;152 return p;153 } else {154 return nullptr;155 } // if156 }157 };158 159 83 // Must harmonize with OperName. 160 84 enum class OperKinds { … … 172 96 173 97 struct LabelNode { 174 std:: list< Label> labels;98 std::vector<ast::Label> labels; 175 99 }; 176 100 177 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string178 Expression * build_constantFloat( std::string & str );179 Expression * build_constantChar( std::string & str );180 Expression * build_constantStr( std::string & str );181 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );182 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );183 Expression * build_field_name_FLOATINGconstant( const std::string & str );184 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );185 186 NameExpr * build_varref( const std::string * name );187 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );188 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );189 DimensionExpr * build_dimensionref( const std::string * name );190 191 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node, CastExpr::CastKind kind = CastExpr::Default );192 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );193 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );194 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );195 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );196 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );197 Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );198 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );199 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );200 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );201 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );202 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );203 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );204 Expression * build_tuple( ExpressionNode * expr_node = nullptr );205 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );206 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );207 208 //##############################################################################209 210 struct TypeData;211 212 struct DeclarationNode : public ParseNode {213 // These enumerations must harmonize with their names in DeclarationNode.cc.214 enum BasicType { Void, Bool, Char, Int, Int128,215 Float, Double, LongDouble, uuFloat80, uuFloat128,216 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };217 static const char * basicTypeNames[];218 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message219 static const char * complexTypeNames[];220 enum Signedness { Signed, Unsigned, NoSignedness };221 static const char * signednessNames[];222 enum Length { Short, Long, LongLong, NoLength };223 static const char * lengthNames[];224 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };225 static const char * builtinTypeNames[];226 227 static DeclarationNode * newStorageClass( Type::StorageClasses );228 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );229 static DeclarationNode * newTypeQualifier( Type::Qualifiers );230 static DeclarationNode * newBasicType( BasicType );231 static DeclarationNode * newComplexType( ComplexType );232 static DeclarationNode * newSignedNess( Signedness );233 static DeclarationNode * newLength( Length );234 static DeclarationNode * newBuiltinType( BuiltinType );235 static DeclarationNode * newForall( DeclarationNode * );236 static DeclarationNode * newFromTypedef( const std::string * );237 static DeclarationNode * newFromGlobalScope();238 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );239 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );240 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );241 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );242 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );243 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );244 static DeclarationNode * newEnumInLine( const std::string name );245 static DeclarationNode * newName( const std::string * );246 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );247 static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );248 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );249 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );250 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );251 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );252 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );253 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );254 static DeclarationNode * newBitfield( ExpressionNode * size );255 static DeclarationNode * newTuple( DeclarationNode * members );256 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );257 static DeclarationNode * newVtableType( DeclarationNode * expr );258 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes259 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement260 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement261 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );262 263 DeclarationNode();264 ~DeclarationNode();265 DeclarationNode * clone() const override;266 267 DeclarationNode * addQualifiers( DeclarationNode * );268 void checkQualifiers( const TypeData *, const TypeData * );269 void checkSpecifiers( DeclarationNode * );270 DeclarationNode * copySpecifiers( DeclarationNode * );271 DeclarationNode * addType( DeclarationNode * );272 DeclarationNode * addTypedef();273 DeclarationNode * addEnumBase( DeclarationNode * );274 DeclarationNode * addAssertions( DeclarationNode * );275 DeclarationNode * addName( std::string * );276 DeclarationNode * addAsmName( DeclarationNode * );277 DeclarationNode * addBitfield( ExpressionNode * size );278 DeclarationNode * addVarArgs();279 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );280 DeclarationNode * addOldDeclList( DeclarationNode * list );281 DeclarationNode * setBase( TypeData * newType );282 DeclarationNode * copyAttribute( DeclarationNode * attr );283 DeclarationNode * addPointer( DeclarationNode * qualifiers );284 DeclarationNode * addArray( DeclarationNode * array );285 DeclarationNode * addNewPointer( DeclarationNode * pointer );286 DeclarationNode * addNewArray( DeclarationNode * array );287 DeclarationNode * addParamList( DeclarationNode * list );288 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions289 DeclarationNode * addInitializer( InitializerNode * init );290 DeclarationNode * addTypeInitializer( DeclarationNode * init );291 292 DeclarationNode * cloneType( std::string * newName );293 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );294 295 DeclarationNode * appendList( DeclarationNode * node ) {296 return (DeclarationNode *)set_last( node );297 }298 299 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;300 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;301 302 Declaration * build() const;303 Type * buildType() const;304 305 LinkageSpec::Spec get_linkage() const { return linkage; }306 DeclarationNode * extractAggregate() const;307 bool has_enumeratorValue() const { return (bool)enumeratorValue; }308 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }309 310 bool get_extension() const { return extension; }311 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }312 313 bool get_inLine() const { return inLine; }314 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }315 316 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }317 318 struct Variable_t {319 // const std::string * name;320 TypeDecl::Kind tyClass;321 DeclarationNode * assertions;322 DeclarationNode * initializer;323 };324 Variable_t variable;325 326 struct Attr_t {327 // const std::string * name;328 ExpressionNode * expr;329 DeclarationNode * type;330 };331 Attr_t attr;332 333 struct StaticAssert_t {334 ExpressionNode * condition;335 Expression * message;336 };337 StaticAssert_t assert;338 339 BuiltinType builtin = NoBuiltinType;340 341 TypeData * type = nullptr;342 343 bool inLine = false;344 bool enumInLine = false;345 Type::FuncSpecifiers funcSpecs;346 Type::StorageClasses storageClasses;347 348 ExpressionNode * bitfieldWidth = nullptr;349 std::unique_ptr<ExpressionNode> enumeratorValue;350 bool hasEllipsis = false;351 LinkageSpec::Spec linkage;352 Expression * asmName = nullptr;353 std::list< Attribute * > attributes;354 InitializerNode * initializer = nullptr;355 bool extension = false;356 std::string error;357 StatementNode * asmStmt = nullptr;358 StatementNode * directiveStmt = nullptr;359 360 static UniqueName anonymous;361 }; // DeclarationNode362 363 Type * buildType( TypeData * type );364 365 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {366 Type * ret = orig ? orig->buildType() : nullptr;367 delete orig;368 return ret;369 }370 371 //##############################################################################372 373 struct StatementNode final : public ParseNode {374 StatementNode() { stmt = nullptr; }375 StatementNode( Statement * stmt ) : stmt( stmt ) {}376 StatementNode( DeclarationNode * decl );377 virtual ~StatementNode() {}378 379 virtual StatementNode * clone() const final { assert( false ); return nullptr; }380 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }381 382 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {383 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );384 delete attr;385 delete name;386 return this;387 }388 389 virtual StatementNode * append_last_case( StatementNode * );390 391 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {392 os << stmt.get() << std::endl;393 }394 395 std::unique_ptr<Statement> stmt;396 }; // StatementNode397 398 Statement * build_expr( ExpressionNode * ctl );399 400 struct CondCtl {401 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :402 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}403 404 StatementNode * init;405 ExpressionNode * condition;406 };407 408 struct ForCtrl {409 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :410 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}411 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :412 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}413 414 StatementNode * init;415 ExpressionNode * condition;416 ExpressionNode * change;417 };418 419 Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );420 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );421 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );422 Statement * build_case( ExpressionNode * ctl );423 Statement * build_default();424 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );425 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );426 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );427 Statement * build_branch( BranchStmt::Type kind );428 Statement * build_branch( std::string * identifier, BranchStmt::Type kind );429 Statement * build_computedgoto( ExpressionNode * ctl );430 Statement * build_return( ExpressionNode * ctl );431 Statement * build_throw( ExpressionNode * ctl );432 Statement * build_resume( ExpressionNode * ctl );433 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );434 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );435 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );436 Statement * build_finally( StatementNode * stmt );437 Statement * build_compound( StatementNode * first );438 StatementNode * maybe_build_compound( StatementNode * first );439 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );440 Statement * build_directive( std::string * directive );441 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);442 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );443 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );444 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );445 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );446 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );447 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );448 449 //##############################################################################450 451 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >452 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {453 SemanticErrorException errors;454 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );455 const NodeType * cur = firstNode;456 457 while ( cur ) {458 try {459 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );460 if ( result ) {461 result->location = cur->location;462 * out++ = result;463 } else {464 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );465 } // if466 } catch( SemanticErrorException & e ) {467 errors.append( e );468 } // try469 const ParseNode * temp = (cur->get_next());470 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr471 if ( ! cur && temp ) { // non-homogeneous nodes ?472 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );473 } // if474 } // while475 if ( ! errors.isEmpty() ) {476 throw errors;477 } // if478 }479 480 // in DeclarationNode.cc481 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );482 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );483 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );484 485 template< typename SynTreeType, typename NodeType >486 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {487 buildList( firstNode, outputList );488 delete firstNode;489 }490 491 // in ParseNode.cc492 101 std::ostream & operator<<( std::ostream & out, const ParseNode * node ); 493 102 -
src/Parser/ParserTypes.h
r34b4268 r24d6572 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // parser.hh -- 8 // 6 // 7 // parser.hh -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 22 08:58:10 2001 -
src/Parser/StatementNode.cc
r34b4268 r24d6572 10 10 // Author : Rodolfo G. Esteves 11 11 // Created On : Sat May 16 14:59:41 2015 12 // Last Modified By : Peter A. Buhr13 // Last Modified On : Wed Feb 2 20:29:30 202214 // Update Count : 42 512 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 11 10:16:00 2023 14 // Update Count : 428 15 15 // 16 16 17 #include "StatementNode.h" 18 17 19 #include <cassert> // for assert, strict_dynamic_cast, assertf 18 #include <list> // for list19 20 #include <memory> // for unique_ptr 20 21 #include <string> // for string 21 22 23 #include "AST/Label.hpp" // for Label 24 #include "AST/Stmt.hpp" // for Stmt, AsmStmt, BranchStmt, CaseCla... 22 25 #include "Common/SemanticError.h" // for SemanticError 23 26 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 24 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 25 #include "SynTree/Expression.h" // for Expression, ConstantExpr 26 #include "SynTree/Label.h" // for Label, noLabels 27 #include "SynTree/Declaration.h" 28 #include "SynTree/Statement.h" // for Statement, BranchStmt, CaseStmt 27 #include "DeclarationNode.h" // for DeclarationNode 28 #include "ExpressionNode.h" // for ExpressionNode 29 29 #include "parserutility.h" // for notZeroExpr 30 30 … … 33 33 using namespace std; 34 34 35 // Some helpers for cases that really want a single node but check for lists. 36 static const ast::Stmt * buildMoveSingle( StatementNode * node ) { 37 std::vector<ast::ptr<ast::Stmt>> list; 38 buildMoveList( node, list ); 39 assertf( list.size() == 1, "CFA Internal Error: Extra/Missing Nodes" ); 40 return list.front().release(); 41 } 42 43 static const ast::Stmt * buildMoveOptional( StatementNode * node ) { 44 std::vector<ast::ptr<ast::Stmt>> list; 45 buildMoveList( node, list ); 46 assertf( list.size() <= 1, "CFA Internal Error: Extra Nodes" ); 47 return list.empty() ? nullptr : list.front().release(); 48 } 35 49 36 50 StatementNode::StatementNode( DeclarationNode * decl ) { … … 38 52 DeclarationNode * agg = decl->extractAggregate(); 39 53 if ( agg ) { 40 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild< Declaration >( decl ) ) ); 54 StatementNode * nextStmt = new StatementNode( 55 new ast::DeclStmt( decl->location, maybeBuild( decl ) ) ); 41 56 set_next( nextStmt ); 42 57 if ( decl->get_next() ) { … … 51 66 agg = decl; 52 67 } // if 53 stmt.reset( new DeclStmt( maybeMoveBuild< Declaration >(agg) ) ); 68 // Local copy to avoid accessing the pointer after it is moved from. 69 CodeLocation declLocation = agg->location; 70 stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) ); 54 71 } // StatementNode::StatementNode 55 72 56 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) { 57 StatementNode * prev = this; 73 StatementNode * StatementNode::add_label( 74 const CodeLocation & location, 75 const std::string * name, 76 DeclarationNode * attr ) { 77 stmt->labels.emplace_back( location, 78 *name, 79 attr ? std::move( attr->attributes ) 80 : std::vector<ast::ptr<ast::Attribute>>{} ); 81 delete attr; 82 delete name; 83 return this; 84 } 85 86 ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) { 87 ClauseNode * prev = this; 58 88 // find end of list and maintain previous pointer 59 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {60 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);61 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );89 for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next() ) { 90 ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr); 91 assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) ); 62 92 prev = curr; 63 93 } // for 94 ClauseNode * node = dynamic_cast< ClauseNode * >(prev); 64 95 // convert from StatementNode list to Statement list 65 StatementNode * node = dynamic_cast< StatementNode * >(prev); 66 list< Statement * > stmts; 96 std::vector<ast::ptr<ast::Stmt>> stmts; 67 97 buildMoveList( stmt, stmts ); 68 98 // splice any new Statements to end of current Statements 69 CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get()); 70 caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts ); 99 auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() ); 100 for ( auto const & newStmt : stmts ) { 101 caseStmt->stmts.emplace_back( newStmt ); 102 } 103 stmts.clear(); 71 104 return this; 72 } // StatementNode::append_last_case 73 74 Statement * build_expr( ExpressionNode * ctl ) { 75 Expression * e = maybeMoveBuild< Expression >( ctl ); 76 77 if ( e ) return new ExprStmt( e ); 78 else return new NullStmt(); 105 } // ClauseNode::append_last_case 106 107 ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) { 108 if ( ast::Expr * e = maybeMoveBuild( ctl ) ) { 109 return new ast::ExprStmt( location, e ); 110 } else { 111 return new ast::NullStmt( location ); 112 } 79 113 } // build_expr 80 114 81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) { 82 if ( ctl->init != 0 ) { 83 buildMoveList( ctl->init, init ); 115 static ast::Expr * build_if_control( CondCtl * ctl, 116 std::vector<ast::ptr<ast::Stmt>> & inits ) { 117 assert( inits.empty() ); 118 if ( nullptr != ctl->init ) { 119 buildMoveList( ctl->init, inits ); 84 120 } // if 85 121 86 Expression* cond = nullptr;122 ast::Expr * cond = nullptr; 87 123 if ( ctl->condition ) { 88 124 // compare the provided condition against 0 89 cond = notZeroExpr( maybeMoveBuild < Expression >(ctl->condition) );125 cond = notZeroExpr( maybeMoveBuild( ctl->condition ) ); 90 126 } else { 91 for ( Statement * stmt : init) {127 for ( ast::ptr<ast::Stmt> & stmt : inits ) { 92 128 // build the && of all of the declared variables compared against 0 93 DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt);94 DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl);95 Expression * nze = notZeroExpr( new VariableExpr(dwt ) );96 cond = cond ? new LogicalExpr( cond, nze, true) : nze;129 auto declStmt = stmt.strict_as<ast::DeclStmt>(); 130 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>(); 131 ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) ); 132 cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze; 97 133 } 98 134 } … … 101 137 } // build_if_control 102 138 103 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 104 list< Statement * > astinit; // maybe empty 105 Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 106 107 Statement * astthen, * astelse = nullptr; 108 list< Statement * > aststmt; 109 buildMoveList< Statement, StatementNode >( then, aststmt ); 110 assert( aststmt.size() == 1 ); 111 astthen = aststmt.front(); 112 113 if ( else_ ) { 114 list< Statement * > aststmt; 115 buildMoveList< Statement, StatementNode >( else_, aststmt ); 116 assert( aststmt.size() == 1 ); 117 astelse = aststmt.front(); 118 } // if 119 120 return new IfStmt( astcond, astthen, astelse, astinit ); 139 ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 140 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 141 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 142 143 ast::Stmt const * astthen = buildMoveSingle( then ); 144 ast::Stmt const * astelse = buildMoveOptional( else_ ); 145 146 return new ast::IfStmt( location, astcond, astthen, astelse, 147 std::move( astinit ) 148 ); 121 149 } // build_if 122 150 123 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { 124 list< Statement * > aststmt; 125 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 126 if ( ! isSwitch ) { // choose statement 127 for ( Statement * stmt : aststmt ) { 128 CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt ); 129 if ( ! caseStmt->stmts.empty() ) { // code after "case" => end of case list 130 CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() ); 131 block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) ); 151 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) { 152 std::vector<ast::ptr<ast::CaseClause>> aststmt; 153 buildMoveList( stmt, aststmt ); 154 // If it is not a switch it is a choose statement. 155 if ( ! isSwitch ) { 156 for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) { 157 // Code after "case" is the end of case list. 158 if ( !stmt->stmts.empty() ) { 159 auto mutStmt = ast::mutate( stmt.get() ); 160 // I believe the stmts are actually always one block. 161 auto stmts = mutStmt->stmts.front().get_and_mutate(); 162 auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts ); 163 block->kids.push_back( new ast::BranchStmt( block->location, 164 ast::BranchStmt::Break, 165 ast::Label( block->location ) ) ); 166 stmt = mutStmt; 132 167 } // if 133 168 } // for 134 169 } // if 135 170 // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements 136 return new SwitchStmt( maybeMoveBuild< Expression >(ctl), aststmt ); 171 return new ast::SwitchStmt( location, 172 maybeMoveBuild( ctl ), std::move( aststmt ) ); 137 173 } // build_switch 138 174 139 Statement * build_case( ExpressionNode * ctl ) { 140 return new CaseStmt( maybeMoveBuild< Expression >(ctl), {} ); // stmt starts empty and then added to 175 ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) { 176 // stmt starts empty and then added to 177 auto expr = maybeMoveBuild( ctl ); 178 return new ast::CaseClause( location, expr, {} ); 141 179 } // build_case 142 180 143 Statement * build_default() { 144 return new CaseStmt( nullptr, {}, true ); // stmt starts empty and then added to 181 ast::CaseClause * build_default( const CodeLocation & location ) { 182 // stmt starts empty and then added to 183 return new ast::CaseClause( location, nullptr, {} ); 145 184 } // build_default 146 185 147 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) { 148 list< Statement * > astinit; // maybe empty 149 Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 150 151 list< Statement * > aststmt; // loop body, compound created if empty 152 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 153 assert( aststmt.size() == 1 ); 154 155 list< Statement * > astelse; // else clause, maybe empty 156 buildMoveList< Statement, StatementNode >( else_, astelse ); 157 158 return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false ); 186 ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) { 187 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 188 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 189 190 return new ast::WhileDoStmt( location, 191 astcond, 192 buildMoveSingle( stmt ), 193 buildMoveOptional( else_ ), 194 std::move( astinit ), 195 ast::While 196 ); 159 197 } // build_while 160 198 161 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 162 list< Statement * > aststmt; // loop body, compound created if empty 163 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 164 assert( aststmt.size() == 1 ); // compound created if empty 165 166 list< Statement * > astelse; // else clause, maybe empty 167 buildMoveList< Statement, StatementNode >( else_, astelse ); 168 199 ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 169 200 // do-while cannot have declarations in the contitional, so init is always empty 170 return new WhileDoStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), aststmt.front(), astelse.front(), {}, true ); 201 return new ast::WhileDoStmt( location, 202 notZeroExpr( maybeMoveBuild( ctl ) ), 203 buildMoveSingle( stmt ), 204 buildMoveOptional( else_ ), 205 {}, 206 ast::DoWhile 207 ); 171 208 } // build_do_while 172 209 173 Statement * build_for(ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {174 list< Statement *> astinit; // maybe empty210 ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) { 211 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 175 212 buildMoveList( forctl->init, astinit ); 176 213 177 Expression* astcond = nullptr; // maybe empty178 astcond = notZeroExpr( maybeMoveBuild < Expression >(forctl->condition) );179 180 Expression* astincr = nullptr; // maybe empty181 astincr = maybeMoveBuild < Expression >(forctl->change);214 ast::Expr * astcond = nullptr; // maybe empty 215 astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) ); 216 217 ast::Expr * astincr = nullptr; // maybe empty 218 astincr = maybeMoveBuild( forctl->change ); 182 219 delete forctl; 183 220 184 list< Statement * > aststmt; // loop body, compound created if empty 185 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 186 assert( aststmt.size() == 1 ); 187 188 list< Statement * > astelse; // else clause, maybe empty 189 buildMoveList< Statement, StatementNode >( else_, astelse ); 190 191 return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() ); 221 return new ast::ForStmt( location, 222 std::move( astinit ), 223 astcond, 224 astincr, 225 buildMoveSingle( stmt ), 226 buildMoveOptional( else_ ) 227 ); 192 228 } // build_for 193 229 194 Statement * build_branch( BranchStmt::Type kind ) { 195 Statement * ret = new BranchStmt( "", kind ); 196 return ret; 230 ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) { 231 return new ast::BranchStmt( location, 232 kind, 233 ast::Label( location ) 234 ); 197 235 } // build_branch 198 236 199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) { 200 Statement * ret = new BranchStmt( * identifier, kind ); 237 ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) { 238 ast::Stmt * ret = new ast::BranchStmt( location, 239 kind, 240 ast::Label( location, *identifier ) 241 ); 201 242 delete identifier; // allocated by lexer 202 243 return ret; 203 244 } // build_branch 204 245 205 Statement * build_computedgoto( ExpressionNode * ctl ) { 206 return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto ); 246 ast::Stmt * build_computedgoto( ExpressionNode * ctl ) { 247 ast::Expr * expr = maybeMoveBuild( ctl ); 248 return new ast::BranchStmt( expr->location, expr ); 207 249 } // build_computedgoto 208 250 209 Statement * build_return(ExpressionNode * ctl ) {210 list< Expression *> exps;251 ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) { 252 std::vector<ast::ptr<ast::Expr>> exps; 211 253 buildMoveList( ctl, exps ); 212 return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr ); 254 return new ast::ReturnStmt( location, 255 exps.size() > 0 ? exps.back().release() : nullptr 256 ); 213 257 } // build_return 214 258 215 Statement * build_throw( ExpressionNode * ctl ) { 216 list< Expression * > exps; 259 static ast::Stmt * build_throw_stmt( 260 const CodeLocation & location, 261 ExpressionNode * ctl, 262 ast::ExceptionKind kind ) { 263 std::vector<ast::ptr<ast::Expr>> exps; 217 264 buildMoveList( ctl, exps ); 218 265 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 219 return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 266 return new ast::ThrowStmt( location, 267 kind, 268 !exps.empty() ? exps.back().release() : nullptr, 269 (ast::Expr *)nullptr 270 ); 271 } 272 273 ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) { 274 return build_throw_stmt( loc, ctl, ast::Terminate ); 220 275 } // build_throw 221 276 222 Statement * build_resume( ExpressionNode * ctl ) { 223 list< Expression * > exps; 224 buildMoveList( ctl, exps ); 225 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 226 return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 277 ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) { 278 return build_throw_stmt( loc, ctl, ast::Resume ); 227 279 } // build_resume 228 280 229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {281 ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) { 230 282 (void)ctl; 231 283 (void)target; … … 233 285 } // build_resume_at 234 286 235 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) { 236 list< CatchStmt * > aststmt; 237 buildMoveList< CatchStmt, StatementNode >( catch_, aststmt ); 238 CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_)); 239 FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_) ); 240 return new TryStmt( tryBlock, aststmt, finallyBlock ); 287 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) { 288 std::vector<ast::ptr<ast::CatchClause>> aststmt; 289 buildMoveList( catch_, aststmt ); 290 ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) ); 291 ast::FinallyClause * finallyBlock = nullptr; 292 if ( finally_ ) { 293 finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() ); 294 } 295 return new ast::TryStmt( location, 296 tryBlock, 297 std::move( aststmt ), 298 finallyBlock 299 ); 241 300 } // build_try 242 301 243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 244 list< Statement * > aststmt; 245 buildMoveList< Statement, StatementNode >( body, aststmt ); 246 assert( aststmt.size() == 1 ); 247 return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), aststmt.front() ); 302 ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 303 return new ast::CatchClause( location, 304 kind, 305 maybeMoveBuild( decl ), 306 maybeMoveBuild( cond ), 307 buildMoveSingle( body ) 308 ); 248 309 } // build_catch 249 310 250 Statement * build_finally( StatementNode * stmt ) { 251 list< Statement * > aststmt; 252 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 253 assert( aststmt.size() == 1 ); 254 return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) ); 311 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 312 return new ast::FinallyClause( location, 313 strict_dynamic_cast<const ast::CompoundStmt *>( 314 buildMoveSingle( stmt ) 315 ) 316 ); 255 317 } // build_finally 256 318 257 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) { 258 auto node = new SuspendStmt(); 259 260 node->type = type; 261 262 list< Statement * > stmts; 263 buildMoveList< Statement, StatementNode >( then, stmts ); 264 if(!stmts.empty()) { 265 assert( stmts.size() == 1 ); 266 node->then = dynamic_cast< CompoundStmt * >( stmts.front() ); 267 } 268 269 return node; 270 } 271 272 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) { 273 auto node = new WaitForStmt(); 274 275 WaitForStmt::Target target; 276 target.function = maybeBuild<Expression>( targetExpr ); 319 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) { 320 return new ast::SuspendStmt( location, 321 strict_dynamic_cast<const ast::CompoundStmt *, nullptr>( 322 buildMoveOptional( then ) 323 ), 324 kind 325 ); 326 } // build_suspend 327 328 ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 329 auto clause = new ast::WaitForClause( location ); 330 clause->target = maybeBuild( targetExpr ); 331 clause->stmt = maybeMoveBuild( stmt ); 332 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 277 333 278 334 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 279 335 targetExpr->set_next( nullptr ); 280 buildMoveList < Expression >( next, target.arguments );336 buildMoveList( next, clause->target_args ); 281 337 282 338 delete targetExpr; 283 339 284 node->clauses.push_back( WaitForStmt::Clause{ 285 target, 286 maybeMoveBuild<Statement >( stmt ), 287 notZeroExpr( maybeMoveBuild<Expression>( when ) ) 288 }); 289 290 return node; 340 existing->clauses.insert( existing->clauses.begin(), clause ); 341 342 return existing; 291 343 } // build_waitfor 292 344 293 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) { 294 WaitForStmt::Target target; 295 target.function = maybeBuild<Expression>( targetExpr ); 296 297 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 298 targetExpr->set_next( nullptr ); 299 buildMoveList< Expression >( next, target.arguments ); 300 301 delete targetExpr; 302 303 node->clauses.insert( node->clauses.begin(), WaitForStmt::Clause{ 304 std::move( target ), 305 maybeMoveBuild<Statement >( stmt ), 306 notZeroExpr( maybeMoveBuild<Expression>( when ) ) 307 }); 308 309 return node; 310 } // build_waitfor 311 312 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) { 313 auto node = new WaitForStmt(); 314 315 if( timeout ) { 316 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 317 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 318 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 319 } else { 320 node->orelse.statement = maybeMoveBuild<Statement >( stmt ); 321 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 322 } // if 323 324 return node; 345 ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 346 existing->else_stmt = maybeMoveBuild( stmt ); 347 existing->else_cond = notZeroExpr( maybeMoveBuild( when ) ); 348 349 (void)location; 350 return existing; 351 } // build_waitfor_else 352 353 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 354 existing->timeout_time = maybeMoveBuild( timeout ); 355 existing->timeout_stmt = maybeMoveBuild( stmt ); 356 existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) ); 357 358 (void)location; 359 return existing; 325 360 } // build_waitfor_timeout 326 361 327 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_, ExpressionNode * else_when ) { 328 auto node = new WaitForStmt(); 329 330 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 331 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 332 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 333 334 node->orelse.statement = maybeMoveBuild<Statement >( else_ ); 335 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( else_when ) ); 336 337 return node; 338 } // build_waitfor_timeout 339 340 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 341 list< Expression * > e; 362 ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 363 ast::WhenClause * clause = new ast::WhenClause( loc ); 364 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 365 clause->stmt = maybeMoveBuild( stmt ); 366 clause->target = maybeMoveBuild( targetExpr ); 367 return new ast::WaitUntilStmt::ClauseNode( clause ); 368 } 369 ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) { 370 ast::WhenClause * clause = new ast::WhenClause( loc ); 371 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 372 clause->stmt = maybeMoveBuild( stmt ); 373 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause ); 374 } 375 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 376 ast::WhenClause * clause = new ast::WhenClause( loc ); 377 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 378 clause->stmt = maybeMoveBuild( stmt ); 379 clause->target = maybeMoveBuild( timeout ); 380 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause ); 381 } 382 383 ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) { 384 ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc ); 385 retStmt->predicateTree = root; 386 387 // iterative tree traversal 388 std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal 389 ast::WaitUntilStmt::ClauseNode * currNode = nullptr; 390 ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr; 391 ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout 392 nodeStack.push_back(root); 393 394 do { 395 currNode = nodeStack.back(); 396 nodeStack.pop_back(); // remove node since it will be processed 397 398 switch (currNode->op) { 399 case ast::WaitUntilStmt::ClauseNode::LEAF: 400 retStmt->clauses.push_back(currNode->leaf); 401 break; 402 case ast::WaitUntilStmt::ClauseNode::ELSE: 403 retStmt->else_stmt = currNode->leaf->stmt 404 ? ast::deepCopy( currNode->leaf->stmt ) 405 : nullptr; 406 407 retStmt->else_cond = currNode->leaf->when_cond 408 ? ast::deepCopy( currNode->leaf->when_cond ) 409 : nullptr; 410 411 delete currNode->leaf; 412 break; 413 case ast::WaitUntilStmt::ClauseNode::TIMEOUT: 414 retStmt->timeout_time = currNode->leaf->target 415 ? ast::deepCopy( currNode->leaf->target ) 416 : nullptr; 417 retStmt->timeout_stmt = currNode->leaf->stmt 418 ? ast::deepCopy( currNode->leaf->stmt ) 419 : nullptr; 420 retStmt->timeout_cond = currNode->leaf->when_cond 421 ? ast::deepCopy( currNode->leaf->when_cond ) 422 : nullptr; 423 424 delete currNode->leaf; 425 break; 426 default: 427 nodeStack.push_back( currNode->right ); // process right after left 428 nodeStack.push_back( currNode->left ); 429 430 // Cut else/timeout out of the tree 431 if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) { 432 if ( lastInternalNode ) 433 lastInternalNode->right = currNode->left; 434 else // if not set then root is LEFT_OR 435 retStmt->predicateTree = currNode->left; 436 437 currNode->left = nullptr; 438 cleanup = currNode; 439 } 440 441 lastInternalNode = currNode; 442 break; 443 } 444 } while ( !nodeStack.empty() ); 445 446 if ( cleanup ) delete cleanup; 447 448 return retStmt; 449 } 450 451 ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 452 std::vector<ast::ptr<ast::Expr>> e; 342 453 buildMoveList( exprs, e ); 343 Statement * s = maybeMoveBuild<Statement>( stmt );344 return new DeclStmt( new WithStmt( e, s ) );454 ast::Stmt * s = maybeMoveBuild( stmt ); 455 return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) ); 345 456 } // build_with 346 457 347 Statement * build_compound(StatementNode * first ) {348 CompoundStmt * cs = new CompoundStmt();349 buildMoveList( first, cs-> get_kids());458 ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) { 459 auto cs = new ast::CompoundStmt( location ); 460 buildMoveList( first, cs->kids ); 350 461 return cs; 351 462 } // build_compound … … 355 466 // statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a 356 467 // conical form for code generation. 357 StatementNode * maybe_build_compound( StatementNode * first ) {468 StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) { 358 469 // Optimization: if the control-structure statement is a compound statement, do not wrap it. 359 470 // e.g., if (...) {...} do not wrap the existing compound statement. 360 if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 361 CompoundStmt * cs = new CompoundStmt(); 362 buildMoveList( first, cs->get_kids() ); 363 return new StatementNode( cs ); 471 if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 472 return new StatementNode( build_compound( location, first ) ); 364 473 } // if 365 474 return first; … … 367 476 368 477 // Question 369 Statement * build_asm( bool voltile, Expression* instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {370 list< Expression *> out, in;371 list< ConstantExpr *> clob;478 ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { 479 std::vector<ast::ptr<ast::Expr>> out, in; 480 std::vector<ast::ptr<ast::ConstantExpr>> clob; 372 481 373 482 buildMoveList( output, out ); 374 483 buildMoveList( input, in ); 375 484 buildMoveList( clobber, clob ); 376 return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 485 return new ast::AsmStmt( location, 486 is_volatile, 487 maybeMoveBuild( instruction ), 488 std::move( out ), 489 std::move( in ), 490 std::move( clob ), 491 gotolabels ? gotolabels->labels : std::vector<ast::Label>() 492 ); 377 493 } // build_asm 378 494 379 Statement * build_directive( string * directive ) { 380 return new DirectiveStmt( *directive ); 495 ast::Stmt * build_directive( const CodeLocation & location, string * directive ) { 496 auto stmt = new ast::DirectiveStmt( location, *directive ); 497 delete directive; 498 return stmt; 381 499 } // build_directive 382 500 383 Statement * build_mutex(ExpressionNode * exprs, StatementNode * stmt ) {384 list< Expression *> expList;501 ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 502 std::vector<ast::ptr<ast::Expr>> expList; 385 503 buildMoveList( exprs, expList ); 386 Statement * body = maybeMoveBuild<Statement>( stmt );387 return new MutexStmt( body, expList);504 ast::Stmt * body = maybeMoveBuild( stmt ); 505 return new ast::MutexStmt( location, body, std::move( expList ) ); 388 506 } // build_mutex 389 507 -
src/Parser/TypeData.cc
r34b4268 r24d6572 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:12:51 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue May 10 22:36:52 202213 // Update Count : 6 7711 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 13:39:00 2023 13 // Update Count : 680 14 14 // 15 16 #include "TypeData.h" 15 17 16 18 #include <cassert> // for assert 17 19 #include <ostream> // for operator<<, ostream, basic_ostream 18 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 19 24 #include "Common/SemanticError.h" // for SemanticError 20 #include "Common/utility.h" // for maybeClone, maybeBuild, maybeMoveB... 21 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 22 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, FunctionDecl 23 #include "SynTree/Expression.h" // for Expression, ConstantExpr (ptr only) 24 #include "SynTree/Initializer.h" // for SingleInit, Initializer (ptr only) 25 #include "SynTree/Statement.h" // for CompoundStmt, Statement 26 #include "SynTree/Type.h" // for BasicType, Type, Type::ForallList 27 #include "TypeData.h" 25 #include "Common/utility.h" // for splice, spliceBegin 26 #include "Parser/ExpressionNode.h" // for ExpressionNode 27 #include "Parser/StatementNode.h" // for StatementNode 28 28 29 29 class Attribute; … … 33 33 TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ { 34 34 switch ( kind ) { 35 case Unknown: 36 case Pointer: 37 case Reference: 38 case EnumConstant: 39 case GlobalScope: 40 // nothing else to initialize 41 break; 42 case Basic: 43 // basic = new Basic_t; 44 break; 45 case Array: 46 // array = new Array_t; 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: 47 44 array.dimension = nullptr; 48 45 array.isVarLen = false; 49 46 array.isStatic = false; 50 47 break; 51 case Function: 52 // function = new Function_t; 48 case Function: 53 49 function.params = nullptr; 54 50 function.idList = nullptr; … … 57 53 function.withExprs = nullptr; 58 54 break; 59 // Enum is an Aggregate, so both structures are initialized together. 60 case Enum: 61 // enumeration = new Enumeration_t; 55 case Enum: 62 56 enumeration.name = nullptr; 63 57 enumeration.constants = nullptr; … … 65 59 enumeration.anon = false; 66 60 break; 67 case Aggregate: 68 // aggregate = new Aggregate_t; 69 aggregate.kind = AggregateDecl::NoAggregate; 61 case Aggregate: 62 aggregate.kind = ast::AggregateDecl::NoAggregate; 70 63 aggregate.name = nullptr; 71 64 aggregate.params = nullptr; … … 77 70 aggregate.anon = false; 78 71 break; 79 case AggregateInst: 80 // aggInst = new AggInst_t; 72 case AggregateInst: 81 73 aggInst.aggregate = nullptr; 82 74 aggInst.params = nullptr; 83 75 aggInst.hoistType = false; 84 76 break; 85 case Symbolic: 86 case SymbolicInst: 87 // symbolic = new Symbolic_t; 77 case Symbolic: 78 case SymbolicInst: 88 79 symbolic.name = nullptr; 89 80 symbolic.params = nullptr; … … 91 82 symbolic.assertions = nullptr; 92 83 break; 93 case Tuple: 94 // tuple = new Tuple_t; 84 case Tuple: 95 85 tuple = nullptr; 96 86 break; 97 case Typeof: 98 case Basetypeof: 99 // typeexpr = new Typeof_t; 87 case Typeof: 88 case Basetypeof: 100 89 typeexpr = nullptr; 101 90 break; 102 103 break;104 case Builtin:105 // builtin = new Builtin_t;106 91 case Vtable: 92 case Builtin: 93 // No unique data to initialize. 94 break; 95 case Qualified: 107 96 qualified.parent = nullptr; 108 97 qualified.child = nullptr; … … 117 106 118 107 switch ( kind ) { 119 case Unknown: 120 case Pointer: 121 case Reference: 122 case EnumConstant: 123 case GlobalScope: 124 // nothing to destroy 125 break; 126 case Basic: 127 // delete basic; 128 break; 129 case Array: 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: 130 117 delete array.dimension; 131 // delete array; 132 break; 133 case Function: 118 break; 119 case Function: 134 120 delete function.params; 135 121 delete function.idList; … … 137 123 delete function.body; 138 124 delete function.withExprs; 139 // delete function; 140 break; 141 case Aggregate: 125 break; 126 case Aggregate: 142 127 delete aggregate.name; 143 128 delete aggregate.params; 144 129 delete aggregate.actuals; 145 130 delete aggregate.fields; 146 // delete aggregate; 147 break; 148 case AggregateInst: 131 break; 132 case AggregateInst: 149 133 delete aggInst.aggregate; 150 134 delete aggInst.params; 151 // delete aggInst; 152 break; 153 case Enum: 135 break; 136 case Enum: 154 137 delete enumeration.name; 155 138 delete enumeration.constants; 156 // delete enumeration; 157 break; 158 case Symbolic: 159 case SymbolicInst: 139 break; 140 case Symbolic: 141 case SymbolicInst: 160 142 delete symbolic.name; 161 143 delete symbolic.params; 162 144 delete symbolic.actuals; 163 145 delete symbolic.assertions; 164 // delete symbolic; 165 break; 166 case Tuple: 167 // delete tuple->members; 146 break; 147 case Tuple: 168 148 delete tuple; 169 149 break; 170 case Typeof: 171 case Basetypeof: 172 // delete typeexpr->expr; 150 case Typeof: 151 case Basetypeof: 173 152 delete typeexpr; 174 153 break; 175 case Vtable: 176 break; 177 case Builtin: 178 // delete builtin; 179 break; 180 case Qualified: 154 case Vtable: 155 case Builtin: 156 // No unique data to deconstruct. 157 break; 158 case Qualified: 181 159 delete qualified.parent; 182 160 delete qualified.child; 161 break; 183 162 } // switch 184 163 } // TypeData::~TypeData … … 192 171 193 172 switch ( kind ) { 194 195 196 197 198 173 case Unknown: 174 case EnumConstant: 175 case Pointer: 176 case Reference: 177 case GlobalScope: 199 178 // nothing else to copy 200 179 break; 201 180 case Basic: 202 181 newtype->basictype = basictype; 203 182 newtype->complextype = complextype; … … 205 184 newtype->length = length; 206 185 break; 207 186 case Array: 208 187 newtype->array.dimension = maybeClone( array.dimension ); 209 188 newtype->array.isVarLen = array.isVarLen; 210 189 newtype->array.isStatic = array.isStatic; 211 190 break; 212 191 case Function: 213 192 newtype->function.params = maybeClone( function.params ); 214 193 newtype->function.idList = maybeClone( function.idList ); … … 217 196 newtype->function.withExprs = maybeClone( function.withExprs ); 218 197 break; 219 198 case Aggregate: 220 199 newtype->aggregate.kind = aggregate.kind; 221 200 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr; … … 228 207 newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr; 229 208 break; 230 209 case AggregateInst: 231 210 newtype->aggInst.aggregate = maybeClone( aggInst.aggregate ); 232 211 newtype->aggInst.params = maybeClone( aggInst.params ); 233 212 newtype->aggInst.hoistType = aggInst.hoistType; 234 213 break; 235 214 case Enum: 236 215 newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr; 237 216 newtype->enumeration.constants = maybeClone( enumeration.constants ); … … 239 218 newtype->enumeration.anon = enumeration.anon; 240 219 break; 241 242 220 case Symbolic: 221 case SymbolicInst: 243 222 newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr; 244 223 newtype->symbolic.params = maybeClone( symbolic.params ); … … 247 226 newtype->symbolic.isTypedef = symbolic.isTypedef; 248 227 break; 249 228 case Tuple: 250 229 newtype->tuple = maybeClone( tuple ); 251 230 break; 252 253 231 case Typeof: 232 case Basetypeof: 254 233 newtype->typeexpr = maybeClone( typeexpr ); 255 234 break; 256 257 break; 258 235 case Vtable: 236 break; 237 case Builtin: 259 238 assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One ); 260 239 newtype->builtintype = builtintype; 261 240 break; 262 241 case Qualified: 263 242 newtype->qualified.parent = maybeClone( qualified.parent ); 264 243 newtype->qualified.child = maybeClone( qualified.child ); … … 270 249 271 250 void TypeData::print( ostream &os, int indent ) const { 272 for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) { 273 if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' '; 274 } // for 251 ast::print( os, qualifiers ); 275 252 276 253 if ( forall ) { … … 280 257 281 258 switch ( kind ) { 282 259 case Basic: 283 260 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " "; 284 261 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " "; … … 286 263 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 287 264 break; 288 265 case Pointer: 289 266 os << "pointer "; 290 267 if ( base ) { … … 293 270 } // if 294 271 break; 295 272 case Reference: 296 273 os << "reference "; 297 274 if ( base ) { … … 300 277 } // if 301 278 break; 302 279 case Array: 303 280 if ( array.isStatic ) { 304 281 os << "static "; … … 316 293 } // if 317 294 break; 318 295 case Function: 319 296 os << "function" << endl; 320 297 if ( function.params ) { … … 344 321 } // if 345 322 break; 346 347 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;323 case Aggregate: 324 os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl; 348 325 if ( aggregate.params ) { 349 326 os << string( indent + 2, ' ' ) << "with type parameters" << endl; … … 362 339 } // if 363 340 break; 364 341 case AggregateInst: 365 342 if ( aggInst.aggregate ) { 366 343 os << "instance of " ; … … 374 351 } // if 375 352 break; 376 377 os << "enumeration " ;353 case Enum: 354 os << "enumeration " << *enumeration.name << endl;; 378 355 if ( enumeration.constants ) { 379 356 os << "with constants" << endl; … … 388 365 } // if 389 366 break; 390 367 case EnumConstant: 391 368 os << "enumeration constant "; 392 369 break; 393 370 case Symbolic: 394 371 if ( symbolic.isTypedef ) { 395 372 os << "typedef definition "; … … 411 388 } // if 412 389 break; 413 390 case SymbolicInst: 414 391 os << *symbolic.name; 415 392 if ( symbolic.actuals ) { … … 419 396 } // if 420 397 break; 421 398 case Tuple: 422 399 os << "tuple "; 423 400 if ( tuple ) { … … 426 403 } // if 427 404 break; 428 405 case Basetypeof: 429 406 os << "base-"; 430 407 #if defined(__GNUC__) && __GNUC__ >= 7 … … 432 409 #endif 433 410 // FALL THROUGH 434 411 case Typeof: 435 412 os << "type-of expression "; 436 413 if ( typeexpr ) { … … 438 415 } // if 439 416 break; 440 417 case Vtable: 441 418 os << "vtable"; 442 419 break; 443 420 case Builtin: 444 421 os << DeclarationNode::builtinTypeNames[builtintype]; 445 422 break; 446 447 break; 448 423 case GlobalScope: 424 break; 425 case Qualified: 449 426 qualified.parent->print( os ); 450 427 os << "."; 451 428 qualified.child->print( os ); 452 429 break; 453 430 case Unknown: 454 431 os << "entity of unknown type "; 455 432 break; 456 433 default: 457 434 os << "internal error: TypeData::print " << kind << endl; 458 435 assert( false ); … … 462 439 const std::string * TypeData::leafName() const { 463 440 switch ( kind ) { 464 465 466 467 468 469 470 471 472 473 474 475 476 477 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: 478 455 assertf(false, "Tried to get leaf name from kind without a name: %d", kind); 479 456 break; 480 457 case Aggregate: 481 458 return aggregate.name; 482 459 case Enum: 483 460 return enumeration.name; 484 485 461 case Symbolic: 462 case SymbolicInst: 486 463 return symbolic.name; 487 464 case Qualified: 488 465 return qualified.child->leafName(); 489 466 } // switch … … 492 469 493 470 494 template< typename ForallList > 495 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { 496 buildList( firstNode, outputList ); 471 void 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 } 497 483 auto n = firstNode; 498 for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) { 499 TypeDecl * td = static_cast<TypeDecl *>(*i); 500 if ( n->variable.tyClass == TypeDecl::Otype ) { 501 // add assertion parameters to `type' tyvars in reverse order 502 // add dtor: void ^?{}(T *) 503 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false ); 504 dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 505 td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) ); 506 507 // add copy ctor: void ?{}(T *, T) 508 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false ); 509 copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 510 copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 511 td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) ); 512 513 // add default ctor: void ?{}(T *) 514 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false ); 515 ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 516 td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) ); 517 518 // add assignment operator: T * ?=?(T *, T) 519 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false ); 520 assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) ); 521 assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 522 assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 523 td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) ); 524 } // if 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 624 void 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 ); 525 769 } // for 526 770 } // buildForall 527 771 528 772 529 Type * typebuild( const TypeData * td ) {773 ast::Type * typebuild( const TypeData * td ) { 530 774 assert( td ); 531 775 switch ( td->kind ) { 532 776 case TypeData::Unknown: 533 777 // fill in implicit int 534 return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); 535 case TypeData::Basic: 778 return new ast::BasicType( 779 ast::BasicType::SignedInt, 780 buildQualifiers( td ) 781 ); 782 case TypeData::Basic: 536 783 return buildBasicType( td ); 537 784 case TypeData::Pointer: 538 785 return buildPointer( td ); 539 786 case TypeData::Array: 540 787 return buildArray( td ); 541 788 case TypeData::Reference: 542 789 return buildReference( td ); 543 544 return buildFunction ( td );545 790 case TypeData::Function: 791 return buildFunctionType( td ); 792 case TypeData::AggregateInst: 546 793 return buildAggInst( td ); 547 548 return new EnumInstType( buildQualifiers( td ), "");549 794 case TypeData::EnumConstant: 795 return new ast::EnumInstType( "", buildQualifiers( td ) ); 796 case TypeData::SymbolicInst: 550 797 return buildSymbolicInst( td ); 551 798 case TypeData::Tuple: 552 799 return buildTuple( td ); 553 554 800 case TypeData::Typeof: 801 case TypeData::Basetypeof: 555 802 return buildTypeof( td ); 556 803 case TypeData::Vtable: 557 804 return buildVtable( td ); 558 805 case TypeData::Builtin: 559 806 switch ( td->builtintype ) { 560 561 return new ZeroType( noQualifiers);562 563 return new OneType( noQualifiers);564 565 return new VarArgsType( buildQualifiers( td ) );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 ) ); 566 813 } // switch 567 case TypeData::GlobalScope: 568 return new GlobalScopeType(); 569 case TypeData::Qualified: 570 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) ); 571 case TypeData::Symbolic: 572 case TypeData::Enum: 573 case TypeData::Aggregate: 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: 574 825 assert( false ); 575 826 } // switch … … 583 834 584 835 switch ( td->kind ) { 585 836 case TypeData::Aggregate: 586 837 if ( ! toplevel && td->aggregate.body ) { 587 838 ret = td->clone(); 588 839 } // if 589 840 break; 590 841 case TypeData::Enum: 591 842 if ( ! toplevel && td->enumeration.body ) { 592 843 ret = td->clone(); 593 844 } // if 594 845 break; 595 846 case TypeData::AggregateInst: 596 847 if ( td->aggInst.aggregate ) { 597 848 ret = typeextractAggregate( td->aggInst.aggregate, false ); 598 849 } // if 599 850 break; 600 851 default: 601 852 if ( td->base ) { 602 853 ret = typeextractAggregate( td->base, false ); … … 607 858 608 859 609 Type::Qualifiers buildQualifiers( const TypeData * td ) {860 ast::CV::Qualifiers buildQualifiers( const TypeData * td ) { 610 861 return td->qualifiers; 611 862 } // buildQualifiers … … 616 867 } // genTSError 617 868 618 Type * buildBasicType( const TypeData * td ) {619 BasicType::Kind ret;869 ast::Type * buildBasicType( const TypeData * td ) { 870 ast::BasicType::Kind ret; 620 871 621 872 switch ( td->basictype ) { 622 873 case DeclarationNode::Void: 623 874 if ( td->signedness != DeclarationNode::NoSignedness ) { 624 875 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); … … 627 878 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 628 879 } // if 629 return new VoidType( buildQualifiers( td ) );630 break; 631 632 880 return new ast::VoidType( buildQualifiers( td ) ); 881 break; 882 883 case DeclarationNode::Bool: 633 884 if ( td->signedness != DeclarationNode::NoSignedness ) { 634 885 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); … … 638 889 } // if 639 890 640 ret = BasicType::Bool;641 break; 642 643 891 ret = ast::BasicType::Bool; 892 break; 893 894 case DeclarationNode::Char: 644 895 // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the 645 896 // character types. The implementation shall define char to have the same range, representation, and behavior as 646 897 // either signed char or unsigned char. 647 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar,BasicType::Char };898 static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char }; 648 899 649 900 if ( td->length != DeclarationNode::NoLength ) { … … 654 905 break; 655 906 656 657 static BasicType::Kind inttype[2][4] = {658 { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt,BasicType::SignedInt },659 { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt,BasicType::UnsignedInt },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 }, 660 911 }; 661 912 662 913 Integral: ; 663 914 if ( td->signedness == DeclarationNode::NoSignedness ) { 664 915 const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed; … … 667 918 break; 668 919 669 670 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 :BasicType::SignedInt128;920 case DeclarationNode::Int128: 921 ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128; 671 922 if ( td->length != DeclarationNode::NoLength ) { 672 923 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); … … 674 925 break; 675 926 676 677 678 679 680 681 682 683 684 685 686 687 688 static BasicType::Kind floattype[2][12] = {689 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex,BasicType::uFloat128xComplex, },690 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128,BasicType::uFloat128x, },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, }, 691 942 }; 692 943 693 944 FloatingPoint: ; 694 945 if ( td->signedness != DeclarationNode::NoSignedness ) { 695 946 genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype ); … … 715 966 break; 716 967 717 968 case DeclarationNode::NoBasicType: 718 969 // No basic type in declaration => default double for Complex/Imaginary and int type for integral types 719 970 if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) { … … 724 975 const_cast<TypeData *>(td)->basictype = DeclarationNode::Int; 725 976 goto Integral; 726 727 977 default: 978 assertf( false, "unknown basic type" ); 728 979 return nullptr; 729 980 } // switch 730 981 731 BasicType * bt = new BasicType( buildQualifiers( td ), ret ); 732 buildForall( td->forall, bt->get_forall() ); 982 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) ); 733 983 return bt; 734 984 } // buildBasicType 735 985 736 986 737 PointerType * buildPointer( const TypeData * td ) {738 PointerType * pt;987 ast::PointerType * buildPointer( const TypeData * td ) { 988 ast::PointerType * pt; 739 989 if ( td->base ) { 740 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) ); 990 pt = new ast::PointerType( 991 typebuild( td->base ), 992 buildQualifiers( td ) 993 ); 741 994 } else { 742 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 995 pt = new ast::PointerType( 996 new ast::BasicType( ast::BasicType::SignedInt ), 997 buildQualifiers( td ) 998 ); 743 999 } // if 744 buildForall( td->forall, pt->get_forall() );745 1000 return pt; 746 1001 } // buildPointer 747 1002 748 1003 749 ArrayType * buildArray( const TypeData * td ) {750 ArrayType * at;1004 ast::ArrayType * buildArray( const TypeData * td ) { 1005 ast::ArrayType * at; 751 1006 if ( td->base ) { 752 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ), 753 td->array.isVarLen, td->array.isStatic ); 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 ); 754 1014 } else { 755 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 756 maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic ); 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 ); 757 1022 } // if 758 buildForall( td->forall, at->get_forall() );759 1023 return at; 760 1024 } // buildArray 761 1025 762 1026 763 ReferenceType * buildReference( const TypeData * td ) {764 ReferenceType * rt;1027 ast::ReferenceType * buildReference( const TypeData * td ) { 1028 ast::ReferenceType * rt; 765 1029 if ( td->base ) { 766 rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) ); 1030 rt = new ast::ReferenceType( 1031 typebuild( td->base ), 1032 buildQualifiers( td ) 1033 ); 767 1034 } else { 768 rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 1035 rt = new ast::ReferenceType( 1036 new ast::BasicType( ast::BasicType::SignedInt ), 1037 buildQualifiers( td ) 1038 ); 769 1039 } // if 770 buildForall( td->forall, rt->get_forall() );771 1040 return rt; 772 1041 } // buildReference 773 1042 774 1043 775 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {1044 ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) { 776 1045 assert( td->kind == TypeData::Aggregate ); 777 AggregateDecl * at;1046 ast::AggregateDecl * at; 778 1047 switch ( td->aggregate.kind ) { 779 case AggregateDecl::Struct: 780 case AggregateDecl::Coroutine: 781 case AggregateDecl::Exception: 782 case AggregateDecl::Generator: 783 case AggregateDecl::Monitor: 784 case AggregateDecl::Thread: 785 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage ); 786 buildForall( td->aggregate.params, at->get_parameters() ); 787 break; 788 case AggregateDecl::Union: 789 at = new UnionDecl( *td->aggregate.name, attributes, linkage ); 790 buildForall( td->aggregate.params, at->get_parameters() ); 791 break; 792 case AggregateDecl::Trait: 793 at = new TraitDecl( *td->aggregate.name, attributes, linkage ); 794 buildList( td->aggregate.params, at->get_parameters() ); 795 break; 796 default: 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: 797 1079 assert( false ); 798 1080 } // switch 799 1081 800 buildList( td->aggregate.fields, at-> get_members());1082 buildList( td->aggregate.fields, at->members ); 801 1083 at->set_body( td->aggregate.body ); 802 1084 … … 805 1087 806 1088 807 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1089 ast::BaseInstType * buildComAggInst( 1090 const TypeData * type, 1091 std::vector<ast::ptr<ast::Attribute>> && attributes, 1092 ast::Linkage::Spec linkage ) { 808 1093 switch ( type->kind ) { 809 case TypeData::Enum: { 810 if ( type->enumeration.body ) { 811 EnumDecl * typedecl = buildEnum( type, attributes, linkage ); 812 return new EnumInstType( buildQualifiers( type ), typedecl ); 813 } else { 814 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name ); 815 } // if 816 } 817 case TypeData::Aggregate: { 818 ReferenceToType * ret; 819 if ( type->aggregate.body ) { 820 AggregateDecl * typedecl = buildAggregate( type, attributes, linkage ); 821 switch ( type->aggregate.kind ) { 822 case AggregateDecl::Struct: 823 case AggregateDecl::Coroutine: 824 case AggregateDecl::Monitor: 825 case AggregateDecl::Thread: 826 ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl ); 827 break; 828 case AggregateDecl::Union: 829 ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl ); 830 break; 831 case AggregateDecl::Trait: 832 assert( false ); 833 //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl ); 834 break; 835 default: 836 assert( false ); 837 } // switch 838 } else { 839 switch ( type->aggregate.kind ) { 840 case AggregateDecl::Struct: 841 case AggregateDecl::Coroutine: 842 case AggregateDecl::Monitor: 843 case AggregateDecl::Thread: 844 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 845 break; 846 case AggregateDecl::Union: 847 ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name ); 848 break; 849 case AggregateDecl::Trait: 850 ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name ); 851 break; 852 default: 853 assert( false ); 854 } // switch 855 } // if 856 return ret; 857 } 858 default: 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: 859 1160 assert( false ); 860 1161 } // switch 1162 assert( false ); 861 1163 } // buildAggInst 862 1164 863 1165 864 ReferenceToType * buildAggInst( const TypeData * td ) {1166 ast::BaseInstType * buildAggInst( const TypeData * td ) { 865 1167 assert( td->kind == TypeData::AggregateInst ); 866 1168 867 // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() ); 868 ReferenceToType * ret = nullptr; 1169 ast::BaseInstType * ret = nullptr; 869 1170 TypeData * type = td->aggInst.aggregate; 870 1171 switch ( type->kind ) { 871 case TypeData::Enum: { 872 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name ); 873 } 874 case TypeData::Aggregate: { 875 switch ( type->aggregate.kind ) { 876 case AggregateDecl::Struct: 877 case AggregateDecl::Coroutine: 878 case AggregateDecl::Monitor: 879 case AggregateDecl::Thread: 880 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 881 break; 882 case AggregateDecl::Union: 883 ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name ); 884 break; 885 case AggregateDecl::Trait: 886 ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name ); 887 break; 888 default: 889 assert( false ); 890 } // switch 891 } 892 break; 893 default: 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: 894 1205 assert( false ); 895 1206 } // switch 896 1207 897 ret->set_hoistType( td->aggInst.hoistType ); 898 buildList( td->aggInst.params, ret->get_parameters() ); 899 buildForall( td->forall, ret->get_forall() ); 1208 ret->hoistType = td->aggInst.hoistType; 1209 buildList( td->aggInst.params, ret->params ); 900 1210 return ret; 901 1211 } // buildAggInst 902 1212 903 1213 904 NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) { 1214 ast::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 ) { 905 1220 assert( td->kind == TypeData::Symbolic ); 906 NamedTypeDecl * ret;1221 ast::NamedTypeDecl * ret; 907 1222 assert( td->base ); 908 1223 if ( td->symbolic.isTypedef ) { 909 ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage ); 1224 ret = new ast::TypedefDecl( 1225 td->location, 1226 name, 1227 scs, 1228 typebuild( td->base ), 1229 linkage 1230 ); 910 1231 } else { 911 ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true ); 1232 ret = new ast::TypeDecl( 1233 td->location, 1234 name, 1235 scs, 1236 typebuild( td->base ), 1237 ast::TypeDecl::Dtype, 1238 true 1239 ); 912 1240 } // if 913 buildList( td->symbolic.assertions, ret-> get_assertions());914 ret->base->attributes.splice( ret->base->attributes.end(), attributes );1241 buildList( td->symbolic.assertions, ret->assertions ); 1242 splice( ret->base.get_and_mutate()->attributes, attributes ); 915 1243 return ret; 916 1244 } // buildSymbolic 917 1245 918 1246 919 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1247 ast::EnumDecl * buildEnum( 1248 const TypeData * td, 1249 std::vector<ast::ptr<ast::Attribute>> && attributes, 1250 ast::Linkage::Spec linkage ) { 920 1251 assert( td->kind == TypeData::Enum ); 921 Type * baseType = td->base ? typebuild(td->base) : nullptr; 922 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType ); 923 buildList( td->enumeration.constants, ret->get_members() ); 924 list< Declaration * >::iterator members = ret->get_members().begin(); 925 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible; 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; 926 1264 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 927 1265 if ( cur->enumInLine ) { … … 930 1268 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); 931 1269 } else if ( cur->has_enumeratorValue() ) { 932 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members); 933 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_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 ); 934 1277 } else if ( !cur->initializer ) { 935 if ( baseType && (!dynamic_cast< BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {1278 if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) { 936 1279 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 937 1280 } … … 940 1283 // if 941 1284 } // for 942 ret-> set_body( td->enumeration.body );1285 ret->body = td->enumeration.body; 943 1286 return ret; 944 1287 } // buildEnum 945 1288 946 1289 947 TypeInstType * buildSymbolicInst( const TypeData * td ) {1290 ast::TypeInstType * buildSymbolicInst( const TypeData * td ) { 948 1291 assert( td->kind == TypeData::SymbolicInst ); 949 TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false ); 950 buildList( td->symbolic.actuals, ret->get_parameters() ); 951 buildForall( td->forall, ret->get_forall() ); 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 ); 952 1298 return ret; 953 1299 } // buildSymbolicInst 954 1300 955 1301 956 TupleType * buildTuple( const TypeData * td ) {1302 ast::TupleType * buildTuple( const TypeData * td ) { 957 1303 assert( td->kind == TypeData::Tuple ); 958 std:: list< Type *> types;1304 std::vector<ast::ptr<ast::Type>> types; 959 1305 buildTypeList( td->tuple, types ); 960 TupleType * ret = new TupleType( buildQualifiers( td ), types ); 961 buildForall( td->forall, ret->get_forall() ); 1306 ast::TupleType * ret = new ast::TupleType( 1307 std::move( types ), 1308 buildQualifiers( td ) 1309 ); 962 1310 return ret; 963 1311 } // buildTuple 964 1312 965 1313 966 TypeofType * buildTypeof( const TypeData * td ) {1314 ast::TypeofType * buildTypeof( const TypeData * td ) { 967 1315 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 968 1316 assert( td->typeexpr ); 969 // assert( td->typeexpr->expr ); 970 return new TypeofType{ buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof }; 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 ); 971 1323 } // buildTypeof 972 1324 973 1325 974 VTableType * buildVtable( const TypeData * td ) {1326 ast::VTableType * buildVtable( const TypeData * td ) { 975 1327 assert( td->base ); 976 return new VTableType{ buildQualifiers( td ), typebuild( td->base ) }; 1328 return new ast::VTableType( 1329 typebuild( td->base ), 1330 buildQualifiers( td ) 1331 ); 977 1332 } // buildVtable 978 1333 979 1334 980 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) { 1335 ast::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 1409 ast::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 ) { 981 1419 if ( td->kind == TypeData::Function ) { 982 1420 if ( td->function.idList ) { // KR function ? … … 984 1422 } // if 985 1423 986 FunctionDecl * decl; 987 Statement * stmt = maybeBuild<Statement>( td->function.body ); 988 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt ); 989 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec ); 990 buildList( td->function.withExprs, decl->withExprs ); 991 return decl->set_asmName( asmName ); 1424 return buildFunctionDecl( 1425 td, name, scs, funcSpec, linkage, 1426 asmName, std::move( attributes ) ); 992 1427 } else if ( td->kind == TypeData::Aggregate ) { 993 return buildAggregate( td, attributes, linkage );1428 return buildAggregate( td, std::move( attributes ), linkage ); 994 1429 } else if ( td->kind == TypeData::Enum ) { 995 return buildEnum( td, attributes, linkage );1430 return buildEnum( td, std::move( attributes ), linkage ); 996 1431 } else if ( td->kind == TypeData::Symbolic ) { 997 return buildSymbolic( td, attributes, name, scs, linkage );1432 return buildSymbolic( td, std::move( attributes ), name, scs, linkage ); 998 1433 } else { 999 return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName ); 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; 1000 1445 } // if 1001 1446 return nullptr; … … 1003 1448 1004 1449 1005 FunctionType * buildFunction( const TypeData * td ) {1450 ast::FunctionType * buildFunctionType( const TypeData * td ) { 1006 1451 assert( td->kind == TypeData::Function ); 1007 FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis ); 1008 buildList( td->function.params, ft->parameters ); 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 ); 1009 1458 buildForall( td->forall, ft->forall ); 1010 1459 if ( td->base ) { 1011 1460 switch ( td->base->kind ) { 1012 1013 build List( td->base->tuple, ft->returnVals );1461 case TypeData::Tuple: 1462 buildTypeList( td->base->tuple, ft->returns ); 1014 1463 break; 1015 default: 1016 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) ); 1464 default: 1465 ft->returns.push_back( typebuild( td->base ) ); 1466 break; 1017 1467 } // switch 1018 1468 } else { 1019 ft->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) ); 1469 ft->returns.push_back( 1470 new ast::BasicType( ast::BasicType::SignedInt ) ); 1020 1471 } // if 1021 1472 return ft; 1022 } // buildFunction 1473 } // buildFunctionType 1023 1474 1024 1475 … … 1051 1502 param->type = decl->type; // set copy declaration type to parameter type 1052 1503 decl->type = nullptr; // reset declaration type 1053 param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter 1504 // Copy and reset attributes from declaration to parameter: 1505 splice( param->attributes, decl->attributes ); 1054 1506 } // if 1055 1507 } // for -
src/Parser/TypeData.h
r34b4268 r24d6572 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 15:18:36 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue May 10 22:18:49 202213 // Update Count : 20 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Mar 1 10:44:00 2023 13 // Update Count : 206 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <iosfwd> 19 #include <list> 20 #include <string> 18 #include <iosfwd> // for ostream 19 #include <list> // for list 20 #include <string> // for string 21 21 22 #include "ParseNode.h" // for DeclarationNode, DeclarationNode::Ag... 23 #include "SynTree/LinkageSpec.h" // for Spec 24 #include "SynTree/Type.h" // for Type, ReferenceToType (ptr only) 25 #include "SynTree/SynTree.h" // for Visitor Nodes 22 #include "AST/Type.hpp" // for Type 23 #include "DeclarationNode.h" // for DeclarationNode 26 24 27 25 struct TypeData { … … 30 28 31 29 struct Aggregate_t { 32 AggregateDecl::Aggregate kind;30 ast::AggregateDecl::Aggregate kind; 33 31 const std::string * name = nullptr; 34 32 DeclarationNode * params = nullptr; … … 37 35 bool body; 38 36 bool anon; 39 40 37 bool tagged; 41 38 const std::string * parent = nullptr; … … 94 91 DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType; 95 92 96 Type::Qualifiers qualifiers;93 ast::CV::Qualifiers qualifiers; 97 94 DeclarationNode * forall = nullptr; 98 95 … … 115 112 }; 116 113 117 Type * typebuild( const TypeData * );114 ast::Type * typebuild( const TypeData * ); 118 115 TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true ); 119 Type::Qualifiers buildQualifiers( const TypeData * td ); 120 Type * buildBasicType( const TypeData * ); 121 PointerType * buildPointer( const TypeData * ); 122 ArrayType * buildArray( const TypeData * ); 123 ReferenceType * buildReference( const TypeData * ); 124 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > ); 125 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ); 126 ReferenceToType * buildAggInst( const TypeData * ); 127 TypeDecl * buildVariable( const TypeData * ); 128 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec ); 129 TypeInstType * buildSymbolicInst( const TypeData * ); 130 TupleType * buildTuple( const TypeData * ); 131 TypeofType * buildTypeof( const TypeData * ); 132 VTableType * buildVtable( const TypeData * ); 133 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, 134 Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() ); 135 FunctionType * buildFunction( const TypeData * ); 136 Declaration * addEnumBase( Declaration *, const TypeData * ); 116 ast::CV::Qualifiers buildQualifiers( const TypeData * td ); 117 ast::Type * buildBasicType( const TypeData * ); 118 ast::PointerType * buildPointer( const TypeData * ); 119 ast::ArrayType * buildArray( const TypeData * ); 120 ast::ReferenceType * buildReference( const TypeData * ); 121 ast::AggregateDecl * buildAggregate( const TypeData *, std::vector<ast::ptr<ast::Attribute>> ); 122 ast::BaseInstType * buildComAggInst( const TypeData *, std::vector<ast::ptr<ast::Attribute>> && attributes, ast::Linkage::Spec linkage ); 123 ast::BaseInstType * buildAggInst( const TypeData * ); 124 ast::TypeDecl * buildVariable( const TypeData * ); 125 ast::EnumDecl * buildEnum( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec ); 126 ast::TypeInstType * buildSymbolicInst( const TypeData * ); 127 ast::TupleType * buildTuple( const TypeData * ); 128 ast::TypeofType * buildTypeof( const TypeData * ); 129 ast::VTableType * buildVtable( const TypeData * ); 130 ast::Decl * buildDecl( 131 const TypeData *, const std::string &, ast::Storage::Classes, ast::Expr *, 132 ast::Function::Specs funcSpec, ast::Linkage::Spec, ast::Expr * asmName, 133 ast::Init * init = nullptr, std::vector<ast::ptr<ast::Attribute>> && attributes = std::vector<ast::ptr<ast::Attribute>>() ); 134 ast::FunctionType * buildFunctionType( const TypeData * ); 135 ast::Decl * addEnumBase( Declaration *, const TypeData * ); 137 136 void buildKRFunction( const TypeData::Function_t & function ); 138 137 -
src/Parser/TypedefTable.cc
r34b4268 r24d6572 16 16 17 17 #include "TypedefTable.h" 18 #include <cassert> // for assert 19 #include <iostream> 18 19 #include <cassert> // for assert 20 #include <string> // for string 21 #include <iostream> // for iostream 22 23 #include "ExpressionNode.h" // for LabelNode 24 #include "ParserTypes.h" // for Token 25 #include "StatementNode.h" // for CondCtl, ForCtrl 26 // This (generated) header must come late as it is missing includes. 27 #include "parser.hh" // for IDENTIFIER, TYPEDEFname, TYPEGENname 28 20 29 using namespace std; 21 30 22 31 #if 0 23 32 #define debugPrint( code ) code 33 34 static const char *kindName( int kind ) { 35 switch ( kind ) { 36 case IDENTIFIER: return "identifier"; 37 case TYPEDIMname: return "typedim"; 38 case TYPEDEFname: return "typedef"; 39 case TYPEGENname: return "typegen"; 40 default: 41 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 42 abort(); 43 } // switch 44 } // kindName 24 45 #else 25 46 #define debugPrint( code ) 26 47 #endif 27 28 using namespace std; // string, iostream29 30 debugPrint(31 static const char *kindName( int kind ) {32 switch ( kind ) {33 case IDENTIFIER: return "identifier";34 case TYPEDIMname: return "typedim";35 case TYPEDEFname: return "typedef";36 case TYPEGENname: return "typegen";37 default:38 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;39 abort();40 } // switch41 } // kindName42 );43 48 44 49 TypedefTable::~TypedefTable() { … … 78 83 typedefTable.addToEnclosingScope( name, kind, "MTD" ); 79 84 } // if 85 } // TypedefTable::makeTypedef 86 87 void TypedefTable::makeTypedef( const string & name ) { 88 return makeTypedef( name, TYPEDEFname ); 80 89 } // TypedefTable::makeTypedef 81 90 -
src/Parser/TypedefTable.h
r34b4268 r24d6572 19 19 20 20 #include "Common/ScopedMap.h" // for ScopedMap 21 #include "ParserTypes.h"22 #include "parser.hh" // for IDENTIFIER, TYPEDEFname, TYPEGENname23 21 24 22 class TypedefTable { 25 23 struct Note { size_t level; bool forall; }; 26 24 typedef ScopedMap< std::string, int, Note > KindTable; 27 KindTable kindTable; 25 KindTable kindTable; 28 26 unsigned int level = 0; 29 27 public: … … 33 31 bool existsCurr( const std::string & identifier ) const; 34 32 int isKind( const std::string & identifier ) const; 35 void makeTypedef( const std::string & name, int kind = TYPEDEFname ); 33 void makeTypedef( const std::string & name, int kind ); 34 void makeTypedef( const std::string & name ); 36 35 void addToScope( const std::string & identifier, int kind, const char * ); 37 36 void addToEnclosingScope( const std::string & identifier, int kind, const char * ); -
src/Parser/lex.ll
r34b4268 r24d6572 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : T hu Oct 13 20:46:04 202213 * Update Count : 76 412 * Last Modified On : Tue May 2 08:45:21 2023 13 * Update Count : 769 14 14 */ 15 15 … … 23 23 // line-number directives) and C/C++ style comments, which are ignored. 24 24 25 // **************************** Includes and Defines ****************************25 // *************************** Includes and Defines **************************** 26 26 27 27 #ifdef __clang__ … … 44 44 45 45 #include "config.h" // configure info 46 #include "DeclarationNode.h" // for DeclarationNode 47 #include "ExpressionNode.h" // for LabelNode 48 #include "InitializerNode.h" // for InitializerNode 46 49 #include "ParseNode.h" 50 #include "ParserTypes.h" // for Token 51 #include "StatementNode.h" // for CondCtl, ForCtrl 47 52 #include "TypedefTable.h" 53 // This (generated) header must come late as it is missing includes. 54 #include "parser.hh" // generated info 48 55 49 56 string * build_postfix_name( string * name ); … … 214 221 __alignof { KEYWORD_RETURN(ALIGNOF); } // GCC 215 222 __alignof__ { KEYWORD_RETURN(ALIGNOF); } // GCC 223 and { QKEYWORD_RETURN(WAND); } // CFA 216 224 asm { KEYWORD_RETURN(ASM); } 217 225 __asm { KEYWORD_RETURN(ASM); } // GCC … … 250 258 enable { KEYWORD_RETURN(ENABLE); } // CFA 251 259 enum { KEYWORD_RETURN(ENUM); } 260 exception { KEYWORD_RETURN(EXCEPTION); } // CFA 252 261 __extension__ { KEYWORD_RETURN(EXTENSION); } // GCC 253 exception { KEYWORD_RETURN(EXCEPTION); } // CFA254 262 extern { KEYWORD_RETURN(EXTERN); } 255 263 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA … … 340 348 vtable { KEYWORD_RETURN(VTABLE); } // CFA 341 349 waitfor { KEYWORD_RETURN(WAITFOR); } // CFA 350 waituntil { KEYWORD_RETURN(WAITUNTIL); } // CFA 342 351 when { KEYWORD_RETURN(WHEN); } // CFA 343 352 while { KEYWORD_RETURN(WHILE); } … … 502 511 SemanticErrorThrow = true; 503 512 cerr << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1 504 << ": " << ErrorHelpers::error_str() << errmsg << " attoken \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;513 << ": " << ErrorHelpers::error_str() << errmsg << " before token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl; 505 514 } 506 515 -
src/Parser/module.mk
r34b4268 r24d6572 21 21 SRC += \ 22 22 Parser/DeclarationNode.cc \ 23 Parser/DeclarationNode.h \ 23 24 Parser/ExpressionNode.cc \ 25 Parser/ExpressionNode.h \ 24 26 Parser/InitializerNode.cc \ 27 Parser/InitializerNode.h \ 25 28 Parser/lex.ll \ 26 29 Parser/ParseNode.cc \ … … 30 33 Parser/parserutility.cc \ 31 34 Parser/parserutility.h \ 35 Parser/RunParser.cpp \ 36 Parser/RunParser.hpp \ 32 37 Parser/StatementNode.cc \ 38 Parser/StatementNode.h \ 33 39 Parser/TypeData.cc \ 34 40 Parser/TypeData.h \ -
src/Parser/parser.yy
r34b4268 r24d6572 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Nov 21 22:34:30 202213 // Update Count : 584812 // Last Modified On : Wed Apr 26 16:45:37 2023 13 // Update Count : 6330 14 14 // 15 15 … … 44 44 45 45 #include <cstdio> 46 #include <sstream> 46 47 #include <stack> 47 48 using namespace std; 48 49 49 #include "SynTree/Declaration.h" 50 #include "ParseNode.h" 50 #include "SynTree/Type.h" // for Type 51 #include "DeclarationNode.h" // for DeclarationNode, ... 52 #include "ExpressionNode.h" // for ExpressionNode, ... 53 #include "InitializerNode.h" // for InitializerNode, ... 54 #include "ParserTypes.h" 55 #include "StatementNode.h" // for build_... 51 56 #include "TypedefTable.h" 52 57 #include "TypeData.h" 53 #include "SynTree/LinkageSpec.h"54 58 #include "Common/SemanticError.h" // error_str 55 59 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 56 60 57 #include "SynTree/Attribute.h" 61 #include "SynTree/Attribute.h" // for Attribute 58 62 59 63 // lex uses __null in a boolean context, it's fine. … … 63 67 64 68 extern DeclarationNode * parseTree; 65 extern LinkageSpec::Spec linkage;69 extern ast::Linkage::Spec linkage; 66 70 extern TypedefTable typedefTable; 67 71 68 stack< LinkageSpec::Spec> linkageStack;72 stack<ast::Linkage::Spec> linkageStack; 69 73 70 74 bool appendStr( string & to, string & from ) { … … 199 203 } // fieldDecl 200 204 201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )202 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) )205 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) ) 206 #define NEW_ONE new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) ) 203 207 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 204 208 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 206 210 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized." 207 211 208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 212 static ForCtrl * makeForCtrl( 213 const CodeLocation & location, 214 DeclarationNode * init, 215 enum OperKinds compop, 216 ExpressionNode * comp, 217 ExpressionNode * inc ) { 218 // Wrap both comp/inc if they are non-null. 219 if ( comp ) comp = new ExpressionNode( build_binary_val( location, 220 compop, 221 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 222 comp ) ); 223 if ( inc ) inc = new ExpressionNode( build_binary_val( location, 224 // choose += or -= for upto/downto 225 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn, 226 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 227 inc ) ); 228 // The StatementNode call frees init->name, it must happen later. 229 return new ForCtrl( new StatementNode( init ), comp, inc ); 230 } 231 232 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 209 233 if ( index->initializer ) { 210 234 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 213 237 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." ); 214 238 } // if 215 return new ForCtrl( index->addInitializer( new InitializerNode( start ) ), 216 // NULL comp/inc => leave blank 217 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr, 218 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 219 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr ); 239 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 240 return makeForCtrl( location, initDecl, compop, comp, inc ); 220 241 } // forCtrl 221 242 222 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {223 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());224 if ( constant && (constant-> get_constant()->get_value() == "0" || constant->get_constant()->get_value()== "1") ) {225 type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(),BasicType::SignedInt ) ) );243 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 244 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get()); 245 if ( constant && (constant->rep == "0" || constant->rep == "1") ) { 246 type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) ); 226 247 } // if 227 // type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) ); 228 return new ForCtrl( 229 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 230 // NULL comp/inc => leave blank 231 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr, 232 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 233 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr ); 248 DeclarationNode * initDecl = distAttr( 249 DeclarationNode::newTypeof( type, true ), 250 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 251 ); 252 return makeForCtrl( location, initDecl, compop, comp, inc ); 234 253 } // forCtrl 235 254 236 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {237 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {238 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );239 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {240 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1) ) {241 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );255 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 256 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) { 257 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc ); 258 } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) { 259 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) { 260 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc ); 242 261 } else { 243 262 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 281 300 %union { 282 301 Token tok; 283 ParseNode * pn; 284 ExpressionNode * en; 302 ExpressionNode * expr; 285 303 DeclarationNode * decl; 286 AggregateDecl::Aggregate aggKey; 287 TypeDecl::Kind tclass; 288 StatementNode * sn; 289 WaitForStmt * wfs; 290 Expression * constant; 304 ast::AggregateDecl::Aggregate aggKey; 305 ast::TypeDecl::Kind tclass; 306 StatementNode * stmt; 307 ClauseNode * clause; 308 ast::WaitForStmt * wfs; 309 ast::WaitUntilStmt::ClauseNode * wucn; 291 310 CondCtl * ifctl; 292 ForCtrl * fctl; 293 OperKinds compop; 294 LabelNode * label; 295 InitializerNode * in; 296 OperKinds op; 311 ForCtrl * forctl; 312 LabelNode * labels; 313 InitializerNode * init; 314 OperKinds oper; 297 315 std::string * str; 298 bool flag;299 EnumHiding hide;300 CatchStmt::Kind catch_kind;301 GenericExpr * genexpr;316 bool is_volatile; 317 EnumHiding enum_hiding; 318 ast::ExceptionKind except_kind; 319 ast::GenericExpr * genexpr; 302 320 } 303 321 304 // ************************* TERMINAL TOKENS ********************************322 // ************************ TERMINAL TOKENS ******************************** 305 323 306 324 // keywords … … 331 349 %token ATTRIBUTE EXTENSION // GCC 332 350 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR 351 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL // CFA 334 352 %token DISABLE ENABLE TRY THROW THROWRESUME AT // CFA 335 353 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) … … 337 355 338 356 // names and constants: lexer differentiates between identifier and typedef names 339 %token<tok> IDENTIFIER QUOTED_IDENTIFIERTYPEDIMname TYPEDEFname TYPEGENname340 %token<tok> TIMEOUT W ORCATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA357 %token<tok> IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname 358 %token<tok> TIMEOUT WAND WOR CATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA 341 359 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 342 360 %token<tok> DIRECTIVE … … 364 382 %type<tok> identifier identifier_at identifier_or_type_name attr_name 365 383 %type<tok> quasi_keyword 366 %type< constant> string_literal384 %type<expr> string_literal 367 385 %type<str> string_literal_list 368 386 369 %type< hide> hide_opt visible_hide_opt387 %type<enum_hiding> hide_opt visible_hide_opt 370 388 371 389 // expressions 372 %type<e n> constant373 %type<e n> tuple tuple_expression_list374 %type<op > ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator375 %type<e n> primary_expression postfix_expression unary_expression376 %type<e n> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression377 %type<e n> shift_expression relational_expression equality_expression378 %type<e n> AND_expression exclusive_OR_expression inclusive_OR_expression379 %type<e n> logical_AND_expression logical_OR_expression380 %type<e n> conditional_expression constant_expression assignment_expression assignment_expression_opt381 %type<e n> comma_expression comma_expression_opt382 %type<e n> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt390 %type<expr> constant 391 %type<expr> tuple tuple_expression_list 392 %type<oper> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator 393 %type<expr> primary_expression postfix_expression unary_expression 394 %type<expr> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression 395 %type<expr> shift_expression relational_expression equality_expression 396 %type<expr> AND_expression exclusive_OR_expression inclusive_OR_expression 397 %type<expr> logical_AND_expression logical_OR_expression 398 %type<expr> conditional_expression constant_expression assignment_expression assignment_expression_opt 399 %type<expr> comma_expression comma_expression_opt 400 %type<expr> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt 383 401 %type<ifctl> conditional_declaration 384 %type<f ctl> for_control_expression for_control_expression_list385 %type< compop> upupeq updown updowneq downupdowneq386 %type<e n> subrange402 %type<forctl> for_control_expression for_control_expression_list 403 %type<oper> upupeq updown updowneq downupdowneq 404 %type<expr> subrange 387 405 %type<decl> asm_name_opt 388 %type<e n> asm_operands_opt asm_operands_list asm_operand389 %type<label > label_list390 %type<e n> asm_clobbers_list_opt391 %type< flag> asm_volatile_opt392 %type<e n> handler_predicate_opt406 %type<expr> asm_operands_opt asm_operands_list asm_operand 407 %type<labels> label_list 408 %type<expr> asm_clobbers_list_opt 409 %type<is_volatile> asm_volatile_opt 410 %type<expr> handler_predicate_opt 393 411 %type<genexpr> generic_association generic_assoc_list 394 412 395 413 // statements 396 %type<sn> statement labeled_statement compound_statement 397 %type<sn> statement_decl statement_decl_list statement_list_nodecl 398 %type<sn> selection_statement if_statement 399 %type<sn> switch_clause_list_opt switch_clause_list 400 %type<en> case_value 401 %type<sn> case_clause case_value_list case_label case_label_list 402 %type<sn> iteration_statement jump_statement 403 %type<sn> expression_statement asm_statement 404 %type<sn> with_statement 405 %type<en> with_clause_opt 406 %type<sn> exception_statement handler_clause finally_clause 407 %type<catch_kind> handler_key 408 %type<sn> mutex_statement 409 %type<en> when_clause when_clause_opt waitfor timeout 410 %type<sn> waitfor_statement 411 %type<wfs> waitfor_clause 414 %type<stmt> statement labeled_statement compound_statement 415 %type<stmt> statement_decl statement_decl_list statement_list_nodecl 416 %type<stmt> selection_statement if_statement 417 %type<clause> switch_clause_list_opt switch_clause_list 418 %type<expr> case_value 419 %type<clause> case_clause case_value_list case_label case_label_list 420 %type<stmt> iteration_statement jump_statement 421 %type<stmt> expression_statement asm_statement 422 %type<stmt> with_statement 423 %type<expr> with_clause_opt 424 %type<stmt> exception_statement 425 %type<clause> handler_clause finally_clause 426 %type<except_kind> handler_key 427 %type<stmt> mutex_statement 428 %type<expr> when_clause when_clause_opt waitfor waituntil timeout 429 %type<stmt> waitfor_statement waituntil_statement 430 %type<wfs> wor_waitfor_clause 431 %type<wucn> waituntil_clause wand_waituntil_clause wor_waituntil_clause 412 432 413 433 // declarations … … 421 441 %type<decl> assertion assertion_list assertion_list_opt 422 442 423 %type<e n> bit_subrange_size_opt bit_subrange_size443 %type<expr> bit_subrange_size_opt bit_subrange_size 424 444 425 445 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 434 454 435 455 %type<decl> enumerator_list enum_type enum_type_nobody 436 %type<in > enumerator_value_opt456 %type<init> enumerator_value_opt 437 457 438 458 %type<decl> external_definition external_definition_list external_definition_list_opt … … 441 461 442 462 %type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract 443 %type<e n> field field_name_list field_name fraction_constants_opt463 %type<expr> field field_name_list field_name fraction_constants_opt 444 464 445 465 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 482 502 %type<decl> typedef_name typedef_declaration typedef_expression 483 503 484 %type<decl> variable_type_redeclarator type_ptr type_array type_function 504 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function 505 %type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr 485 506 486 507 %type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function … … 489 510 %type<decl> type_parameter type_parameter_list type_initializer_opt 490 511 491 %type<e n> type_parameters_opt type_list array_type_list512 %type<expr> type_parameters_opt type_list array_type_list 492 513 493 514 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 500 521 501 522 // initializers 502 %type<in > initializer initializer_list_opt initializer_opt523 %type<init> initializer initializer_list_opt initializer_opt 503 524 504 525 // designators 505 %type<e n> designator designator_list designation526 %type<expr> designator designator_list designation 506 527 507 528 … … 512 533 // Similar issues exit with the waitfor statement. 513 534 514 // Order of these lines matters (low-to-high precedence). THEN is left associative over W OR/TIMEOUT/ELSE, WOR is left515 // associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.535 // Order of these lines matters (low-to-high precedence). THEN is left associative over WAND/WOR/TIMEOUT/ELSE, WAND/WOR 536 // is left associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE. 516 537 %precedence THEN // rule precedence for IF/WAITFOR statement 538 %precedence ANDAND // token precedence for start of WAND in WAITFOR statement 539 %precedence WAND // token precedence for start of WAND in WAITFOR statement 540 %precedence OROR // token precedence for start of WOR in WAITFOR statement 517 541 %precedence WOR // token precedence for start of WOR in WAITFOR statement 518 542 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement … … 592 616 constant: 593 617 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant". 594 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }595 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }596 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }597 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }598 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }618 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); } 619 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); } 620 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); } 621 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); } 622 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); } 599 623 ; 600 624 601 625 quasi_keyword: // CFA 602 626 TIMEOUT 627 | WAND 603 628 | WOR 604 629 | CATCH … … 621 646 622 647 string_literal: 623 string_literal_list { $$ = build_constantStr( *$1); }648 string_literal_list { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); } 624 649 ; 625 650 … … 638 663 primary_expression: 639 664 IDENTIFIER // typedef name cannot be used as a variable name 640 { $$ = new ExpressionNode( build_varref( $1 ) ); }665 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 641 666 | quasi_keyword 642 { $$ = new ExpressionNode( build_varref( $1 ) ); }667 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 643 668 | TYPEDIMname // CFA, generic length argument 644 669 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 645 670 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 646 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }671 { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); } 647 672 | tuple 648 673 | '(' comma_expression ')' 649 674 { $$ = $2; } 650 675 | '(' compound_statement ')' // GCC, lambda expression 651 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }676 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); } 652 677 | type_name '.' identifier // CFA, nested type 653 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref($3 ) ) ); }678 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 654 679 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 655 680 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 657 682 { 658 683 // add the missing control expression to the GenericExpr and return it 659 $5->control = maybeMoveBuild <Expression>( $3 );684 $5->control = maybeMoveBuild( $3 ); 660 685 $$ = new ExpressionNode( $5 ); 661 686 } … … 683 708 { 684 709 // steal the association node from the singleton and delete the wrapper 685 $1->associations.splice($1->associations.end(), $3->associations); 710 assert( 1 == $3->associations.size() ); 711 $1->associations.push_back( $3->associations.front() ); 686 712 delete $3; 687 713 $$ = $1; … … 693 719 { 694 720 // create a GenericExpr wrapper with one association pair 695 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } );721 $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } ); 696 722 } 697 723 | DEFAULT ':' assignment_expression 698 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); }724 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); } 699 725 ; 700 726 … … 705 731 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 706 732 // Current: Commas in subscripts make tuples. 707 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple((ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }733 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 708 734 | postfix_expression '[' assignment_expression ']' 709 735 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 711 737 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 712 738 // equivalent to the old x[i,j]. 713 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }739 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 714 740 | constant '[' assignment_expression ']' // 3[a], 'a'[a], 3.5[a] 715 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }741 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 716 742 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 717 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }743 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 718 744 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 719 745 { 720 746 Token fn; 721 747 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 722 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref(fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );748 $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 723 749 } 724 750 | postfix_expression '(' argument_expression_list_opt ')' 725 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }751 { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); } 726 752 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 727 753 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 728 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(new string( "__builtin_va_arg") ) ),754 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ), 729 755 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 730 756 | postfix_expression '`' identifier // CFA, postfix call 731 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(build_postfix_name( $3 ) ) ), $1 ) ); }757 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 732 758 | constant '`' identifier // CFA, postfix call 733 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(build_postfix_name( $3 ) ) ), $1 ) ); }759 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 734 760 | string_literal '`' identifier // CFA, postfix call 735 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 )) ); }761 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 736 762 | postfix_expression '.' identifier 737 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref($3 ) ) ); }763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 738 764 | postfix_expression '.' INTEGERconstant // CFA, tuple index 739 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger(*$3 ) ) ); }765 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); } 740 766 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 741 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant(*$2 ) ) ); }767 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); } 742 768 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 743 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple($4 ) ) ); }769 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 744 770 | postfix_expression '.' aggregate_control 745 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }771 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); } 746 772 | postfix_expression ARROW identifier 747 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref($3 ) ) ); }773 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 748 774 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 749 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger(*$3 ) ) ); }775 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); } 750 776 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 751 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple($4 ) ) ); }777 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 752 778 | postfix_expression ICR 753 { $$ = new ExpressionNode( build_unary_ptr(OperKinds::IncrPost, $1 ) ); }779 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); } 754 780 | postfix_expression DECR 755 { $$ = new ExpressionNode( build_unary_ptr(OperKinds::DecrPost, $1 ) ); }781 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); } 756 782 | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal 757 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }783 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); } 758 784 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 759 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }785 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); } 760 786 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 761 787 { 762 788 Token fn; 763 789 fn.str = new string( "^?{}" ); // location undefined 764 $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );790 $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) ); 765 791 } 766 792 ; … … 781 807 '@' // CFA, default parameter 782 808 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 783 809 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } 784 810 | assignment_expression 785 811 ; … … 793 819 field_name 794 820 | FLOATING_DECIMALconstant field 795 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }821 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); } 796 822 | FLOATING_DECIMALconstant '[' field_name_list ']' 797 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple($3 ) ) ); }823 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); } 798 824 | field_name '.' field 799 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }825 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); } 800 826 | field_name '.' '[' field_name_list ']' 801 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple($4 ) ) ); }827 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 802 828 | field_name ARROW field 803 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }829 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); } 804 830 | field_name ARROW '[' field_name_list ']' 805 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple($4 ) ) ); }831 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 806 832 ; 807 833 808 834 field_name: 809 835 INTEGERconstant fraction_constants_opt 810 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger(*$1 ), $2 ) ); }836 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); } 811 837 | FLOATINGconstant fraction_constants_opt 812 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant(*$1 ), $2 ) ); }838 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); } 813 839 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 814 840 { 815 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref($1 ), $2 ) );841 $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) ); 816 842 } 817 843 ; … … 822 848 | fraction_constants_opt FLOATING_FRACTIONconstant 823 849 { 824 Expression * constant = build_field_name_FLOATING_FRACTIONconstant(*$2 );825 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1,constant ) ) : new ExpressionNode( constant );850 ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ); 851 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant ); 826 852 } 827 853 ; … … 833 859 | constant 834 860 | string_literal 835 { $$ = new ExpressionNode( $1 ); }861 { $$ = $1; } 836 862 | EXTENSION cast_expression // GCC 837 863 { $$ = $2->set_extension( true ); } … … 842 868 { 843 869 switch ( $1 ) { 844 845 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) );870 case OperKinds::AddressOf: 871 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ); 846 872 break; 847 848 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );873 case OperKinds::PointTo: 874 $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); 849 875 break; 850 851 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) );876 case OperKinds::And: 877 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) ); 852 878 break; 853 879 default: 854 880 assert( false ); 855 881 } 856 882 } 857 883 | unary_operator cast_expression 858 { $$ = new ExpressionNode( build_unary_val($1, $2 ) ); }884 { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); } 859 885 | ICR unary_expression 860 { $$ = new ExpressionNode( build_unary_ptr(OperKinds::Incr, $2 ) ); }886 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); } 861 887 | DECR unary_expression 862 { $$ = new ExpressionNode( build_unary_ptr(OperKinds::Decr, $2 ) ); }888 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); } 863 889 | SIZEOF unary_expression 864 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }890 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); } 865 891 | SIZEOF '(' type_no_function ')' 866 { $$ = new ExpressionNode( new SizeofExpr(maybeMoveBuildType( $3 ) ) ); }892 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 867 893 | ALIGNOF unary_expression // GCC, variable alignment 868 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }894 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); } 869 895 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 870 { $$ = new ExpressionNode( new AlignofExpr(maybeMoveBuildType( $3 ) ) ); }896 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 871 897 | OFFSETOF '(' type_no_function ',' identifier ')' 872 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref($5 ) ) ); }898 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); } 873 899 | TYPEID '(' type_no_function ')' 874 900 { … … 895 921 unary_expression 896 922 | '(' type_no_function ')' cast_expression 897 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }923 { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); } 898 924 | '(' aggregate_control '&' ')' cast_expression // CFA 899 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }925 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); } 900 926 | '(' aggregate_control '*' ')' cast_expression // CFA 901 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }927 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); } 902 928 | '(' VIRTUAL ')' cast_expression // CFA 903 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); }929 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); } 904 930 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 905 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); }931 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); } 906 932 | '(' RETURN type_no_function ')' cast_expression // CFA 907 { $$ = new ExpressionNode( build_cast( $3, $5,CastExpr::Return ) ); }933 { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast::CastExpr::Return ) ); } 908 934 | '(' COERCE type_no_function ')' cast_expression // CFA 909 935 { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; } … … 911 937 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 912 938 // | '(' type_no_function ')' tuple 913 // { $$ = new ExpressionNode( build_cast($2, $4 ) ); }939 // { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); } 914 940 ; 915 941 … … 929 955 cast_expression 930 956 | exponential_expression '\\' cast_expression 931 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }957 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); } 932 958 ; 933 959 … … 935 961 exponential_expression 936 962 | multiplicative_expression '*' exponential_expression 937 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }963 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); } 938 964 | multiplicative_expression '/' exponential_expression 939 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }965 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); } 940 966 | multiplicative_expression '%' exponential_expression 941 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }967 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); } 942 968 ; 943 969 … … 945 971 multiplicative_expression 946 972 | additive_expression '+' multiplicative_expression 947 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }973 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); } 948 974 | additive_expression '-' multiplicative_expression 949 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }975 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); } 950 976 ; 951 977 … … 953 979 additive_expression 954 980 | shift_expression LS additive_expression 955 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }981 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); } 956 982 | shift_expression RS additive_expression 957 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }983 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); } 958 984 ; 959 985 … … 961 987 shift_expression 962 988 | relational_expression '<' shift_expression 963 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }989 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); } 964 990 | relational_expression '>' shift_expression 965 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }991 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); } 966 992 | relational_expression LE shift_expression 967 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }993 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); } 968 994 | relational_expression GE shift_expression 969 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }995 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); } 970 996 ; 971 997 … … 973 999 relational_expression 974 1000 | equality_expression EQ relational_expression 975 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }1001 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); } 976 1002 | equality_expression NE relational_expression 977 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }1003 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); } 978 1004 ; 979 1005 … … 981 1007 equality_expression 982 1008 | AND_expression '&' equality_expression 983 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }1009 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); } 984 1010 ; 985 1011 … … 987 1013 AND_expression 988 1014 | exclusive_OR_expression '^' AND_expression 989 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }1015 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); } 990 1016 ; 991 1017 … … 993 1019 exclusive_OR_expression 994 1020 | inclusive_OR_expression '|' exclusive_OR_expression 995 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }1021 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); } 996 1022 ; 997 1023 … … 999 1025 inclusive_OR_expression 1000 1026 | logical_AND_expression ANDAND inclusive_OR_expression 1001 { $$ = new ExpressionNode( build_and_or( $1, $3, true) ); }1027 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); } 1002 1028 ; 1003 1029 … … 1005 1031 logical_AND_expression 1006 1032 | logical_OR_expression OROR logical_AND_expression 1007 { $$ = new ExpressionNode( build_and_or( $1, $3, false) ); }1033 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); } 1008 1034 ; 1009 1035 … … 1011 1037 logical_OR_expression 1012 1038 | logical_OR_expression '?' comma_expression ':' conditional_expression 1013 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }1039 { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); } 1014 1040 // FIX ME: computes $1 twice 1015 1041 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 1016 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }1042 { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); } 1017 1043 ; 1018 1044 … … 1029 1055 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1030 1056 // } else { 1031 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );1057 $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) ); 1032 1058 // } // if 1033 1059 } … … 1074 1100 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1075 1101 '[' ',' tuple_expression_list ']' 1076 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }1102 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 1077 1103 | '[' push assignment_expression pop ',' tuple_expression_list ']' 1078 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }1104 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); } 1079 1105 ; 1080 1106 … … 1092 1118 assignment_expression 1093 1119 | comma_expression ',' assignment_expression 1094 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }1120 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1095 1121 ; 1096 1122 … … 1113 1139 | mutex_statement 1114 1140 | waitfor_statement 1141 | waituntil_statement 1115 1142 | exception_statement 1116 1143 | enable_disable_statement … … 1118 1145 | asm_statement 1119 1146 | DIRECTIVE 1120 { $$ = new StatementNode( build_directive( $1 ) ); }1147 { $$ = new StatementNode( build_directive( yylloc, $1 ) ); } 1121 1148 ; 1122 1149 … … 1124 1151 // labels cannot be identifiers 0 or 1 1125 1152 identifier_or_type_name ':' attribute_list_opt statement 1126 { $$ = $4->add_label( $1, $3 ); }1153 { $$ = $4->add_label( yylloc, $1, $3 ); } 1127 1154 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1128 1155 { … … 1136 1163 compound_statement: 1137 1164 '{' '}' 1138 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }1165 { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); } 1139 1166 | '{' push 1140 1167 local_label_declaration_opt // GCC, local labels appear at start of block 1141 1168 statement_decl_list // C99, intermix declarations and statements 1142 1169 pop '}' 1143 { $$ = new StatementNode( build_compound( $4 ) ); }1170 { $$ = new StatementNode( build_compound( yylloc, $4 ) ); } 1144 1171 ; 1145 1172 … … 1172 1199 expression_statement: 1173 1200 comma_expression_opt ';' 1174 { $$ = new StatementNode( build_expr( $1 ) ); } 1175 | MUTEX '(' ')' comma_expression ';' 1176 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); } 1201 { $$ = new StatementNode( build_expr( yylloc, $1 ) ); } 1177 1202 ; 1178 1203 … … 1183 1208 { $$ = $2; } 1184 1209 | SWITCH '(' comma_expression ')' case_clause 1185 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }1210 { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); } 1186 1211 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1187 1212 { 1188 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );1213 StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) ); 1189 1214 // The semantics of the declaration list is changed to include associated initialization, which is performed 1190 1215 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1192 1217 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1193 1218 // statement. 1194 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1219 $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1195 1220 } 1196 1221 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1197 1222 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1198 1223 | CHOOSE '(' comma_expression ')' case_clause // CFA 1199 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }1224 { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); } 1200 1225 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1201 1226 { 1202 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );1203 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1227 StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) ); 1228 $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1204 1229 } 1205 1230 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error … … 1210 1235 IF '(' conditional_declaration ')' statement %prec THEN 1211 1236 // explicitly deal with the shift/reduce conflict on if/else 1212 { $$ = new StatementNode( build_if( $3, maybe_build_compound($5 ), nullptr ) ); }1237 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); } 1213 1238 | IF '(' conditional_declaration ')' statement ELSE statement 1214 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound($7 ) ) ); }1239 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); } 1215 1240 ; 1216 1241 … … 1224 1249 | declaration comma_expression // semi-colon separated 1225 1250 { $$ = new CondCtl( $1, $2 ); } 1226 1251 ; 1227 1252 1228 1253 // CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case … … 1232 1257 constant_expression { $$ = $1; } 1233 1258 | constant_expression ELLIPSIS constant_expression // GCC, subrange 1234 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }1259 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1235 1260 | subrange // CFA, subrange 1236 1261 ; 1237 1262 1238 1263 case_value_list: // CFA 1239 case_value { $$ = new StatementNode( build_case($1 ) ); }1264 case_value { $$ = new ClauseNode( build_case( yylloc, $1 ) ); } 1240 1265 // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5" 1241 | case_value_list ',' case_value { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 )) ) ); }1266 | case_value_list ',' case_value { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3 ) ) ); } 1242 1267 ; 1243 1268 … … 1248 1273 | CASE case_value_list error // syntax error 1249 1274 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1250 | DEFAULT ':' { $$ = new StatementNode( build_default() ); }1275 | DEFAULT ':' { $$ = new ClauseNode( build_default( yylloc ) ); } 1251 1276 // A semantic check is required to ensure only one default clause per switch/choose statement. 1252 1277 | DEFAULT error // syntax error … … 1256 1281 case_label_list: // CFA 1257 1282 case_label 1258 | case_label_list case_label { $$ = (StatementNode *)( $1->set_last( $2 )); }1283 | case_label_list case_label { $$ = $1->set_last( $2 ); } 1259 1284 ; 1260 1285 1261 1286 case_clause: // CFA 1262 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }1287 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); } 1263 1288 ; 1264 1289 … … 1271 1296 switch_clause_list: // CFA 1272 1297 case_label_list statement_list_nodecl 1273 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }1298 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); } 1274 1299 | switch_clause_list case_label_list statement_list_nodecl 1275 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 )) ) ) ); }1300 { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ); } 1276 1301 ; 1277 1302 1278 1303 iteration_statement: 1279 1304 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1280 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound($4 ) ) ); }1305 { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); } 1281 1306 | WHILE '(' ')' statement ELSE statement // CFA 1282 1307 { 1283 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound($4 ) ) );1284 SemanticWarning( yylloc, Warning::SuperfluousElse , "");1308 $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); 1309 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1285 1310 } 1286 1311 | WHILE '(' conditional_declaration ')' statement %prec THEN 1287 { $$ = new StatementNode( build_while( $3, maybe_build_compound($5 ) ) ); }1312 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1288 1313 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1289 { $$ = new StatementNode( build_while( $3, maybe_build_compound($5 ), $7 ) ); }1314 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); } 1290 1315 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1291 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound($2 ) ) ); }1316 { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); } 1292 1317 | DO statement WHILE '(' ')' ELSE statement // CFA 1293 1318 { 1294 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound($2 ) ) );1295 SemanticWarning( yylloc, Warning::SuperfluousElse , "");1319 $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); 1320 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1296 1321 } 1297 1322 | DO statement WHILE '(' comma_expression ')' ';' 1298 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound($2 ) ) ); }1323 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); } 1299 1324 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1300 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound($2 ), $8 ) ); }1325 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); } 1301 1326 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1302 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound($4 ) ) ); }1327 { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); } 1303 1328 | FOR '(' ')' statement ELSE statement // CFA 1304 1329 { 1305 $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound($4 ) ) );1306 SemanticWarning( yylloc, Warning::SuperfluousElse , "");1330 $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); 1331 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1307 1332 } 1308 1333 | FOR '(' for_control_expression_list ')' statement %prec THEN 1309 { $$ = new StatementNode( build_for( $3, maybe_build_compound($5 ) ) ); }1334 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1310 1335 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1311 { $$ = new StatementNode( build_for( $3, maybe_build_compound($5 ), $7 ) ); }1336 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); } 1312 1337 ; 1313 1338 … … 1323 1348 if ( $1->condition ) { 1324 1349 if ( $3->condition ) { 1325 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true) );1350 $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) ); 1326 1351 } // if 1327 1352 } else $1->condition = $3->condition; 1328 1353 if ( $1->change ) { 1329 1354 if ( $3->change ) { 1330 $1->change->expr.reset( new CommaExpr($1->change->expr.release(), $3->change->expr.release() ) );1355 $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) ); 1331 1356 } // if 1332 1357 } else $1->change = $3->change; … … 1337 1362 for_control_expression: 1338 1363 ';' comma_expression_opt ';' comma_expression_opt 1339 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }1364 { $$ = new ForCtrl( nullptr, $2, $4 ); } 1340 1365 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1341 { $$ = new ForCtrl( $1, $3, $5 ); } 1366 { 1367 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr; 1368 $$ = new ForCtrl( init, $3, $5 ); 1369 } 1342 1370 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1343 { $$ = new ForCtrl( $1, $2, $4 ); }1371 { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); } 1344 1372 1345 1373 | '@' ';' comma_expression // CFA, empty loop-index 1346 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }1374 { $$ = new ForCtrl( nullptr, $3, nullptr ); } 1347 1375 | '@' ';' comma_expression ';' comma_expression // CFA, empty loop-index 1348 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }1376 { $$ = new ForCtrl( nullptr, $3, $5 ); } 1349 1377 1350 1378 | comma_expression // CFA, anonymous loop-index 1351 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }1379 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1352 1380 | downupdowneq comma_expression // CFA, anonymous loop-index 1353 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }1381 { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1354 1382 1355 1383 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1356 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }1384 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1357 1385 | '@' updowneq comma_expression // CFA, anonymous loop-index 1358 1386 { 1359 1387 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1360 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );1388 else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1361 1389 } 1362 1390 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1366 1394 } 1367 1395 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1368 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }1396 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1369 1397 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1370 1398 { 1371 1399 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1372 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );1400 else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1373 1401 } 1374 1402 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1389 1417 1390 1418 | comma_expression ';' comma_expression // CFA 1391 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }1419 { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1392 1420 | comma_expression ';' downupdowneq comma_expression // CFA 1393 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }1421 { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1394 1422 1395 1423 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1396 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }1424 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1397 1425 | comma_expression ';' '@' updowneq comma_expression // CFA 1398 1426 { 1399 1427 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1400 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );1428 else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1401 1429 } 1402 1430 | comma_expression ';' comma_expression updowneq '@' // CFA … … 1404 1432 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1405 1433 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1406 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );1434 else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1407 1435 } 1408 1436 | comma_expression ';' '@' updowneq '@' // CFA, error … … 1410 1438 1411 1439 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1412 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }1440 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1413 1441 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1414 1442 { 1415 1443 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1416 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );1444 else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 ); 1417 1445 } 1418 1446 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA … … 1420 1448 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1421 1449 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1422 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );1450 else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 ); 1423 1451 } 1424 1452 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1425 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }1453 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1426 1454 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1427 1455 { 1428 1456 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1429 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );1457 else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr ); 1430 1458 } 1431 1459 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA … … 1433 1461 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1434 1462 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1435 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );1463 else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr ); 1436 1464 } 1437 1465 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA … … 1439 1467 1440 1468 | declaration comma_expression // CFA 1441 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }1469 { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1442 1470 | declaration downupdowneq comma_expression // CFA 1443 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }1471 { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1444 1472 1445 1473 | declaration comma_expression updowneq comma_expression // CFA 1446 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }1474 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1447 1475 | declaration '@' updowneq comma_expression // CFA 1448 1476 { 1449 1477 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1450 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );1478 else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE ); 1451 1479 } 1452 1480 | declaration comma_expression updowneq '@' // CFA … … 1454 1482 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1455 1483 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1456 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );1484 else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE ); 1457 1485 } 1458 1486 1459 1487 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1460 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }1488 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1461 1489 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1462 1490 { 1463 1491 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1464 else $$ = forCtrl( $1, $4, $3, nullptr, $6 );1492 else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 ); 1465 1493 } 1466 1494 | declaration comma_expression updowneq '@' '~' comma_expression // CFA … … 1468 1496 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1469 1497 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1470 else $$ = forCtrl( $1, $2, $3, nullptr, $6 );1498 else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 ); 1471 1499 } 1472 1500 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1473 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }1501 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1474 1502 | declaration '@' updowneq comma_expression '~' '@' // CFA 1475 1503 { 1476 1504 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1477 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );1505 else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr ); 1478 1506 } 1479 1507 | declaration comma_expression updowneq '@' '~' '@' // CFA … … 1481 1509 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1482 1510 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1483 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );1511 else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr ); 1484 1512 } 1485 1513 | declaration '@' updowneq '@' '~' '@' // CFA, error … … 1496 1524 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1497 1525 } 1498 1526 ; 1499 1527 1500 1528 downupdowneq: … … 1505 1533 | ErangeDownEq 1506 1534 { $$ = OperKinds::GEThan; } 1507 1535 ; 1508 1536 1509 1537 updown: … … 1512 1540 | ErangeDown 1513 1541 { $$ = OperKinds::GThan; } 1514 1542 ; 1515 1543 1516 1544 updowneq: … … 1520 1548 | ErangeDownEq 1521 1549 { $$ = OperKinds::GEThan; } 1522 1550 ; 1523 1551 1524 1552 jump_statement: 1525 1553 GOTO identifier_or_type_name ';' 1526 { $$ = new StatementNode( build_branch( $2,BranchStmt::Goto ) ); }1554 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); } 1527 1555 | GOTO '*' comma_expression ';' // GCC, computed goto 1528 1556 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1531 1559 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1532 1560 | fall_through_name ';' // CFA 1533 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }1561 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); } 1534 1562 | fall_through_name identifier_or_type_name ';' // CFA 1535 { $$ = new StatementNode( build_branch( $2,BranchStmt::FallThrough ) ); }1563 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); } 1536 1564 | fall_through_name DEFAULT ';' // CFA 1537 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }1565 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); } 1538 1566 | CONTINUE ';' 1539 1567 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1540 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }1568 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); } 1541 1569 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1542 1570 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1543 1571 // the target of the transfer appears only at the start of an iteration statement. 1544 { $$ = new StatementNode( build_branch( $2,BranchStmt::Continue ) ); }1572 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); } 1545 1573 | BREAK ';' 1546 1574 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1547 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }1575 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); } 1548 1576 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1549 1577 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1550 1578 // the target of the transfer appears only at the start of an iteration statement. 1551 { $$ = new StatementNode( build_branch( $2,BranchStmt::Break ) ); }1579 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); } 1552 1580 | RETURN comma_expression_opt ';' 1553 { $$ = new StatementNode( build_return( $2 ) ); }1581 { $$ = new StatementNode( build_return( yylloc, $2 ) ); } 1554 1582 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1555 1583 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1556 1584 | SUSPEND ';' 1557 { $$ = new StatementNode( build_suspend( nullptr) ); }1585 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); } 1558 1586 | SUSPEND compound_statement 1559 { $$ = new StatementNode( build_suspend( $2) ); }1587 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); } 1560 1588 | SUSPEND COROUTINE ';' 1561 { $$ = new StatementNode( build_suspend( nullptr,SuspendStmt::Coroutine ) ); }1589 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); } 1562 1590 | SUSPEND COROUTINE compound_statement 1563 { $$ = new StatementNode( build_suspend( $3,SuspendStmt::Coroutine ) ); }1591 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); } 1564 1592 | SUSPEND GENERATOR ';' 1565 { $$ = new StatementNode( build_suspend( nullptr,SuspendStmt::Generator ) ); }1593 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); } 1566 1594 | SUSPEND GENERATOR compound_statement 1567 { $$ = new StatementNode( build_suspend( $3,SuspendStmt::Generator ) ); }1595 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); } 1568 1596 | THROW assignment_expression_opt ';' // handles rethrow 1569 { $$ = new StatementNode( build_throw( $2 ) ); }1597 { $$ = new StatementNode( build_throw( yylloc, $2 ) ); } 1570 1598 | THROWRESUME assignment_expression_opt ';' // handles reresume 1571 { $$ = new StatementNode( build_resume( $2 ) ); }1599 { $$ = new StatementNode( build_resume( yylloc, $2 ) ); } 1572 1600 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1573 1601 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1581 1609 with_statement: 1582 1610 WITH '(' tuple_expression_list ')' statement 1583 { $$ = new StatementNode( build_with( $3, $5 ) ); }1584 ; 1585 1586 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex".1611 { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); } 1612 ; 1613 1614 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possibly change syntax to "with mutex". 1587 1615 mutex_statement: 1588 MUTEX '(' argument_expression_list ')' statement 1589 { $$ = new StatementNode( build_mutex( $3, $5 ) ); } 1616 MUTEX '(' argument_expression_list_opt ')' statement 1617 { 1618 if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; } 1619 $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) ); 1620 } 1590 1621 ; 1591 1622 … … 1598 1629 { $$ = nullptr; } 1599 1630 | when_clause 1600 ;1601 1602 waitfor:1603 WAITFOR '(' cast_expression ')'1604 { $$ = $3; }1605 // | WAITFOR '(' cast_expression ',' argument_expression_list_opt ')'1606 // { $$ = (ExpressionNode *)$3->set_last( $5 ); }1607 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'1608 { $$ = (ExpressionNode *)($3->set_last( $5 )); }1609 1631 ; 1610 1632 … … 1617 1639 1618 1640 timeout: 1619 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1620 ; 1621 1622 waitfor_clause: 1641 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1642 ; 1643 1644 wor: 1645 OROR 1646 | WOR 1647 1648 waitfor: 1649 WAITFOR '(' cast_expression ')' 1650 { $$ = $3; } 1651 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1652 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1653 ; 1654 1655 wor_waitfor_clause: 1623 1656 when_clause_opt waitfor statement %prec THEN 1624 { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1 ); } 1625 | when_clause_opt waitfor statement WOR waitfor_clause 1626 { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1, $5 ); } 1627 | when_clause_opt timeout statement %prec THEN 1628 { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1 ); } 1629 | when_clause_opt ELSE statement 1630 { $$ = build_waitfor_timeout( nullptr, maybe_build_compound( $3 ), $1 ); } 1657 // Called first: create header for WaitForStmt. 1658 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1659 | wor_waitfor_clause wor when_clause_opt waitfor statement 1660 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1661 | wor_waitfor_clause wor when_clause_opt ELSE statement 1662 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); } 1663 | wor_waitfor_clause wor when_clause_opt timeout statement %prec THEN 1664 { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1631 1665 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1632 | w hen_clause_opt timeout statement WORELSE statement // syntax error1666 | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1633 1667 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1634 | w hen_clause_opt timeout statement WORwhen_clause ELSE statement1635 { $$ = build_waitfor_ timeout( $2, maybe_build_compound( $3 ), $1, maybe_build_compound( $7 ), $5); }1668 | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1669 { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); } 1636 1670 ; 1637 1671 1638 1672 waitfor_statement: 1639 when_clause_opt waitfor statement %prec THEN 1640 { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); } 1641 | when_clause_opt waitfor statement WOR waitfor_clause 1642 { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); } 1673 wor_waitfor_clause %prec THEN 1674 { $$ = new StatementNode( $1 ); } 1675 ; 1676 1677 wand: 1678 ANDAND 1679 | WAND 1680 ; 1681 1682 waituntil: 1683 WAITUNTIL '(' comma_expression ')' 1684 { $$ = $3; } 1685 ; 1686 1687 waituntil_clause: 1688 when_clause_opt waituntil statement 1689 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1690 | '(' wor_waituntil_clause ')' 1691 { $$ = $2; } 1692 ; 1693 1694 wand_waituntil_clause: 1695 waituntil_clause %prec THEN 1696 { $$ = $1; } 1697 | waituntil_clause wand wand_waituntil_clause 1698 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); } 1699 ; 1700 1701 wor_waituntil_clause: 1702 wand_waituntil_clause 1703 { $$ = $1; } 1704 | wor_waituntil_clause wor wand_waituntil_clause 1705 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); } 1706 | wor_waituntil_clause wor when_clause_opt ELSE statement 1707 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1708 | wor_waituntil_clause wor when_clause_opt timeout statement %prec THEN 1709 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); } 1710 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1711 | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1712 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1713 | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1714 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, 1715 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, 1716 build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ), 1717 build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); } 1718 ; 1719 1720 waituntil_statement: 1721 wor_waituntil_clause %prec THEN 1722 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1723 { 1724 $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) ); 1725 // $$ = new StatementNode( build_compound( yylloc, nullptr ) ); 1726 } 1643 1727 ; 1644 1728 1645 1729 exception_statement: 1646 TRY compound_statement handler_clause 1647 { $$ = new StatementNode( build_try( $2, $3, 0) ); }1730 TRY compound_statement handler_clause %prec THEN 1731 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); } 1648 1732 | TRY compound_statement finally_clause 1649 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }1733 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); } 1650 1734 | TRY compound_statement handler_clause finally_clause 1651 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }1735 { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); } 1652 1736 ; 1653 1737 1654 1738 handler_clause: 1655 1739 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1656 { $$ = new StatementNode( build_catch($1, $4, $6, $8 ) ); }1740 { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); } 1657 1741 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1658 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch($2, $5, $7, $9 ) ) ); }1742 { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); } 1659 1743 ; 1660 1744 … … 1666 1750 1667 1751 handler_key: 1668 CATCH { $$ = CatchStmt::Terminate; }1669 | RECOVER { $$ = CatchStmt::Terminate; }1670 | CATCHRESUME { $$ = CatchStmt::Resume; }1671 | FIXUP { $$ = CatchStmt::Resume; }1752 CATCH { $$ = ast::Terminate; } 1753 | RECOVER { $$ = ast::Terminate; } 1754 | CATCHRESUME { $$ = ast::Resume; } 1755 | FIXUP { $$ = ast::Resume; } 1672 1756 ; 1673 1757 1674 1758 finally_clause: 1675 FINALLY compound_statement { $$ = new StatementNode( build_finally($2 ) ); }1759 FINALLY compound_statement { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); } 1676 1760 ; 1677 1761 … … 1699 1783 asm_statement: 1700 1784 ASM asm_volatile_opt '(' string_literal ')' ';' 1701 { $$ = new StatementNode( build_asm( $2, $4, 0) ); }1785 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); } 1702 1786 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1703 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }1787 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); } 1704 1788 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1705 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }1789 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); } 1706 1790 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1707 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }1791 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); } 1708 1792 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1709 { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); }1793 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); } 1710 1794 ; 1711 1795 … … 1731 1815 asm_operand: // GCC 1732 1816 string_literal '(' constant_expression ')' 1733 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }1817 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1734 1818 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1735 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); } 1819 { 1820 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) ); 1821 delete $2.str; 1822 } 1736 1823 ; 1737 1824 … … 1740 1827 { $$ = nullptr; } // use default argument 1741 1828 | string_literal 1742 { $$ = new ExpressionNode( $1 ); }1829 { $$ = $1; } 1743 1830 | asm_clobbers_list_opt ',' string_literal 1744 { $$ = (ExpressionNode *)( $1->set_last( new ExpressionNode( $3 ) )); }1831 { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); } 1745 1832 ; 1746 1833 … … 1748 1835 identifier 1749 1836 { 1750 $$ = new LabelNode(); $$->labels. push_back(*$1 );1837 $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 ); 1751 1838 delete $1; // allocated by lexer 1752 1839 } 1753 1840 | label_list ',' identifier 1754 1841 { 1755 $$ = $1; $1->labels. push_back(*$3 );1842 $$ = $1; $1->labels.emplace_back( yylloc, *$3 ); 1756 1843 delete $3; // allocated by lexer 1757 1844 } … … 1804 1891 { 1805 1892 // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" ); 1806 1893 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 1807 1894 // printf( "\tattr %s\n", attr->name.c_str() ); 1808 1895 // } // for … … 1814 1901 static_assert: 1815 1902 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1816 { $$ = DeclarationNode::newStaticAssert( $3, $5); }1903 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); } 1817 1904 | STATICASSERT '(' constant_expression ')' ';' // CFA 1818 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }1905 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); } 1819 1906 1820 1907 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 1880 1967 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 1881 1968 // { 1882 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );1969 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true ); 1883 1970 // } 1884 1971 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 1885 1972 // { 1886 1973 // typedefTable.setNextIdentifier( *$5 ); 1887 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );1974 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true ); 1888 1975 // } 1889 1976 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 1890 1977 // { 1891 1978 // typedefTable.setNextIdentifier( *$5 ); 1892 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );1979 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true ); 1893 1980 // } 1894 1981 // | '[' ']' typegen_name … … 1902 1989 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1903 1990 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 1904 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0)->addQualifiers( $8 ); }1991 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); } 1905 1992 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1906 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0)->addQualifiers( $8 ); }1993 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); } 1907 1994 ; 1908 1995 … … 1940 2027 { 1941 2028 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 1942 $$ = $3->addType( $2 )->addTypedef(); 2029 if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) { 2030 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr; 2031 } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1943 2032 } 1944 2033 | typedef_declaration pop ',' push declarator … … 1948 2037 } 1949 2038 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 1950 { 1951 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" ); 1952 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef(); 1953 } 2039 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1954 2040 | type_specifier TYPEDEF declarator 1955 { 1956 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" ); 1957 $$ = $3->addType( $1 )->addTypedef(); 1958 } 2041 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1959 2042 | type_specifier TYPEDEF type_qualifier_list declarator 1960 { 1961 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" ); 1962 $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 ); 1963 } 2043 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1964 2044 ; 1965 2045 … … 1968 2048 TYPEDEF identifier '=' assignment_expression 1969 2049 { 1970 SemanticError( yylloc, "T ypedefexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;2050 SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 1971 2051 } 1972 2052 | typedef_expression pop ',' push identifier '=' assignment_expression 1973 2053 { 1974 SemanticError( yylloc, "T ypedefexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;2054 SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 1975 2055 } 1976 2056 ; … … 1982 2062 | typedef_expression // deprecated GCC, naming expression type 1983 2063 | sue_declaration_specifier 2064 { 2065 assert( $1->type ); 2066 if ( $1->type->qualifiers.any() ) { // CV qualifiers ? 2067 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr; 2068 } 2069 // enums are never empty declarations because there must have at least one enumeration. 2070 if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ? 2071 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr; 2072 } 2073 } 1984 2074 ; 1985 2075 … … 1987 2077 // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 1988 2078 // storage-class 1989 declarator asm_name_opt initializer_opt2079 variable_declarator asm_name_opt initializer_opt 1990 2080 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2081 | variable_type_redeclarator asm_name_opt initializer_opt 2082 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2083 2084 | general_function_declarator asm_name_opt 2085 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); } 2086 | general_function_declarator asm_name_opt '=' VOID 2087 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); } 2088 1991 2089 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 1992 2090 { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 1993 2091 ; 1994 2092 2093 general_function_declarator: 2094 function_type_redeclarator 2095 | function_declarator 2096 ; 2097 1995 2098 declaration_specifier: // type specifier + storage class 1996 2099 basic_declaration_specifier 2100 | type_declaration_specifier 1997 2101 | sue_declaration_specifier 1998 | type_declaration_specifier 2102 | sue_declaration_specifier invalid_types 2103 { 2104 SemanticError( yylloc, ::toString( "Missing ';' after end of ", 2105 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ), 2106 " declaration" ) ); 2107 $$ = nullptr; 2108 } 2109 ; 2110 2111 invalid_types: 2112 aggregate_key 2113 | basic_type_name 2114 | indirect_type 1999 2115 ; 2000 2116 … … 2013 2129 basic_type_specifier 2014 2130 | sue_type_specifier 2015 {2016 // printf( "sue_type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );2017 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2018 // printf( "\tattr %s\n", attr->name.c_str() );2019 // } // for2020 }2021 2131 | type_type_specifier 2022 2132 ; … … 2065 2175 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } 2066 2176 | forall 2177 { $$ = DeclarationNode::newForall( $1 ); } 2067 2178 ; 2068 2179 2069 2180 forall: 2070 2181 FORALL '(' type_parameter_list ')' // CFA 2071 { $$ = DeclarationNode::newForall( $3 ); }2182 { $$ = $3; } 2072 2183 ; 2073 2184 … … 2226 2337 { $$ = DeclarationNode::newTypeof( $3 ); } 2227 2338 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2228 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ), true ); }2339 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); } 2229 2340 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2230 2341 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2239 2350 { 2240 2351 // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2241 2352 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2242 2353 // printf( "\tattr %s\n", attr->name.c_str() ); 2243 2354 // } // for … … 2255 2366 { 2256 2367 // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2257 2368 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2258 2369 // printf( "\tattr %s\n", attr->name.c_str() ); 2259 2370 // } // for … … 2333 2444 { 2334 2445 // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2335 2446 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2336 2447 // printf( "\tattr %s\n", attr->name.c_str() ); 2337 2448 // } // for … … 2357 2468 '{' field_declaration_list_opt '}' type_parameters_opt 2358 2469 { 2359 // printf( "aggregate_type1 %s\n", $3.str->c_str() );2360 // if ( $2 )2361 // for ( Attribute * attr: reverseIterate( $2->attributes ) ) {2362 // printf( "copySpecifiers12 %s\n", attr->name.c_str() );2363 // } // for2364 2470 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); 2365 // printf( "aggregate_type2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );2366 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2367 // printf( "aggregate_type3 %s\n", attr->name.c_str() );2368 // } // for2369 2471 } 2370 2472 | aggregate_key attribute_list_opt TYPEDEFname // unqualified type name … … 2375 2477 '{' field_declaration_list_opt '}' type_parameters_opt 2376 2478 { 2377 // printf( "AGG3\n" );2378 2479 DeclarationNode::newFromTypedef( $3 ); 2379 2480 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2386 2487 '{' field_declaration_list_opt '}' type_parameters_opt 2387 2488 { 2388 // printf( "AGG4\n" );2389 2489 DeclarationNode::newFromTypeGen( $3, nullptr ); 2390 2490 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2413 2513 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 2414 2514 // delete newFromTypeGen. 2415 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2416 $3->type->symbolic.name = nullptr; 2417 $3->type->symbolic.actuals = nullptr; 2418 delete $3; 2515 if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) { 2516 $$ = $3->addQualifiers( $2 ); 2517 } else { 2518 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2519 $3->type->symbolic.name = nullptr; // copied to $$ 2520 $3->type->symbolic.actuals = nullptr; 2521 delete $3; 2522 } 2419 2523 } 2420 2524 ; … … 2427 2531 aggregate_data: 2428 2532 STRUCT vtable_opt 2429 { $$ = AggregateDecl::Struct; }2533 { $$ = ast::AggregateDecl::Struct; } 2430 2534 | UNION 2431 { $$ = AggregateDecl::Union; }2535 { $$ = ast::AggregateDecl::Union; } 2432 2536 | EXCEPTION // CFA 2433 { $$ = AggregateDecl::Exception; }2434 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }2537 { $$ = ast::AggregateDecl::Exception; } 2538 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; } 2435 2539 ; 2436 2540 2437 2541 aggregate_control: // CFA 2438 2542 MONITOR 2439 { $$ = AggregateDecl::Monitor; }2543 { $$ = ast::AggregateDecl::Monitor; } 2440 2544 | MUTEX STRUCT 2441 { $$ = AggregateDecl::Monitor; }2545 { $$ = ast::AggregateDecl::Monitor; } 2442 2546 | GENERATOR 2443 { $$ = AggregateDecl::Generator; }2547 { $$ = ast::AggregateDecl::Generator; } 2444 2548 | MUTEX GENERATOR 2445 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2549 { 2550 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2551 $$ = ast::AggregateDecl::NoAggregate; 2552 } 2446 2553 | COROUTINE 2447 { $$ = AggregateDecl::Coroutine; }2554 { $$ = ast::AggregateDecl::Coroutine; } 2448 2555 | MUTEX COROUTINE 2449 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2556 { 2557 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2558 $$ = ast::AggregateDecl::NoAggregate; 2559 } 2450 2560 | THREAD 2451 { $$ = AggregateDecl::Thread; }2561 { $$ = ast::AggregateDecl::Thread; } 2452 2562 | MUTEX THREAD 2453 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2563 { 2564 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2565 $$ = ast::AggregateDecl::NoAggregate; 2566 } 2454 2567 ; 2455 2568 … … 2467 2580 $$ = fieldDecl( $1, $2 ); 2468 2581 // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2469 2582 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2470 2583 // printf( "\tattr %s\n", attr->name.c_str() ); 2471 2584 // } // for … … 2473 2586 | EXTENSION type_specifier field_declaring_list_opt ';' // GCC 2474 2587 { $$ = fieldDecl( $2, $3 ); distExt( $$ ); } 2588 | STATIC type_specifier field_declaring_list_opt ';' // CFA 2589 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; } 2475 2590 | INLINE type_specifier field_abstract_list_opt ';' // CFA 2476 2591 { … … 2483 2598 } 2484 2599 | INLINE aggregate_control ';' // CFA 2485 2600 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; } 2486 2601 | typedef_declaration ';' // CFA 2487 2602 | cfa_field_declaring_list ';' // CFA, new style field declaration … … 2509 2624 { $$ = $1->addBitfield( $2 ); } 2510 2625 | variable_type_redeclarator bit_subrange_size_opt 2626 // A semantic check is required to ensure bit_subrange only appears on integral types. 2627 { $$ = $1->addBitfield( $2 ); } 2628 | function_type_redeclarator bit_subrange_size_opt 2511 2629 // A semantic check is required to ensure bit_subrange only appears on integral types. 2512 2630 { $$ = $1->addBitfield( $2 ); } … … 2563 2681 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2564 2682 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2565 2566 if ( $3->storageClasses.val != 0 || $3->type->qualifiers. val != 0)2683 { 2684 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() ) 2567 2685 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2568 2686 … … 2575 2693 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2576 2694 { 2577 if ( $3->storageClasses. val != 0|| $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }2695 if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2578 2696 typedefTable.makeTypedef( *$6 ); 2579 2697 } … … 2609 2727 enum_type_nobody: // enum - {...} 2610 2728 ENUM attribute_list_opt identifier 2611 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }2729 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); } 2612 2730 | ENUM attribute_list_opt type_name 2613 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }2731 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); } 2614 2732 ; 2615 2733 … … 2751 2869 type_no_function: // sizeof, alignof, cast (constructor) 2752 2870 cfa_abstract_declarator_tuple // CFA 2753 | type_specifier 2871 | type_specifier // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing 2754 2872 | type_specifier abstract_declarator 2755 2873 { $$ = $2->addType( $1 ); } … … 2796 2914 designator_list ':' // C99, CFA uses ":" instead of "=" 2797 2915 | identifier_at ':' // GCC, field name 2798 { $$ = new ExpressionNode( build_varref( $1 ) ); }2916 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 2799 2917 ; 2800 2918 … … 2808 2926 designator: 2809 2927 '.' identifier_at // C99, field name 2810 { $$ = new ExpressionNode( build_varref( $2 ) ); }2928 { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); } 2811 2929 | '[' push assignment_expression pop ']' // C99, single array element 2812 2930 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2815 2933 { $$ = $3; } 2816 2934 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2817 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }2935 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); } 2818 2936 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2819 2937 { $$ = $4; } … … 2855 2973 { 2856 2974 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2857 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2858 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2859 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2975 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2976 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2977 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2860 2978 } 2861 2979 type_initializer_opt assertion_list_opt … … 2868 2986 { 2869 2987 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2870 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );2988 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 ); 2871 2989 } 2872 2990 // | type_specifier identifier_parameter_declarator 2873 2991 | assertion_list 2874 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2992 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2875 2993 ; 2876 2994 2877 2995 new_type_class: // CFA 2878 2996 // empty 2879 { $$ = TypeDecl::Otype; }2997 { $$ = ast::TypeDecl::Otype; } 2880 2998 | '&' 2881 { $$ = TypeDecl::Dtype; }2999 { $$ = ast::TypeDecl::Dtype; } 2882 3000 | '*' 2883 { $$ = TypeDecl::DStype; } // dtype + sized3001 { $$ = ast::TypeDecl::DStype; } // dtype + sized 2884 3002 // | '(' '*' ')' 2885 // { $$ = TypeDecl::Ftype; }3003 // { $$ = ast::TypeDecl::Ftype; } 2886 3004 | ELLIPSIS 2887 { $$ = TypeDecl::Ttype; }3005 { $$ = ast::TypeDecl::Ttype; } 2888 3006 ; 2889 3007 2890 3008 type_class: // CFA 2891 3009 OTYPE 2892 { $$ = TypeDecl::Otype; }3010 { $$ = ast::TypeDecl::Otype; } 2893 3011 | DTYPE 2894 { $$ = TypeDecl::Dtype; }3012 { $$ = ast::TypeDecl::Dtype; } 2895 3013 | FTYPE 2896 { $$ = TypeDecl::Ftype; }3014 { $$ = ast::TypeDecl::Ftype; } 2897 3015 | TTYPE 2898 { $$ = TypeDecl::Ttype; }3016 { $$ = ast::TypeDecl::Ttype; } 2899 3017 ; 2900 3018 … … 2922 3040 type_list: // CFA 2923 3041 type 2924 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3042 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 2925 3043 | assignment_expression 2926 3044 | type_list ',' type 2927 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ) )); }3045 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); } 2928 3046 | type_list ',' assignment_expression 2929 3047 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 2950 3068 { 2951 3069 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 2952 $$ = DeclarationNode::newTypeDecl( $1, 0);3070 $$ = DeclarationNode::newTypeDecl( $1, nullptr ); 2953 3071 } 2954 3072 | identifier_or_type_name '(' type_parameter_list ')' … … 2961 3079 trait_specifier: // CFA 2962 3080 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 2963 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 3081 { 3082 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3083 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 3084 } 3085 | forall TRAIT identifier_or_type_name '{' '}' // alternate 3086 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); } 2964 3087 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 2965 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 3088 { 3089 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3090 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 3091 } 3092 | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 3093 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); } 2966 3094 ; 2967 3095 … … 3022 3150 external_definition: 3023 3151 DIRECTIVE 3024 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }3152 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); } 3025 3153 | declaration 3154 { 3155 // Variable declarations of anonymous types requires creating a unique type-name across multiple translation 3156 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is 3157 // disallowed at the moment. 3158 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) { 3159 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) { 3160 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr; 3161 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union 3162 SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr; 3163 } 3164 } 3165 } 3026 3166 | IDENTIFIER IDENTIFIER 3027 3167 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } … … 3043 3183 } 3044 3184 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3045 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0) ) ); }3185 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); } 3046 3186 | EXTERN STRINGliteral 3047 3187 { 3048 3188 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3049 linkage = LinkageSpec::update( yylloc, linkage, $2 );3189 linkage = ast::Linkage::update( yylloc, linkage, $2 ); 3050 3190 } 3051 3191 up external_definition down … … 3058 3198 { 3059 3199 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3060 linkage = LinkageSpec::update( yylloc, linkage, $2 );3200 linkage = ast::Linkage::update( yylloc, linkage, $2 ); 3061 3201 } 3062 3202 '{' up external_definition_list_opt down '}' … … 3069 3209 | type_qualifier_list 3070 3210 { 3071 if ( $1->type->qualifiers. val) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3211 if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3072 3212 if ( $1->type->forall ) forall = true; // remember generic type 3073 3213 } … … 3075 3215 { 3076 3216 distQual( $5, $1 ); 3077 3217 forall = false; 3078 3218 $$ = $5; 3079 3219 } 3080 3220 | declaration_qualifier_list 3081 3221 { 3082 if ( $1->type && $1->type->qualifiers. val) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3222 if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3083 3223 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 3084 3224 } … … 3086 3226 { 3087 3227 distQual( $5, $1 ); 3088 3228 forall = false; 3089 3229 $$ = $5; 3090 3230 } 3091 3231 | declaration_qualifier_list type_qualifier_list 3092 3232 { 3093 if ( ($1->type && $1->type->qualifiers. val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3233 if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3094 3234 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3095 3235 } … … 3097 3237 { 3098 3238 distQual( $6, $1->addQualifiers( $2 ) ); 3099 3239 forall = false; 3100 3240 $$ = $6; 3101 3241 } … … 3141 3281 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 3142 3282 } 3143 | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement3283 | declaration_specifier function_type_redeclarator with_clause_opt compound_statement 3144 3284 { 3145 3285 rebindForall( $1, $2 ); … … 3177 3317 | variable_type_redeclarator 3178 3318 | function_declarator 3319 | function_type_redeclarator 3179 3320 ; 3180 3321 3181 3322 subrange: 3182 3323 constant_expression '~' constant_expression // CFA, integer subrange 3183 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }3324 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 3184 3325 ; 3185 3326 … … 3190 3331 { 3191 3332 DeclarationNode * name = new DeclarationNode(); 3192 name->asmName = $3;3333 name->asmName = maybeMoveBuild( $3 ); 3193 3334 $$ = name->addQualifiers( $5 ); 3194 3335 } … … 3287 3428 variable_ptr: 3288 3429 ptrref_operator variable_declarator 3289 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3430 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3290 3431 | ptrref_operator type_qualifier_list variable_declarator 3291 3432 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3303 3444 | '(' attribute_list variable_ptr ')' array_dimension 3304 3445 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3305 | '(' variable_array ')' multi_array_dimension 3446 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 3306 3447 { $$ = $2->addArray( $4 ); } 3307 3448 | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis … … 3351 3492 function_ptr: 3352 3493 ptrref_operator function_declarator 3353 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3494 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3354 3495 | ptrref_operator type_qualifier_list function_declarator 3355 3496 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3403 3544 KR_function_ptr: 3404 3545 ptrref_operator KR_function_declarator 3405 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3546 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3406 3547 | ptrref_operator type_qualifier_list KR_function_declarator 3407 3548 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3427 3568 ; 3428 3569 3429 // This pattern parses a declaration for a variable or function prototypethat redefines a type name, e.g.:3570 // This pattern parses a declaration for a variable that redefines a type name, e.g.: 3430 3571 // 3431 3572 // typedef int foo; … … 3433 3574 // int foo; // redefine typedef name in new scope 3434 3575 // } 3435 //3436 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays3437 // and functions versus pointers to arrays and functions.3438 3576 3439 3577 paren_type: … … 3450 3588 paren_type attribute_list_opt 3451 3589 { $$ = $1->addQualifiers( $2 ); } 3452 | type_ptr3453 | type_array attribute_list_opt3590 | variable_type_ptr 3591 | variable_type_array attribute_list_opt 3454 3592 { $$ = $1->addQualifiers( $2 ); } 3455 | type_function attribute_list_opt3593 | variable_type_function attribute_list_opt 3456 3594 { $$ = $1->addQualifiers( $2 ); } 3457 3595 ; 3458 3596 3459 type_ptr:3597 variable_type_ptr: 3460 3598 ptrref_operator variable_type_redeclarator 3461 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3599 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3462 3600 | ptrref_operator type_qualifier_list variable_type_redeclarator 3463 3601 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3464 | '(' type_ptr ')' attribute_list_opt// redundant parenthesis3602 | '(' variable_type_ptr ')' attribute_list_opt // redundant parenthesis 3465 3603 { $$ = $2->addQualifiers( $4 ); } 3466 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis3604 | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis 3467 3605 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3468 3606 ; 3469 3607 3470 type_array:3608 variable_type_array: 3471 3609 paren_type array_dimension 3472 3610 { $$ = $1->addArray( $2 ); } 3473 | '(' type_ptr ')' array_dimension3611 | '(' variable_type_ptr ')' array_dimension 3474 3612 { $$ = $2->addArray( $4 ); } 3475 | '(' attribute_list type_ptr ')' array_dimension3613 | '(' attribute_list variable_type_ptr ')' array_dimension 3476 3614 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3477 | '(' type_array ')' multi_array_dimension// redundant parenthesis3615 | '(' variable_type_array ')' multi_array_dimension // redundant parenthesis 3478 3616 { $$ = $2->addArray( $4 ); } 3479 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis3617 | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis 3480 3618 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3481 | '(' type_array ')'// redundant parenthesis3619 | '(' variable_type_array ')' // redundant parenthesis 3482 3620 { $$ = $2; } 3483 | '(' attribute_list type_array ')'// redundant parenthesis3621 | '(' attribute_list variable_type_array ')' // redundant parenthesis 3484 3622 { $$ = $3->addQualifiers( $2 ); } 3485 3623 ; 3486 3624 3487 type_function: 3625 variable_type_function: 3626 '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3627 { $$ = $2->addParamList( $6 ); } 3628 | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3629 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3630 | '(' variable_type_function ')' // redundant parenthesis 3631 { $$ = $2; } 3632 | '(' attribute_list variable_type_function ')' // redundant parenthesis 3633 { $$ = $3->addQualifiers( $2 ); } 3634 ; 3635 3636 // This pattern parses a declaration for a function prototype that redefines a type name. It precludes declaring an 3637 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to 3638 // arrays and functions. 3639 3640 function_type_redeclarator: 3641 function_type_no_ptr attribute_list_opt 3642 { $$ = $1->addQualifiers( $2 ); } 3643 | function_type_ptr 3644 | function_type_array attribute_list_opt 3645 { $$ = $1->addQualifiers( $2 ); } 3646 ; 3647 3648 function_type_no_ptr: 3488 3649 paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3489 3650 { $$ = $1->addParamList( $4 ); } 3490 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)3651 | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')' 3491 3652 { $$ = $2->addParamList( $6 ); } 3492 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)3653 | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')' 3493 3654 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3494 | '(' type_function ')'// redundant parenthesis3655 | '(' function_type_no_ptr ')' // redundant parenthesis 3495 3656 { $$ = $2; } 3496 | '(' attribute_list type_function ')' // redundant parenthesis 3657 | '(' attribute_list function_type_no_ptr ')' // redundant parenthesis 3658 { $$ = $3->addQualifiers( $2 ); } 3659 ; 3660 3661 function_type_ptr: 3662 ptrref_operator function_type_redeclarator 3663 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3664 | ptrref_operator type_qualifier_list function_type_redeclarator 3665 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3666 | '(' function_type_ptr ')' attribute_list_opt 3667 { $$ = $2->addQualifiers( $4 ); } 3668 | '(' attribute_list function_type_ptr ')' attribute_list_opt 3669 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3670 ; 3671 3672 function_type_array: 3673 '(' function_type_ptr ')' array_dimension 3674 { $$ = $2->addArray( $4 ); } 3675 | '(' attribute_list function_type_ptr ')' array_dimension 3676 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3677 | '(' function_type_array ')' multi_array_dimension // redundant parenthesis 3678 { $$ = $2->addArray( $4 ); } 3679 | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis 3680 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3681 | '(' function_type_array ')' // redundant parenthesis 3682 { $$ = $2; } 3683 | '(' attribute_list function_type_array ')' // redundant parenthesis 3497 3684 { $$ = $3->addQualifiers( $2 ); } 3498 3685 ; … … 3517 3704 identifier_parameter_ptr: 3518 3705 ptrref_operator identifier_parameter_declarator 3519 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3706 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3520 3707 | ptrref_operator type_qualifier_list identifier_parameter_declarator 3521 3708 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3574 3761 type_parameter_ptr: 3575 3762 ptrref_operator type_parameter_redeclarator 3576 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3763 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3577 3764 | ptrref_operator type_qualifier_list type_parameter_redeclarator 3578 3765 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3617 3804 abstract_ptr: 3618 3805 ptrref_operator 3619 { $$ = DeclarationNode::newPointer( 0, $1 ); }3806 { $$ = DeclarationNode::newPointer( nullptr, $1 ); } 3620 3807 | ptrref_operator type_qualifier_list 3621 3808 { $$ = DeclarationNode::newPointer( $2, $1 ); } 3622 3809 | ptrref_operator abstract_declarator 3623 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }3810 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3624 3811 | ptrref_operator type_qualifier_list abstract_declarator 3625 3812 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3650 3837 // Only the first dimension can be empty. 3651 3838 '[' ']' 3652 { $$ = DeclarationNode::newArray( 0, 0, false ); }3839 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); } 3653 3840 | '[' ']' multi_array_dimension 3654 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }3841 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); } 3655 3842 // Cannot use constant_expression because of tuples => semantic check 3656 3843 | '[' push assignment_expression pop ',' comma_expression ']' // CFA 3657 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }3844 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); } 3658 3845 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3659 3846 | '[' push array_type_list pop ']' // CFA … … 3664 3851 array_type_list: 3665 3852 basic_type_name 3666 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3853 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3667 3854 | type_name 3668 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3855 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3669 3856 | assignment_expression upupeq assignment_expression 3670 3857 | array_type_list ',' basic_type_name 3671 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ) )); }3672 | array_type_list ',' type_name 3673 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ) )); }3858 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); } 3859 | array_type_list ',' type_name 3860 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); } 3674 3861 | array_type_list ',' assignment_expression upupeq assignment_expression 3675 3862 ; … … 3680 3867 | ErangeUpEq 3681 3868 { $$ = OperKinds::LEThan; } 3682 3869 ; 3683 3870 3684 3871 multi_array_dimension: 3685 3872 '[' push assignment_expression pop ']' 3686 { $$ = DeclarationNode::newArray( $3, 0, false ); }3873 { $$ = DeclarationNode::newArray( $3, nullptr, false ); } 3687 3874 | '[' push '*' pop ']' // C99 3688 3875 { $$ = DeclarationNode::newVarArray( 0 ); } 3689 3876 | multi_array_dimension '[' push assignment_expression pop ']' 3690 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }3877 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); } 3691 3878 | multi_array_dimension '[' push '*' pop ']' // C99 3692 3879 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } … … 3785 3972 array_parameter_1st_dimension: 3786 3973 '[' ']' 3787 { $$ = DeclarationNode::newArray( 0, 0, false ); }3974 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); } 3788 3975 // multi_array_dimension handles the '[' '*' ']' case 3789 3976 | '[' push type_qualifier_list '*' pop ']' // remaining C99 3790 3977 { $$ = DeclarationNode::newVarArray( $3 ); } 3791 3978 | '[' push type_qualifier_list pop ']' 3792 { $$ = DeclarationNode::newArray( 0, $3, false ); }3979 { $$ = DeclarationNode::newArray( nullptr, $3, false ); } 3793 3980 // multi_array_dimension handles the '[' assignment_expression ']' case 3794 3981 | '[' push type_qualifier_list assignment_expression pop ']' … … 3819 4006 variable_abstract_ptr: 3820 4007 ptrref_operator 3821 { $$ = DeclarationNode::newPointer( 0, $1 ); }4008 { $$ = DeclarationNode::newPointer( nullptr, $1 ); } 3822 4009 | ptrref_operator type_qualifier_list 3823 4010 { $$ = DeclarationNode::newPointer( $2, $1 ); } 3824 4011 | ptrref_operator variable_abstract_declarator 3825 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }4012 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3826 4013 | ptrref_operator type_qualifier_list variable_abstract_declarator 3827 4014 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3865 4052 // No SUE declaration in parameter list. 3866 4053 ptrref_operator type_specifier_nobody 3867 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }4054 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3868 4055 | type_qualifier_list ptrref_operator type_specifier_nobody 3869 4056 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 3870 4057 | ptrref_operator cfa_abstract_function 3871 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }4058 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3872 4059 | type_qualifier_list ptrref_operator cfa_abstract_function 3873 4060 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 3874 4061 | ptrref_operator cfa_identifier_parameter_declarator_tuple 3875 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }4062 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3876 4063 | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple 3877 4064 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } … … 3882 4069 // shift/reduce conflict with new-style empty (void) function return type. 3883 4070 '[' ']' type_specifier_nobody 3884 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }4071 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); } 3885 4072 | cfa_array_parameter_1st_dimension type_specifier_nobody 3886 4073 { $$ = $2->addNewArray( $1 ); } 3887 4074 | '[' ']' multi_array_dimension type_specifier_nobody 3888 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }4075 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); } 3889 4076 | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody 3890 4077 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 3893 4080 3894 4081 | '[' ']' cfa_identifier_parameter_ptr 3895 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }4082 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); } 3896 4083 | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr 3897 4084 { $$ = $2->addNewArray( $1 ); } 3898 4085 | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr 3899 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }4086 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); } 3900 4087 | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr 3901 4088 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 3953 4140 cfa_abstract_ptr: // CFA 3954 4141 ptrref_operator type_specifier 3955 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }4142 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3956 4143 | type_qualifier_list ptrref_operator type_specifier 3957 4144 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 3958 4145 | ptrref_operator cfa_abstract_function 3959 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }4146 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3960 4147 | type_qualifier_list ptrref_operator cfa_abstract_function 3961 4148 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 3962 4149 | ptrref_operator cfa_abstract_declarator_tuple 3963 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }4150 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3964 4151 | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple 3965 4152 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } -
src/Parser/parserutility.cc
r34b4268 r24d6572 10 10 // Created On : Sat May 16 15:30:39 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 18 10:12:00 201713 // Update Count : 812 // Last Modified On : Wed Mar 1 10:42:00 2023 13 // Update Count : 9 14 14 // 15 15 … … 19 19 #include <string> // for string 20 20 21 #include "SynTree/Constant.h" // for Constant 22 #include "SynTree/Expression.h" // for UntypedExpr, CastExpr, ConstantExpr 23 #include "SynTree/Type.h" // for BasicType, ZeroType, BasicType::Kind... 21 #include "AST/Expr.hpp" // for UntypedExpr, CastExpr, ConstantExpr 22 #include "AST/Type.hpp" // for BasicType, ZeroType, BasicType::Kind... 24 23 25 24 // rewrite … … 28 27 // if ( (int)(x != 0) ) ... 29 28 30 Expression *notZeroExpr( Expression *orig ) { 31 if( !orig ) return nullptr; 32 UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) ); 33 comparison->get_args().push_back( orig ); 34 comparison->get_args().push_back( new ConstantExpr( Constant( new ZeroType( noQualifiers ), "0", (unsigned long long int)0 ) ) ); 35 return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 29 ast::Expr * notZeroExpr( ast::Expr * orig ) { 30 return ( !orig ) ? nullptr : new ast::CastExpr( orig->location, 31 ast::UntypedExpr::createCall( orig->location, 32 "?!=?", 33 { 34 orig, 35 new ast::ConstantExpr( orig->location, 36 new ast::ZeroType(), 37 "0", 38 std::optional<unsigned long long>( 0 ) 39 ), 40 } 41 ), 42 new ast::BasicType( ast::BasicType::SignedInt ) 43 ); 36 44 } 37 45 -
src/Parser/parserutility.h
r34b4268 r24d6572 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // parserutility.h -- 7 // parserutility.h -- Collected utilities for the parser. 8 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:31:46 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:32:58 201713 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 14:03:00 2023 13 // Update Count : 7 14 14 // 15 15 16 16 #pragma once 17 17 18 class Expression; 18 #include "AST/Copy.hpp" // for shallowCopy 19 namespace ast { 20 class Expr; 21 } 19 22 20 Expression *notZeroExpr( Expression *orig ); 23 ast::Expr * notZeroExpr( ast::Expr *orig ); 24 25 template< typename T > 26 static inline auto maybeBuild( T * orig ) -> decltype(orig->build()) { 27 return (orig) ? orig->build() : nullptr; 28 } 29 30 template< typename T > 31 static inline auto maybeMoveBuild( T * orig ) -> decltype(orig->build()) { 32 auto ret = maybeBuild<T>(orig); 33 delete orig; 34 return ret; 35 } 36 37 template<typename node_t> 38 node_t * maybeCopy( node_t const * node ) { 39 return node ? ast::shallowCopy( node ) : nullptr; 40 } 21 41 22 42 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.