Skip to content

Commit e3618dd

Browse files
committed
[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.
1 parent 01b2789 commit e3618dd

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6200,8 +6200,32 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62006200
ClangDirectLookupRequest({recordDecl, recordDecl->getClangDecl(), name}),
62016201
{});
62026202

6203-
// Find the results that are actually a member of "recordDecl".
6203+
// The set of declarations we found.
62046204
TinyPtrVector<ValueDecl *> result;
6205+
auto addResult = [&result, name](ValueDecl *imported) {
6206+
result.push_back(imported);
6207+
6208+
// Expand any macros introduced by the Clang importer.
6209+
imported->visitAuxiliaryDecls([&](Decl *decl) {
6210+
auto valueDecl = dyn_cast<ValueDecl>(decl);
6211+
if (!valueDecl)
6212+
return;
6213+
6214+
// Bail out if the auxiliary decl was not produced by a macro.
6215+
auto module = decl->getDeclContext()->getParentModule();
6216+
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
6217+
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
6218+
return;
6219+
6220+
// Only produce results that match the requested name.
6221+
if (!valueDecl->getName().matchesRef(name))
6222+
return;
6223+
6224+
result.push_back(valueDecl);
6225+
});
6226+
};
6227+
6228+
// Find the results that are actually a member of "recordDecl".
62056229
ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader();
62066230
for (auto foundEntry : directResults) {
62076231
auto found = foundEntry.get<clang::NamedDecl *>();
@@ -6236,7 +6260,8 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62366260
if (!imported)
62376261
continue;
62386262
}
6239-
result.push_back(cast<ValueDecl>(imported));
6263+
6264+
addResult(cast<ValueDecl>(imported));
62406265
}
62416266

62426267
if (inheritance) {
@@ -6255,7 +6280,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62556280
if (!imported)
62566281
continue;
62576282

6258-
result.push_back(cast<ValueDecl>(imported));
6283+
addResult(imported);
62596284
}
62606285
}
62616286

@@ -6304,7 +6329,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
63046329
if (foundNameArities.count(getArity(foundInBase)))
63056330
continue;
63066331

6307-
result.push_back(foundInBase);
6332+
addResult(foundInBase);
63086333
}
63096334
}
63106335
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// REQUIRES: swift_feature_SafeInteropWrappers
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// 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
6+
// 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
7+
8+
// CHECK: @_alwaysEmitIntoClient
9+
// CHECK: public mutating func bar(_ p: UnsafeMutableBufferPointer<Int32>)
10+
11+
//--- Inputs/module.modulemap
12+
module Method {
13+
header "method.h"
14+
requires cplusplus
15+
}
16+
17+
//--- Inputs/method.h
18+
19+
class Foo {
20+
public:
21+
__attribute__((swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(1), count: \"len\"))"))) void bar(float *p, int len);
22+
};
23+
24+
//--- method.swift
25+
import Method
26+
27+
func test(s: UnsafeMutableBufferPointer<Float>) {
28+
var foo = Foo()
29+
foo.bar(s)
30+
}

0 commit comments

Comments
 (0)