@@ -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,48 @@ 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 , method->getType (), clang::ExprValueKind::VK_LValue,
2143
+ clang::SourceLocation ());
2144
+ memberCall = clangSema.BuildCallExpr (nullptr , memberExpr, clang::SourceLocation (),
2145
+ args, clang::SourceLocation ());
2146
+ } else {
2147
+ // Construct the method's body.
2148
+ clang::Expr *thisExpr = new (clangCtx) clang::CXXThisExpr (
2149
+ clang::SourceLocation (), newMethod->getThisType (), /* IsImplicit=*/ false );
2150
+ if (castThisToNonConstThis) {
2151
+ auto baseClassPtr =
2152
+ clangCtx.getPointerType (clangCtx.getRecordType (derivedClass));
2153
+ clang::CastKind Kind;
2154
+ clang::CXXCastPath Path;
2155
+ clangSema.CheckPointerConversion (thisExpr, baseClassPtr, Kind, Path,
2156
+ /* IgnoreBaseAccess=*/ false ,
2157
+ /* Diagnose=*/ true );
2158
+ auto conv = clangSema.ImpCastExprToType (thisExpr, baseClassPtr, Kind,
2159
+ clang::VK_PRValue, &Path);
2160
+ if (!conv.isUsable ())
2161
+ return nullptr ;
2162
+ thisExpr = conv.get ();
2163
+ }
2164
+ auto memberExpr = clangSema.BuildMemberExpr (
2165
+ thisExpr, /* isArrow=*/ true , clang::SourceLocation (),
2166
+ clang::NestedNameSpecifierLoc (), clang::SourceLocation (),
2167
+ const_cast <clang::CXXMethodDecl *>(method),
2168
+ clang::DeclAccessPair::make (const_cast <clang::CXXMethodDecl *>(method),
2169
+ clang::AS_public),
2170
+ /* HadMultipleCandidates=*/ false , method->getNameInfo (),
2171
+ clangCtx.BoundMemberTy , clang::VK_PRValue, clang::OK_Ordinary);
2172
+
2173
+ memberCall = clangSema.BuildCallToMemberFunction (
2174
+ nullptr , memberExpr, clang::SourceLocation (), args,
2175
+ clang::SourceLocation ());
2176
+ }
2162
2177
if (!memberCall.isUsable ())
2163
2178
return nullptr ;
2164
2179
auto returnStmt =
0 commit comments