@@ -2011,6 +2011,8 @@ clang::CXXMethodDecl *SwiftDeclSynthesizer::synthesizeCXXForwardingMethod(
2011
2011
assert (!method->isStatic () ||
2012
2012
method->getNameInfo ().getName ().getCXXOverloadedOperator () ==
2013
2013
clang::OO_Call);
2014
+ // instance to static `operator ()` call.
2015
+ bool isInstanceToStatic = method->isStatic ();
2014
2016
// When emitting symbolic decls, the method might not have a concrete
2015
2017
// record type as this type.
2016
2018
if (ImporterImpl.importSymbolicCXXDecls && !method->isStatic () &&
@@ -2120,32 +2122,6 @@ clang::CXXMethodDecl *SwiftDeclSynthesizer::synthesizeCXXForwardingMethod(
2120
2122
clangSema.DelayedDiagnostics .getCurrentPool ()};
2121
2123
auto diagState = clangSema.DelayedDiagnostics .push (diagPool);
2122
2124
2123
- // Construct the method's body.
2124
- clang::Expr *thisExpr = new (clangCtx) clang::CXXThisExpr (
2125
- clang::SourceLocation (), newMethod->getThisType (), /* IsImplicit=*/ false );
2126
- if (castThisToNonConstThis) {
2127
- auto baseClassPtr =
2128
- clangCtx.getPointerType (clangCtx.getRecordType (derivedClass));
2129
- clang::CastKind Kind;
2130
- clang::CXXCastPath Path;
2131
- clangSema.CheckPointerConversion (thisExpr, baseClassPtr, Kind, Path,
2132
- /* IgnoreBaseAccess=*/ false ,
2133
- /* Diagnose=*/ true );
2134
- auto conv = clangSema.ImpCastExprToType (thisExpr, baseClassPtr, Kind,
2135
- clang::VK_PRValue, &Path);
2136
- if (!conv.isUsable ())
2137
- return nullptr ;
2138
- thisExpr = conv.get ();
2139
- }
2140
-
2141
- auto memberExpr = clangSema.BuildMemberExpr (
2142
- thisExpr, /* isArrow=*/ true , clang::SourceLocation (),
2143
- clang::NestedNameSpecifierLoc (), clang::SourceLocation (),
2144
- const_cast <clang::CXXMethodDecl *>(method),
2145
- clang::DeclAccessPair::make (const_cast <clang::CXXMethodDecl *>(method),
2146
- clang::AS_public),
2147
- /* HadMultipleCandidates=*/ false , method->getNameInfo (),
2148
- clangCtx.BoundMemberTy , clang::VK_PRValue, clang::OK_Ordinary);
2149
2125
llvm::SmallVector<clang::Expr *, 4 > args;
2150
2126
for (size_t i = 0 ; i < newMethod->getNumParams (); ++i) {
2151
2127
auto *param = newMethod->getParamDecl (i);
@@ -2156,9 +2132,51 @@ clang::CXXMethodDecl *SwiftDeclSynthesizer::synthesizeCXXForwardingMethod(
2156
2132
clangCtx, param, false , type, clang::ExprValueKind::VK_LValue,
2157
2133
clang::SourceLocation ()));
2158
2134
}
2159
- auto memberCall = clangSema.BuildCallToMemberFunction (
2160
- nullptr , memberExpr, clang::SourceLocation (), args,
2161
- clang::SourceLocation ());
2135
+
2136
+ clang::ExprResult memberCall;
2137
+ if (isInstanceToStatic) {
2138
+ // Constuct a direct call to a static member instead of going
2139
+ // through a member expression to avoid clang's semantic analysis failure
2140
+ // when analysis the return on a member with non-existing `this`.
2141
+ auto memberExpr = new (clangCtx) clang::DeclRefExpr (
2142
+ clangCtx, const_cast <clang::CXXMethodDecl *>(method), false ,
2143
+ method->getType (), clang::ExprValueKind::VK_LValue,
2144
+ clang::SourceLocation ());
2145
+ memberCall =
2146
+ clangSema.BuildCallExpr (nullptr , memberExpr, clang::SourceLocation (),
2147
+ args, clang::SourceLocation ());
2148
+ } else {
2149
+ // Construct the method's body.
2150
+ clang::Expr *thisExpr = new (clangCtx)
2151
+ clang::CXXThisExpr (clang::SourceLocation (), newMethod->getThisType (),
2152
+ /* IsImplicit=*/ false );
2153
+ if (castThisToNonConstThis) {
2154
+ auto baseClassPtr =
2155
+ clangCtx.getPointerType (clangCtx.getRecordType (derivedClass));
2156
+ clang::CastKind Kind;
2157
+ clang::CXXCastPath Path;
2158
+ clangSema.CheckPointerConversion (thisExpr, baseClassPtr, Kind, Path,
2159
+ /* IgnoreBaseAccess=*/ false ,
2160
+ /* Diagnose=*/ true );
2161
+ auto conv = clangSema.ImpCastExprToType (thisExpr, baseClassPtr, Kind,
2162
+ clang::VK_PRValue, &Path);
2163
+ if (!conv.isUsable ())
2164
+ return nullptr ;
2165
+ thisExpr = conv.get ();
2166
+ }
2167
+ auto memberExpr = clangSema.BuildMemberExpr (
2168
+ thisExpr, /* isArrow=*/ true , clang::SourceLocation (),
2169
+ clang::NestedNameSpecifierLoc (), clang::SourceLocation (),
2170
+ const_cast <clang::CXXMethodDecl *>(method),
2171
+ clang::DeclAccessPair::make (const_cast <clang::CXXMethodDecl *>(method),
2172
+ clang::AS_public),
2173
+ /* HadMultipleCandidates=*/ false , method->getNameInfo (),
2174
+ clangCtx.BoundMemberTy , clang::VK_PRValue, clang::OK_Ordinary);
2175
+
2176
+ memberCall = clangSema.BuildCallToMemberFunction (
2177
+ nullptr , memberExpr, clang::SourceLocation (), args,
2178
+ clang::SourceLocation ());
2179
+ }
2162
2180
if (!memberCall.isUsable ())
2163
2181
return nullptr ;
2164
2182
auto returnStmt =
0 commit comments