- Timestamp:
- Oct 15, 2020, 3:41:38 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b9537e6
- Parents:
- 33c3ded (diff), 0b18db7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 31 edited
-
AST/Convert.cpp (modified) (7 diffs)
-
AST/Decl.hpp (modified) (1 diff)
-
AST/ForallSubstitutor.hpp (modified) (2 diffs)
-
AST/Pass.impl.hpp (modified) (1 diff)
-
AST/SymbolTable.cpp (modified) (3 diffs)
-
AST/SymbolTable.hpp (modified) (1 diff)
-
AST/Type.cpp (modified) (2 diffs)
-
AST/Type.hpp (modified) (1 diff)
-
Concurrency/Keywords.cc (modified) (6 diffs)
-
GenPoly/InstantiateGeneric.cc (modified) (2 diffs)
-
InitTweak/FixGlobalInit.cc (modified) (1 diff)
-
InitTweak/InitTweak.cc (modified) (1 diff)
-
Parser/DeclarationNode.cc (modified) (5 diffs)
-
Parser/lex.ll (modified) (3 diffs)
-
Parser/parser.yy (modified) (13 diffs)
-
ResolvExpr/CandidateFinder.cpp (modified) (3 diffs)
-
ResolvExpr/CurrentObject.cc (modified) (2 diffs)
-
ResolvExpr/ResolveAssertions.cc (modified) (1 diff)
-
ResolvExpr/Resolver.cc (modified) (3 diffs)
-
ResolvExpr/SatisfyAssertions.cpp (modified) (2 diffs)
-
ResolvExpr/SpecCost.cc (modified) (1 diff)
-
ResolvExpr/Unify.cc (modified) (12 diffs)
-
SymTab/Autogen.cc (modified) (1 diff)
-
SymTab/Mangler.cc (modified) (1 diff)
-
SymTab/Validate.cc (modified) (3 diffs)
-
SynTree/AggregateDecl.cc (modified) (2 diffs)
-
SynTree/Declaration.h (modified) (1 diff)
-
SynTree/TypeDecl.cc (modified) (2 diffs)
-
Virtual/Tables.cc (modified) (5 diffs)
-
Virtual/Tables.h (modified) (1 diff)
-
main.cc (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r33c3ded r223a633 177 177 const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final { 178 178 if ( inCache( node ) ) return nullptr; 179 180 // function decl contains real variables that the type must use. 181 // the structural change means function type in and out of decl 182 // must be handled **differently** on convert back to old. 183 auto ftype = new FunctionType( 184 cv(node->type), 185 (bool)node->type->isVarArgs 186 ); 187 ftype->returnVals = get<DeclarationWithType>().acceptL(node->returns); 188 ftype->parameters = get<DeclarationWithType>().acceptL(node->params); 189 190 ftype->forall = get<TypeDecl>().acceptL( node->type->forall ); 191 192 visitType(node->type, ftype); 193 179 194 auto decl = new FunctionDecl( 180 195 node->name, 181 196 Type::StorageClasses( node->storage.val ), 182 197 LinkageSpec::Spec( node->linkage.val ), 183 get<FunctionType>().accept1( node->type ), 198 ftype, 199 //get<FunctionType>().accept1( node->type ), 184 200 {}, 185 201 get<Attribute>().acceptL( node->attributes ), … … 1152 1168 1153 1169 const ast::Type * visit( const ast::FunctionType * node ) override final { 1170 static std::string dummy_paramvar_prefix = "__param_"; 1171 static std::string dummy_returnvar_prefix = "__retval_"; 1172 1154 1173 auto ty = new FunctionType { 1155 1174 cv( node ), 1156 1175 (bool)node->isVarArgs 1157 1176 }; 1158 ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1159 ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1177 auto returns = get<Type>().acceptL(node->returns); 1178 auto params = get<Type>().acceptL(node->params); 1179 1180 int ret_index = 0; 1181 for (auto t: returns) { 1182 // xxx - LinkageSpec shouldn't matter but needs to be something 1183 ObjectDecl * dummy = new ObjectDecl(dummy_returnvar_prefix + std::to_string(ret_index++), {}, LinkageSpec::C, nullptr, t, nullptr); 1184 ty->returnVals.push_back(dummy); 1185 } 1186 int param_index = 0; 1187 for (auto t: params) { 1188 ObjectDecl * dummy = new ObjectDecl(dummy_paramvar_prefix + std::to_string(param_index++), {}, LinkageSpec::C, nullptr, t, nullptr); 1189 ty->parameters.push_back(dummy); 1190 } 1191 1192 // ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1193 // ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1160 1194 ty->forall = get<TypeDecl>().acceptL( node->forall ); 1161 1195 return visitType( node, ty ); … … 1374 1408 ast::Node * node = nullptr; 1375 1409 /// cache of nodes that might be referenced by readonly<> for de-duplication 1376 std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {}; 1410 /// in case that some nodes are dropped by conversion (due to possible structural change) 1411 /// use smart pointers in cache value to prevent accidental invalidation. 1412 /// at conversion stage, all created nodes are guaranteed to be unique, therefore 1413 /// const_casting out of smart pointers is permitted. 1414 std::unordered_map< const BaseSyntaxNode *, ast::ptr<ast::Node> > cache = {}; 1377 1415 1378 1416 // Local Utilities: … … 1447 1485 auto it = cache.find( old ); 1448 1486 if ( it == cache.end() ) return false; 1449 node = it->second;1487 node = const_cast<ast::Node *>(it->second.get()); 1450 1488 return true; 1451 1489 } … … 1486 1524 virtual void visit( const FunctionDecl * old ) override final { 1487 1525 if ( inCache( old ) ) return; 1526 auto paramVars = GET_ACCEPT_V(type->parameters, DeclWithType); 1527 auto returnVars = GET_ACCEPT_V(type->returnVals, DeclWithType); 1528 auto forall = GET_ACCEPT_V(type->forall, TypeDecl); 1529 1530 // function type is now derived from parameter decls instead of storing them 1531 auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type)); 1532 ftype->params.reserve(paramVars.size()); 1533 ftype->returns.reserve(returnVars.size()); 1534 1535 for (auto & v: paramVars) { 1536 ftype->params.emplace_back(v->get_type()); 1537 } 1538 for (auto & v: returnVars) { 1539 ftype->returns.emplace_back(v->get_type()); 1540 } 1541 ftype->forall = std::move(forall); 1542 visitType(old->type, ftype); 1543 1488 1544 auto decl = new ast::FunctionDecl{ 1489 1545 old->location, 1490 1546 old->name, 1491 GET_ACCEPT_1(type, FunctionType), 1547 // GET_ACCEPT_1(type, FunctionType), 1548 std::move(paramVars), 1549 std::move(returnVars), 1492 1550 {}, 1493 1551 { old->storageClasses.val }, … … 1496 1554 { old->get_funcSpec().val } 1497 1555 }; 1556 1557 decl->type = ftype; 1498 1558 cache.emplace( old, decl ); 1559 1499 1560 decl->withExprs = GET_ACCEPT_V(withExprs, Expr); 1500 1561 decl->stmts = GET_ACCEPT_1(statements, CompoundStmt); … … 2515 2576 cv( old ) 2516 2577 }; 2517 ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 2518 ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 2578 auto returnVars = GET_ACCEPT_V(returnVals, DeclWithType); 2579 auto paramVars = GET_ACCEPT_V(parameters, DeclWithType); 2580 // ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 2581 // ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 2582 for (auto & v: returnVars) { 2583 ty->returns.emplace_back(v->get_type()); 2584 } 2585 for (auto & v: paramVars) { 2586 ty->params.emplace_back(v->get_type()); 2587 } 2519 2588 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 2520 2589 visitType( old, ty ); -
src/AST/Decl.hpp
r33c3ded r223a633 124 124 class FunctionDecl : public DeclWithType { 125 125 public: 126 std::vector<ptr<DeclWithType>> params; 127 std::vector<ptr<DeclWithType>> returns; 128 // declared type, derived from parameter declarations 126 129 ptr<FunctionType> type; 127 130 ptr<CompoundStmt> stmts; 128 131 std::vector< ptr<Expr> > withExprs; 129 132 130 FunctionDecl( const CodeLocation & loc, const std::string & name, FunctionType * type, 133 FunctionDecl( const CodeLocation & loc, const std::string & name, 134 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 131 135 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 132 136 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}) 133 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type),137 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 134 138 stmts( stmts ) {} 135 139 -
src/AST/ForallSubstitutor.hpp
r33c3ded r223a633 33 33 } 34 34 35 template<typename node_t > 36 std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) { 37 std::vector<ptr<node_t>> n; 38 n.reserve(o.size()); 39 for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); } 40 return n; 41 } 42 43 /* 44 35 45 /// Substitute parameter/return type 36 46 std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) { … … 48 58 return n; 49 59 } 60 61 */ 50 62 }; 51 63 -
src/AST/Pass.impl.hpp
r33c3ded r223a633 465 465 __pass::symtab::addId( core, 0, func ); 466 466 VISIT( 467 // parameter declarations are now directly here 468 maybe_accept( node, &FunctionDecl::params ); 469 maybe_accept( node, &FunctionDecl::returns ); 470 // foralls are still in function type 467 471 maybe_accept( node, &FunctionDecl::type ); 468 472 // function body needs to have the same scope as parameters - CompoundStmt will not enter -
src/AST/SymbolTable.cpp
r33c3ded r223a633 335 335 } 336 336 337 /* 337 338 void SymbolTable::addFunctionType( const FunctionType * ftype ) { 338 339 addTypes( ftype->forall ); … … 340 341 addIds( ftype->params ); 341 342 } 343 */ 342 344 343 345 void SymbolTable::lazyInitScope() { … … 368 370 assert( ! params.empty() ); 369 371 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 370 const Type * base = InitTweak::getPointerBase( params.front() ->get_type());372 const Type * base = InitTweak::getPointerBase( params.front() ); 371 373 assert( base ); 372 374 return Mangle::mangle( base ); -
src/AST/SymbolTable.hpp
r33c3ded r223a633 145 145 146 146 /// convenience function for adding all of the declarations in a function type to the indexer 147 void addFunctionType( const FunctionType * ftype );147 // void addFunctionType( const FunctionType * ftype ); 148 148 149 149 private: -
src/AST/Type.cpp
r33c3ded r223a633 102 102 // --- FunctionType 103 103 104 104 105 FunctionType::FunctionType( const FunctionType & o ) 105 106 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(), … … 112 113 113 114 namespace { 114 bool containsTtype( const std::vector<ptr< DeclWithType>> & l ) {115 bool containsTtype( const std::vector<ptr<Type>> & l ) { 115 116 if ( ! l.empty() ) { 116 return Tuples::isTtype( l.back() ->get_type());117 return Tuples::isTtype( l.back() ); 117 118 } 118 119 return false; -
src/AST/Type.hpp
r33c3ded r223a633 302 302 class FunctionType final : public ParameterizedType { 303 303 public: 304 std::vector<ptr<DeclWithType>> returns; 305 std::vector<ptr<DeclWithType>> params; 304 // std::vector<ptr<DeclWithType>> returns; 305 // std::vector<ptr<DeclWithType>> params; 306 307 std::vector<ptr<Type>> returns; 308 std::vector<ptr<Type>> params; 306 309 307 310 /// Does the function accept a variable number of arguments following the arguments specified -
src/Concurrency/Keywords.cc
r33c3ded r223a633 66 66 bool needs_main, AggregateDecl::Aggregate cast_target ) : 67 67 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), 68 context_error( context_error ), vtable_name( getVTableName( exception_name ) ), 68 context_error( context_error ), exception_name( exception_name ), 69 vtable_name( getVTableName( exception_name ) ), 69 70 needs_main( needs_main ), cast_target( cast_target ) {} 70 71 … … 89 90 const std::string getter_name; 90 91 const std::string context_error; 92 const std::string exception_name; 91 93 const std::string vtable_name; 92 94 bool needs_main; … … 95 97 StructDecl * type_decl = nullptr; 96 98 FunctionDecl * dtor_decl = nullptr; 99 StructDecl * except_decl = nullptr; 97 100 StructDecl * vtable_decl = nullptr; 98 101 }; … … 376 379 else if ( is_target(decl) ) { 377 380 handle( decl ); 381 } 382 else if ( !except_decl && exception_name == decl->name && decl->body ) { 383 except_decl = decl; 378 384 } 379 385 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) { … … 398 404 assert( struct_type ); 399 405 400 declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, { 401 new TypeExpr( struct_type->clone() ), 402 }, struct_type, nullptr ) ); 406 std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) }; 407 ObjectDecl * vtable_object = Virtual::makeVtableInstance( 408 vtable_decl->makeInst( poly_args ), struct_type, nullptr ); 409 declsToAddAfter.push_back( vtable_object ); 410 declsToAddAfter.push_back( Virtual::makeGetExceptionFunction( 411 vtable_object, except_decl->makeInst( std::move( poly_args ) ) 412 ) ); 403 413 } 404 414 … … 434 444 void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) { 435 445 if ( vtable_decl ) { 436 declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl,{446 std::list< Expression * > poly_args = { 437 447 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 438 } ) ); 448 }; 449 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 450 vtable_decl->makeInst( poly_args ), 451 except_decl->makeInst( poly_args ) 452 ) ); 453 declsToAddBefore.push_back( Virtual::makeVtableForward( 454 vtable_decl->makeInst( move( poly_args ) ) ) ); 439 455 // Its only an error if we want a vtable and don't have one. 440 456 } else if ( ! vtable_name.empty() ) { -
src/GenPoly/InstantiateGeneric.cc
r33c3ded r223a633 172 172 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 173 173 /// Set of types which are dtype-only generic (and therefore have static layout) 174 ScopedSet< AggregateDecl*> dtypeStatics;174 std::set<AggregateDecl *> dtypeStatics; 175 175 /// Namer for concrete types 176 176 UniqueName typeNamer; … … 505 505 void GenericInstantiator::beginScope() { 506 506 instantiations.beginScope(); 507 dtypeStatics.beginScope();508 507 } 509 508 510 509 void GenericInstantiator::endScope() { 511 510 instantiations.endScope(); 512 dtypeStatics.endScope();513 511 } 514 512 -
src/InitTweak/FixGlobalInit.cc
r33c3ded r223a633 112 112 } // if 113 113 if ( Statement * ctor = ctorInit->ctor ) { 114 // Translation 1: Add this attribute on the global declaration: 115 // __attribute__((section (".data#"))) 116 // which makes gcc put the global in the data section, 117 // so that the global is writeable (via a const cast) in the init function. 118 // The trailing # is an injected assembly comment, to suppress the "a" in 119 // .section .data,"a" 120 // .section .data#,"a" 121 // to avoid assembler warning "ignoring changed section attributes for .data" 122 Type *strLitT = new PointerType( Type::Qualifiers( ), 123 new BasicType( Type::Qualifiers( ), BasicType::Char ) ); 124 std::list< Expression * > attr_params; 125 attr_params.push_back( 126 new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) ); 127 objDecl->attributes.push_back(new Attribute("section", attr_params)); 128 // Translation 2: Move the initizliation off the global declaration, 129 // into the startup function. 114 130 initStatements.push_back( ctor ); 115 131 objDecl->init = nullptr; -
src/InitTweak/InitTweak.cc
r33c3ded r223a633 1026 1026 if ( ftype->params.size() != 2 ) return false; 1027 1027 1028 const ast::Type * t1 = getPointerBase( ftype->params.front() ->get_type());1028 const ast::Type * t1 = getPointerBase( ftype->params.front() ); 1029 1029 if ( ! t1 ) return false; 1030 const ast::Type * t2 = ftype->params.back() ->get_type();1030 const ast::Type * t2 = ftype->params.back(); 1031 1031 1032 1032 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); -
src/Parser/DeclarationNode.cc
r33c3ded r223a633 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Jun 9 20:26:55202013 // Update Count : 113 412 // Last Modified On : Thu Oct 8 08:03:38 2020 13 // Update Count : 1135 14 14 // 15 15 … … 1016 1016 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 1017 1017 dwt->location = cur->location; 1018 * out++ = dwt;1018 *out++ = dwt; 1019 1019 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1020 1020 // e.g., int foo(struct S) {} … … 1022 1022 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1023 1023 obj->location = cur->location; 1024 * out++ = obj;1024 *out++ = obj; 1025 1025 delete agg; 1026 1026 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { … … 1029 1029 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1030 1030 obj->location = cur->location; 1031 * out++ = obj;1031 *out++ = obj; 1032 1032 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) { 1033 1033 // e.g., int foo(enum E) {} … … 1035 1035 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1036 1036 obj->location = cur->location; 1037 * out++ = obj;1037 *out++ = obj; 1038 1038 } // if 1039 1039 } catch( SemanticErrorException & e ) { -
src/Parser/lex.ll
r33c3ded r223a633 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Sat Feb 15 11:05:50202013 * Update Count : 7 3712 * Last Modified On : Tue Oct 6 18:15:41 2020 13 * Update Count : 743 14 14 */ 15 15 … … 62 62 #define IDENTIFIER_RETURN() RETURN_VAL( typedefTable.isKind( yytext ) ) 63 63 64 #ifdef HAVE_KEYWORDS_FLOATXX // GCC >= 7 => keyword, otherwise typedef64 #ifdef HAVE_KEYWORDS_FLOATXX // GCC >= 7 => keyword, otherwise typedef 65 65 #define FLOATXX(v) KEYWORD_RETURN(v); 66 66 #else … … 292 292 __restrict__ { KEYWORD_RETURN(RESTRICT); } // GCC 293 293 return { KEYWORD_RETURN(RETURN); } 294 /* resume { KEYWORD_RETURN(RESUME); } // CFA */294 /* resume { KEYWORD_RETURN(RESUME); } // CFA */ 295 295 short { KEYWORD_RETURN(SHORT); } 296 296 signed { KEYWORD_RETURN(SIGNED); } -
src/Parser/parser.yy
r33c3ded r223a633 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 28 12:11:45202013 // Update Count : 4 50012 // Last Modified On : Fri Oct 9 18:09:09 2020 13 // Update Count : 4614 14 14 // 15 15 … … 204 204 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 205 205 } else { 206 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed " ); return nullptr;206 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; 207 207 } // if 208 208 } else { 209 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed " ); return nullptr;209 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; 210 210 } // if 211 211 } // forCtrl … … 278 278 %token OTYPE FTYPE DTYPE TTYPE TRAIT // CFA 279 279 %token SIZEOF OFFSETOF 280 // %token RESUME // CFA281 %token SUSPEND // CFA280 // %token RESUME // CFA 281 %token SUSPEND // CFA 282 282 %token ATTRIBUTE EXTENSION // GCC 283 283 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN … … 329 329 %type<en> conditional_expression constant_expression assignment_expression assignment_expression_opt 330 330 %type<en> comma_expression comma_expression_opt 331 %type<en> argument_expression_list_opt argument_expression default_initialize_opt331 %type<en> argument_expression_list_opt argument_expression default_initialize_opt 332 332 %type<ifctl> if_control_expression 333 333 %type<fctl> for_control_expression for_control_expression_list … … 370 370 %type<decl> assertion assertion_list assertion_list_opt 371 371 372 %type<en> bit_subrange_size_opt bit_subrange_size372 %type<en> bit_subrange_size_opt bit_subrange_size 373 373 374 374 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 793 793 | '(' aggregate_control '&' ')' cast_expression // CFA 794 794 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 795 // VIRTUAL cannot be opt because of look ahead issues796 795 | '(' VIRTUAL ')' cast_expression // CFA 797 796 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); } … … 920 919 | unary_expression assignment_operator assignment_expression 921 920 { 922 if ( $2 == OperKinds::AtAssn ) {923 SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;924 } else {921 // if ( $2 == OperKinds::AtAssn ) { 922 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 923 // } else { 925 924 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); 926 } // if925 // } // if 927 926 } 928 927 | unary_expression '=' '{' initializer_list_opt comma_opt '}' … … 1676 1675 1677 1676 typedef_expression: 1678 // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression1677 // deprecated GCC, naming expression type: typedef name = exp; gives a name to the type of an expression 1679 1678 TYPEDEF identifier '=' assignment_expression 1680 1679 { 1681 // $$ = DeclarationNode::newName( 0 ); // unimplemented 1682 SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr; 1680 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 1683 1681 } 1684 1682 | typedef_expression pop ',' push identifier '=' assignment_expression 1685 1683 { 1686 // $$ = DeclarationNode::newName( 0 ); // unimplemented 1687 SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr; 1688 } 1689 ; 1690 1691 //c_declaration: 1692 // declaring_list pop ';' 1693 // | typedef_declaration pop ';' 1694 // | typedef_expression pop ';' // GCC, naming expression type 1695 // | sue_declaration_specifier pop ';' 1696 // ; 1697 // 1698 //declaring_list: 1699 // // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 1700 // // storage-class 1701 // declarator asm_name_opt initializer_opt 1702 // { 1703 // typedefTable.addToEnclosingScope( IDENTIFIER ); 1704 // $$ = ( $2->addType( $1 ))->addAsmName( $3 )->addInitializer( $4 ); 1705 // } 1706 // | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 1707 // { 1708 // typedefTable.addToEnclosingScope( IDENTIFIER ); 1709 // $$ = $1->appendList( $1->cloneBaseType( $4->addAsmName( $5 )->addInitializer( $6 ) ) ); 1710 // } 1711 // ; 1684 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 1685 } 1686 ; 1712 1687 1713 1688 c_declaration: … … 1715 1690 { $$ = distAttr( $1, $2 ); } 1716 1691 | typedef_declaration 1717 | typedef_expression // GCC, naming expression type1692 | typedef_expression // deprecated GCC, naming expression type 1718 1693 | sue_declaration_specifier 1719 1694 ; … … 2094 2069 { yyy = true; $$ = AggregateDecl::Union; } 2095 2070 | EXCEPTION // CFA 2096 { yyy = true; $$ = AggregateDecl::Exception; } 2071 // { yyy = true; $$ = AggregateDecl::Exception; } 2072 { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2097 2073 ; 2098 2074 … … 2436 2412 // Overloading: function, data, and operator identifiers may be overloaded. 2437 2413 // 2438 // Type declarations: " type" is used to generate new types for declaring objects. Similarly, "dtype" is used for object2414 // Type declarations: "otype" is used to generate new types for declaring objects. Similarly, "dtype" is used for object 2439 2415 // and incomplete types, and "ftype" is used for function types. Type declarations with initializers provide 2440 2416 // definitions of new types. Type declarations with storage class "extern" provide opaque types. … … 2465 2441 type_class identifier_or_type_name 2466 2442 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); } 2467 type_initializer_opt assertion_list_opt2443 type_initializer_opt assertion_list_opt 2468 2444 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); } 2469 2445 | type_specifier identifier_parameter_declarator … … 2492 2468 assertion 2493 2469 | assertion_list assertion 2494 { $$ = $1 ? $1->appendList( $2 ) : $2; }2470 { $$ = $1->appendList( $2 ); } 2495 2471 ; 2496 2472 -
src/ResolvExpr/CandidateFinder.cpp
r33c3ded r223a633 188 188 189 189 // mark conversion cost and also specialization cost of param type 190 const ast::Type * paramType = (*param)->get_type();190 // const ast::Type * paramType = (*param)->get_type(); 191 191 cand->expr = ast::mutate_field_index( 192 192 appExpr, &ast::ApplicationExpr::args, i, 193 193 computeExpressionConversionCost( 194 args[i], paramType, symtab, cand->env, convCost ) );195 convCost.decSpec( specCost( paramType) );194 args[i], *param, symtab, cand->env, convCost ) ); 195 convCost.decSpec( specCost( *param ) ); 196 196 ++param; // can't be in for-loop update because of the continue 197 197 } … … 698 698 if ( targetType && ! targetType->isVoid() && ! funcType->returns.empty() ) { 699 699 // attempt to narrow based on expected target type 700 const ast::Type * returnType = funcType->returns.front() ->get_type();700 const ast::Type * returnType = funcType->returns.front(); 701 701 if ( ! unify( 702 702 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) … … 712 712 std::size_t genStart = 0; 713 713 714 for ( const ast::DeclWithType * param : funcType->params ) { 715 auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param ); 714 // xxx - how to handle default arg after change to ftype representation? 715 if (const ast::VariableExpr * varExpr = func->expr.as<ast::VariableExpr>()) { 716 if (const ast::FunctionDecl * funcDecl = varExpr->var.as<ast::FunctionDecl>()) { 717 // function may have default args only if directly calling by name 718 // must use types on candidate however, due to RenameVars substitution 719 auto nParams = funcType->params.size(); 720 721 for (size_t i=0; i<nParams; ++i) { 722 auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>(); 723 if (!instantiateArgument( 724 funcType->params[i], obj->init, args, results, genStart, symtab)) return; 725 } 726 goto endMatch; 727 } 728 } 729 for ( const auto & param : funcType->params ) { 716 730 // Try adding the arguments corresponding to the current parameter to the existing 717 731 // matches 732 // no default args for indirect calls 718 733 if ( ! instantiateArgument( 719 obj->type, obj->init, args, results, genStart, symtab ) ) return; 720 } 721 734 param, nullptr, args, results, genStart, symtab ) ) return; 735 } 736 737 endMatch: 722 738 if ( funcType->isVarArgs ) { 723 739 // append any unused arguments to vararg pack -
src/ResolvExpr/CurrentObject.cc
r33c3ded r223a633 594 594 class SimpleIterator final : public MemberIterator { 595 595 CodeLocation location; 596 readonly< Type >type = nullptr;596 const Type * type = nullptr; 597 597 public: 598 598 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} … … 630 630 class ArrayIterator final : public MemberIterator { 631 631 CodeLocation location; 632 readonly< ArrayType >array = nullptr;633 readonly< Type >base = nullptr;632 const ArrayType * array = nullptr; 633 const Type * base = nullptr; 634 634 size_t index = 0; 635 635 size_t size = 0; -
src/ResolvExpr/ResolveAssertions.cc
r33c3ded r223a633 277 277 const DeclarationWithType * candidate = cdata.id; 278 278 279 // build independent unification context for candidate 279 // ignore deleted candidates. 280 // NOTE: this behavior is different from main resolver. 281 // further investigations might be needed to determine 282 // if we should implement the same rule here 283 // (i.e. error if unique best match is deleted) 284 if (candidate->isDeleted) continue; 285 286 // build independent unification context. for candidate 280 287 AssertionSet have, newNeed; 281 288 TypeEnvironment newEnv{ resn.alt.env }; -
src/ResolvExpr/Resolver.cc
r33c3ded r223a633 1223 1223 template<typename Iter> 1224 1224 inline bool nextMutex( Iter & it, const Iter & end ) { 1225 while ( it != end && ! (*it)-> get_type()->is_mutex() ) { ++it; }1225 while ( it != end && ! (*it)->is_mutex() ) { ++it; } 1226 1226 return it != end; 1227 1227 } … … 1638 1638 // Check if the argument matches the parameter type in the current 1639 1639 // scope 1640 ast::ptr< ast::Type > paramType = (*param)->get_type();1640 // ast::ptr< ast::Type > paramType = (*param)->get_type(); 1641 1641 if ( 1642 1642 ! unify( 1643 arg->expr->result, paramType, resultEnv, need, have, open,1643 arg->expr->result, *param, resultEnv, need, have, open, 1644 1644 symtab ) 1645 1645 ) { … … 1648 1648 ss << "candidate function not viable: no known conversion " 1649 1649 "from '"; 1650 ast::print( ss, (*param)->get_type());1650 ast::print( ss, *param ); 1651 1651 ss << "' to '"; 1652 1652 ast::print( ss, arg->expr->result ); -
src/ResolvExpr/SatisfyAssertions.cpp
r33c3ded r223a633 170 170 const ast::DeclWithType * candidate = cdata.id; 171 171 172 // ignore deleted candidates. 173 // NOTE: this behavior is different from main resolver. 174 // further investigations might be needed to determine 175 // if we should implement the same rule here 176 // (i.e. error if unique best match is deleted) 177 if (candidate->isDeleted) continue; 178 172 179 // build independent unification context for candidate 173 180 ast::AssertionSet have, newNeed; … … 318 325 if ( ! func ) continue; 319 326 320 for ( const a st::DeclWithType *param : func->params ) {321 cost.decSpec( specCost( param ->get_type()) );327 for ( const auto & param : func->params ) { 328 cost.decSpec( specCost( param ) ); 322 329 } 323 330 -
src/ResolvExpr/SpecCost.cc
r33c3ded r223a633 178 178 void previsit( const ast::FunctionType * fty ) { 179 179 int minCount = std::numeric_limits<int>::max(); 180 updateMinimumPresent( minCount, fty->params, decl_type);181 updateMinimumPresent( minCount, fty->returns, decl_type);180 updateMinimumPresent( minCount, fty->params, type_deref ); 181 updateMinimumPresent( minCount, fty->returns, type_deref ); 182 182 // Add another level to minCount if set. 183 183 count = toNoneOrInc( minCount ); -
src/ResolvExpr/Unify.cc
r33c3ded r223a633 395 395 396 396 template< typename Iterator1, typename Iterator2 > 397 bool unify DeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {397 bool unifyTypeList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 398 398 auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); }; 399 399 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { … … 489 489 || flatOther->isTtype() 490 490 ) { 491 if ( unify DeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {492 if ( unify DeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {491 if ( unifyTypeList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 492 if ( unifyTypeList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 493 493 494 494 // the original types must be used in mark assertions, since pointer comparisons are used … … 784 784 785 785 /// returns flattened version of `src` 786 static std::vector< ast::ptr< ast:: DeclWithType > > flattenList(787 const std::vector< ast::ptr< ast:: DeclWithType > > & src, ast::TypeEnvironment & env786 static std::vector< ast::ptr< ast::Type > > flattenList( 787 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env 788 788 ) { 789 std::vector< ast::ptr< ast:: DeclWithType > > dst;789 std::vector< ast::ptr< ast::Type > > dst; 790 790 dst.reserve( src.size() ); 791 for ( const a st::DeclWithType *d : src ) {791 for ( const auto & d : src ) { 792 792 ast::Pass<TtypeExpander_new> expander{ env }; 793 793 // TtypeExpander pass is impure (may mutate nodes in place) 794 794 // need to make nodes shared to prevent accidental mutation 795 ast::ptr<ast:: DeclWithType> dc = d->accept(expander);796 auto types = flatten( dc ->get_type());795 ast::ptr<ast::Type> dc = d->accept(expander); 796 auto types = flatten( dc ); 797 797 for ( ast::ptr< ast::Type > & t : types ) { 798 798 // outermost const, volatile, _Atomic qualifiers in parameters should not play … … 803 803 // requirements than a non-mutex function 804 804 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 805 dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t });805 dst.emplace_back( t ); 806 806 } 807 807 } … … 811 811 /// Creates a tuple type based on a list of DeclWithType 812 812 template< typename Iter > 813 static ast::ptr< ast::Type > tupleFrom Decls( Iter crnt, Iter end ) {813 static ast::ptr< ast::Type > tupleFromTypes( Iter crnt, Iter end ) { 814 814 std::vector< ast::ptr< ast::Type > > types; 815 815 while ( crnt != end ) { 816 816 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 817 817 // that this results in a flat tuple 818 flatten( (*crnt)->get_type(), types );818 flatten( *crnt, types ); 819 819 820 820 ++crnt; … … 825 825 826 826 template< typename Iter > 827 static bool unify DeclList(827 static bool unifyTypeList( 828 828 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 829 829 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, … … 831 831 ) { 832 832 while ( crnt1 != end1 && crnt2 != end2 ) { 833 const ast::Type * t1 = (*crnt1)->get_type();834 const ast::Type * t2 = (*crnt2)->get_type();833 const ast::Type * t1 = *crnt1; 834 const ast::Type * t2 = *crnt2; 835 835 bool isTuple1 = Tuples::isTtype( t1 ); 836 836 bool isTuple2 = Tuples::isTtype( t2 ); … … 840 840 // combine remainder of list2, then unify 841 841 return unifyExact( 842 t1, tupleFrom Decls( crnt2, end2 ), env, need, have, open,842 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 843 843 noWiden(), symtab ); 844 844 } else if ( ! isTuple1 && isTuple2 ) { 845 845 // combine remainder of list1, then unify 846 846 return unifyExact( 847 tupleFrom Decls( crnt1, end1 ), t2, env, need, have, open,847 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 848 848 noWiden(), symtab ); 849 849 } … … 860 860 if ( crnt1 != end1 ) { 861 861 // try unifying empty tuple with ttype 862 const ast::Type * t1 = (*crnt1)->get_type();862 const ast::Type * t1 = *crnt1; 863 863 if ( ! Tuples::isTtype( t1 ) ) return false; 864 864 return unifyExact( 865 t1, tupleFrom Decls( crnt2, end2 ), env, need, have, open,865 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 866 866 noWiden(), symtab ); 867 867 } else if ( crnt2 != end2 ) { 868 868 // try unifying empty tuple with ttype 869 const ast::Type * t2 = (*crnt2)->get_type();869 const ast::Type * t2 = *crnt2; 870 870 if ( ! Tuples::isTtype( t2 ) ) return false; 871 871 return unifyExact( 872 tupleFrom Decls( crnt1, end1 ), t2, env, need, have, open,872 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 873 873 noWiden(), symtab ); 874 874 } … … 877 877 } 878 878 879 static bool unify DeclList(880 const std::vector< ast::ptr< ast:: DeclWithType > > & list1,881 const std::vector< ast::ptr< ast:: DeclWithType > > & list2,879 static bool unifyTypeList( 880 const std::vector< ast::ptr< ast::Type > > & list1, 881 const std::vector< ast::ptr< ast::Type > > & list2, 882 882 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 883 883 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 884 884 ) { 885 return unify DeclList(885 return unifyTypeList( 886 886 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 887 887 symtab ); … … 928 928 ) return; 929 929 930 if ( ! unify DeclList( params, params2, tenv, need, have, open, symtab ) ) return;931 if ( ! unify DeclList(930 if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return; 931 if ( ! unifyTypeList( 932 932 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 933 933 … … 1232 1232 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) { 1233 1233 if ( func->returns.empty() ) return new ast::VoidType{}; 1234 if ( func->returns.size() == 1 ) return func->returns[0] ->get_type();1234 if ( func->returns.size() == 1 ) return func->returns[0]; 1235 1235 1236 1236 std::vector<ast::ptr<ast::Type>> tys; 1237 for ( const a st::DeclWithType *decl : func->returns ) {1238 tys.emplace_back( decl ->get_type());1237 for ( const auto & decl : func->returns ) { 1238 tys.emplace_back( decl ); 1239 1239 } 1240 1240 return new ast::TupleType{ std::move(tys) }; -
src/SymTab/Autogen.cc
r33c3ded r223a633 339 339 } catch ( SemanticErrorException & ) { 340 340 // okay if decl does not resolve - that means the function should not be generated 341 delete dcl; 341 // delete dcl; 342 delete dcl->statements; 343 dcl->statements = nullptr; 344 dcl->isDeleted = true; 345 definitions.push_back( dcl ); 346 indexer.addId( dcl ); 342 347 } 343 348 } -
src/SymTab/Mangler.cc
r33c3ded r223a633 551 551 GuardValue( inFunctionType ); 552 552 inFunctionType = true; 553 std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns ); 554 if (returnTypes.empty()) mangleName << Encoding::void_t; 555 else accept_each( returnTypes, *visitor ); 553 if (functionType->returns.empty()) mangleName << Encoding::void_t; 554 else accept_each( functionType->returns, *visitor ); 556 555 mangleName << "_"; 557 std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params ); 558 accept_each( paramTypes, *visitor ); 556 accept_each( functionType->params, *visitor ); 559 557 mangleName << "_"; 560 558 } -
src/SymTab/Validate.cc
r33c3ded r223a633 1384 1384 /// Replaces enum types by int, and function/array types in function parameter and return 1385 1385 /// lists by appropriate pointers 1386 /* 1386 1387 struct EnumAndPointerDecay_new { 1387 1388 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { … … 1434 1435 } 1435 1436 }; 1437 */ 1436 1438 1437 1439 /// expand assertions from a trait instance, performing appropriate type variable substitutions … … 1837 1839 const ast::Type * validateType( 1838 1840 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1839 ast::Pass< EnumAndPointerDecay_new > epc;1841 // ast::Pass< EnumAndPointerDecay_new > epc; 1840 1842 ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab }; 1841 1843 ast::Pass< ForallPointerDecay_new > fpd{ loc }; 1842 1844 1843 return type->accept( epc )->accept(lrt )->accept( fpd );1845 return type->accept( lrt )->accept( fpd ); 1844 1846 } 1845 1847 -
src/SynTree/AggregateDecl.cc
r33c3ded r223a633 21 21 #include "Common/utility.h" // for printAll, cloneAll, deleteAll 22 22 #include "Declaration.h" // for AggregateDecl, TypeDecl, Declaration 23 #include "Expression.h" 23 24 #include "Initializer.h" 24 25 #include "LinkageSpec.h" // for Spec, linkageName, Cforall … … 88 89 const char * StructDecl::typeString() const { return aggrString( kind ); } 89 90 91 StructInstType * StructDecl::makeInst( std::list< Expression * > const & new_parameters ) { 92 std::list< Expression * > copy_parameters; 93 cloneAll( new_parameters, copy_parameters ); 94 return makeInst( move( copy( copy_parameters ) ) ); 95 } 96 97 StructInstType * StructDecl::makeInst( std::list< Expression * > && new_parameters ) { 98 assert( parameters.size() == new_parameters.size() ); 99 StructInstType * type = new StructInstType( noQualifiers, this ); 100 type->parameters = std::move( new_parameters ); 101 return type; 102 } 103 90 104 const char * UnionDecl::typeString() const { return aggrString( Union ); } 91 105 -
src/SynTree/Declaration.h
r33c3ded r223a633 306 306 bool is_thread () { return kind == Thread ; } 307 307 308 // Make a type instance of this declaration. 309 StructInstType * makeInst( std::list< Expression * > const & parameters ); 310 StructInstType * makeInst( std::list< Expression * > && parameters ); 311 308 312 virtual StructDecl * clone() const override { return new StructDecl( *this ); } 309 313 virtual void accept( Visitor & v ) override { v.visit( this ); } -
src/SynTree/TypeDecl.cc
r33c3ded r223a633 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 15:26:14 201913 // Update Count : 2 112 // Last Modified On : Thu Oct 8 18:18:55 2020 13 // Update Count : 22 14 14 // 15 15 … … 21 21 #include "Type.h" // for Type, Type::StorageClasses 22 22 23 TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) : Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) { 23 TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) : 24 Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) { 24 25 } 25 26 -
src/Virtual/Tables.cc
r33c3ded r223a633 14 14 // 15 15 16 #include <SynTree/Attribute.h> 16 17 #include <SynTree/Declaration.h> 17 18 #include <SynTree/Expression.h> 19 #include <SynTree/Statement.h> 18 20 #include <SynTree/Type.h> 19 21 … … 38 40 } 39 41 40 // Fuse base polymorphic declaration and forall arguments into a new type.41 static StructInstType * vtableInstType(42 StructDecl * polyDecl, std::list< Expression * > && parameters ) {43 assert( parameters.size() == polyDecl->parameters.size() );44 StructInstType * type = new StructInstType(45 Type::Qualifiers( /* Type::Const */ ), polyDecl );46 type->parameters = std::move( parameters );47 return type;48 }49 50 42 static ObjectDecl * makeVtableDeclaration( 51 43 StructInstType * type, Initializer * init ) { … … 66 58 67 59 ObjectDecl * makeVtableForward( StructInstType * type ) { 60 assert( type ); 68 61 return makeVtableDeclaration( type, nullptr ); 69 62 } 70 63 71 ObjectDecl * makeVtableForward(72 StructDecl * polyDecl, std::list< Expression * > && parameters ) {73 return makeVtableForward( vtableInstType( polyDecl, std::move( parameters ) ) );74 }75 76 64 ObjectDecl * makeVtableInstance( 77 StructInstType * vtableType, Type * vobject_type, Initializer * init ) { 65 StructInstType * vtableType, Type * objectType, Initializer * init ) { 66 assert( vtableType ); 67 assert( objectType ); 78 68 StructDecl * vtableStruct = vtableType->baseStruct; 79 69 // Build the initialization … … 92 82 new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) ); 93 83 } else if ( std::string( "size" ) == field->name ) { 94 inits.push_back( new SingleInit( new SizeofExpr( vobject_type->clone() ) ) );84 inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) ); 95 85 } else if ( std::string( "align" ) == field->name ) { 96 inits.push_back( new SingleInit( new AlignofExpr( vobject_type->clone() ) ) );86 inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) ); 97 87 } else { 98 88 inits.push_back( new SingleInit( new NameExpr( field->name ) ) ); … … 108 98 } 109 99 110 ObjectDecl * makeVtableInstance( 111 StructDecl * polyDecl, std::list< Expression * > && parameters, 112 Type * vobject, Initializer * init ) { 113 return makeVtableInstance( 114 vtableInstType( polyDecl, std::move( parameters ) ), vobject, init ); 100 namespace { 101 std::string const functionName = "get_exception_vtable"; 102 } 103 104 FunctionDecl * makeGetExceptionForward( 105 Type * vtableType, Type * exceptType ) { 106 assert( vtableType ); 107 assert( exceptType ); 108 FunctionType * type = new FunctionType( noQualifiers, false ); 109 vtableType->tq.is_const = true; 110 type->returnVals.push_back( new ObjectDecl( 111 "_retvalue", 112 noStorageClasses, 113 LinkageSpec::Cforall, 114 nullptr, 115 new ReferenceType( noQualifiers, vtableType ), 116 nullptr, 117 { new Attribute("unused") } 118 ) ); 119 type->parameters.push_back( new ObjectDecl( 120 "__unused", 121 noStorageClasses, 122 LinkageSpec::Cforall, 123 nullptr, 124 new PointerType( noQualifiers, exceptType ), 125 nullptr, 126 { new Attribute("unused") } 127 ) ); 128 return new FunctionDecl( 129 functionName, 130 noStorageClasses, 131 LinkageSpec::Cforall, 132 type, 133 nullptr 134 ); 135 } 136 137 FunctionDecl * makeGetExceptionFunction( 138 ObjectDecl * vtableInstance, Type * exceptType ) { 139 assert( vtableInstance ); 140 assert( exceptType ); 141 FunctionDecl * func = makeGetExceptionForward( 142 vtableInstance->type->clone(), exceptType ); 143 func->statements = new CompoundStmt( { 144 new ReturnStmt( new VariableExpr( vtableInstance ) ), 145 } ); 146 return func; 115 147 } 116 148 -
src/Virtual/Tables.h
r33c3ded r223a633 27 27 bool isVTableInstanceName( std::string const & name ); 28 28 29 /// Converts exceptions into regular structures. 30 //void ( std::list< Declaration * > & translationUnit ); 31 32 ObjectDecl * makeVtableForward( StructInstType * ); 33 ObjectDecl * makeVtableForward( StructDecl *, std::list< Expression * > && ); 34 /* Create a forward definition of a vtable of the given type. 35 * 36 * Instead of the virtual table type you may provide the declaration and all 37 * the forall parameters. 29 ObjectDecl * makeVtableForward( StructInstType * vtableType ); 30 /* Create a forward declaration of a vtable of the given type. 31 * vtableType node is consumed. 38 32 */ 39 33 40 ObjectDecl * makeVtableInstance( StructInstType *, Type *, Initializer * ); 41 ObjectDecl * makeVtableInstance( 42 StructDecl *, std::list< Expression * > &&, Type *, Initializer * ); 34 ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType, 35 Initializer * init = nullptr ); 43 36 /* Create an initialized definition of a vtable. 44 * 45 * The parameters are the virtual table type (or the base declaration and the 46 * forall parameters), the object type and optionally an initializer. 47 * 48 * Instead of the virtual table type you may provide the declaration and all 49 * the forall parameters. 37 * vtableType and init (if provided) nodes are consumed. 38 */ 39 40 // Some special code for how exceptions interact with virtual tables. 41 FunctionDecl * makeGetExceptionForward( Type * vtableType, Type * exceptType ); 42 /* Create a forward declaration of the exception virtual function 43 * linking the vtableType to the exceptType. Both nodes are consumed. 44 */ 45 46 FunctionDecl * makeGetExceptionFunction( 47 ObjectDecl * vtableInstance, Type * exceptType ); 48 /* Create the definition of the exception virtual function. 49 * exceptType node is consumed. 50 50 */ 51 51 -
src/main.cc
r33c3ded r223a633 9 9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : T ue May 19 12:03:00202013 // Update Count : 63 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Oct 8 18:17:46 2020 13 // Update Count : 637 14 14 // 15 15 … … 451 451 452 452 453 static const char optstring[] = ":c:ghlLmNnpd P:S:twW:D:";453 static const char optstring[] = ":c:ghlLmNnpdOAP:S:twW:D:"; 454 454 455 455 enum { PreludeDir = 128 }; … … 478 478 479 479 static const char * description[] = { 480 "diagnostic color: never, always, or auto.", // -c481 "wait for gdb to attach", // -g482 "print help message", // -h483 "generate libcfa.c", // -l484 "generate line marks", // -L485 "do not replace main", // -m486 "do not generate line marks", // -N487 "do not read prelude", // -n480 "diagnostic color: never, always, or auto.", // -c 481 "wait for gdb to attach", // -g 482 "print help message", // -h 483 "generate libcfa.c", // -l 484 "generate line marks", // -L 485 "do not replace main", // -m 486 "do not generate line marks", // -N 487 "do not read prelude", // -n 488 488 "generate prototypes for prelude functions", // -p 489 " don't print output that isn't deterministic",// -d490 "Use the old-ast", // -O491 "Use the new-ast", // -A492 "print", // -P489 "only print deterministic output", // -d 490 "Use the old-ast", // -O 491 "Use the new-ast", // -A 492 "print", // -P 493 493 "<directory> prelude directory for debug/nodebug", // no flag 494 494 "<option-list> enable profiling information:\n counters,heap,time,all,none", // -S 495 "building cfa standard lib", // -t496 "", // -w497 "", // -W498 "", // -D495 "building cfa standard lib", // -t 496 "", // -w 497 "", // -W 498 "", // -D 499 499 }; // description 500 500
Note:
See TracChangeset
for help on using the changeset viewer.