30
30
31
31
#include " clang/AST/DeclObjC.h"
32
32
#include " clang/Basic/Module.h"
33
+ #include " llvm/ADT/STLExtras.h"
33
34
#include " llvm/ADT/SmallString.h"
34
35
#include < optional>
35
36
@@ -241,10 +242,12 @@ swift::cxx_translation::getNameForCxx(const ValueDecl *VD,
241
242
namespace {
242
243
struct ObjCTypeWalker : TypeWalker {
243
244
bool hadObjCType = false ;
245
+ const ASTContext &ctx;
246
+ ObjCTypeWalker (const ASTContext &ctx) : ctx(ctx) {}
244
247
Action walkToTypePre (Type ty) override {
245
248
if (auto *nominal = ty->getNominalOrBoundGenericNominal ()) {
246
249
if (auto clangDecl = nominal->getClangDecl ()) {
247
- if (cxx_translation::isObjCxxOnly (clangDecl)) {
250
+ if (cxx_translation::isObjCxxOnly (clangDecl, ctx )) {
248
251
hadObjCType = true ;
249
252
return Action::Stop;
250
253
}
@@ -256,19 +259,29 @@ struct ObjCTypeWalker : TypeWalker {
256
259
} // namespace
257
260
258
261
bool swift::cxx_translation::isObjCxxOnly (const ValueDecl *VD) {
259
- ObjCTypeWalker walker;
262
+ ObjCTypeWalker walker{VD-> getASTContext ()} ;
260
263
VD->getInterfaceType ().walk (walker);
261
264
return walker.hadObjCType ;
262
265
}
263
266
264
- bool swift::cxx_translation::isObjCxxOnly (const clang::Decl *D) {
267
+ bool swift::cxx_translation::isObjCxxOnly (const clang::Decl *D,
268
+ const ASTContext &ctx) {
265
269
// By default, we import all modules in Obj-C++ mode, so there is no robust
266
- // way to tell if something is coming from an Obj-C module. The best
267
- // approximation is to check if something is a framework module as most of
268
- // those are written in Obj-C. Ideally, we want to add `requires ObjC` to all
269
- // ObjC modules and respect that here to make this completely precise.
270
- return D->getASTContext ().getLangOpts ().ObjC &&
271
- D->getOwningModule ()->isPartOfFramework ();
270
+ // way to tell if something is coming from an Obj-C module. Use the
271
+ // requirements and the language options to check if we should actually
272
+ // consider the module to have ObjC constructs.
273
+ const auto &langOpts = D->getASTContext ().getLangOpts ();
274
+ auto clangModule = D->getOwningModule ()->getTopLevelModule ();
275
+ bool requiresObjC = false ;
276
+ for (auto req : clangModule->Requirements )
277
+ if (req.RequiredState && req.FeatureName == " objc" )
278
+ requiresObjC = true ;
279
+ return langOpts.ObjC &&
280
+ (requiresObjC ||
281
+ llvm::any_of (ctx.LangOpts .ModulesRequiringObjC ,
282
+ [clangModule](StringRef moduleName) {
283
+ return clangModule->getFullModuleName () == moduleName;
284
+ }));
272
285
}
273
286
274
287
swift::cxx_translation::DeclRepresentation
0 commit comments