Changeset bb7422a
- Timestamp:
- Apr 4, 2023, 2:25:52 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- beeff61e, e02e13f
- Parents:
- 4541b09
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/AST/SymbolTable.cpp ¶
r4541b09 rbb7422a 70 70 if ( baseExpr ) { 71 71 if (baseExpr->env) { 72 Expr * base = shallowCopy(baseExpr);72 Expr * base = deepCopy(baseExpr); 73 73 const TypeSubstitution * subs = baseExpr->env; 74 74 base->env = nullptr; -
TabularUnified src/Parser/DeclarationNode.cc ¶
r4541b09 rbb7422a 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Mar 14 11:56:00 202313 // Update Count : 1 40612 // Last Modified On : Tue Apr 4 10:28:00 2023 13 // Update Count : 1392 14 14 // 15 15 … … 21 21 #include <string> // for string, operator+, allocator, char... 22 22 23 #include "AST/Attribute.hpp" // for Attribute 24 #include "AST/Copy.hpp" // for shallowCopy 25 #include "AST/Decl.hpp" // for Decl 26 #include "AST/Expr.hpp" // for Expr 27 #include "AST/Print.hpp" // for print 28 #include "AST/Stmt.hpp" // for AsmStmt, DirectiveStmt 29 #include "AST/StorageClasses.hpp" // for Storage::Class 30 #include "AST/Type.hpp" // for Type 31 #include "Common/CodeLocation.h" // for CodeLocation 32 #include "Common/Iterate.hpp" // for reverseIterate 23 33 #include "Common/SemanticError.h" // for SemanticError 24 34 #include "Common/UniqueName.h" // for UniqueName 25 #include "Common/utility.h" // for maybeClone , maybeBuild, CodeLocation35 #include "Common/utility.h" // for maybeClone 26 36 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 27 #include "SynTree/LinkageSpec.h" // for Spec, linkageName, Cforall28 #include "SynTree/Attribute.h" // for Attribute29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration30 #include "SynTree/Expression.h" // for Expression, ConstantExpr31 #include "SynTree/Statement.h" // for AsmStmt32 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Type::...33 37 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 34 38 #include "TypedefTable.h" // for TypedefTable … … 61 65 UniqueName DeclarationNode::anonymous( "__anonymous" ); 62 66 63 extern LinkageSpec::Spec linkage; // defined in parser.yy67 extern ast::Linkage::Spec linkage; // defined in parser.yy 64 68 65 69 DeclarationNode::DeclarationNode() : … … 67 71 68 72 // variable.name = nullptr; 69 variable.tyClass = TypeDecl::NUMBER_OF_KINDS;73 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS; 70 74 variable.assertions = nullptr; 71 75 variable.initializer = nullptr; … … 105 109 newnode->hasEllipsis = hasEllipsis; 106 110 newnode->linkage = linkage; 107 newnode->asmName = maybeC lone( asmName );108 cloneAll( attributes, newnode->attributes );111 newnode->asmName = maybeCopy( asmName ); 112 newnode->attributes = attributes; 109 113 newnode->initializer = maybeClone( initializer ); 110 114 newnode->extension = extension; … … 118 122 119 123 newnode->assert.condition = maybeClone( assert.condition ); 120 newnode->assert.message = maybeC lone( assert.message );124 newnode->assert.message = maybeCopy( assert.message ); 121 125 return newnode; 122 126 } // DeclarationNode::clone … … 128 132 } // if 129 133 130 if ( linkage != LinkageSpec::Cforall ) {131 os << LinkageSpec::name( linkage ) << " ";132 } // if 133 134 storageClasses.print( os );135 funcSpecs.print( os );134 if ( linkage != ast::Linkage::Cforall ) { 135 os << ast::Linkage::name( linkage ) << " "; 136 } // if 137 138 ast::print( os, storageClasses ); 139 ast::print( os, funcSpecs ); 136 140 137 141 if ( type ) { … … 154 158 if ( ! attributes.empty() ) { 155 159 os << string( indent + 2, ' ' ) << "with attributes " << endl; 156 for ( Attribute * attr: reverseIterate( attributes ) ) {160 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) { 157 161 os << string( indent + 4, ' ' ) << attr->name.c_str() << endl; 158 162 } // for … … 169 173 } 170 174 171 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {175 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) { 172 176 DeclarationNode * newnode = new DeclarationNode; 173 177 newnode->storageClasses = sc; … … 175 179 } // DeclarationNode::newStorageClass 176 180 177 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {181 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) { 178 182 DeclarationNode * newnode = new DeclarationNode; 179 183 newnode->funcSpecs = fs; … … 181 185 } // DeclarationNode::newFuncSpecifier 182 186 183 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {187 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) { 184 188 DeclarationNode * newnode = new DeclarationNode; 185 189 newnode->type = new TypeData(); … … 241 245 } 242 246 243 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {247 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 244 248 DeclarationNode * newnode = new DeclarationNode; 245 249 newnode->type = new TypeData( TypeData::Aggregate ); … … 271 275 } // DeclarationNode::newEnum 272 276 273 274 275 277 DeclarationNode * DeclarationNode::newName( const string * name ) { 276 278 DeclarationNode * newnode = new DeclarationNode; … … 324 326 } // DeclarationNode::newFromTypeGen 325 327 326 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {328 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) { 327 329 DeclarationNode * newnode = newName( name ); 328 330 newnode->type = nullptr; … … 336 338 newnode->type = new TypeData( TypeData::Aggregate ); 337 339 newnode->type->aggregate.name = name; 338 newnode->type->aggregate.kind = AggregateDecl::Trait;340 newnode->type->aggregate.kind = ast::AggregateDecl::Trait; 339 341 newnode->type->aggregate.params = params; 340 342 newnode->type->aggregate.fields = asserts; … … 346 348 newnode->type = new TypeData( TypeData::AggregateInst ); 347 349 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate ); 348 newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;350 newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait; 349 351 newnode->type->aggInst.aggregate->aggregate.name = name; 350 352 newnode->type->aggInst.params = params; … … 381 383 newnode->type->array.dimension = size; 382 384 newnode->type->array.isStatic = isStatic; 383 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType< ConstantExpr *>() ) {385 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) { 384 386 newnode->type->array.isVarLen = false; 385 387 } else { … … 451 453 DeclarationNode * newnode = new DeclarationNode; 452 454 newnode->type = nullptr; 453 std:: list< Expression *> exprs;455 std::vector<ast::ptr<ast::Expr>> exprs; 454 456 buildList( expr, exprs ); 455 newnode->attributes.push_back( new Attribute( *name, exprs ) ); 457 newnode->attributes.push_back( 458 new ast::Attribute( *name, std::move( exprs ) ) ); 456 459 delete name; 457 460 return newnode; … … 470 473 } 471 474 472 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression* message ) {475 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) { 473 476 DeclarationNode * newnode = new DeclarationNode; 474 477 newnode->assert.condition = condition; … … 477 480 } 478 481 479 480 void appendError( string & dst, const string & src ) { 482 static void appendError( string & dst, const string & src ) { 481 483 if ( src.empty() ) return; 482 484 if ( dst.empty() ) { dst = src; return; } … … 485 487 486 488 void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) { 487 const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 488 489 if ( (qsrc & qdst).any() ) { // duplicates ? 490 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates 491 if ( qsrc[i] && qdst[i] ) { 492 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] ); 493 } // if 494 } // for 489 const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 490 const ast::CV::Qualifiers duplicates = qsrc & qdst; 491 492 if ( duplicates.any() ) { 493 std::stringstream str; 494 str << "duplicate "; 495 ast::print( str, duplicates ); 496 str << "qualifier(s)"; 497 appendError( error, str.str() ); 495 498 } // for 496 499 } // DeclarationNode::checkQualifiers 497 500 498 501 void DeclarationNode::checkSpecifiers( DeclarationNode * src ) { 499 if ( (funcSpecs & src->funcSpecs).any() ) { // duplicates ? 500 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates 501 if ( funcSpecs[i] && src->funcSpecs[i] ) { 502 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] ); 503 } // if 504 } // for 505 } // if 506 507 if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ? 508 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ? 509 for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates 510 if ( storageClasses[i] && src->storageClasses[i] ) { 511 appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] ); 512 } // if 513 } // for 514 // src is the new item being added and has a single bit 515 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ? 516 appendError( error, string( "conflicting " ) 517 + Type::StorageClassesNames[storageClasses.ffs()] 518 + " & " + Type::StorageClassesNames[src->storageClasses.ffs()] ); 519 src->storageClasses.reset(); // FIX to preserve invariant of one basic storage specifier 520 } // if 502 ast::Function::Specs fsDups = funcSpecs & src->funcSpecs; 503 if ( fsDups.any() ) { 504 std::stringstream str; 505 str << "duplicate "; 506 ast::print( str, fsDups ); 507 str << "function specifier(s)"; 508 appendError( error, str.str() ); 509 } // if 510 511 // Skip if everything is unset. 512 if ( storageClasses.any() && src->storageClasses.any() ) { 513 ast::Storage::Classes dups = storageClasses & src->storageClasses; 514 // Check for duplicates. 515 if ( dups.any() ) { 516 std::stringstream str; 517 str << "duplicate "; 518 ast::print( str, dups ); 519 str << "storage class(es)"; 520 appendError( error, str.str() ); 521 // Check for conflicts. 522 } else if ( !src->storageClasses.is_threadlocal_any() ) { 523 std::stringstream str; 524 str << "conflicting "; 525 ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) ); 526 str << "& "; 527 ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) ); 528 str << "storage classes"; 529 appendError( error, str.str() ); 530 // FIX to preserve invariant of one basic storage specifier 531 src->storageClasses.reset(); 532 } 521 533 } // if 522 534 … … 528 540 storageClasses |= q->storageClasses; 529 541 530 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 531 attributes.push_front( attr->clone() ); 532 } // for 542 std::vector<ast::ptr<ast::Attribute>> tmp; 543 tmp.reserve( q->attributes.size() ); 544 for ( auto const & attr : q->attributes ) { 545 tmp.emplace_back( ast::shallowCopy( attr.get() ) ); 546 } 547 spliceBegin( attributes, tmp ); 548 533 549 return this; 534 550 } // DeclarationNode::copySpecifiers … … 716 732 717 733 DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) { 718 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {734 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 719 735 if ( variable.assertions ) { 720 736 variable.assertions->appendList( assertions ); … … 798 814 DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) { 799 815 if ( a ) { 800 for ( Attribute *attr: reverseIterate( a->attributes ) ) { 801 attributes.push_front( attr ); 802 } // for 816 spliceBegin( attributes, a->attributes ); 803 817 a->attributes.clear(); 804 818 } // if … … 921 935 922 936 DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) { 923 assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );937 assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." ); 924 938 variable.initializer = init; 925 939 return this; … … 985 999 } 986 1000 987 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 1001 void buildList( const DeclarationNode * firstNode, 1002 std::vector<ast::ptr<ast::Decl>> & outputList ) { 988 1003 SemanticErrorException errors; 989 std::back_insert_iterator< std::list< Declaration * >> out( outputList );1004 std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList ); 990 1005 991 1006 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 992 1007 try { 993 1008 bool extracted = false, anon = false; 994 AggregateDecl * unionDecl = nullptr;1009 ast::AggregateDecl * unionDecl = nullptr; 995 1010 996 1011 if ( DeclarationNode * extr = cur->extractAggregate() ) { … … 1029 1044 } // if 1030 1045 1031 Declaration* decl = extr->build();1046 ast::Decl * decl = extr->build(); 1032 1047 if ( decl ) { 1033 1048 // Remember the declaration if it is a union aggregate ? 1034 unionDecl = dynamic_cast< UnionDecl *>( decl );1049 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 1035 1050 1036 1051 decl->location = cur->location; … … 1051 1066 } // if 1052 1067 1053 Declaration* decl = cur->build();1068 ast::Decl * decl = cur->build(); 1054 1069 if ( decl ) { 1055 if ( TypedefDecl * typedefDecl = dynamic_cast<TypedefDecl *>( decl ) ) {1070 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) { 1056 1071 if ( unionDecl ) { // is the typedef alias a union aggregate ? 1057 1072 // This code handles a special issue with the attribute transparent_union. … … 1065 1080 1066 1081 // If typedef is an alias for a union, then its alias type was hoisted above and remembered. 1067 if ( UnionInstType * unionInstType = dynamic_cast<UnionInstType *>( typedefDecl->base ) ) { 1082 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) { 1083 auto instType = ast::mutate( unionInstType ); 1068 1084 // Remove all transparent_union attributes from typedef and move to alias union. 1069 list<Attribute *>::iterator attr;1070 for ( attr = unionInstType->attributes.begin(); attr != unionInstType->attributes.end(); ) { // forward order1085 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { // forward order 1086 assert( *attr ); 1071 1087 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) { 1072 list<Attribute *>::iterator cur = attr; // remember current node 1073 attr++; // advance iterator 1074 unionDecl->attributes.emplace_back( *cur ); // move current 1075 unionInstType->attributes.erase( cur ); // remove current 1088 unionDecl->attributes.emplace_back( attr->release() ); 1089 attr = instType->attributes.erase( attr ); 1076 1090 } else { 1077 attr++; // advance iterator1091 attr++; 1078 1092 } // if 1079 1093 } // for 1094 typedefDecl->base = instType; 1080 1095 } // if 1081 1096 } // if … … 1090 1105 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 1091 1106 if ( decl->name == "" ) { 1092 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) {1093 if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType*>( dwt->get_type() ) ) {1107 if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1108 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) { 1094 1109 if ( aggr->name.find("anonymous") == std::string::npos ) { 1095 1110 if ( ! cur->get_inLine() ) { … … 1117 1132 1118 1133 // currently only builds assertions, function parameters, and return values 1119 void buildList( const DeclarationNode * firstNode, std:: list< DeclarationWithType *> & outputList ) {1134 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) { 1120 1135 SemanticErrorException errors; 1121 std::back_insert_iterator< std::list< DeclarationWithType * >> out( outputList );1136 std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList ); 1122 1137 1123 1138 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1124 1139 try { 1125 Declaration* decl = cur->build();1140 ast::Decl * decl = cur->build(); 1126 1141 assert( decl ); 1127 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {1142 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1128 1143 dwt->location = cur->location; 1129 1144 *out++ = dwt; 1130 } else if ( StructDecl * agg = dynamic_cast< StructDecl *>( decl ) ) {1145 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) { 1131 1146 // e.g., int foo(struct S) {} 1132 StructInstType * inst = new StructInstType( Type::Qualifiers(),agg->name );1133 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr);1134 obj->l ocation = cur->location;1147 auto inst = new ast::StructInstType( agg->name ); 1148 auto obj = new ast::ObjectDecl( cur->location, "", inst ); 1149 obj->linkage = linkage; 1135 1150 *out++ = obj; 1136 1151 delete agg; 1137 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl *>( decl ) ) {1152 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) { 1138 1153 // e.g., int foo(union U) {} 1139 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name ); 1140 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1141 obj->location = cur->location; 1154 auto inst = new ast::UnionInstType( agg->name ); 1155 auto obj = new ast::ObjectDecl( cur->location, 1156 "", inst, nullptr, ast::Storage::Classes(), 1157 linkage ); 1142 1158 *out++ = obj; 1143 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl *>( decl ) ) {1159 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) { 1144 1160 // e.g., int foo(enum E) {} 1145 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name ); 1146 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1147 obj->location = cur->location; 1161 auto inst = new ast::EnumInstType( agg->name ); 1162 auto obj = new ast::ObjectDecl( cur->location, 1163 "", 1164 inst, 1165 nullptr, 1166 ast::Storage::Classes(), 1167 linkage 1168 ); 1148 1169 *out++ = obj; 1149 1170 } // if … … 1158 1179 } // buildList 1159 1180 1160 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1181 void buildTypeList( const DeclarationNode * firstNode, 1182 std::vector<ast::ptr<ast::Type>> & outputList ) { 1161 1183 SemanticErrorException errors; 1162 std::back_insert_iterator< std::list< Type * >> out( outputList );1184 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList ); 1163 1185 const DeclarationNode * cur = firstNode; 1164 1186 … … 1177 1199 } // buildTypeList 1178 1200 1179 Declaration* DeclarationNode::build() const {1201 ast::Decl * DeclarationNode::build() const { 1180 1202 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1181 1203 1182 1204 if ( asmStmt ) { 1183 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) ); 1205 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() ); 1206 return new ast::AsmDecl( stmt->location, stmt ); 1184 1207 } // if 1185 1208 if ( directiveStmt ) { 1186 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) ); 1187 } // if 1188 1189 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 1209 auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() ); 1210 return new ast::DirectiveDecl( stmt->location, stmt ); 1211 } // if 1212 1213 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 1190 1214 // otype is internally converted to dtype + otype parameters 1191 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype,TypeDecl::Dimension };1192 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );1215 static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension }; 1216 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." ); 1193 1217 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." ); 1194 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 ); 1195 buildList( variable.assertions, ret->get_assertions() ); 1218 ast::TypeDecl * ret = new ast::TypeDecl( location, 1219 *name, 1220 ast::Storage::Classes(), 1221 (ast::Type *)nullptr, 1222 kindMap[ variable.tyClass ], 1223 variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype, 1224 variable.initializer ? variable.initializer->buildType() : nullptr 1225 ); 1226 buildList( variable.assertions, ret->assertions ); 1196 1227 return ret; 1197 1228 } // if … … 1215 1246 } // if 1216 1247 bool isDelete = initializer && initializer->get_isDelete(); 1217 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild(initializer), attributes )->set_extension( extension ); 1248 ast::Decl * decl = buildDecl( 1249 type, 1250 name ? *name : string( "" ), 1251 storageClasses, 1252 maybeBuild( bitfieldWidth ), 1253 funcSpecs, 1254 linkage, 1255 asmName, 1256 isDelete ? nullptr : maybeBuild( initializer ), 1257 copy( attributes ) 1258 )->set_extension( extension ); 1218 1259 if ( isDelete ) { 1219 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );1260 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl ); 1220 1261 dwt->isDeleted = true; 1221 1262 } … … 1224 1265 1225 1266 if ( assert.condition ) { 1226 return new StaticAssertDecl( maybeBuild( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 1267 auto cond = maybeBuild( assert.condition ); 1268 auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) ); 1269 return new ast::StaticAssertDecl( location, cond, msg ); 1227 1270 } 1228 1271 … … 1235 1278 } // if 1236 1279 if ( enumInLine ) { 1237 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1280 return new ast::InlineMemberDecl( location, 1281 *name, (ast::Type*)nullptr, storageClasses, linkage ); 1238 1282 } // if 1239 1283 assertf( name, "ObjectDecl must a have name\n" ); 1240 return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild( bitfieldWidth ), nullptr, maybeBuild( initializer ) ))->set_asmName( asmName )->set_extension( extension ); 1241 } 1242 1243 Type * DeclarationNode::buildType() const { 1284 auto ret = new ast::ObjectDecl( location, 1285 *name, 1286 (ast::Type*)nullptr, 1287 maybeBuild( initializer ), 1288 storageClasses, 1289 linkage, 1290 maybeBuild( bitfieldWidth ) 1291 ); 1292 ret->asmName = asmName; 1293 ret->extension = extension; 1294 return ret; 1295 } 1296 1297 ast::Type * DeclarationNode::buildType() const { 1244 1298 assert( type ); 1245 1299 … … 1247 1301 case TypeData::Enum: 1248 1302 case TypeData::Aggregate: { 1249 ReferenceToType * ret = buildComAggInst( type, attributes, linkage ); 1250 buildList( type->aggregate.actuals, ret->get_parameters() ); 1303 ast::BaseInstType * ret = 1304 buildComAggInst( type, copy( attributes ), linkage ); 1305 buildList( type->aggregate.actuals, ret->params ); 1251 1306 return ret; 1252 1307 } 1253 1308 case TypeData::Symbolic: { 1254 TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes ); 1255 buildList( type->symbolic.actuals, ret->get_parameters() ); 1309 ast::TypeInstType * ret = new ast::TypeInstType( 1310 *type->symbolic.name, 1311 // This is just a default, the true value is not known yet. 1312 ast::TypeDecl::Dtype, 1313 buildQualifiers( type ), 1314 copy( attributes ) ); 1315 buildList( type->symbolic.actuals, ret->params ); 1256 1316 return ret; 1257 1317 } 1258 1318 default: 1259 Type * simpletypes = typebuild( type ); 1260 simpletypes->get_attributes() = attributes; // copy because member is const 1319 ast::Type * simpletypes = typebuild( type ); 1320 // copy because member is const 1321 simpletypes->attributes = attributes; 1261 1322 return simpletypes; 1262 1323 } // switch -
TabularUnified src/Parser/ExpressionNode.cc ¶
r4541b09 rbb7422a 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Mar 14 12:00:00 202313 // Update Count : 108 212 // Last Modified On : Tue Apr 4 11:07:00 2023 13 // Update Count : 1083 14 14 // 15 15 … … 21 21 #include <string> // for string, operator+, operator== 22 22 23 #include "AST/Expr.hpp" // for NameExpr 24 #include "AST/Type.hpp" // for BaseType, SueInstType 23 25 #include "Common/SemanticError.h" // for SemanticError 24 26 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 25 27 #include "ParseNode.h" // for ExpressionNode, maybeMoveBuildType 26 #include "SynTree/Constant.h" // for Constant27 #include "SynTree/Declaration.h" // for EnumDecl, StructDecl, UnionDecl28 #include "SynTree/Expression.h" // for Expression, ConstantExpr, NameExpr29 #include "SynTree/Statement.h" // for CompoundStmt, Statement30 #include "SynTree/Type.h" // for BasicType, Type, Type::Qualifiers31 28 #include "parserutility.h" // for notZeroExpr 32 33 class Initializer;34 29 35 30 using namespace std; … … 48 43 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 49 44 // type. 50 51 extern const Type::Qualifiers noQualifiers; // no qualifiers on constants52 45 53 46 // static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } … … 127 120 } // scanbin 128 121 129 Expression * build_constantInteger( string & str ) { 130 static const BasicType::Kind kind[2][6] = { 122 ast::Expr * build_constantInteger( 123 const CodeLocation & location, string & str ) { 124 static const ast::BasicType::Kind kind[2][6] = { 131 125 // 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, },126 { ast::BasicType::ShortSignedInt, ast::BasicType::SignedChar, ast::BasicType::SignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ ast::BasicType::LongLongSignedInt, }, 127 { ast::BasicType::ShortUnsignedInt, ast::BasicType::UnsignedChar, ast::BasicType::UnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ ast::BasicType::LongLongUnsignedInt, }, 134 128 }; 135 129 … … 141 135 string str2( "0x0" ); 142 136 unsigned long long int v, v2 = 0; // converted integral value 143 Expression* ret, * ret2;137 ast::Expr * ret, * ret2; 144 138 145 139 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 … … 149 143 // special constants 150 144 if ( str == "0" ) { 151 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ));145 ret = new ast::ConstantExpr( location, new ast::ZeroType(), str, 0 ); 152 146 goto CLEANUP; 153 147 } // if 154 148 if ( str == "1" ) { 155 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ));149 ret = new ast::ConstantExpr( location, new ast::OneType(), str, 1 ); 156 150 goto CLEANUP; 157 151 } // if … … 304 298 305 299 // Constant type is correct for overload resolving. 306 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) ); 300 ret = new ast::ConstantExpr( location, 301 new ast::BasicType( kind[Unsigned][type] ), str, v ); 307 302 if ( Unsigned && type < 2 ) { // hh or h, less than int ? 308 303 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 309 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 304 ret = new ast::CastExpr( location, 305 ret, 306 new ast::BasicType( kind[Unsigned][type] ), 307 ast::ExplicitCast ); 310 308 } else if ( ltype != -1 ) { // explicit length ? 311 309 if ( ltype == 6 ) { // int128, (int128)constant 312 // ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 313 ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) ); 314 ret = build_compoundLiteral( 315 DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 316 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) ); 310 ret2 = new ast::ConstantExpr( location, 311 new ast::BasicType( ast::BasicType::LongLongSignedInt ), 312 str2, 313 v2 ); 314 ret = build_compoundLiteral( location, 315 DeclarationNode::newBasicType( 316 DeclarationNode::Int128 317 )->addType( 318 DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 319 new InitializerNode( 320 (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) 321 ); 317 322 } else { // explicit length, (length_type)constant 318 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); 323 ret = new ast::CastExpr( location, 324 ret, 325 new ast::TypeInstType( lnthsInt[Unsigned][ltype], ast::TypeDecl::Dtype ), 326 ast::ExplicitCast ); 319 327 if ( ltype == 5 ) { // pointer, intptr( (uintptr_t)constant ) 320 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) ); 328 ret = build_func( location, 329 new ExpressionNode( 330 build_varref( location, new string( "intptr" ) ) ), 331 new ExpressionNode( ret ) ); 321 332 } // if 322 333 } // if … … 362 373 363 374 364 Expression * build_constantFloat( string & str ) { 365 static const BasicType::Kind kind[2][12] = { 366 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x }, 367 { 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 }, 375 ast::Expr * build_constantFloat( 376 const CodeLocation & location, string & str ) { 377 static const ast::BasicType::Kind kind[2][12] = { 378 { 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 }, 379 { 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 }, 368 380 }; 369 381 … … 402 414 403 415 assert( 0 <= type && type < 12 ); 404 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) ); 405 if ( explnth ) { // explicit length ? 406 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false ); 416 ast::Expr * ret = new ast::ConstantExpr( location, 417 new ast::BasicType( kind[complx][type] ), 418 str, 419 v ); 420 // explicit length ? 421 if ( explnth ) { 422 ret = new ast::CastExpr( location, 423 ret, 424 new ast::BasicType( kind[complx][type] ), 425 ast::ExplicitCast ); 407 426 } // if 408 427 … … 419 438 } // sepString 420 439 421 Expression * build_constantChar(string & str ) {440 ast::Expr * build_constantChar( const CodeLocation & location, string & str ) { 422 441 string units; // units 423 442 sepString( str, units, '\'' ); // separate constant from units 424 443 425 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) ); 444 ast::Expr * ret = new ast::ConstantExpr( location, 445 new ast::BasicType( ast::BasicType::Char ), 446 str, 447 (unsigned long long int)(unsigned char)str[1] ); 426 448 if ( units.length() != 0 ) { 427 ret = new UntypedExpr( new NameExpr( units ), { ret } ); 449 ret = new ast::UntypedExpr( location, 450 new ast::NameExpr( location, units ), 451 { ret } ); 428 452 } // if 429 453 … … 432 456 } // build_constantChar 433 457 434 Expression * build_constantStr( string & str ) { 458 ast::Expr * build_constantStr( 459 const CodeLocation & location, 460 string & str ) { 435 461 assert( str.length() > 0 ); 436 462 string units; // units 437 463 sepString( str, units, '"' ); // separate constant from units 438 464 439 Type * strtype;465 ast::Type * strtype; 440 466 switch ( str[0] ) { // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1 441 467 case 'u': 442 468 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char 443 469 // lookup type of associated typedef 444 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );470 strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype ); 445 471 break; 446 472 case 'U': 447 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );473 strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype ); 448 474 break; 449 475 case 'L': 450 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );476 strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype ); 451 477 break; 452 478 Default: // char default string type 453 479 default: 454 strtype = new BasicType( Type::Qualifiers( ),BasicType::Char );480 strtype = new ast::BasicType( ast::BasicType::Char ); 455 481 } // switch 456 ArrayType * at = new ArrayType( noQualifiers, strtype, 457 new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"' 458 false, false ); 459 Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) ); 482 ast::ArrayType * at = new ast::ArrayType( 483 strtype, 484 // Length is adjusted: +1 for '\0' and -2 for '"' 485 ast::ConstantExpr::from_ulong( location, str.size() + 1 - 2 ), 486 ast::FixedLen, 487 ast::DynamicDim ); 488 ast::Expr * ret = new ast::ConstantExpr( location, at, str, std::nullopt ); 460 489 if ( units.length() != 0 ) { 461 ret = new UntypedExpr( new NameExpr( units ), { ret } ); 490 ret = new ast::UntypedExpr( location, 491 new ast::NameExpr( location, units ), 492 { ret } ); 462 493 } // if 463 494 … … 466 497 } // build_constantStr 467 498 468 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) { 499 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( 500 const CodeLocation & location, const string & str ) { 469 501 if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str ); 470 Expression * ret = build_constantInteger( *new string( str.substr(1) ) ); 502 ast::Expr * ret = build_constantInteger( location, 503 *new string( str.substr(1) ) ); 471 504 delete &str; 472 505 return ret; 473 506 } // build_field_name_FLOATING_FRACTIONconstant 474 507 475 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) { 508 ast::Expr * build_field_name_FLOATING_DECIMALconstant( 509 const CodeLocation & location, const string & str ) { 476 510 if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str ); 477 Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) ); 511 ast::Expr * ret = build_constantInteger( 512 location, *new string( str.substr( 0, str.size()-1 ) ) ); 478 513 delete &str; 479 514 return ret; 480 515 } // build_field_name_FLOATING_DECIMALconstant 481 516 482 Expression * build_field_name_FLOATINGconstant( const string & str ) { 517 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location, 518 const string & str ) { 483 519 // str is of the form A.B -> separate at the . and return member expression 484 520 int a, b; … … 486 522 stringstream ss( str ); 487 523 ss >> a >> dot >> b; 488 UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) ); 524 auto ret = new ast::UntypedMemberExpr( location, 525 ast::ConstantExpr::from_int( location, b ), 526 ast::ConstantExpr::from_int( location, a ) 527 ); 489 528 delete &str; 490 529 return ret; 491 530 } // build_field_name_FLOATINGconstant 492 531 493 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) { 494 if ( fracts ) { 495 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) { 496 memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) ); 497 return memberExpr; 498 } else { 499 return new UntypedMemberExpr( fracts, fieldName ); 500 } // if 501 } // if 502 return fieldName; 532 ast::Expr * make_field_name_fraction_constants( const CodeLocation & location, 533 ast::Expr * fieldName, 534 ast::Expr * fracts ) { 535 if ( nullptr == fracts ) { 536 return fieldName; 537 } else if ( auto memberExpr = dynamic_cast<ast::UntypedMemberExpr *>( fracts ) ) { 538 memberExpr->member = make_field_name_fraction_constants( location, 539 fieldName, 540 ast::mutate( memberExpr->aggregate.get() ) ); 541 return memberExpr; 542 } else { 543 return new ast::UntypedMemberExpr( location, fracts, fieldName ); 544 } // if 503 545 } // make_field_name_fraction_constants 504 546 505 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) { 506 return make_field_name_fraction_constants( fieldName, maybeMoveBuild( fracts ) ); 547 ast::Expr * build_field_name_fraction_constants( const CodeLocation & location, 548 ast::Expr * fieldName, 549 ExpressionNode * fracts ) { 550 return make_field_name_fraction_constants( location, fieldName, maybeMoveBuild( fracts ) ); 507 551 } // build_field_name_fraction_constants 508 552 509 NameExpr * build_varref( const string * name ) { 510 NameExpr * expr = new NameExpr( *name ); 553 ast::NameExpr * build_varref( const CodeLocation & location, 554 const string * name ) { 555 ast::NameExpr * expr = new ast::NameExpr( location, *name ); 511 556 delete name; 512 557 return expr; 513 558 } // build_varref 514 559 515 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) { 516 Declaration * newDecl = maybeBuild(decl_node); 517 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { 518 const Type * t = newDeclWithType->get_type(); 519 if ( t ) { 520 if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) { 521 newDecl= new EnumDecl( typeInst->name ); 560 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location, 561 const DeclarationNode * decl_node, 562 const ast::NameExpr * name ) { 563 ast::Decl * newDecl = maybeBuild( decl_node ); 564 if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) { 565 if ( const ast::Type * t = newDeclWithType->get_type() ) { 566 if ( auto typeInst = dynamic_cast<const ast::TypeInstType *>( t ) ) { 567 newDecl = new ast::EnumDecl( location, typeInst->name ); 522 568 } 523 569 } 524 570 } 525 return new QualifiedNameExpr(newDecl, name->name );571 return new ast::QualifiedNameExpr( location, newDecl, name->name ); 526 572 } 527 573 528 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) { 529 EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node ); 530 return new QualifiedNameExpr( newDecl, name->name ); 574 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location, 575 const ast::EnumDecl * decl, 576 const ast::NameExpr * name ) { 577 return new ast::QualifiedNameExpr( location, decl, name->name ); 531 578 } 532 579 533 DimensionExpr * build_dimensionref( const string * name ) { 534 DimensionExpr * expr = new DimensionExpr( *name ); 580 ast::DimensionExpr * build_dimensionref( const CodeLocation & location, 581 const string * name ) { 582 ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name ); 535 583 delete name; 536 584 return expr; … … 548 596 }; // OperName 549 597 550 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) { 551 Type * targetType = maybeMoveBuildType( decl_node ); 552 if ( dynamic_cast< VoidType * >( targetType ) ) { 598 ast::Expr * build_cast( const CodeLocation & location, 599 DeclarationNode * decl_node, 600 ExpressionNode * expr_node ) { 601 ast::Type * targetType = maybeMoveBuildType( decl_node ); 602 if ( dynamic_cast<ast::VoidType *>( targetType ) ) { 553 603 delete targetType; 554 return new CastExpr( maybeMoveBuild( expr_node ), false ); 604 return new ast::CastExpr( location, 605 maybeMoveBuild( expr_node ), 606 ast::ExplicitCast ); 555 607 } else { 556 return new CastExpr( maybeMoveBuild( expr_node ), targetType, false ); 608 return new ast::CastExpr( location, 609 maybeMoveBuild( expr_node ), 610 targetType, 611 ast::ExplicitCast ); 557 612 } // if 558 613 } // build_cast 559 614 560 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) { 561 return new KeywordCastExpr( maybeMoveBuild( expr_node ), target ); 615 ast::Expr * build_keyword_cast( const CodeLocation & location, 616 ast::AggregateDecl::Aggregate target, 617 ExpressionNode * expr_node ) { 618 return new ast::KeywordCastExpr( location, 619 maybeMoveBuild( expr_node ), 620 target 621 ); 562 622 } 563 623 564 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) { 565 return new VirtualCastExpr( maybeMoveBuild( expr_node ), maybeMoveBuildType( decl_node ) ); 624 ast::Expr * build_virtual_cast( const CodeLocation & location, 625 DeclarationNode * decl_node, 626 ExpressionNode * expr_node ) { 627 return new ast::VirtualCastExpr( location, 628 maybeMoveBuild( expr_node ), 629 maybeMoveBuildType( decl_node ) 630 ); 566 631 } // build_virtual_cast 567 632 568 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) { 569 return new UntypedMemberExpr( member, maybeMoveBuild( expr_node ) ); 633 ast::Expr * build_fieldSel( const CodeLocation & location, 634 ExpressionNode * expr_node, 635 ast::Expr * member ) { 636 return new ast::UntypedMemberExpr( location, 637 member, 638 maybeMoveBuild( expr_node ) 639 ); 570 640 } // build_fieldSel 571 641 572 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) { 573 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 642 ast::Expr * build_pfieldSel( const CodeLocation & location, 643 ExpressionNode * expr_node, 644 ast::Expr * member ) { 645 auto deref = new ast::UntypedExpr( location, 646 new ast::NameExpr( location, "*?" ) 647 ); 574 648 deref->location = expr_node->location; 575 deref-> get_args().push_back( maybeMoveBuild( expr_node ) );576 UntypedMemberExpr * ret = new UntypedMemberExpr(member, deref );649 deref->args.push_back( maybeMoveBuild( expr_node ) ); 650 auto ret = new ast::UntypedMemberExpr( location, member, deref ); 577 651 return ret; 578 652 } // build_pfieldSel 579 653 580 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) { 581 Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() ); 654 ast::Expr * build_offsetOf( const CodeLocation & location, 655 DeclarationNode * decl_node, 656 ast::NameExpr * member ) { 657 ast::Expr * ret = new ast::UntypedOffsetofExpr( location, 658 maybeMoveBuildType( decl_node ), 659 member->name 660 ); 661 ret->result = new ast::BasicType( ast::BasicType::LongUnsignedInt ); 582 662 delete member; 583 663 return ret; 584 664 } // build_offsetOf 585 665 586 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) { 587 return new LogicalExpr( notZeroExpr( maybeMoveBuild( expr_node1 ) ), notZeroExpr( maybeMoveBuild( expr_node2 ) ), kind ); 666 ast::Expr * build_and_or( const CodeLocation & location, 667 ExpressionNode * expr_node1, 668 ExpressionNode * expr_node2, 669 ast::LogicalFlag flag ) { 670 return new ast::LogicalExpr( location, 671 notZeroExpr( maybeMoveBuild( expr_node1 ) ), 672 notZeroExpr( maybeMoveBuild( expr_node2 ) ), 673 flag 674 ); 588 675 } // build_and_or 589 676 590 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) { 591 list< Expression * > args; 677 ast::Expr * build_unary_val( const CodeLocation & location, 678 OperKinds op, 679 ExpressionNode * expr_node ) { 680 std::vector<ast::ptr<ast::Expr>> args; 592 681 args.push_back( maybeMoveBuild( expr_node ) ); 593 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 682 return new ast::UntypedExpr( location, 683 new ast::NameExpr( location, OperName[ (int)op ] ), 684 std::move( args ) 685 ); 594 686 } // build_unary_val 595 687 596 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 597 list< Expression * > args; 688 ast::Expr * build_binary_val( const CodeLocation & location, 689 OperKinds op, 690 ExpressionNode * expr_node1, 691 ExpressionNode * expr_node2 ) { 692 std::vector<ast::ptr<ast::Expr>> args; 598 693 args.push_back( maybeMoveBuild( expr_node1 ) ); 599 694 args.push_back( maybeMoveBuild( expr_node2 ) ); 600 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 695 return new ast::UntypedExpr( location, 696 new ast::NameExpr( location, OperName[ (int)op ] ), 697 std::move( args ) 698 ); 601 699 } // build_binary_val 602 700 603 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 604 list< Expression * > args;605 args.push_back( maybeMoveBuild( expr_node1 ) );606 args.push_back( maybeMoveBuild( expr_node2 ) );607 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args);701 ast::Expr * build_binary_ptr( const CodeLocation & location, 702 OperKinds op, 703 ExpressionNode * expr_node1, 704 ExpressionNode * expr_node2 ) { 705 return build_binary_val( location, op, expr_node1, expr_node2 ); 608 706 } // build_binary_ptr 609 707 610 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) { 611 return new ConditionalExpr( notZeroExpr( maybeMoveBuild( expr_node1 ) ), maybeMoveBuild( expr_node2 ), maybeMoveBuild( expr_node3 ) ); 708 ast::Expr * build_cond( const CodeLocation & location, 709 ExpressionNode * expr_node1, 710 ExpressionNode * expr_node2, 711 ExpressionNode * expr_node3 ) { 712 return new ast::ConditionalExpr( location, 713 notZeroExpr( maybeMoveBuild( expr_node1 ) ), 714 maybeMoveBuild( expr_node2 ), 715 maybeMoveBuild( expr_node3 ) 716 ); 612 717 } // build_cond 613 718 614 Expression * build_tuple( ExpressionNode * expr_node ) { 615 list< Expression * > exprs; 719 ast::Expr * build_tuple( const CodeLocation & location, 720 ExpressionNode * expr_node ) { 721 std::vector<ast::ptr<ast::Expr>> exprs; 616 722 buildMoveList( expr_node, exprs ); 617 return new UntypedTupleExpr( exprs );;723 return new ast::UntypedTupleExpr( location, std::move( exprs ) ); 618 724 } // build_tuple 619 725 620 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) { 621 list< Expression * > args; 726 ast::Expr * build_func( const CodeLocation & location, 727 ExpressionNode * function, 728 ExpressionNode * expr_node ) { 729 std::vector<ast::ptr<ast::Expr>> args; 622 730 buildMoveList( expr_node, args ); 623 return new UntypedExpr( maybeMoveBuild( function ), args ); 731 return new ast::UntypedExpr( location, 732 maybeMoveBuild( function ), 733 std::move( args ) 734 ); 624 735 } // build_func 625 736 626 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) { 627 Declaration * newDecl = maybeBuild( decl_node ); // compound literal type 628 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type 629 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild( kids ) ); 737 ast::Expr * build_compoundLiteral( const CodeLocation & location, 738 DeclarationNode * decl_node, 739 InitializerNode * kids ) { 740 // compound literal type 741 ast::Decl * newDecl = maybeBuild( decl_node ); 742 // non-sue compound-literal type 743 if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) { 744 return new ast::CompoundLiteralExpr( location, 745 newDeclWithType->get_type(), 746 maybeMoveBuild( kids ) ); 630 747 // these types do not have associated type information 631 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) { 632 if ( newDeclStructDecl->has_body() ) { 633 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild( kids ) ); 748 } else if ( auto newDeclStructDecl = dynamic_cast<ast::StructDecl *>( newDecl ) ) { 749 if ( newDeclStructDecl->body ) { 750 return new ast::CompoundLiteralExpr( location, 751 new ast::StructInstType( newDeclStructDecl ), 752 maybeMoveBuild( kids ) ); 634 753 } else { 635 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild( kids ) ); 636 } // if 637 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) { 638 if ( newDeclUnionDecl->has_body() ) { 639 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild( kids ) ); 754 return new ast::CompoundLiteralExpr( location, 755 new ast::StructInstType( newDeclStructDecl->name ), 756 maybeMoveBuild( kids ) ); 757 } // if 758 } else if ( auto newDeclUnionDecl = dynamic_cast<ast::UnionDecl *>( newDecl ) ) { 759 if ( newDeclUnionDecl->body ) { 760 return new ast::CompoundLiteralExpr( location, 761 new ast::UnionInstType( newDeclUnionDecl ), 762 maybeMoveBuild( kids ) ); 640 763 } else { 641 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild( kids ) ); 642 } // if 643 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) { 644 if ( newDeclEnumDecl->has_body() ) { 645 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild( kids ) ); 764 return new ast::CompoundLiteralExpr( location, 765 new ast::UnionInstType( newDeclUnionDecl->name ), 766 maybeMoveBuild( kids ) ); 767 } // if 768 } else if ( auto newDeclEnumDecl = dynamic_cast<ast::EnumDecl *>( newDecl ) ) { 769 if ( newDeclEnumDecl->body ) { 770 return new ast::CompoundLiteralExpr( location, 771 new ast::EnumInstType( newDeclEnumDecl ), 772 maybeMoveBuild( kids ) ); 646 773 } else { 647 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild( kids ) ); 774 return new ast::CompoundLiteralExpr( location, 775 new ast::EnumInstType( newDeclEnumDecl->name ), 776 maybeMoveBuild( kids ) ); 648 777 } // if 649 778 } else { -
TabularUnified src/Parser/InitializerNode.cc ¶
r4541b09 rbb7422a 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 15 … … 20 20 using namespace std; 21 21 22 #include "AST/Expr.hpp" // for Expr 23 #include "AST/Init.hpp" // for Designator, Init, ListInit, Sing... 22 24 #include "Common/SemanticError.h" // for SemanticError 23 25 #include "Common/utility.h" // for maybeBuild 24 26 #include "ParseNode.h" // for InitializerNode, ExpressionNode 25 #include "SynTree/Expression.h" // for Expression 26 #include "SynTree/Initializer.h" // for Initializer, ListInit, SingleInit 27 28 static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) { 29 return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct; 30 } 27 31 28 32 InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des ) … … 33 37 if ( kids ) 34 38 set_last( nullptr ); 35 } // InitializerNode::InitializerNode 39 } // InitializerNode::InitializerNode 36 40 37 41 InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des ) … … 85 89 } // InitializerNode::printOneLine 86 90 87 Initializer* InitializerNode::build() const {91 ast::Init * InitializerNode::build() const { 88 92 assertf( ! isDelete, "Should not build delete stmt InitializerNode" ); 89 93 if ( aggregate ) { 90 94 // steal designators from children 91 std:: list< Designation *> designlist;95 std::vector<ast::ptr<ast::Designation>> designlist; 92 96 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 ) ); 97 for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) { 98 std::deque<ast::ptr<ast::Expr>> desList; 99 buildList( child->designator, desList ); 100 designlist.push_back( 101 new ast::Designation( location, std::move( desList ) ) ); 97 102 } // 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( get_expression() ), maybeConstructed ); 105 } // if 103 std::vector<ast::ptr<ast::Init>> initlist; 104 buildList( next_init(), initlist ); 105 return new ast::ListInit( location, 106 std::move( initlist ), 107 std::move( designlist ), 108 toConstructFlag( maybeConstructed ) 109 ); 110 } else if ( get_expression() ) { 111 assertf( get_expression()->expr, "The expression of initializer must have value" ); 112 return new ast::SingleInit( location, 113 maybeBuild( get_expression() ), 114 toConstructFlag( maybeConstructed ) 115 ); 106 116 } // if 107 117 return nullptr; -
TabularUnified src/Parser/ParseNode.h ¶
r4541b09 rbb7422a 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 Mar 29 08:40:27202313 // Update Count : 94 811 // 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 32 #include "Common/utility.h" // for maybeClone 30 #include "Parser/parserutility.h" // for maybeBuild 31 #include "SynTree/LinkageSpec.h" // for Spec 32 #include "SynTree/Declaration.h" // for Aggregate 33 #include "SynTree/Expression.h" // for Expression, ConstantExpr (ptr only) 34 #include "SynTree/Label.h" // for Label 35 #include "SynTree/Statement.h" // for Statement, BranchStmt, BranchStmt:... 36 #include "SynTree/Type.h" // for Type, Type::FuncSpecifiers, Type::... 33 #include "Parser/parserutility.h" // for maybeBuild, maybeCopy 37 34 38 35 class Attribute; … … 108 105 void printOneLine( std::ostream & ) const; 109 106 110 virtual Initializer* build() const;107 virtual ast::Init * build() const; 111 108 private: 112 109 ExpressionNode * expr; … … 122 119 class ExpressionNode final : public ParseNode { 123 120 public: 124 ExpressionNode( Expression* expr = nullptr ) : expr( expr ) {}121 ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {} 125 122 virtual ~ExpressionNode() {} 126 virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; } 123 virtual ExpressionNode * clone() const override { 124 if ( nullptr == expr ) return nullptr; 125 return static_cast<ExpressionNode*>( 126 (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) )); 127 } 127 128 128 129 bool get_extension() const { return extension; } … … 137 138 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); } 138 139 139 Expression* build() const {140 Expression* node = const_cast<ExpressionNode *>(this)->expr.release();140 ast::Expr * build() const { 141 ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release(); 141 142 node->set_extension( this->get_extension() ); 142 143 node->location = this->location; … … 144 145 } 145 146 146 std::unique_ptr<Expression> expr; // public because of lifetime implications 147 // Public because of lifetime implications (what lifetime implications?) 148 std::unique_ptr<ast::Expr> expr; 147 149 private: 148 150 bool extension = false; … … 164 166 165 167 struct LabelNode { 166 std:: list< Label> labels;168 std::vector<ast::Label> labels; 167 169 }; 168 170 169 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string 170 Expression * build_constantFloat( std::string & str ); 171 Expression * build_constantChar( std::string & str ); 172 Expression * build_constantStr( std::string & str ); 173 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str ); 174 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str ); 175 Expression * build_field_name_FLOATINGconstant( const std::string & str ); 176 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ); 177 178 NameExpr * build_varref( const std::string * name ); 179 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ); 180 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name ); 181 DimensionExpr * build_dimensionref( const std::string * name ); 182 183 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ); 184 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ); 185 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ); 186 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ); 187 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ); 188 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ); 189 Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 190 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ); 191 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ); 192 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 193 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 194 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ); 195 Expression * build_tuple( ExpressionNode * expr_node = nullptr ); 196 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ); 197 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ); 171 // These 4 routines modify the string: 172 ast::Expr * build_constantInteger( const CodeLocation &, std::string & ); 173 ast::Expr * build_constantFloat( const CodeLocation &, std::string & ); 174 ast::Expr * build_constantChar( const CodeLocation &, std::string & ); 175 ast::Expr * build_constantStr( const CodeLocation &, std::string & ); 176 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str ); 177 ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str ); 178 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str ); 179 ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts ); 180 181 ast::NameExpr * build_varref( const CodeLocation &, const std::string * name ); 182 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name ); 183 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name ); 184 ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name ); 185 186 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node ); 187 ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node ); 188 ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node ); 189 ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member ); 190 ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member ); 191 ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member ); 192 ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 193 ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag ); 194 ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node ); 195 ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 196 ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 197 ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ); 198 ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr ); 199 ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node ); 200 ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids ); 198 201 199 202 //############################################################################## … … 219 222 static const char * builtinTypeNames[]; 220 223 221 static DeclarationNode * newStorageClass( Type::StorageClasses );222 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );223 static DeclarationNode * newTypeQualifier( Type::Qualifiers );224 static DeclarationNode * newStorageClass( ast::Storage::Classes ); 225 static DeclarationNode * newFuncSpecifier( ast::Function::Specs ); 226 static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers ); 224 227 static DeclarationNode * newBasicType( BasicType ); 225 228 static DeclarationNode * newComplexType( ComplexType ); … … 232 235 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * ); 233 236 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 234 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );237 static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); 235 238 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible ); 236 239 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); … … 239 242 static DeclarationNode * newName( const std::string * ); 240 243 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params ); 241 static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );244 static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * ); 242 245 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts ); 243 246 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params ); … … 253 256 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement 254 257 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement 255 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression* message );258 static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message ); 256 259 257 260 DeclarationNode(); … … 294 297 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 295 298 296 Declaration* build() const;297 Type * buildType() const;298 299 LinkageSpec::Spec get_linkage() const { return linkage; }299 ast::Decl * build() const; 300 ast::Type * buildType() const; 301 302 ast::Linkage::Spec get_linkage() const { return linkage; } 300 303 DeclarationNode * extractAggregate() const; 301 304 bool has_enumeratorValue() const { return (bool)enumeratorValue; } … … 312 315 struct Variable_t { 313 316 // const std::string * name; 314 TypeDecl::Kind tyClass;317 ast::TypeDecl::Kind tyClass; 315 318 DeclarationNode * assertions; 316 319 DeclarationNode * initializer; … … 320 323 struct StaticAssert_t { 321 324 ExpressionNode * condition; 322 Expression* message;325 ast::Expr * message; 323 326 }; 324 327 StaticAssert_t assert; … … 330 333 bool inLine = false; 331 334 bool enumInLine = false; 332 Type::FuncSpecifiers funcSpecs;333 Type::StorageClasses storageClasses;335 ast::Function::Specs funcSpecs; 336 ast::Storage::Classes storageClasses; 334 337 335 338 ExpressionNode * bitfieldWidth = nullptr; 336 339 std::unique_ptr<ExpressionNode> enumeratorValue; 337 340 bool hasEllipsis = false; 338 LinkageSpec::Spec linkage;339 Expression* asmName = nullptr;340 std:: list< Attribute *> attributes;341 ast::Linkage::Spec linkage; 342 ast::Expr * asmName = nullptr; 343 std::vector<ast::ptr<ast::Attribute>> attributes; 341 344 InitializerNode * initializer = nullptr; 342 345 bool extension = false; … … 348 351 }; // DeclarationNode 349 352 350 Type * buildType( TypeData * type );351 352 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {353 Type * ret = orig ? orig->buildType() : nullptr;353 ast::Type * buildType( TypeData * type ); 354 355 static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) { 356 ast::Type * ret = orig ? orig->buildType() : nullptr; 354 357 delete orig; 355 358 return ret; … … 359 362 360 363 struct StatementNode final : public ParseNode { 361 StatementNode() { stmt = nullptr; } 362 StatementNode( Statement * stmt ) : stmt( stmt ) {} 364 StatementNode() : 365 stmt( nullptr ), clause( nullptr ) {} 366 StatementNode( ast::Stmt * stmt ) : 367 stmt( stmt ), clause( nullptr ) {} 368 StatementNode( ast::StmtClause * clause ) : 369 stmt( nullptr ), clause( clause ) {} 363 370 StatementNode( DeclarationNode * decl ); 364 371 virtual ~StatementNode() {} 365 372 366 373 virtual StatementNode * clone() const final { assert( false ); return nullptr; } 367 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); } 368 369 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) { 370 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} ); 374 ast::Stmt * build() const { return const_cast<StatementNode *>(this)->stmt.release(); } 375 376 virtual StatementNode * add_label( 377 const CodeLocation & location, 378 const std::string * name, 379 DeclarationNode * attr = nullptr ) { 380 stmt->labels.emplace_back( location, 381 *name, 382 attr ? std::move( attr->attributes ) 383 : std::vector<ast::ptr<ast::Attribute>>{} ); 371 384 delete attr; 372 385 delete name; … … 380 393 } 381 394 382 std::unique_ptr<Statement> stmt; 395 std::unique_ptr<ast::Stmt> stmt; 396 std::unique_ptr<ast::StmtClause> clause; 383 397 }; // StatementNode 384 398 385 Statement * build_expr(ExpressionNode * ctl );399 ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl ); 386 400 387 401 struct CondCtl { … … 402 416 }; 403 417 404 Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init ); 405 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ); 406 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ); 407 Statement * build_case( ExpressionNode * ctl ); 408 Statement * build_default(); 409 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 410 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 411 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 412 Statement * build_branch( BranchStmt::Type kind ); 413 Statement * build_branch( std::string * identifier, BranchStmt::Type kind ); 414 Statement * build_computedgoto( ExpressionNode * ctl ); 415 Statement * build_return( ExpressionNode * ctl ); 416 Statement * build_throw( ExpressionNode * ctl ); 417 Statement * build_resume( ExpressionNode * ctl ); 418 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target ); 419 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ); 420 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ); 421 Statement * build_finally( StatementNode * stmt ); 422 Statement * build_compound( StatementNode * first ); 423 StatementNode * maybe_build_compound( StatementNode * first ); 424 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr ); 425 Statement * build_directive( std::string * directive ); 426 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None); 427 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ); 428 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ); 429 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ); 430 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ); 431 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ); 432 433 //############################################################################## 434 435 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args > 436 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) { 418 ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ ); 419 ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ); 420 ast::CaseClause * build_case( ExpressionNode * ctl ); 421 ast::CaseClause * build_default( const CodeLocation & ); 422 ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 423 ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 424 ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 425 ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind ); 426 ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind ); 427 ast::Stmt * build_computedgoto( ExpressionNode * ctl ); 428 ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl ); 429 ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl ); 430 ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl ); 431 ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target ); 432 ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ); 433 ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ); 434 ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt ); 435 ast::Stmt * build_compound( const CodeLocation &, StatementNode * first ); 436 StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first ); 437 ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr ); 438 ast::Stmt * build_directive( const CodeLocation &, std::string * directive ); 439 ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Type ); 440 ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ); 441 ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ); 442 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ); 443 ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt ); 444 ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt ); 445 446 //############################################################################## 447 448 template<typename AstType, typename NodeType, 449 template<typename, typename...> class Container, typename... Args> 450 void buildList( const NodeType * firstNode, 451 Container<ast::ptr<AstType>, Args...> & output ) { 437 452 SemanticErrorException errors; 438 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );453 std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output ); 439 454 const NodeType * cur = firstNode; 440 455 441 456 while ( cur ) { 442 457 try { 443 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild( cur ) ); 444 if ( result ) { 445 result->location = cur->location; 446 * out++ = result; 458 if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) { 459 *out++ = result; 447 460 } else { 461 assertf(false, __PRETTY_FUNCTION__ ); 448 462 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." ); 449 463 } // if … … 451 465 errors.append( e ); 452 466 } // try 453 const ParseNode * temp = (cur->get_next()); 454 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr 455 if ( ! cur && temp ) { // non-homogeneous nodes ? 467 const ParseNode * temp = cur->get_next(); 468 // Should not return nullptr, then it is non-homogeneous: 469 cur = dynamic_cast<const NodeType *>( temp ); 470 if ( !cur && temp ) { 456 471 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 457 472 } // if … … 463 478 464 479 // in DeclarationNode.cc 465 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ); 466 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ); 467 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ); 468 469 template< typename SynTreeType, typename NodeType > 470 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) { 471 buildList( firstNode, outputList ); 480 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList ); 481 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ); 482 void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList ); 483 484 template<typename AstType, typename NodeType, 485 template<typename, typename...> class Container, typename... Args> 486 void buildMoveList( const NodeType * firstNode, 487 Container<ast::ptr<AstType>, Args...> & output ) { 488 buildList<AstType, NodeType, Container, Args...>( firstNode, output ); 472 489 delete firstNode; 473 490 } -
TabularUnified src/Parser/ParserTypes.h ¶
r4541b09 rbb7422a 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 -
TabularUnified src/Parser/RunParser.cpp ¶
r4541b09 rbb7422a 10 10 // Created On : Mon Dec 19 11:00:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Feb 16 10:08:00 202313 // Update Count : 212 // Last Modified On : Mon Mar 6 9:42:00 2023 13 // Update Count : 3 14 14 // 15 15 … … 46 46 47 47 ast::TranslationUnit buildUnit(void) { 48 std::list<Declaration *> translationUnit; 49 buildList( parseTree, translationUnit ); 50 48 std::vector<ast::ptr<ast::Decl>> decls; 49 buildList( parseTree, decls ); 51 50 delete parseTree; 52 51 parseTree = nullptr; 53 52 54 // When the parse/buildList code is translated to the new ast, these 55 // fill passes (and the one after 'Hoist Type Decls') should be redundent 56 // because the code locations should already be filled. 57 CodeTools::fillLocations( translationUnit ); 58 ast::TranslationUnit transUnit = convert( std::move( translationUnit ) ); 59 forceFillCodeLocations( transUnit ); 53 ast::TranslationUnit transUnit; 54 for ( auto decl : decls ) { 55 transUnit.decls.emplace_back( std::move( decl ) ); 56 } 60 57 return transUnit; 61 58 } -
TabularUnified src/Parser/StatementNode.cc ¶
r4541b09 rbb7422a 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 Mar 29 08:51:23202314 // Update Count : 4 5412 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 4 11:40:00 2023 14 // Update Count : 427 15 15 // 16 16 17 17 #include <cassert> // for assert, strict_dynamic_cast, assertf 18 #include <list> // for list19 18 #include <memory> // for unique_ptr 20 19 #include <string> // for string 21 20 21 #include "AST/Label.hpp" // for Label 22 #include "AST/Stmt.hpp" // for Stmt, AsmStmt, BranchStmt, CaseCla... 22 23 #include "Common/SemanticError.h" // for SemanticError 23 24 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 24 25 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 25 #include "SynTree/Expression.h" // for Expression, ConstantExpr26 #include "SynTree/Label.h" // for Label, noLabels27 #include "SynTree/Declaration.h"28 #include "SynTree/Statement.h" // for Statement, BranchStmt, CaseStmt29 26 #include "parserutility.h" // for notZeroExpr 30 27 … … 32 29 33 30 using namespace std; 34 35 31 36 32 StatementNode::StatementNode( DeclarationNode * decl ) { … … 38 34 DeclarationNode * agg = decl->extractAggregate(); 39 35 if ( agg ) { 40 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) ); 36 StatementNode * nextStmt = new StatementNode( 37 new ast::DeclStmt( decl->location, maybeBuild( decl ) ) ); 41 38 set_next( nextStmt ); 42 39 if ( decl->get_next() ) { … … 51 48 agg = decl; 52 49 } // if 53 stmt.reset( new DeclStmt( maybeMoveBuild( agg ) ) ); 50 // Local copy to avoid accessing the pointer after it is moved from. 51 CodeLocation declLocation = agg->location; 52 stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) ); 54 53 } // StatementNode::StatementNode 55 54 … … 59 58 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 60 59 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr); 61 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) ); 60 assert( nullptr == node->stmt.get() ); 61 assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) ); 62 62 prev = curr; 63 63 } // for 64 64 // convert from StatementNode list to Statement list 65 65 StatementNode * node = dynamic_cast< StatementNode * >(prev); 66 list< Statement *> stmts;66 std::vector<ast::ptr<ast::Stmt>> stmts; 67 67 buildMoveList( stmt, stmts ); 68 68 // 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 ); 69 auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() ); 70 for ( auto const & newStmt : stmts ) { 71 caseStmt->stmts.emplace_back( newStmt ); 72 } 73 stmts.clear(); 71 74 return this; 72 75 } // StatementNode::append_last_case 73 76 74 Statement * build_expr( ExpressionNode * ctl ) { 75 Expression * e = maybeMoveBuild( ctl ); 76 77 if ( e ) return new ExprStmt( e ); 78 else return new NullStmt(); 77 ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) { 78 if ( ast::Expr * e = maybeMoveBuild( ctl ) ) { 79 return new ast::ExprStmt( location, e ); 80 } else { 81 return new ast::NullStmt( location ); 82 } 79 83 } // build_expr 80 84 81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) { 82 if ( ctl->init != 0 ) { 83 buildMoveList( ctl->init, init ); 84 } // if 85 86 Expression * cond = nullptr; 85 static ast::Expr * build_if_control( CondCtl * ctl, 86 std::vector<ast::ptr<ast::Stmt>> & inits ) { 87 assert( inits.empty() ); 88 if ( nullptr != ctl->init ) { 89 buildMoveList( ctl->init, inits ); 90 } // if 91 92 ast::Expr * cond = nullptr; 87 93 if ( ctl->condition ) { 88 94 // compare the provided condition against 0 89 95 cond = notZeroExpr( maybeMoveBuild( ctl->condition ) ); 90 96 } else { 91 for ( Statement * stmt : init) {97 for ( ast::ptr<ast::Stmt> & stmt : inits ) { 92 98 // 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; 99 //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt ); 100 auto declStmt = stmt.strict_as<ast::DeclStmt>(); 101 //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl ); 102 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>(); 103 ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) ); 104 cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze; 97 105 } 98 106 } … … 101 109 } // build_if_control 102 110 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 ); 111 ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 112 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 113 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 114 115 std::vector<ast::ptr<ast::Stmt>> aststmt; 116 buildMoveList( then, aststmt ); 110 117 assert( aststmt.size() == 1 ); 111 astthen = aststmt.front(); 112 118 ast::Stmt const * astthen = aststmt.front().release(); 119 120 ast::Stmt const * astelse = nullptr; 113 121 if ( else_ ) { 114 list< Statement *> aststmt;115 buildMoveList < Statement, StatementNode >( else_, aststmt );122 std::vector<ast::ptr<ast::Stmt>> aststmt; 123 buildMoveList( else_, aststmt ); 116 124 assert( aststmt.size() == 1 ); 117 astelse = aststmt.front(); 118 } // if 119 120 return new IfStmt( astcond, astthen, astelse, astinit ); 125 astelse = aststmt.front().release(); 126 } // if 127 128 return new ast::IfStmt( location, astcond, astthen, astelse, 129 std::move( astinit ) 130 ); 121 131 } // build_if 122 132 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 ) ); 133 // Temporary work around. Split StmtClause off from StatementNode. 134 template<typename clause_t> 135 static void buildMoveClauseList( StatementNode * firstNode, 136 std::vector<ast::ptr<clause_t>> & output ) { 137 SemanticErrorException errors; 138 std::back_insert_iterator<std::vector<ast::ptr<clause_t>>> 139 out( output ); 140 StatementNode * cur = firstNode; 141 142 while ( cur ) { 143 try { 144 auto clause = cur->clause.release(); 145 if ( auto result = dynamic_cast<clause_t *>( clause ) ) { 146 *out++ = result; 147 } else { 148 assertf(false, __PRETTY_FUNCTION__ ); 149 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." ); 150 } // if 151 } catch( SemanticErrorException & e ) { 152 errors.append( e ); 153 } // try 154 ParseNode * temp = cur->get_next(); 155 // Should not return nullptr, then it is non-homogeneous: 156 cur = dynamic_cast<StatementNode *>( temp ); 157 if ( !cur && temp ) { 158 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 159 } // if 160 } // while 161 if ( ! errors.isEmpty() ) { 162 throw errors; 163 } // if 164 // Usually in the wrapper. 165 delete firstNode; 166 } 167 168 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { 169 std::vector<ast::ptr<ast::CaseClause>> aststmt; 170 buildMoveClauseList( stmt, aststmt ); 171 // If it is not a switch it is a choose statement. 172 if ( ! isSwitch ) { 173 for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) { 174 // Code after "case" is the end of case list. 175 if ( !stmt->stmts.empty() ) { 176 auto mutStmt = ast::mutate( stmt.get() ); 177 // I believe the stmts are actually always one block. 178 auto stmts = mutStmt->stmts.front().get_and_mutate(); 179 auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts ); 180 block->kids.push_back( new ast::BranchStmt( block->location, 181 ast::BranchStmt::Break, 182 ast::Label( block->location ) ) ); 183 stmt = mutStmt; 132 184 } // if 133 185 } // for 134 186 } // if 135 187 // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements 136 return new SwitchStmt( maybeMoveBuild( ctl ), aststmt ); 188 return new ast::SwitchStmt( location, 189 maybeMoveBuild( ctl ), std::move( aststmt ) ); 137 190 } // build_switch 138 191 139 Statement * build_case( ExpressionNode * ctl ) { 140 return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to 192 ast::CaseClause * build_case( ExpressionNode * ctl ) { 193 // stmt starts empty and then added to 194 auto expr = maybeMoveBuild( ctl ); 195 return new ast::CaseClause( expr->location, expr, {} ); 141 196 } // build_case 142 197 143 Statement * build_default() { 144 return new CaseStmt( nullptr, {}, true ); // stmt starts empty and then added to 198 ast::CaseClause * build_default( const CodeLocation & location ) { 199 // stmt starts empty and then added to 200 return new ast::CaseClause( location, nullptr, {} ); 145 201 } // build_default 146 202 147 Statement * build_while(CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {148 list< Statement *> astinit; // maybe empty149 Expression* astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set150 151 list< Statement *> aststmt; // loop body, compound created if empty152 buildMoveList < Statement, StatementNode >( stmt, aststmt );203 ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) { 204 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 205 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 206 207 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty 208 buildMoveList( stmt, aststmt ); 153 209 assert( aststmt.size() == 1 ); 154 210 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 ); 211 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty 212 buildMoveList( else_, astelse ); 213 assert( astelse.size() <= 1 ); 214 215 return new ast::WhileDoStmt( location, 216 astcond, 217 aststmt.front(), 218 astelse.empty() ? nullptr : astelse.front().release(), 219 std::move( astinit ), 220 false 221 ); 159 222 } // build_while 160 223 161 Statement * build_do_while(ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {162 list< Statement *> aststmt; // loop body, compound created if empty163 buildMoveList < Statement, StatementNode >( stmt, aststmt );224 ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 225 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty 226 buildMoveList( stmt, aststmt ); 164 227 assert( aststmt.size() == 1 ); // compound created if empty 165 228 166 list< Statement * > astelse; // else clause, maybe empty 167 buildMoveList< Statement, StatementNode >( else_, astelse ); 229 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty 230 buildMoveList( else_, astelse ); 231 assert( astelse.size() <= 1 ); 168 232 169 233 // do-while cannot have declarations in the contitional, so init is always empty 170 return new WhileDoStmt( notZeroExpr( maybeMoveBuild( ctl ) ), aststmt.front(), astelse.front(), {}, true ); 234 return new ast::WhileDoStmt( location, 235 notZeroExpr( maybeMoveBuild( ctl ) ), 236 aststmt.front(), 237 astelse.empty() ? nullptr : astelse.front().release(), 238 {}, 239 true 240 ); 171 241 } // build_do_while 172 242 173 Statement * build_for(ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {174 list< Statement *> astinit; // maybe empty243 ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) { 244 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 175 245 buildMoveList( forctl->init, astinit ); 176 246 177 Expression* astcond = nullptr; // maybe empty247 ast::Expr * astcond = nullptr; // maybe empty 178 248 astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) ); 179 249 180 Expression* astincr = nullptr; // maybe empty250 ast::Expr * astincr = nullptr; // maybe empty 181 251 astincr = maybeMoveBuild( forctl->change ); 182 252 delete forctl; 183 253 184 list< Statement *> aststmt; // loop body, compound created if empty185 buildMoveList < Statement, StatementNode >( stmt, aststmt );254 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty 255 buildMoveList( stmt, aststmt ); 186 256 assert( aststmt.size() == 1 ); 187 257 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() ); 258 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty 259 buildMoveList( else_, astelse ); 260 assert( astelse.size() <= 1 ); 261 262 return new ast::ForStmt( location, 263 std::move( astinit ), 264 astcond, 265 astincr, 266 aststmt.front(), 267 astelse.empty() ? nullptr : astelse.front().release() 268 ); 192 269 } // build_for 193 270 194 Statement * build_branch( BranchStmt::Type kind ) { 195 Statement * ret = new BranchStmt( "", kind ); 271 ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) { 272 return new ast::BranchStmt( location, 273 kind, 274 ast::Label( location ) 275 ); 276 } // build_branch 277 278 ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) { 279 ast::Stmt * ret = new ast::BranchStmt( location, 280 kind, 281 ast::Label( location, *identifier ) 282 ); 283 delete identifier; // allocated by lexer 196 284 return ret; 197 285 } // build_branch 198 286 199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) { 200 Statement * ret = new BranchStmt( * identifier, kind ); 201 delete identifier; // allocated by lexer 202 return ret; 203 } // build_branch 204 205 Statement * build_computedgoto( ExpressionNode * ctl ) { 206 return new BranchStmt( maybeMoveBuild( ctl ), BranchStmt::Goto ); 287 ast::Stmt * build_computedgoto( ExpressionNode * ctl ) { 288 ast::Expr * expr = maybeMoveBuild( ctl ); 289 return new ast::BranchStmt( expr->location, expr ); 207 290 } // build_computedgoto 208 291 209 Statement * build_return(ExpressionNode * ctl ) {210 list< Expression *> exps;292 ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) { 293 std::vector<ast::ptr<ast::Expr>> exps; 211 294 buildMoveList( ctl, exps ); 212 return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr ); 295 return new ast::ReturnStmt( location, 296 exps.size() > 0 ? exps.back().release() : nullptr 297 ); 213 298 } // build_return 214 299 215 Statement * build_throw( ExpressionNode * ctl ) { 216 list< Expression * > exps; 300 static ast::Stmt * build_throw_stmt( 301 const CodeLocation & location, 302 ExpressionNode * ctl, 303 ast::ExceptionKind kind ) { 304 std::vector<ast::ptr<ast::Expr>> exps; 217 305 buildMoveList( ctl, exps ); 218 306 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 219 return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 307 return new ast::ThrowStmt( location, 308 kind, 309 !exps.empty() ? exps.back().release() : nullptr, 310 (ast::Expr *)nullptr 311 ); 312 } 313 314 ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) { 315 return build_throw_stmt( loc, ctl, ast::Terminate ); 220 316 } // build_throw 221 317 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 ); 318 ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) { 319 return build_throw_stmt( loc, ctl, ast::Resume ); 227 320 } // build_resume 228 321 229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {322 ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) { 230 323 (void)ctl; 231 324 (void)target; … … 233 326 } // build_resume_at 234 327 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( try_ ) ); 239 FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >( maybeMoveBuild( finally_ ) ); 240 return new TryStmt( tryBlock, aststmt, finallyBlock ); 328 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) { 329 std::vector<ast::ptr<ast::CatchClause>> aststmt; 330 buildMoveClauseList( catch_, aststmt ); 331 ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) ); 332 ast::FinallyClause * finallyBlock = nullptr; 333 if ( finally_ ) { 334 finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() ); 335 } 336 return new ast::TryStmt( location, 337 tryBlock, 338 std::move( aststmt ), 339 finallyBlock 340 ); 241 341 } // build_try 242 342 243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {244 list< Statement *> aststmt;245 buildMoveList < Statement, StatementNode >( body, aststmt );343 ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 344 std::vector<ast::ptr<ast::Stmt>> aststmt; 345 buildMoveList( body, aststmt ); 246 346 assert( aststmt.size() == 1 ); 247 return new CatchStmt( kind, maybeMoveBuild( decl ), maybeMoveBuild( cond ), aststmt.front() ); 347 return new ast::CatchClause( location, 348 kind, 349 maybeMoveBuild( decl ), 350 maybeMoveBuild( cond ), 351 aststmt.front().release() 352 ); 248 353 } // build_catch 249 354 250 Statement * build_finally(StatementNode * stmt ) {251 list< Statement *> aststmt;252 buildMoveList < Statement, StatementNode >( stmt, aststmt );355 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 356 std::vector<ast::ptr<ast::Stmt>> aststmt; 357 buildMoveList( stmt, aststmt ); 253 358 assert( aststmt.size() == 1 ); 254 return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) ); 359 return new ast::FinallyClause( location, 360 aststmt.front().strict_as<ast::CompoundStmt>() 361 ); 255 362 } // build_finally 256 363 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 ); 364 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) { 365 std::vector<ast::ptr<ast::Stmt>> stmts; 366 buildMoveList( then, stmts ); 367 ast::CompoundStmt const * then2 = nullptr; 264 368 if(!stmts.empty()) { 265 369 assert( stmts.size() == 1 ); 266 node->then = dynamic_cast< CompoundStmt * >( stmts.front());370 then2 = stmts.front().strict_as<ast::CompoundStmt>(); 267 371 } 268 372 auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None ); 373 node->type = type; 269 374 return node; 270 375 } // build_suspend 271 376 272 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 273 WaitForStmt::Target target; 274 target.function = maybeBuild( targetExpr ); 377 ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 378 auto clause = new ast::WaitForClause( location ); 379 clause->target_func = maybeBuild( targetExpr ); 380 clause->stmt = maybeMoveBuild( stmt ); 381 clause->cond = notZeroExpr( maybeMoveBuild( when ) ); 275 382 276 383 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 277 384 targetExpr->set_next( nullptr ); 278 buildMoveList < Expression >( next, target.arguments );385 buildMoveList( next, clause->target_args ); 279 386 280 387 delete targetExpr; 281 388 282 existing->clauses.insert( existing->clauses.begin(), WaitForStmt::Clause{ 283 std::move( target ), 284 maybeMoveBuild( stmt ), 285 notZeroExpr( maybeMoveBuild( when ) ) 286 }); 389 existing->clauses.insert( existing->clauses.begin(), clause ); 287 390 288 391 return existing; 289 392 } // build_waitfor 290 393 291 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 292 existing->orelse.statement = maybeMoveBuild( stmt ); 293 existing->orelse.condition = notZeroExpr( maybeMoveBuild( when ) ); 294 394 ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 395 existing->else_stmt = maybeMoveBuild( stmt ); 396 existing->else_cond = notZeroExpr( maybeMoveBuild( when ) ); 397 398 (void)location; 295 399 return existing; 296 400 } // build_waitfor_else 297 401 298 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 299 existing->timeout.time = maybeMoveBuild( timeout ); 300 existing->timeout.statement = maybeMoveBuild( stmt ); 301 existing->timeout.condition = notZeroExpr( maybeMoveBuild( when ) ); 302 402 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 403 existing->timeout_time = maybeMoveBuild( timeout ); 404 existing->timeout_stmt = maybeMoveBuild( stmt ); 405 existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) ); 406 407 (void)location; 303 408 return existing; 304 409 } // build_waitfor_timeout 305 410 306 Statement * build_with(ExpressionNode * exprs, StatementNode * stmt ) {307 list< Expression *> e;411 ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 412 std::vector<ast::ptr<ast::Expr>> e; 308 413 buildMoveList( exprs, e ); 309 Statement * s = maybeMoveBuild( stmt );310 return new DeclStmt( new WithStmt( e, s ) );414 ast::Stmt * s = maybeMoveBuild( stmt ); 415 return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) ); 311 416 } // build_with 312 417 313 Statement * build_compound(StatementNode * first ) {314 CompoundStmt * cs = new CompoundStmt();315 buildMoveList( first, cs-> get_kids());418 ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) { 419 auto cs = new ast::CompoundStmt( location ); 420 buildMoveList( first, cs->kids ); 316 421 return cs; 317 422 } // build_compound … … 321 426 // statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a 322 427 // conical form for code generation. 323 StatementNode * maybe_build_compound( StatementNode * first ) {428 StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) { 324 429 // Optimization: if the control-structure statement is a compound statement, do not wrap it. 325 430 // e.g., if (...) {...} do not wrap the existing compound statement. 326 if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 327 CompoundStmt * cs = new CompoundStmt(); 328 buildMoveList( first, cs->get_kids() ); 329 return new StatementNode( cs ); 431 if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 432 return new StatementNode( build_compound( location, first ) ); 330 433 } // if 331 434 return first; … … 333 436 334 437 // Question 335 Statement * build_asm( bool voltile, Expression* instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {336 list< Expression *> out, in;337 list< ConstantExpr *> clob;438 ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { 439 std::vector<ast::ptr<ast::Expr>> out, in; 440 std::vector<ast::ptr<ast::ConstantExpr>> clob; 338 441 339 442 buildMoveList( output, out ); 340 443 buildMoveList( input, in ); 341 444 buildMoveList( clobber, clob ); 342 return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 445 return new ast::AsmStmt( location, 446 voltile, 447 instruction, 448 std::move( out ), 449 std::move( in ), 450 std::move( clob ), 451 gotolabels ? gotolabels->labels : std::vector<ast::Label>() 452 ); 343 453 } // build_asm 344 454 345 Statement * build_directive( string * directive ) { 346 return new DirectiveStmt( *directive ); 455 ast::Stmt * build_directive( const CodeLocation & location, string * directive ) { 456 auto stmt = new ast::DirectiveStmt( location, *directive ); 457 delete directive; 458 return stmt; 347 459 } // build_directive 348 460 349 Statement * build_mutex(ExpressionNode * exprs, StatementNode * stmt ) {350 list< Expression *> expList;461 ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 462 std::vector<ast::ptr<ast::Expr>> expList; 351 463 buildMoveList( exprs, expList ); 352 Statement * body = maybeMoveBuild( stmt );353 return new MutexStmt( body, expList);464 ast::Stmt * body = maybeMoveBuild( stmt ); 465 return new ast::MutexStmt( location, body, std::move( expList ) ); 354 466 } // build_mutex 355 467 -
TabularUnified src/Parser/TypeData.cc ¶
r4541b09 rbb7422a 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 : Sun Feb 19 11:00:46202313 // Update Count : 6 7911 // 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... 25 #include "Common/utility.h" // for splice, spliceBegin 26 #include "Parser/parserutility.h" // for maybeCopy, maybeBuild, maybeMoveB... 21 27 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 22 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, FunctionDecl23 #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, Statement26 #include "SynTree/Type.h" // for BasicType, Type, Type::ForallList27 #include "TypeData.h"28 28 29 29 class Attribute; … … 60 60 break; 61 61 case Aggregate: 62 aggregate.kind = AggregateDecl::NoAggregate;62 aggregate.kind = ast::AggregateDecl::NoAggregate; 63 63 aggregate.name = nullptr; 64 64 aggregate.params = nullptr; … … 89 89 typeexpr = nullptr; 90 90 break; 91 case Vtable: 91 92 case Builtin: 92 case Vtable:93 93 // No unique data to initialize. 94 94 break; … … 111 111 case EnumConstant: 112 112 case GlobalScope: 113 case Basic: 113 114 // No unique data to deconstruct. 114 break;115 case Basic:116 115 break; 117 116 case Array: … … 250 249 251 250 void TypeData::print( ostream &os, int indent ) const { 252 for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) { 253 if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' '; 254 } // for 251 ast::print( os, qualifiers ); 255 252 256 253 if ( forall ) { … … 325 322 break; 326 323 case Aggregate: 327 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;324 os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl; 328 325 if ( aggregate.params ) { 329 326 os << string( indent + 2, ' ' ) << "with type parameters" << endl; … … 472 469 473 470 474 template< typename ForallList > 475 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { 476 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 } 477 483 auto n = firstNode; 478 for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) { 479 TypeDecl * td = static_cast<TypeDecl *>(*i); 480 if ( n->variable.tyClass == TypeDecl::Otype ) { 481 // add assertion parameters to `type' tyvars in reverse order 482 // add dtor: void ^?{}(T *) 483 FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false ); 484 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 ) ); 485 td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) ); 486 487 // add copy ctor: void ?{}(T *, T) 488 FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false ); 489 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 ) ); 490 copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 491 td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) ); 492 493 // add default ctor: void ?{}(T *) 494 FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false ); 495 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 ) ); 496 td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) ); 497 498 // add assignment operator: T * ?=?(T *, T) 499 FunctionType * assignType = new FunctionType( Type::Qualifiers(), false ); 500 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 ) ); 501 assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 502 assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) ); 503 td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) ); 504 } // 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 ); 505 769 } // for 506 770 } // buildForall 507 771 508 772 509 Type * typebuild( const TypeData * td ) {773 ast::Type * typebuild( const TypeData * td ) { 510 774 assert( td ); 511 775 switch ( td->kind ) { 512 776 case TypeData::Unknown: 513 777 // fill in implicit int 514 return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); 778 return new ast::BasicType( 779 ast::BasicType::SignedInt, 780 buildQualifiers( td ) 781 ); 515 782 case TypeData::Basic: 516 783 return buildBasicType( td ); … … 522 789 return buildReference( td ); 523 790 case TypeData::Function: 524 return buildFunction ( td );791 return buildFunctionType( td ); 525 792 case TypeData::AggregateInst: 526 793 return buildAggInst( td ); 527 794 case TypeData::EnumConstant: 528 return new EnumInstType( buildQualifiers( td ), "");795 return new ast::EnumInstType( "", buildQualifiers( td ) ); 529 796 case TypeData::SymbolicInst: 530 797 return buildSymbolicInst( td ); … … 539 806 switch ( td->builtintype ) { 540 807 case DeclarationNode::Zero: 541 return new ZeroType( noQualifiers);808 return new ast::ZeroType(); 542 809 case DeclarationNode::One: 543 return new OneType( noQualifiers);810 return new ast::OneType(); 544 811 default: 545 return new VarArgsType( buildQualifiers( td ) );812 return new ast::VarArgsType( buildQualifiers( td ) ); 546 813 } // switch 547 814 case TypeData::GlobalScope: 548 return new GlobalScopeType();815 return new ast::GlobalScopeType(); 549 816 case TypeData::Qualified: 550 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) ); 817 return new ast::QualifiedType( 818 typebuild( td->qualified.parent ), 819 typebuild( td->qualified.child ), 820 buildQualifiers( td ) 821 ); 551 822 case TypeData::Symbolic: 552 823 case TypeData::Enum: … … 587 858 588 859 589 Type::Qualifiers buildQualifiers( const TypeData * td ) {860 ast::CV::Qualifiers buildQualifiers( const TypeData * td ) { 590 861 return td->qualifiers; 591 862 } // buildQualifiers … … 596 867 } // genTSError 597 868 598 Type * buildBasicType( const TypeData * td ) {599 BasicType::Kind ret;869 ast::Type * buildBasicType( const TypeData * td ) { 870 ast::BasicType::Kind ret; 600 871 601 872 switch ( td->basictype ) { … … 607 878 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 608 879 } // if 609 return new VoidType( buildQualifiers( td ) );880 return new ast::VoidType( buildQualifiers( td ) ); 610 881 break; 611 882 … … 618 889 } // if 619 890 620 ret = BasicType::Bool;891 ret = ast::BasicType::Bool; 621 892 break; 622 893 … … 625 896 // character types. The implementation shall define char to have the same range, representation, and behavior as 626 897 // either signed char or unsigned char. 627 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 }; 628 899 629 900 if ( td->length != DeclarationNode::NoLength ) { … … 635 906 636 907 case DeclarationNode::Int: 637 static BasicType::Kind inttype[2][4] = {638 { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt,BasicType::SignedInt },639 { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt,BasicType::UnsignedInt },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 }, 640 911 }; 641 912 … … 648 919 649 920 case DeclarationNode::Int128: 650 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 :BasicType::SignedInt128;921 ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128; 651 922 if ( td->length != DeclarationNode::NoLength ) { 652 923 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); … … 666 937 case DeclarationNode::uFloat128: 667 938 case DeclarationNode::uFloat128x: 668 static BasicType::Kind floattype[2][12] = {669 { 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, },670 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128,BasicType::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, }, 671 942 }; 672 943 … … 709 980 } // switch 710 981 711 BasicType * bt = new BasicType( buildQualifiers( td ), ret ); 712 buildForall( td->forall, bt->get_forall() ); 982 ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) ); 713 983 return bt; 714 984 } // buildBasicType 715 985 716 986 717 PointerType * buildPointer( const TypeData * td ) {718 PointerType * pt;987 ast::PointerType * buildPointer( const TypeData * td ) { 988 ast::PointerType * pt; 719 989 if ( td->base ) { 720 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) ); 990 pt = new ast::PointerType( 991 typebuild( td->base ), 992 buildQualifiers( td ) 993 ); 721 994 } else { 722 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 ); 723 999 } // if 724 buildForall( td->forall, pt->get_forall() );725 1000 return pt; 726 1001 } // buildPointer 727 1002 728 1003 729 ArrayType * buildArray( const TypeData * td ) {730 ArrayType * at;1004 ast::ArrayType * buildArray( const TypeData * td ) { 1005 ast::ArrayType * at; 731 1006 if ( td->base ) { 732 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild( td->array.dimension ), 733 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 ); 734 1014 } else { 735 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 736 maybeBuild( 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 ); 737 1022 } // if 738 buildForall( td->forall, at->get_forall() );739 1023 return at; 740 1024 } // buildArray 741 1025 742 1026 743 ReferenceType * buildReference( const TypeData * td ) {744 ReferenceType * rt;1027 ast::ReferenceType * buildReference( const TypeData * td ) { 1028 ast::ReferenceType * rt; 745 1029 if ( td->base ) { 746 rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) ); 1030 rt = new ast::ReferenceType( 1031 typebuild( td->base ), 1032 buildQualifiers( td ) 1033 ); 747 1034 } else { 748 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 ); 749 1039 } // if 750 buildForall( td->forall, rt->get_forall() );751 1040 return rt; 752 1041 } // buildReference 753 1042 754 1043 755 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 ) { 756 1045 assert( td->kind == TypeData::Aggregate ); 757 AggregateDecl * at;1046 ast::AggregateDecl * at; 758 1047 switch ( td->aggregate.kind ) { 759 case AggregateDecl::Struct: 760 case AggregateDecl::Coroutine: 761 case AggregateDecl::Exception: 762 case AggregateDecl::Generator: 763 case AggregateDecl::Monitor: 764 case AggregateDecl::Thread: 765 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage ); 766 buildForall( td->aggregate.params, at->get_parameters() ); 767 break; 768 case AggregateDecl::Union: 769 at = new UnionDecl( *td->aggregate.name, attributes, linkage ); 770 buildForall( td->aggregate.params, at->get_parameters() ); 771 break; 772 case AggregateDecl::Trait: 773 at = new TraitDecl( *td->aggregate.name, attributes, linkage ); 774 buildList( td->aggregate.params, at->get_parameters() ); 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 ); 775 1077 break; 776 1078 default: … … 778 1080 } // switch 779 1081 780 buildList( td->aggregate.fields, at-> get_members());1082 buildList( td->aggregate.fields, at->members ); 781 1083 at->set_body( td->aggregate.body ); 782 1084 … … 785 1087 786 1088 787 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 ) { 788 1093 switch ( type->kind ) { 789 1094 case TypeData::Enum: 790 1095 if ( type->enumeration.body ) { 791 EnumDecl * typedecl = buildEnum( type, attributes, linkage ); 792 return new EnumInstType( buildQualifiers( type ), typedecl ); 1096 ast::EnumDecl * typedecl = 1097 buildEnum( type, std::move( attributes ), linkage ); 1098 return new ast::EnumInstType( 1099 typedecl, 1100 buildQualifiers( type ) 1101 ); 793 1102 } else { 794 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name ); 795 } // if 1103 return new ast::EnumInstType( 1104 *type->enumeration.name, 1105 buildQualifiers( type ) 1106 ); 1107 } // if 1108 break; 796 1109 case TypeData::Aggregate: 797 1110 if ( type->aggregate.body ) { 798 AggregateDecl * typedecl = buildAggregate( type, attributes, linkage ); 1111 ast::AggregateDecl * typedecl = 1112 buildAggregate( type, std::move( attributes ), linkage ); 799 1113 switch ( type->aggregate.kind ) { 800 case AggregateDecl::Struct: 801 case AggregateDecl::Coroutine: 802 case AggregateDecl::Monitor: 803 case AggregateDecl::Thread: 804 return new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl ); 805 case AggregateDecl::Union: 806 return new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl ); 807 case AggregateDecl::Trait: 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: 808 1128 assert( false ); 809 //return new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );810 1129 break; 811 1130 default: … … 814 1133 } else { 815 1134 switch ( type->aggregate.kind ) { 816 case AggregateDecl::Struct: 817 case AggregateDecl::Coroutine: 818 case AggregateDecl::Monitor: 819 case AggregateDecl::Thread: 820 return new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 821 case AggregateDecl::Union: 822 return new UnionInstType( buildQualifiers( type ), *type->aggregate.name ); 823 case AggregateDecl::Trait: 824 return new TraitInstType( buildQualifiers( type ), *type->aggregate.name ); 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 ); 825 1153 default: 826 1154 assert( false ); 827 1155 } // switch 828 } // if 829 return nullptr; 1156 break; 1157 } // if 1158 break; 830 1159 default: 831 1160 assert( false ); 832 1161 } // switch 1162 assert( false ); 833 1163 } // buildAggInst 834 1164 835 1165 836 ReferenceToType * buildAggInst( const TypeData * td ) {1166 ast::BaseInstType * buildAggInst( const TypeData * td ) { 837 1167 assert( td->kind == TypeData::AggregateInst ); 838 1168 839 // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() ); 840 ReferenceToType * ret = nullptr; 1169 ast::BaseInstType * ret = nullptr; 841 1170 TypeData * type = td->aggInst.aggregate; 842 1171 switch ( type->kind ) { 843 1172 case TypeData::Enum: 844 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name ); 1173 return new ast::EnumInstType( 1174 *type->enumeration.name, 1175 buildQualifiers( type ) 1176 ); 845 1177 case TypeData::Aggregate: 846 1178 switch ( type->aggregate.kind ) { 847 case AggregateDecl::Struct: 848 case AggregateDecl::Coroutine: 849 case AggregateDecl::Monitor: 850 case AggregateDecl::Thread: 851 ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name ); 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 ); 852 1187 break; 853 case AggregateDecl::Union: 854 ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name ); 1188 case ast::AggregateDecl::Union: 1189 ret = new ast::UnionInstType( 1190 *type->aggregate.name, 1191 buildQualifiers( type ) 1192 ); 855 1193 break; 856 case AggregateDecl::Trait: 857 ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name ); 1194 case ast::AggregateDecl::Trait: 1195 ret = new ast::TraitInstType( 1196 *type->aggregate.name, 1197 buildQualifiers( type ) 1198 ); 858 1199 break; 859 1200 default: … … 865 1206 } // switch 866 1207 867 ret->set_hoistType( td->aggInst.hoistType ); 868 buildList( td->aggInst.params, ret->get_parameters() ); 869 buildForall( td->forall, ret->get_forall() ); 1208 ret->hoistType = td->aggInst.hoistType; 1209 buildList( td->aggInst.params, ret->params ); 870 1210 return ret; 871 1211 } // buildAggInst 872 1212 873 1213 874 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 ) { 875 1220 assert( td->kind == TypeData::Symbolic ); 876 NamedTypeDecl * ret;1221 ast::NamedTypeDecl * ret; 877 1222 assert( td->base ); 878 1223 if ( td->symbolic.isTypedef ) { 879 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 ); 880 1231 } else { 881 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 ); 882 1240 } // if 883 buildList( td->symbolic.assertions, ret-> get_assertions());884 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 ); 885 1243 return ret; 886 1244 } // buildSymbolic 887 1245 888 1246 889 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 ) { 890 1251 assert( td->kind == TypeData::Enum ); 891 Type * baseType = td->base ? typebuild(td->base) : nullptr; 892 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType ); 893 buildList( td->enumeration.constants, ret->get_members() ); 894 list< Declaration * >::iterator members = ret->get_members().begin(); 895 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; 896 1264 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 897 1265 if ( cur->enumInLine ) { … … 900 1268 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); 901 1269 } else if ( cur->has_enumeratorValue() ) { 902 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members); 903 member->set_init( new SingleInit( maybeMoveBuild( 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 ); 904 1277 } else if ( !cur->initializer ) { 905 if ( baseType && (!dynamic_cast< BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {1278 if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) { 906 1279 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 907 1280 } … … 910 1283 // if 911 1284 } // for 912 ret-> set_body( td->enumeration.body );1285 ret->body = td->enumeration.body; 913 1286 return ret; 914 1287 } // buildEnum 915 1288 916 1289 917 TypeInstType * buildSymbolicInst( const TypeData * td ) {1290 ast::TypeInstType * buildSymbolicInst( const TypeData * td ) { 918 1291 assert( td->kind == TypeData::SymbolicInst ); 919 TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false ); 920 buildList( td->symbolic.actuals, ret->get_parameters() ); 921 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 ); 922 1298 return ret; 923 1299 } // buildSymbolicInst 924 1300 925 1301 926 TupleType * buildTuple( const TypeData * td ) {1302 ast::TupleType * buildTuple( const TypeData * td ) { 927 1303 assert( td->kind == TypeData::Tuple ); 928 std:: list< Type *> types;1304 std::vector<ast::ptr<ast::Type>> types; 929 1305 buildTypeList( td->tuple, types ); 930 TupleType * ret = new TupleType( buildQualifiers( td ), types ); 931 buildForall( td->forall, ret->get_forall() ); 1306 ast::TupleType * ret = new ast::TupleType( 1307 std::move( types ), 1308 buildQualifiers( td ) 1309 ); 932 1310 return ret; 933 1311 } // buildTuple 934 1312 935 1313 936 TypeofType * buildTypeof( const TypeData * td ) {1314 ast::TypeofType * buildTypeof( const TypeData * td ) { 937 1315 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 938 1316 assert( td->typeexpr ); 939 // assert( td->typeexpr->expr ); 940 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 ); 941 1323 } // buildTypeof 942 1324 943 1325 944 VTableType * buildVtable( const TypeData * td ) {1326 ast::VTableType * buildVtable( const TypeData * td ) { 945 1327 assert( td->base ); 946 return new VTableType{ buildQualifiers( td ), typebuild( td->base ) }; 1328 return new ast::VTableType( 1329 typebuild( td->base ), 1330 buildQualifiers( td ) 1331 ); 947 1332 } // buildVtable 948 1333 949 1334 950 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 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 ) { 951 1419 if ( td->kind == TypeData::Function ) { 952 1420 if ( td->function.idList ) { // KR function ? … … 954 1422 } // if 955 1423 956 FunctionDecl * decl; 957 Statement * stmt = maybeBuild( td->function.body ); 958 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt ); 959 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec ); 960 buildList( td->function.withExprs, decl->withExprs ); 961 return decl->set_asmName( asmName ); 1424 return buildFunctionDecl( 1425 td, name, scs, funcSpec, linkage, 1426 asmName, std::move( attributes ) ); 962 1427 } else if ( td->kind == TypeData::Aggregate ) { 963 return buildAggregate( td, attributes, linkage );1428 return buildAggregate( td, std::move( attributes ), linkage ); 964 1429 } else if ( td->kind == TypeData::Enum ) { 965 return buildEnum( td, attributes, linkage );1430 return buildEnum( td, std::move( attributes ), linkage ); 966 1431 } else if ( td->kind == TypeData::Symbolic ) { 967 return buildSymbolic( td, attributes, name, scs, linkage );1432 return buildSymbolic( td, std::move( attributes ), name, scs, linkage ); 968 1433 } else { 969 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; 970 1445 } // if 971 1446 return nullptr; … … 973 1448 974 1449 975 FunctionType * buildFunction( const TypeData * td ) {1450 ast::FunctionType * buildFunctionType( const TypeData * td ) { 976 1451 assert( td->kind == TypeData::Function ); 977 FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis ); 978 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 ); 979 1458 buildForall( td->forall, ft->forall ); 980 1459 if ( td->base ) { 981 1460 switch ( td->base->kind ) { 982 1461 case TypeData::Tuple: 983 build List( td->base->tuple, ft->returnVals );1462 buildTypeList( td->base->tuple, ft->returns ); 984 1463 break; 985 1464 default: 986 ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) ); 1465 ft->returns.push_back( typebuild( td->base ) ); 1466 break; 987 1467 } // switch 988 1468 } else { 989 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 ) ); 990 1471 } // if 991 1472 return ft; 992 } // buildFunction 1473 } // buildFunctionType 993 1474 994 1475 … … 1021 1502 param->type = decl->type; // set copy declaration type to parameter type 1022 1503 decl->type = nullptr; // reset declaration type 1023 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 ); 1024 1506 } // if 1025 1507 } // for -
TabularUnified src/Parser/TypeData.h ¶
r4541b09 rbb7422a 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 : Fri Feb 24 14:25:02202313 // Update Count : 20 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Mar 1 10:44:00 2023 13 // Update Count : 206 14 14 // 15 15 … … 20 20 #include <string> // for string 21 21 22 #include "AST/Type.hpp" // for Type 22 23 #include "ParseNode.h" // for DeclarationNode, DeclarationNode::Ag... 23 #include "SynTree/LinkageSpec.h" // for Spec24 #include "SynTree/Type.h" // for Type, ReferenceToType (ptr only)25 #include "SynTree/SynTree.h" // for Visitor Nodes26 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; … … 41 39 }; 42 40 43 struct AggInst_t { // handles SUE41 struct AggInst_t { 44 42 TypeData * aggregate = nullptr; 45 43 ExpressionNode * params = nullptr; … … 93 91 DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType; 94 92 95 Type::Qualifiers qualifiers;93 ast::CV::Qualifiers qualifiers; 96 94 DeclarationNode * forall = nullptr; 97 95 … … 114 112 }; 115 113 116 Type * typebuild( const TypeData * );114 ast::Type * typebuild( const TypeData * ); 117 115 TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true ); 118 Type::Qualifiers buildQualifiers( const TypeData * td );119 Type * buildBasicType( const TypeData * );120 PointerType * buildPointer( const TypeData * );121 ArrayType * buildArray( const TypeData * );122 ReferenceType * buildReference( const TypeData * );123 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute *> );124 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage );125 ReferenceToType * buildAggInst( const TypeData * );126 TypeDecl * buildVariable( const TypeData * );127 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec );128 TypeInstType * buildSymbolicInst( const TypeData * );129 TupleType * buildTuple( const TypeData * );130 TypeofType * buildTypeof( const TypeData * );131 VTableType * buildVtable( const TypeData * );132 Declaration* buildDecl(133 const TypeData *, const std::string &, Type::StorageClasses, Expression*,134 Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression* asmName,135 Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute *>() );136 FunctionType * buildFunction( const TypeData * );137 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 * ); 138 136 void buildKRFunction( const TypeData::Function_t & function ); 139 137 -
TabularUnified src/Parser/lex.ll ¶
r4541b09 rbb7422a 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__ -
TabularUnified src/Parser/parser.yy ¶
r4541b09 rbb7422a 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T hu Mar 30 21:28:25202313 // Update Count : 632 811 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 14:02:00 2023 13 // Update Count : 6329 14 14 // 15 15 … … 64 64 65 65 extern DeclarationNode * parseTree; 66 extern LinkageSpec::Spec linkage;66 extern ast::Linkage::Spec linkage; 67 67 extern TypedefTable typedefTable; 68 68 69 stack< LinkageSpec::Spec> linkageStack;69 stack<ast::Linkage::Spec> linkageStack; 70 70 71 71 bool appendStr( string & to, string & from ) { … … 200 200 } // fieldDecl 201 201 202 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )203 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) )202 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) ) 203 #define NEW_ONE new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) ) 204 204 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 205 205 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 208 208 209 209 static ForCtrl * makeForCtrl( 210 const CodeLocation & location, 210 211 DeclarationNode * init, 211 212 enum OperKinds compop, … … 213 214 ExpressionNode * inc ) { 214 215 // Wrap both comp/inc if they are non-null. 215 if ( comp ) comp = new ExpressionNode( build_binary_val( 216 if ( comp ) comp = new ExpressionNode( build_binary_val( location, 216 217 compop, 217 new ExpressionNode( build_varref( new string( *init->name ) ) ),218 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 218 219 comp ) ); 219 if ( inc ) inc = new ExpressionNode( build_binary_val( 220 if ( inc ) inc = new ExpressionNode( build_binary_val( location, 220 221 // choose += or -= for upto/downto 221 222 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn, 222 new ExpressionNode( build_varref( new string( *init->name ) ) ),223 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 223 224 inc ) ); 224 225 // The StatementNode call frees init->name, it must happen later. … … 226 227 } 227 228 228 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {229 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 229 230 if ( index->initializer ) { 230 231 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 234 235 } // if 235 236 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 236 return makeForCtrl( initDecl, compop, comp, inc );237 return makeForCtrl( location, initDecl, compop, comp, inc ); 237 238 } // forCtrl 238 239 239 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {240 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());241 if ( constant && (constant-> get_constant()->get_value() == "0" || constant->get_constant()->get_value()== "1") ) {242 type = new ExpressionNode( new CastExpr( maybeMoveBuild( type ), new BasicType( Type::Qualifiers(),BasicType::SignedInt ) ) );240 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 241 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get()); 242 if ( constant && (constant->rep == "0" || constant->rep == "1") ) { 243 type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) ); 243 244 } // if 244 245 DeclarationNode * initDecl = distAttr( … … 246 247 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 247 248 ); 248 return makeForCtrl( initDecl, compop, comp, inc );249 return makeForCtrl( location, initDecl, compop, comp, inc ); 249 250 } // forCtrl 250 251 251 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {252 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {253 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );254 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {255 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1) ) {256 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );252 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 253 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) { 254 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc ); 255 } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) { 256 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) { 257 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc ); 257 258 } else { 258 259 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 299 300 ExpressionNode * en; 300 301 DeclarationNode * decl; 301 AggregateDecl::Aggregate aggKey;302 TypeDecl::Kind tclass;302 ast::AggregateDecl::Aggregate aggKey; 303 ast::TypeDecl::Kind tclass; 303 304 StatementNode * sn; 304 WaitForStmt * wfs;305 Expression* constant;305 ast::WaitForStmt * wfs; 306 ast::Expr * constant; 306 307 CondCtl * ifctl; 307 308 ForCtrl * fctl; … … 313 314 bool flag; 314 315 EnumHiding hide; 315 CatchStmt::Kind catch_kind;316 GenericExpr * genexpr;316 ast::ExceptionKind catch_kind; 317 ast::GenericExpr * genexpr; 317 318 } 318 319 319 // ************************* TERMINAL TOKENS ********************************320 // ************************ TERMINAL TOKENS ******************************** 320 321 321 322 // keywords … … 611 612 constant: 612 613 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant". 613 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }614 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }615 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }616 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }617 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }614 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); } 615 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); } 616 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); } 617 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); } 618 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); } 618 619 ; 619 620 … … 641 642 642 643 string_literal: 643 string_literal_list { $$ = build_constantStr( *$1 ); }644 string_literal_list { $$ = build_constantStr( yylloc, *$1 ); } 644 645 ; 645 646 … … 658 659 primary_expression: 659 660 IDENTIFIER // typedef name cannot be used as a variable name 660 { $$ = new ExpressionNode( build_varref( $1 ) ); }661 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 661 662 | quasi_keyword 662 { $$ = new ExpressionNode( build_varref( $1 ) ); }663 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 663 664 | TYPEDIMname // CFA, generic length argument 664 665 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 665 666 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 666 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }667 { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); } 667 668 | tuple 668 669 | '(' comma_expression ')' 669 670 { $$ = $2; } 670 671 | '(' compound_statement ')' // GCC, lambda expression 671 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild( $2 ) ) ) ); }672 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); } 672 673 | type_name '.' identifier // CFA, nested type 673 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref($3 ) ) ); }674 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 674 675 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 675 676 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 703 704 { 704 705 // steal the association node from the singleton and delete the wrapper 705 $1->associations.splice($1->associations.end(), $3->associations); 706 assert( 1 == $3->associations.size() ); 707 $1->associations.push_back( $3->associations.front() ); 706 708 delete $3; 707 709 $$ = $1; … … 713 715 { 714 716 // create a GenericExpr wrapper with one association pair 715 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild( $3 ) } } );717 $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } ); 716 718 } 717 719 | DEFAULT ':' assignment_expression 718 { $$ = new GenericExpr(nullptr, { { maybeMoveBuild( $3 ) } } ); }720 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); } 719 721 ; 720 722 … … 725 727 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 726 728 // Current: Commas in subscripts make tuples. 727 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple((ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }729 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 728 730 | postfix_expression '[' assignment_expression ']' 729 731 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 731 733 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 732 734 // equivalent to the old x[i,j]. 733 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }735 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 734 736 | constant '[' assignment_expression ']' // 3[a], 'a'[a], 3.5[a] 735 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }737 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 736 738 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 737 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }739 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); } 738 740 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 739 741 { 740 742 Token fn; 741 743 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 742 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref(fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );744 $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 743 745 } 744 746 | postfix_expression '(' argument_expression_list_opt ')' 745 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }747 { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); } 746 748 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 747 749 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 748 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(new string( "__builtin_va_arg") ) ),750 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ), 749 751 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 750 752 | postfix_expression '`' identifier // CFA, postfix call 751 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(build_postfix_name( $3 ) ) ), $1 ) ); }753 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 752 754 | constant '`' identifier // CFA, postfix call 753 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(build_postfix_name( $3 ) ) ), $1 ) ); }755 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 754 756 | string_literal '`' identifier // CFA, postfix call 755 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }757 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); } 756 758 | postfix_expression '.' identifier 757 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref($3 ) ) ); }759 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 758 760 | postfix_expression '.' INTEGERconstant // CFA, tuple index 759 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger(*$3 ) ) ); }761 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); } 760 762 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 761 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant(*$2 ) ) ); }763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); } 762 764 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 763 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple($4 ) ) ); }765 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 764 766 | postfix_expression '.' aggregate_control 765 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }767 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); } 766 768 | postfix_expression ARROW identifier 767 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref($3 ) ) ); }769 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 768 770 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 769 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger(*$3 ) ) ); }771 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); } 770 772 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 771 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple($4 ) ) ); }773 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 772 774 | postfix_expression ICR 773 { $$ = new ExpressionNode( build_unary_val( OperKinds::IncrPost, $1 ) ); }775 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); } 774 776 | postfix_expression DECR 775 { $$ = new ExpressionNode( build_unary_val( OperKinds::DecrPost, $1 ) ); }777 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); } 776 778 | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal 777 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }779 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); } 778 780 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 779 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }781 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); } 780 782 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 781 783 { 782 784 Token fn; 783 785 fn.str = new string( "^?{}" ); // location undefined 784 $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref(fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );786 $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) ); 785 787 } 786 788 ; … … 813 815 field_name 814 816 | FLOATING_DECIMALconstant field 815 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant(*$1 ) ), maybeMoveBuild( $2 ) ) ); }817 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); } 816 818 | FLOATING_DECIMALconstant '[' field_name_list ']' 817 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple($3 ) ) ); }819 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); } 818 820 | field_name '.' field 819 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild( $3 ) ) ); }821 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); } 820 822 | field_name '.' '[' field_name_list ']' 821 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple($4 ) ) ); }823 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 822 824 | field_name ARROW field 823 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild( $3 ) ) ); }825 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); } 824 826 | field_name ARROW '[' field_name_list ']' 825 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple($4 ) ) ); }827 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); } 826 828 ; 827 829 828 830 field_name: 829 831 INTEGERconstant fraction_constants_opt 830 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger(*$1 ), $2 ) ); }832 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); } 831 833 | FLOATINGconstant fraction_constants_opt 832 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant(*$1 ), $2 ) ); }834 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); } 833 835 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 834 836 { 835 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref($1 ), $2 ) );837 $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) ); 836 838 } 837 839 ; … … 842 844 | fraction_constants_opt FLOATING_FRACTIONconstant 843 845 { 844 Expression * constant = build_field_name_FLOATING_FRACTIONconstant(*$2 );845 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1,constant ) ) : new ExpressionNode( constant );846 ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ); 847 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant ); 846 848 } 847 849 ; … … 862 864 { 863 865 switch ( $1 ) { 864 865 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild( $2 ) ) );866 case OperKinds::AddressOf: 867 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ); 866 868 break; 867 868 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );869 case OperKinds::PointTo: 870 $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); 869 871 break; 870 871 $$ = new ExpressionNode( new AddressExpr( newAddressExpr( maybeMoveBuild( $2 ) ) ) );872 case OperKinds::And: 873 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) ); 872 874 break; 873 875 default: 874 876 assert( false ); 875 877 } 876 878 } 877 879 | unary_operator cast_expression 878 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }880 { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); } 879 881 | ICR unary_expression 880 { $$ = new ExpressionNode( build_unary_val( OperKinds::Incr, $2 ) ); }882 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); } 881 883 | DECR unary_expression 882 { $$ = new ExpressionNode( build_unary_val( OperKinds::Decr, $2 ) ); }884 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); } 883 885 | SIZEOF unary_expression 884 { $$ = new ExpressionNode( new SizeofExpr(maybeMoveBuild( $2 ) ) ); }886 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); } 885 887 | SIZEOF '(' type_no_function ')' 886 { $$ = new ExpressionNode( new SizeofExpr(maybeMoveBuildType( $3 ) ) ); }888 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 887 889 | ALIGNOF unary_expression // GCC, variable alignment 888 { $$ = new ExpressionNode( new AlignofExpr(maybeMoveBuild( $2 ) ) ); }890 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); } 889 891 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 890 { $$ = new ExpressionNode( new AlignofExpr(maybeMoveBuildType( $3 ) ) ); }892 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 891 893 | OFFSETOF '(' type_no_function ',' identifier ')' 892 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref($5 ) ) ); }894 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); } 893 895 | TYPEID '(' type_no_function ')' 894 896 { … … 915 917 unary_expression 916 918 | '(' type_no_function ')' cast_expression 917 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }919 { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); } 918 920 | '(' aggregate_control '&' ')' cast_expression // CFA 919 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }921 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); } 920 922 | '(' aggregate_control '*' ')' cast_expression // CFA 921 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }923 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); } 922 924 | '(' VIRTUAL ')' cast_expression // CFA 923 { $$ = new ExpressionNode( new VirtualCastExpr(maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }925 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); } 924 926 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 925 { $$ = new ExpressionNode( new VirtualCastExpr(maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }927 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); } 926 928 | '(' RETURN type_no_function ')' cast_expression // CFA 927 929 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; } … … 931 933 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 932 934 // | '(' type_no_function ')' tuple 933 // { $$ = new ExpressionNode( build_cast($2, $4 ) ); }935 // { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); } 934 936 ; 935 937 … … 949 951 cast_expression 950 952 | exponential_expression '\\' cast_expression 951 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }953 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); } 952 954 ; 953 955 … … 955 957 exponential_expression 956 958 | multiplicative_expression '*' exponential_expression 957 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }959 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); } 958 960 | multiplicative_expression '/' exponential_expression 959 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }961 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); } 960 962 | multiplicative_expression '%' exponential_expression 961 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }963 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); } 962 964 ; 963 965 … … 965 967 multiplicative_expression 966 968 | additive_expression '+' multiplicative_expression 967 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }969 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); } 968 970 | additive_expression '-' multiplicative_expression 969 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }971 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); } 970 972 ; 971 973 … … 973 975 additive_expression 974 976 | shift_expression LS additive_expression 975 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }977 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); } 976 978 | shift_expression RS additive_expression 977 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }979 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); } 978 980 ; 979 981 … … 981 983 shift_expression 982 984 | relational_expression '<' shift_expression 983 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }985 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); } 984 986 | relational_expression '>' shift_expression 985 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }987 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); } 986 988 | relational_expression LE shift_expression 987 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }989 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); } 988 990 | relational_expression GE shift_expression 989 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }991 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); } 990 992 ; 991 993 … … 993 995 relational_expression 994 996 | equality_expression EQ relational_expression 995 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }997 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); } 996 998 | equality_expression NE relational_expression 997 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }999 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); } 998 1000 ; 999 1001 … … 1001 1003 equality_expression 1002 1004 | AND_expression '&' equality_expression 1003 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }1005 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); } 1004 1006 ; 1005 1007 … … 1007 1009 AND_expression 1008 1010 | exclusive_OR_expression '^' AND_expression 1009 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }1011 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); } 1010 1012 ; 1011 1013 … … 1013 1015 exclusive_OR_expression 1014 1016 | inclusive_OR_expression '|' exclusive_OR_expression 1015 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }1017 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); } 1016 1018 ; 1017 1019 … … 1019 1021 inclusive_OR_expression 1020 1022 | logical_AND_expression ANDAND inclusive_OR_expression 1021 { $$ = new ExpressionNode( build_and_or( $1, $3, true) ); }1023 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); } 1022 1024 ; 1023 1025 … … 1025 1027 logical_AND_expression 1026 1028 | logical_OR_expression OROR logical_AND_expression 1027 { $$ = new ExpressionNode( build_and_or( $1, $3, false) ); }1029 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); } 1028 1030 ; 1029 1031 … … 1031 1033 logical_OR_expression 1032 1034 | logical_OR_expression '?' comma_expression ':' conditional_expression 1033 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }1035 { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); } 1034 1036 // FIX ME: computes $1 twice 1035 1037 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 1036 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }1038 { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); } 1037 1039 ; 1038 1040 … … 1049 1051 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1050 1052 // } else { 1051 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );1053 $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) ); 1052 1054 // } // if 1053 1055 } … … 1094 1096 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1095 1097 '[' ',' tuple_expression_list ']' 1096 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }1098 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 1097 1099 | '[' push assignment_expression pop ',' tuple_expression_list ']' 1098 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }1100 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); } 1099 1101 ; 1100 1102 … … 1112 1114 assignment_expression 1113 1115 | comma_expression ',' assignment_expression 1114 { $$ = new ExpressionNode( new CommaExpr(maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1116 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1115 1117 ; 1116 1118 … … 1139 1141 | asm_statement 1140 1142 | DIRECTIVE 1141 { $$ = new StatementNode( build_directive( $1 ) ); }1143 { $$ = new StatementNode( build_directive( yylloc, $1 ) ); } 1142 1144 ; 1143 1145 … … 1145 1147 // labels cannot be identifiers 0 or 1 1146 1148 identifier_or_type_name ':' attribute_list_opt statement 1147 { $$ = $4->add_label( $1, $3 ); }1149 { $$ = $4->add_label( yylloc, $1, $3 ); } 1148 1150 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1149 1151 { … … 1157 1159 compound_statement: 1158 1160 '{' '}' 1159 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }1161 { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); } 1160 1162 | '{' push 1161 1163 local_label_declaration_opt // GCC, local labels appear at start of block 1162 1164 statement_decl_list // C99, intermix declarations and statements 1163 1165 pop '}' 1164 { $$ = new StatementNode( build_compound( $4 ) ); }1166 { $$ = new StatementNode( build_compound( yylloc, $4 ) ); } 1165 1167 ; 1166 1168 … … 1193 1195 expression_statement: 1194 1196 comma_expression_opt ';' 1195 { $$ = new StatementNode( build_expr( $1 ) ); }1197 { $$ = new StatementNode( build_expr( yylloc, $1 ) ); } 1196 1198 ; 1197 1199 … … 1202 1204 { $$ = $2; } 1203 1205 | SWITCH '(' comma_expression ')' case_clause 1204 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }1206 { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); } 1205 1207 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1206 1208 { 1207 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );1209 StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) ); 1208 1210 // The semantics of the declaration list is changed to include associated initialization, which is performed 1209 1211 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1211 1213 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1212 1214 // statement. 1213 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1215 $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1214 1216 } 1215 1217 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1216 1218 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1217 1219 | CHOOSE '(' comma_expression ')' case_clause // CFA 1218 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }1220 { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); } 1219 1221 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1220 1222 { 1221 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );1222 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1223 StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) ); 1224 $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1223 1225 } 1224 1226 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error … … 1229 1231 IF '(' conditional_declaration ')' statement %prec THEN 1230 1232 // explicitly deal with the shift/reduce conflict on if/else 1231 { $$ = new StatementNode( build_if( $3, maybe_build_compound($5 ), nullptr ) ); }1233 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); } 1232 1234 | IF '(' conditional_declaration ')' statement ELSE statement 1233 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound($7 ) ) ); }1235 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); } 1234 1236 ; 1235 1237 … … 1251 1253 constant_expression { $$ = $1; } 1252 1254 | constant_expression ELLIPSIS constant_expression // GCC, subrange 1253 { $$ = new ExpressionNode( new RangeExpr(maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1255 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1254 1256 | subrange // CFA, subrange 1255 1257 ; … … 1267 1269 | CASE case_value_list error // syntax error 1268 1270 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1269 | DEFAULT ':' { $$ = new StatementNode( build_default( ) ); }1271 | DEFAULT ':' { $$ = new StatementNode( build_default( yylloc ) ); } 1270 1272 // A semantic check is required to ensure only one default clause per switch/choose statement. 1271 1273 | DEFAULT error // syntax error … … 1279 1281 1280 1282 case_clause: // CFA 1281 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }1283 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); } 1282 1284 ; 1283 1285 … … 1290 1292 switch_clause_list: // CFA 1291 1293 case_label_list statement_list_nodecl 1292 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }1294 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); } 1293 1295 | switch_clause_list case_label_list statement_list_nodecl 1294 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }1296 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ) ); } 1295 1297 ; 1296 1298 1297 1299 iteration_statement: 1298 1300 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1299 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound($4 ) ) ); }1301 { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); } 1300 1302 | WHILE '(' ')' statement ELSE statement // CFA 1301 1303 { 1302 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound($4 ) ) );1304 $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); 1303 1305 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1304 1306 } 1305 1307 | WHILE '(' conditional_declaration ')' statement %prec THEN 1306 { $$ = new StatementNode( build_while( $3, maybe_build_compound($5 ) ) ); }1308 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1307 1309 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1308 { $$ = new StatementNode( build_while( $3, maybe_build_compound($5 ), $7 ) ); }1310 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); } 1309 1311 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1310 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound($2 ) ) ); }1312 { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); } 1311 1313 | DO statement WHILE '(' ')' ELSE statement // CFA 1312 1314 { 1313 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound($2 ) ) );1315 $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); 1314 1316 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1315 1317 } 1316 1318 | DO statement WHILE '(' comma_expression ')' ';' 1317 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound($2 ) ) ); }1319 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); } 1318 1320 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1319 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound($2 ), $8 ) ); }1321 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); } 1320 1322 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1321 { $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound($4 ) ) ); }1323 { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); } 1322 1324 | FOR '(' ')' statement ELSE statement // CFA 1323 1325 { 1324 $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound($4 ) ) );1326 $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); 1325 1327 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1326 1328 } 1327 1329 | FOR '(' for_control_expression_list ')' statement %prec THEN 1328 { $$ = new StatementNode( build_for( $3, maybe_build_compound($5 ) ) ); }1330 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1329 1331 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1330 { $$ = new StatementNode( build_for( $3, maybe_build_compound($5 ), $7 ) ); }1332 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); } 1331 1333 ; 1332 1334 … … 1342 1344 if ( $1->condition ) { 1343 1345 if ( $3->condition ) { 1344 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true) );1346 $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) ); 1345 1347 } // if 1346 1348 } else $1->condition = $3->condition; 1347 1349 if ( $1->change ) { 1348 1350 if ( $3->change ) { 1349 $1->change->expr.reset( new CommaExpr($1->change->expr.release(), $3->change->expr.release() ) );1351 $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) ); 1350 1352 } // if 1351 1353 } else $1->change = $3->change; … … 1359 1361 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1360 1362 { 1361 StatementNode * init = $1 ? new StatementNode( new ExprStmt(maybeMoveBuild( $1 ) ) ) : nullptr;1363 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr; 1362 1364 $$ = new ForCtrl( init, $3, $5 ); 1363 1365 } … … 1371 1373 1372 1374 | comma_expression // CFA, anonymous loop-index 1373 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }1375 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1374 1376 | downupdowneq comma_expression // CFA, anonymous loop-index 1375 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }1377 { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1376 1378 1377 1379 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1378 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }1380 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1379 1381 | '@' updowneq comma_expression // CFA, anonymous loop-index 1380 1382 { 1381 1383 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1382 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );1384 else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1383 1385 } 1384 1386 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1388 1390 } 1389 1391 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1390 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }1392 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1391 1393 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1392 1394 { 1393 1395 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1394 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );1396 else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1395 1397 } 1396 1398 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1411 1413 1412 1414 | comma_expression ';' comma_expression // CFA 1413 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }1415 { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1414 1416 | comma_expression ';' downupdowneq comma_expression // CFA 1415 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }1417 { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1416 1418 1417 1419 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1418 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }1420 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1419 1421 | comma_expression ';' '@' updowneq comma_expression // CFA 1420 1422 { 1421 1423 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1422 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );1424 else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1423 1425 } 1424 1426 | comma_expression ';' comma_expression updowneq '@' // CFA … … 1426 1428 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1427 1429 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1428 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );1430 else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1429 1431 } 1430 1432 | comma_expression ';' '@' updowneq '@' // CFA, error … … 1432 1434 1433 1435 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1434 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }1436 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1435 1437 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1436 1438 { 1437 1439 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1438 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );1440 else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 ); 1439 1441 } 1440 1442 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA … … 1442 1444 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1443 1445 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1444 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );1446 else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 ); 1445 1447 } 1446 1448 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1447 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }1449 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1448 1450 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1449 1451 { 1450 1452 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1451 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );1453 else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr ); 1452 1454 } 1453 1455 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA … … 1455 1457 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1456 1458 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1457 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );1459 else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr ); 1458 1460 } 1459 1461 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA … … 1461 1463 1462 1464 | declaration comma_expression // CFA 1463 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }1465 { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1464 1466 | declaration downupdowneq comma_expression // CFA 1465 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }1467 { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1466 1468 1467 1469 | declaration comma_expression updowneq comma_expression // CFA 1468 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }1470 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1469 1471 | declaration '@' updowneq comma_expression // CFA 1470 1472 { 1471 1473 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1472 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );1474 else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE ); 1473 1475 } 1474 1476 | declaration comma_expression updowneq '@' // CFA … … 1476 1478 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1477 1479 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1478 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );1480 else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE ); 1479 1481 } 1480 1482 1481 1483 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1482 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }1484 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1483 1485 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1484 1486 { 1485 1487 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1486 else $$ = forCtrl( $1, $4, $3, nullptr, $6 );1488 else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 ); 1487 1489 } 1488 1490 | declaration comma_expression updowneq '@' '~' comma_expression // CFA … … 1490 1492 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1491 1493 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1492 else $$ = forCtrl( $1, $2, $3, nullptr, $6 );1494 else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 ); 1493 1495 } 1494 1496 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1495 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }1497 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1496 1498 | declaration '@' updowneq comma_expression '~' '@' // CFA 1497 1499 { 1498 1500 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1499 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );1501 else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr ); 1500 1502 } 1501 1503 | declaration comma_expression updowneq '@' '~' '@' // CFA … … 1503 1505 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1504 1506 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1505 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );1507 else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr ); 1506 1508 } 1507 1509 | declaration '@' updowneq '@' '~' '@' // CFA, error … … 1546 1548 jump_statement: 1547 1549 GOTO identifier_or_type_name ';' 1548 { $$ = new StatementNode( build_branch( $2,BranchStmt::Goto ) ); }1550 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); } 1549 1551 | GOTO '*' comma_expression ';' // GCC, computed goto 1550 1552 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1553 1555 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1554 1556 | fall_through_name ';' // CFA 1555 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }1557 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); } 1556 1558 | fall_through_name identifier_or_type_name ';' // CFA 1557 { $$ = new StatementNode( build_branch( $2,BranchStmt::FallThrough ) ); }1559 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); } 1558 1560 | fall_through_name DEFAULT ';' // CFA 1559 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }1561 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); } 1560 1562 | CONTINUE ';' 1561 1563 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1562 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }1564 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); } 1563 1565 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1564 1566 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1565 1567 // the target of the transfer appears only at the start of an iteration statement. 1566 { $$ = new StatementNode( build_branch( $2,BranchStmt::Continue ) ); }1568 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); } 1567 1569 | BREAK ';' 1568 1570 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1569 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }1571 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); } 1570 1572 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1571 1573 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1572 1574 // the target of the transfer appears only at the start of an iteration statement. 1573 { $$ = new StatementNode( build_branch( $2,BranchStmt::Break ) ); }1575 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); } 1574 1576 | RETURN comma_expression_opt ';' 1575 { $$ = new StatementNode( build_return( $2 ) ); }1577 { $$ = new StatementNode( build_return( yylloc, $2 ) ); } 1576 1578 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1577 1579 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1578 1580 | SUSPEND ';' 1579 { $$ = new StatementNode( build_suspend( nullptr) ); }1581 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); } 1580 1582 | SUSPEND compound_statement 1581 { $$ = new StatementNode( build_suspend( $2) ); }1583 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); } 1582 1584 | SUSPEND COROUTINE ';' 1583 { $$ = new StatementNode( build_suspend( nullptr,SuspendStmt::Coroutine ) ); }1585 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); } 1584 1586 | SUSPEND COROUTINE compound_statement 1585 { $$ = new StatementNode( build_suspend( $3,SuspendStmt::Coroutine ) ); }1587 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); } 1586 1588 | SUSPEND GENERATOR ';' 1587 { $$ = new StatementNode( build_suspend( nullptr,SuspendStmt::Generator ) ); }1589 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); } 1588 1590 | SUSPEND GENERATOR compound_statement 1589 { $$ = new StatementNode( build_suspend( $3,SuspendStmt::Generator ) ); }1591 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); } 1590 1592 | THROW assignment_expression_opt ';' // handles rethrow 1591 { $$ = new StatementNode( build_throw( $2 ) ); }1593 { $$ = new StatementNode( build_throw( yylloc, $2 ) ); } 1592 1594 | THROWRESUME assignment_expression_opt ';' // handles reresume 1593 { $$ = new StatementNode( build_resume( $2 ) ); }1595 { $$ = new StatementNode( build_resume( yylloc, $2 ) ); } 1594 1596 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1595 1597 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1603 1605 with_statement: 1604 1606 WITH '(' tuple_expression_list ')' statement 1605 { $$ = new StatementNode( build_with( $3, $5 ) ); }1607 { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); } 1606 1608 ; 1607 1609 … … 1611 1613 { 1612 1614 if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; } 1613 $$ = new StatementNode( build_mutex( $3, $5 ) );1615 $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) ); 1614 1616 } 1615 1617 ; … … 1650 1652 when_clause_opt waitfor statement %prec THEN 1651 1653 // Called first: create header for WaitForStmt. 1652 { $$ = build_waitfor( new WaitForStmt(), $1, $2, maybe_build_compound($3 ) ); }1654 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1653 1655 | wor_waitfor_clause wor when_clause_opt waitfor statement 1654 { $$ = build_waitfor( $1, $3, $4, maybe_build_compound($5 ) ); }1656 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1655 1657 | wor_waitfor_clause wor when_clause_opt ELSE statement 1656 { $$ = build_waitfor_else( $1, $3, maybe_build_compound($5 ) ); }1658 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); } 1657 1659 | wor_waitfor_clause wor when_clause_opt timeout statement %prec THEN 1658 { $$ = build_waitfor_timeout( $1, $3, $4, maybe_build_compound($5 ) ); }1660 { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1659 1661 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1660 1662 | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1661 1663 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1662 1664 | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1663 { $$ = build_waitfor_else( build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ), $7, maybe_build_compound( $9 ) ); } 1665 { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); } 1666 ; 1664 1667 1665 1668 waitfor_statement: … … 1711 1714 wor_waituntil_clause %prec THEN 1712 1715 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1713 { $$ = new StatementNode( build_compound( (StatementNode *)0) ); }1716 { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); } 1714 1717 ; 1715 1718 1716 1719 exception_statement: 1717 TRY compound_statement handler_clause %prec THEN1718 { $$ = new StatementNode( build_try( $2, $3, nullptr ) ); }1720 TRY compound_statement handler_clause %prec THEN 1721 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); } 1719 1722 | TRY compound_statement finally_clause 1720 { $$ = new StatementNode( build_try( $2, nullptr, $3 ) ); }1723 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); } 1721 1724 | TRY compound_statement handler_clause finally_clause 1722 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }1725 { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); } 1723 1726 ; 1724 1727 1725 1728 handler_clause: 1726 1729 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1727 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }1730 { $$ = new StatementNode( build_catch( yylloc, $1, $4, $6, $8 ) ); } 1728 1731 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1729 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }1732 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); } 1730 1733 ; 1731 1734 … … 1737 1740 1738 1741 handler_key: 1739 CATCH { $$ = CatchStmt::Terminate; }1740 | RECOVER { $$ = CatchStmt::Terminate; }1741 | CATCHRESUME { $$ = CatchStmt::Resume; }1742 | FIXUP { $$ = CatchStmt::Resume; }1742 CATCH { $$ = ast::Terminate; } 1743 | RECOVER { $$ = ast::Terminate; } 1744 | CATCHRESUME { $$ = ast::Resume; } 1745 | FIXUP { $$ = ast::Resume; } 1743 1746 ; 1744 1747 1745 1748 finally_clause: 1746 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); }1749 FINALLY compound_statement { $$ = new StatementNode( build_finally( yylloc, $2 ) ); } 1747 1750 ; 1748 1751 … … 1770 1773 asm_statement: 1771 1774 ASM asm_volatile_opt '(' string_literal ')' ';' 1772 { $$ = new StatementNode( build_asm( $2, $4, nullptr ) ); }1775 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); } 1773 1776 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1774 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }1777 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); } 1775 1778 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1776 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }1779 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); } 1777 1780 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1778 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }1781 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); } 1779 1782 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1780 { $$ = new StatementNode( build_asm( $2, $5, nullptr, $8, $10, $12 ) ); }1783 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); } 1781 1784 ; 1782 1785 … … 1802 1805 asm_operand: // GCC 1803 1806 string_literal '(' constant_expression ')' 1804 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild( $3 ) ) ); }1807 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); } 1805 1808 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1806 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild( $6 ) ) ); } 1809 { 1810 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) ); 1811 delete $2.str; 1812 } 1807 1813 ; 1808 1814 … … 1819 1825 identifier 1820 1826 { 1821 $$ = new LabelNode(); $$->labels. push_back(*$1 );1827 $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 ); 1822 1828 delete $1; // allocated by lexer 1823 1829 } 1824 1830 | label_list ',' identifier 1825 1831 { 1826 $$ = $1; $1->labels. push_back(*$3 );1832 $$ = $1; $1->labels.emplace_back( yylloc, *$3 ); 1827 1833 delete $3; // allocated by lexer 1828 1834 } … … 1887 1893 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1888 1894 | STATICASSERT '(' constant_expression ')' ';' // CFA 1889 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }1895 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); } 1890 1896 1891 1897 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 2087 2093 { 2088 2094 SemanticError( yylloc, ::toString( "Missing ';' after end of ", 2089 $1->type->enumeration.name ? "enum" : AggregateDecl::aggrString( $1->type->aggregate.kind ),2095 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ), 2090 2096 " declaration" ) ); 2091 2097 $$ = nullptr; … … 2321 2327 { $$ = DeclarationNode::newTypeof( $3 ); } 2322 2328 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2323 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ), true ); }2329 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); } 2324 2330 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2325 2331 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2515 2521 aggregate_data: 2516 2522 STRUCT vtable_opt 2517 { $$ = AggregateDecl::Struct; }2523 { $$ = ast::AggregateDecl::Struct; } 2518 2524 | UNION 2519 { $$ = AggregateDecl::Union; }2525 { $$ = ast::AggregateDecl::Union; } 2520 2526 | EXCEPTION // CFA 2521 { $$ = AggregateDecl::Exception; }2522 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }2527 { $$ = ast::AggregateDecl::Exception; } 2528 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; } 2523 2529 ; 2524 2530 2525 2531 aggregate_control: // CFA 2526 2532 MONITOR 2527 { $$ = AggregateDecl::Monitor; }2533 { $$ = ast::AggregateDecl::Monitor; } 2528 2534 | MUTEX STRUCT 2529 { $$ = AggregateDecl::Monitor; }2535 { $$ = ast::AggregateDecl::Monitor; } 2530 2536 | GENERATOR 2531 { $$ = AggregateDecl::Generator; }2537 { $$ = ast::AggregateDecl::Generator; } 2532 2538 | MUTEX GENERATOR 2533 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2539 { 2540 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2541 $$ = ast::AggregateDecl::NoAggregate; 2542 } 2534 2543 | COROUTINE 2535 { $$ = AggregateDecl::Coroutine; }2544 { $$ = ast::AggregateDecl::Coroutine; } 2536 2545 | MUTEX COROUTINE 2537 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2546 { 2547 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2548 $$ = ast::AggregateDecl::NoAggregate; 2549 } 2538 2550 | THREAD 2539 { $$ = AggregateDecl::Thread; }2551 { $$ = ast::AggregateDecl::Thread; } 2540 2552 | MUTEX THREAD 2541 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2553 { 2554 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2555 $$ = ast::AggregateDecl::NoAggregate; 2556 } 2542 2557 ; 2543 2558 … … 2889 2904 designator_list ':' // C99, CFA uses ":" instead of "=" 2890 2905 | identifier_at ':' // GCC, field name 2891 { $$ = new ExpressionNode( build_varref( $1 ) ); }2906 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 2892 2907 ; 2893 2908 … … 2901 2916 designator: 2902 2917 '.' identifier_at // C99, field name 2903 { $$ = new ExpressionNode( build_varref( $2 ) ); }2918 { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); } 2904 2919 | '[' push assignment_expression pop ']' // C99, single array element 2905 2920 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2908 2923 { $$ = $3; } 2909 2924 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2910 { $$ = new ExpressionNode( new RangeExpr(maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }2925 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); } 2911 2926 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2912 2927 { $$ = $4; } … … 2948 2963 { 2949 2964 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2950 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2951 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2952 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2965 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2966 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2967 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2953 2968 } 2954 2969 type_initializer_opt assertion_list_opt … … 2961 2976 { 2962 2977 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2963 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );2978 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 ); 2964 2979 } 2965 2980 // | type_specifier identifier_parameter_declarator 2966 2981 | assertion_list 2967 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2982 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2968 2983 ; 2969 2984 2970 2985 new_type_class: // CFA 2971 2986 // empty 2972 { $$ = TypeDecl::Otype; }2987 { $$ = ast::TypeDecl::Otype; } 2973 2988 | '&' 2974 { $$ = TypeDecl::Dtype; }2989 { $$ = ast::TypeDecl::Dtype; } 2975 2990 | '*' 2976 { $$ = TypeDecl::DStype; } // dtype + sized2991 { $$ = ast::TypeDecl::DStype; } // dtype + sized 2977 2992 // | '(' '*' ')' 2978 // { $$ = TypeDecl::Ftype; }2993 // { $$ = ast::TypeDecl::Ftype; } 2979 2994 | ELLIPSIS 2980 { $$ = TypeDecl::Ttype; }2995 { $$ = ast::TypeDecl::Ttype; } 2981 2996 ; 2982 2997 2983 2998 type_class: // CFA 2984 2999 OTYPE 2985 { $$ = TypeDecl::Otype; }3000 { $$ = ast::TypeDecl::Otype; } 2986 3001 | DTYPE 2987 { $$ = TypeDecl::Dtype; }3002 { $$ = ast::TypeDecl::Dtype; } 2988 3003 | FTYPE 2989 { $$ = TypeDecl::Ftype; }3004 { $$ = ast::TypeDecl::Ftype; } 2990 3005 | TTYPE 2991 { $$ = TypeDecl::Ttype; }3006 { $$ = ast::TypeDecl::Ttype; } 2992 3007 ; 2993 3008 … … 3015 3030 type_list: // CFA 3016 3031 type 3017 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3032 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3018 3033 | assignment_expression 3019 3034 | type_list ',' type 3020 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ) )); }3035 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); } 3021 3036 | type_list ',' assignment_expression 3022 3037 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3125 3140 external_definition: 3126 3141 DIRECTIVE 3127 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }3142 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); } 3128 3143 | declaration 3129 3144 { … … 3131 3146 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is 3132 3147 // disallowed at the moment. 3133 if ( $1->linkage == LinkageSpec::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {3148 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) { 3134 3149 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) { 3135 3150 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr; … … 3158 3173 } 3159 3174 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3160 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, nullptr ) ) ); }3175 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); } 3161 3176 | EXTERN STRINGliteral 3162 3177 { 3163 3178 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3164 linkage = LinkageSpec::update( yylloc, linkage, $2 );3179 linkage = ast::Linkage::update( yylloc, linkage, $2 ); 3165 3180 } 3166 3181 up external_definition down … … 3173 3188 { 3174 3189 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3175 linkage = LinkageSpec::update( yylloc, linkage, $2 );3190 linkage = ast::Linkage::update( yylloc, linkage, $2 ); 3176 3191 } 3177 3192 '{' up external_definition_list_opt down '}' … … 3297 3312 subrange: 3298 3313 constant_expression '~' constant_expression // CFA, integer subrange 3299 { $$ = new ExpressionNode( new RangeExpr(maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }3314 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 3300 3315 ; 3301 3316 … … 3826 3841 array_type_list: 3827 3842 basic_type_name 3828 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3843 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3829 3844 | type_name 3830 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3845 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3831 3846 | assignment_expression upupeq assignment_expression 3832 3847 | array_type_list ',' basic_type_name 3833 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ) )); }3834 | array_type_list ',' type_name 3835 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr(maybeMoveBuildType( $3 ) ) ) )); }3848 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); } 3849 | array_type_list ',' type_name 3850 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); } 3836 3851 | array_type_list ',' assignment_expression upupeq assignment_expression 3837 3852 ; -
TabularUnified src/Parser/parserutility.cc ¶
r4541b09 rbb7422a 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 -
TabularUnified src/Parser/parserutility.h ¶
r4541b09 rbb7422a 10 10 // Created On : Sat May 16 15:31:46 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Mar 9 12:16:00 202313 // Update Count : 612 // 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 ); 21 24 22 25 template< typename T > … … 32 35 } 33 36 37 template<typename node_t> 38 node_t * maybeCopy( node_t const * node ) { 39 return node ? ast::shallowCopy( node ) : nullptr; 40 } 41 34 42 // Local Variables: // 35 43 // tab-width: 4 // -
TabularUnified tests/.expect/attributes.arm64.txt ¶
r4541b09 rbb7422a 1351 1351 signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0)); 1352 1352 signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)()); 1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)( signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
TabularUnified tests/.expect/attributes.x64.txt ¶
r4541b09 rbb7422a 1351 1351 signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0)); 1352 1352 signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)()); 1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)( signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
TabularUnified tests/.expect/attributes.x86.txt ¶
r4541b09 rbb7422a 1351 1351 signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0)); 1352 1352 signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)()); 1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)( signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
TabularUnified tests/errors/.expect/declaration.txt ¶
r4541b09 rbb7422a 1 errors/declaration.cfa:16:1 error: duplicate static in declaration of x1: static const volatile short int1 errors/declaration.cfa:16:1 error: duplicate static storage class(es) in declaration of x1: static const volatile short int 2 2 3 errors/declaration.cfa:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int3 errors/declaration.cfa:17:1 error: conflicting extern & static storage classes in declaration of x2: extern const volatile short int 4 4 5 errors/declaration.cfa:18:1 error: conflicting extern & auto , conflicting extern & static, conflicting extern & static, duplicate externin declaration of x3: extern const volatile short int5 errors/declaration.cfa:18:1 error: conflicting extern & auto storage classes, conflicting extern & static storage classes, conflicting extern & static storage classes, duplicate extern storage class(es) in declaration of x3: extern const volatile short int 6 6 7 errors/declaration.cfa:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous07 errors/declaration.cfa:19:1 error: duplicate static storage class(es) in declaration of x4: static const volatile instance of const volatile struct __anonymous0 8 8 with members 9 9 i: int … … 11 11 12 12 13 errors/declaration.cfa:20:1 error: duplicate const , duplicate static, duplicate volatilein declaration of x5: static const volatile instance of const volatile struct __anonymous113 errors/declaration.cfa:20:1 error: duplicate const qualifier(s), duplicate static storage class(es), duplicate volatile qualifier(s) in declaration of x5: static const volatile instance of const volatile struct __anonymous1 14 14 with members 15 15 i: int … … 17 17 18 18 19 errors/declaration.cfa:22:1 error: duplicate static in declaration of x6: static const volatile Int19 errors/declaration.cfa:22:1 error: duplicate static storage class(es) in declaration of x6: static const volatile Int 20 20 21 errors/declaration.cfa:24:1 error: duplicate const in declaration of f01: static inline function21 errors/declaration.cfa:24:1 error: duplicate const qualifier(s) in declaration of f01: static inline function 22 22 with no parameters 23 23 returning const volatile int 24 24 25 25 26 errors/declaration.cfa:25:1 error: duplicate volatile in declaration of f02: static inline function26 errors/declaration.cfa:25:1 error: duplicate volatile qualifier(s) in declaration of f02: static inline function 27 27 with no parameters 28 28 returning const volatile int 29 29 30 30 31 errors/declaration.cfa:26:1 error: duplicate const in declaration of f03: static inline function31 errors/declaration.cfa:26:1 error: duplicate const qualifier(s) in declaration of f03: static inline function 32 32 with no parameters 33 33 returning const volatile int 34 34 35 35 36 errors/declaration.cfa:27:1 error: duplicate volatile in declaration of f04: static inline function36 errors/declaration.cfa:27:1 error: duplicate volatile qualifier(s) in declaration of f04: static inline function 37 37 with no parameters 38 38 returning const volatile int 39 39 40 40 41 errors/declaration.cfa:28:1 error: duplicate const in declaration of f05: static inline function41 errors/declaration.cfa:28:1 error: duplicate const qualifier(s) in declaration of f05: static inline function 42 42 with no parameters 43 43 returning const volatile int 44 44 45 45 46 errors/declaration.cfa:29:1 error: duplicate volatile in declaration of f06: static inline function46 errors/declaration.cfa:29:1 error: duplicate volatile qualifier(s) in declaration of f06: static inline function 47 47 with no parameters 48 48 returning const volatile int 49 49 50 50 51 errors/declaration.cfa:30:1 error: duplicate const in declaration of f07: static inline function51 errors/declaration.cfa:30:1 error: duplicate const qualifier(s) in declaration of f07: static inline function 52 52 with no parameters 53 53 returning const volatile int 54 54 55 55 56 errors/declaration.cfa:31:1 error: duplicate const , duplicate volatilein declaration of f08: static inline function56 errors/declaration.cfa:31:1 error: duplicate const volatile qualifier(s) in declaration of f08: static inline function 57 57 with no parameters 58 58 returning const volatile int 59 59 60 60 61 errors/declaration.cfa:33:1 error: duplicate const , duplicate volatilein declaration of f09: static inline function61 errors/declaration.cfa:33:1 error: duplicate const volatile qualifier(s) in declaration of f09: static inline function 62 62 with no parameters 63 63 returning const volatile int 64 64 65 65 66 errors/declaration.cfa:34:1 error: duplicate const , duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatilein declaration of f09: static inline function66 errors/declaration.cfa:34:1 error: duplicate const qualifier(s), duplicate _Atomic qualifier(s), duplicate _Atomic qualifier(s), duplicate const restrict volatile qualifier(s) in declaration of f09: static inline function 67 67 with no parameters 68 68 returning const restrict volatile _Atomic int
Note: See TracChangeset
for help on using the changeset viewer.