mirror of
https://github.com/apple/swift.git
synced 2026-03-04 18:24:35 +01:00
[Clang importer] Report auxiliary decls from C++ member lookup
When performing name lookup into a C++ record type, make sure that we also walk through auxiliary declarations (i.e., declarations that can come from peer macro expansions) to find results. Fixes rdar://146833294.
This commit is contained in:
@@ -6200,8 +6200,32 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
|
||||
ClangDirectLookupRequest({recordDecl, recordDecl->getClangDecl(), name}),
|
||||
{});
|
||||
|
||||
// Find the results that are actually a member of "recordDecl".
|
||||
// The set of declarations we found.
|
||||
TinyPtrVector<ValueDecl *> result;
|
||||
auto addResult = [&result, name](ValueDecl *imported) {
|
||||
result.push_back(imported);
|
||||
|
||||
// Expand any macros introduced by the Clang importer.
|
||||
imported->visitAuxiliaryDecls([&](Decl *decl) {
|
||||
auto valueDecl = dyn_cast<ValueDecl>(decl);
|
||||
if (!valueDecl)
|
||||
return;
|
||||
|
||||
// Bail out if the auxiliary decl was not produced by a macro.
|
||||
auto module = decl->getDeclContext()->getParentModule();
|
||||
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
|
||||
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
|
||||
return;
|
||||
|
||||
// Only produce results that match the requested name.
|
||||
if (!valueDecl->getName().matchesRef(name))
|
||||
return;
|
||||
|
||||
result.push_back(valueDecl);
|
||||
});
|
||||
};
|
||||
|
||||
// Find the results that are actually a member of "recordDecl".
|
||||
ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader();
|
||||
for (auto foundEntry : directResults) {
|
||||
auto found = foundEntry.get<clang::NamedDecl *>();
|
||||
@@ -6236,7 +6260,8 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
|
||||
if (!imported)
|
||||
continue;
|
||||
}
|
||||
result.push_back(cast<ValueDecl>(imported));
|
||||
|
||||
addResult(cast<ValueDecl>(imported));
|
||||
}
|
||||
|
||||
if (inheritance) {
|
||||
@@ -6255,7 +6280,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
|
||||
if (!imported)
|
||||
continue;
|
||||
|
||||
result.push_back(cast<ValueDecl>(imported));
|
||||
addResult(imported);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6304,7 +6329,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
|
||||
if (foundNameArities.count(getArity(foundInBase)))
|
||||
continue;
|
||||
|
||||
result.push_back(foundInBase);
|
||||
addResult(foundInBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
test/Interop/Cxx/swiftify-import/counted-by-method.swift
Normal file
30
test/Interop/Cxx/swiftify-import/counted-by-method.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
// REQUIRES: swift_feature_SafeInteropWrappers
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUNx: %target-swift-ide-test -plugin-path %swift-plugin-dir -I %t/Inputs -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature SafeInteropWrappers -print-module -module-to-print=Method -source-filename=x | %FileCheck %s
|
||||
// RUN: %target-swift-frontend -plugin-path %swift-plugin-dir -I %t/Inputs -cxx-interoperability-mode=default -enable-experimental-feature SafeInteropWrappers %t/method.swift -dump-macro-expansions -typecheck -verify
|
||||
|
||||
// CHECK: @_alwaysEmitIntoClient
|
||||
// CHECK: public mutating func bar(_ p: UnsafeMutableBufferPointer<Int32>)
|
||||
|
||||
//--- Inputs/module.modulemap
|
||||
module Method {
|
||||
header "method.h"
|
||||
requires cplusplus
|
||||
}
|
||||
|
||||
//--- Inputs/method.h
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
__attribute__((swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(1), count: \"len\"))"))) void bar(float *p, int len);
|
||||
};
|
||||
|
||||
//--- method.swift
|
||||
import Method
|
||||
|
||||
func test(s: UnsafeMutableBufferPointer<Float>) {
|
||||
var foo = Foo()
|
||||
foo.bar(s)
|
||||
}
|
||||
Reference in New Issue
Block a user