Skip to content

Commit 9247d53

Browse files
committed
[cxx-interop] Do not auto-complete unsafe underscored methods, part 2
Previous patch removed unsafe C++ methods from the module interface, but not from auto-completion results. rdar://103252957
1 parent 8ddbc68 commit 9247d53

File tree

6 files changed

+34
-14
lines changed

6 files changed

+34
-14
lines changed

include/swift/AST/ClangModuleLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace swift {
3333

3434
class ConcreteDeclRef;
3535
class Decl;
36+
class FuncDecl;
3637
class VarDecl;
3738
class DeclContext;
3839
class EffectiveClangContext;
@@ -267,6 +268,8 @@ class ClangModuleLoader : public ModuleLoader {
267268

268269
virtual bool isCXXMethodMutating(const clang::CXXMethodDecl *method) = 0;
269270

271+
virtual bool isUnsafeCXXMethod(const FuncDecl *func) = 0;
272+
270273
virtual Type importFunctionReturnType(const clang::FunctionDecl *clangDecl,
271274
DeclContext *dc) = 0;
272275

include/swift/ClangImporter/ClangImporter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ class ClangImporter final : public ClangModuleLoader {
532532

533533
bool isCXXMethodMutating(const clang::CXXMethodDecl *method) override;
534534

535+
bool isUnsafeCXXMethod(const FuncDecl *func) override;
536+
535537
bool isAnnotatedWith(const clang::CXXMethodDecl *method, StringRef attr);
536538

537539
/// Find the lookup table that corresponds to the given Clang module.

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,19 +1952,11 @@ bool ShouldPrintChecker::shouldPrint(const Decl *D,
19521952
D->isPrivateStdlibDecl(!Options.SkipUnderscoredStdlibProtocols))
19531953
return false;
19541954

1955-
auto isUnsafeCxxMethod = [](const Decl* decl) {
1956-
if (!decl->hasClangNode()) return false;
1957-
auto clangDecl = decl->getClangNode().getAsDecl();
1958-
if (!clangDecl) return false;
1959-
auto cxxMethod = dyn_cast<clang::CXXMethodDecl>(clangDecl);
1960-
if (!cxxMethod) return false;
1961-
auto func = dyn_cast<FuncDecl>(decl);
1962-
if (!func || !func->hasName()) return false;
1963-
auto id = func->getBaseIdentifier().str();
1964-
return id.startswith("__") && id.endswith("Unsafe");
1965-
};
1966-
if (Options.SkipUnsafeCXXMethods && isUnsafeCxxMethod(D))
1967-
return false;
1955+
auto &ctx = D->getASTContext();
1956+
if (Options.SkipUnsafeCXXMethods)
1957+
if (auto func = dyn_cast<FuncDecl>(D))
1958+
if (ctx.getClangModuleLoader()->isUnsafeCXXMethod(func))
1959+
return false;
19681960

19691961
if (Options.SkipEmptyExtensionDecls && isa<ExtensionDecl>(D)) {
19701962
auto Ext = cast<ExtensionDecl>(D);

lib/ClangImporter/ClangImporter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6199,6 +6199,21 @@ bool ClangImporter::isCXXMethodMutating(const clang::CXXMethodDecl *method) {
61996199
return false;
62006200
}
62016201

6202+
bool ClangImporter::isUnsafeCXXMethod(const FuncDecl *func) {
6203+
if (!func->hasClangNode())
6204+
return false;
6205+
auto clangDecl = func->getClangNode().getAsDecl();
6206+
if (!clangDecl)
6207+
return false;
6208+
auto cxxMethod = dyn_cast<clang::CXXMethodDecl>(clangDecl);
6209+
if (!cxxMethod)
6210+
return false;
6211+
if (!func->hasName())
6212+
return false;
6213+
auto id = func->getBaseIdentifier().str();
6214+
return id.startswith("__") && id.endswith("Unsafe");
6215+
}
6216+
62026217
bool ClangImporter::isAnnotatedWith(const clang::CXXMethodDecl *method,
62036218
StringRef attr) {
62046219
return method->hasAttrs() &&

lib/IDE/CompletionLookup.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,10 @@ void CompletionLookup::addMethodCall(const FuncDecl *FD,
14711471
Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
14721472
};
14731473

1474+
// Do not add imported C++ methods that are treated as unsafe in Swift.
1475+
if (Importer->isUnsafeCXXMethod(FD))
1476+
return;
1477+
14741478
if (!AFT || IsImplicitlyCurriedInstanceMethod) {
14751479
addMethodImpl();
14761480
} else {
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=METHOD -I %S/Inputs | %FileCheck %s -check-prefix=CHECK-METHOD
1+
// RUN: %target-swift-ide-test -code-completion -enable-experimental-cxx-interop -source-filename %s -code-completion-token=METHOD -I %S/Inputs | %FileCheck %s -check-prefix=CHECK-METHOD
22

33
import TypeClassification
44

55
func foo(x: HasMethodThatReturnsIterator) {
66
x.#^METHOD^#
77
}
8+
// CHECK-METHOD: Begin completions
89
// CHECK-METHOD-NOT: getIterator
10+
// CHECK-METHOD-NOT: Decl[InstanceMethod]/CurrNominal: getIterator
911
// CHECK-METHOD-NOT: __getIteratorUnsafe
12+
// CHECK-METHOD-NOT: Decl[InstanceMethod]/CurrNominal: __getIteratorUnsafe
13+
// CHECK-METHOD: End completions

0 commit comments

Comments
 (0)