Skip to content

Commit bf387c5

Browse files
authored
Merge pull request swiftlang#80030 from DougGregor/import-macro-in-cpp-class-and-namespace
[Clang importer] Report auxiliary decls from C++ class and namespace lookup
2 parents f7655ae + 896cbad commit bf387c5

File tree

6 files changed

+156
-6
lines changed

6 files changed

+156
-6
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2750,8 +2750,24 @@ static void addNamespaceMembers(Decl *decl,
27502750
auto clangMember = found.get<clang::NamedDecl *>();
27512751
if (auto importedDecl =
27522752
ctx.getClangModuleLoader()->importDeclDirectly(clangMember)) {
2753-
if (addedMembers.insert(importedDecl).second)
2753+
if (addedMembers.insert(importedDecl).second) {
27542754
members.push_back(importedDecl);
2755+
2756+
// Handle macro-expanded declarations.
2757+
importedDecl->visitAuxiliaryDecls([&](Decl *decl) {
2758+
auto valueDecl = dyn_cast<ValueDecl>(decl);
2759+
if (!valueDecl)
2760+
return;
2761+
2762+
// Bail out if the auxiliary decl was not produced by a macro.
2763+
auto module = decl->getDeclContext()->getParentModule();
2764+
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
2765+
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
2766+
return;
2767+
2768+
members.push_back(valueDecl);
2769+
});
2770+
}
27552771
}
27562772
}
27572773
};

lib/ClangImporter/ClangImporter.cpp

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5084,6 +5084,42 @@ ClangDirectLookupRequest::evaluate(Evaluator &evaluator,
50845084
return filteredDecls;
50855085
}
50865086

5087+
namespace {
5088+
/// Collects name lookup results into the given tiny vector, for use in the
5089+
/// various Clang importer lookup routines.
5090+
class CollectLookupResults {
5091+
DeclName name;
5092+
TinyPtrVector<ValueDecl *> &result;
5093+
5094+
public:
5095+
CollectLookupResults(DeclName name, TinyPtrVector<ValueDecl *> &result)
5096+
: name(name), result(result) { }
5097+
5098+
void add(ValueDecl *imported) {
5099+
result.push_back(imported);
5100+
5101+
// Expand any macros introduced by the Clang importer.
5102+
imported->visitAuxiliaryDecls([&](Decl *decl) {
5103+
auto valueDecl = dyn_cast<ValueDecl>(decl);
5104+
if (!valueDecl)
5105+
return;
5106+
5107+
// Bail out if the auxiliary decl was not produced by a macro.
5108+
auto module = decl->getDeclContext()->getParentModule();
5109+
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
5110+
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
5111+
return;
5112+
5113+
// Only produce results that match the requested name.
5114+
if (!valueDecl->getName().matchesRef(name))
5115+
return;
5116+
5117+
result.push_back(valueDecl);
5118+
});
5119+
}
5120+
};
5121+
}
5122+
50875123
TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
50885124
Evaluator &evaluator, CXXNamespaceMemberLookupDescriptor desc) const {
50895125
EnumDecl *namespaceDecl = desc.namespaceDecl;
@@ -5093,6 +5129,8 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
50935129
auto &ctx = namespaceDecl->getASTContext();
50945130

50955131
TinyPtrVector<ValueDecl *> result;
5132+
CollectLookupResults collector(name, result);
5133+
50965134
llvm::SmallPtrSet<clang::NamedDecl *, 8> importedDecls;
50975135
for (auto redecl : clangNamespaceDecl->redecls()) {
50985136
auto allResults = evaluateOrDefault(
@@ -5108,7 +5146,7 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
51085146
continue;
51095147
if (auto import =
51105148
ctx.getClangModuleLoader()->importDeclDirectly(clangMember))
5111-
result.push_back(cast<ValueDecl>(import));
5149+
collector.add(cast<ValueDecl>(import));
51125150
}
51135151
}
51145152

@@ -6206,8 +6244,11 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62066244
ClangDirectLookupRequest({recordDecl, recordDecl->getClangDecl(), name}),
62076245
{});
62086246

6209-
// Find the results that are actually a member of "recordDecl".
6247+
// The set of declarations we found.
62106248
TinyPtrVector<ValueDecl *> result;
6249+
CollectLookupResults collector(name, result);
6250+
6251+
// Find the results that are actually a member of "recordDecl".
62116252
ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader();
62126253
for (auto foundEntry : directResults) {
62136254
auto found = foundEntry.get<clang::NamedDecl *>();
@@ -6242,7 +6283,8 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62426283
if (!imported)
62436284
continue;
62446285
}
6245-
result.push_back(cast<ValueDecl>(imported));
6286+
6287+
collector.add(cast<ValueDecl>(imported));
62466288
}
62476289

62486290
if (inheritance) {
@@ -6261,7 +6303,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62616303
if (!imported)
62626304
continue;
62636305

6264-
result.push_back(cast<ValueDecl>(imported));
6306+
collector.add(imported);
62656307
}
62666308
}
62676309

@@ -6310,7 +6352,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
63106352
if (foundNameArities.count(getArity(foundInBase)))
63116353
continue;
63126354

6313-
result.push_back(foundInBase);
6355+
collector.add(foundInBase);
63146356
}
63156357
}
63166358
}

lib/Sema/ImportResolution.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,11 @@ void swift::performImportResolutionForClangMacroBuffer(
329329
ImportResolver resolver(SF);
330330
resolver.addImplicitImport(clangModule);
331331

332+
// FIXME: This is a hack that we shouldn't need, but be sure that we can
333+
// see the Swift standard library.
334+
if (auto stdlib = SF.getASTContext().getStdlibModule())
335+
resolver.addImplicitImport(stdlib);
336+
332337
SF.setImports(resolver.getFinishedImports());
333338
SF.setImportedUnderlyingModule(resolver.getUnderlyingClangModule());
334339

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// REQUIRES: swift_feature_SafeInteropWrappers
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: %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=Namespace -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/namespace.swift -dump-macro-expansions -typecheck -verify
7+
8+
// CHECK: enum foo {
9+
// CHECK: static func bar(_ p: UnsafeMutableBufferPointer<Float>)
10+
11+
//--- Inputs/module.modulemap
12+
module Namespace {
13+
header "namespace.h"
14+
requires cplusplus
15+
}
16+
17+
//--- Inputs/namespace.h
18+
19+
namespace foo {
20+
__attribute__((swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(1), count: \"len\"))"))) void bar(float *p, int len);
21+
}
22+
23+
//--- namespace.swift
24+
import Namespace
25+
26+
func test(s: UnsafeMutableBufferPointer<Float>) {
27+
foo.bar(s)
28+
}
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+
// RUN: %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-SAME: public mutating func bar(_ p: UnsafeMutableBufferPointer<Float>)
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+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// REQUIRES: swift_feature_SafeInteropWrappers
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: %target-swift-ide-test -plugin-path %swift-plugin-dir -I %t/Inputs -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 -enable-experimental-feature SafeInteropWrappers %t/method.swift -dump-macro-expansions -typecheck -verify
7+
8+
// REQUIRES: objc_interop
9+
10+
// CHECK: class Foo {
11+
// CHECK: func bar(_ p: UnsafeMutableBufferPointer<Float>)
12+
13+
//--- Inputs/module.modulemap
14+
module Method {
15+
header "method.h"
16+
}
17+
18+
//--- Inputs/method.h
19+
20+
@interface Foo
21+
-(void)bar:(float *)p count:(int)len __attribute__((swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(1), count: \"len\"))")));
22+
@end
23+
24+
//--- method.swift
25+
import Method
26+
27+
func test(foo: Foo, s: UnsafeMutableBufferPointer<Float>) {
28+
foo.bar(s)
29+
}

0 commit comments

Comments
 (0)