Skip to content

Commit 84a4a8b

Browse files
committed
[Importer] Ensure that we can see macro-expanded declarations in C++ namespaces
Lookup into C++ namespaces uses a different path from C++ record declarations. Augment the C++ namespace lookup path to also account for the auxiliary declarations introduced by peer macro expansions.
1 parent e3618dd commit 84a4a8b

File tree

5 files changed

+95
-29
lines changed

5 files changed

+95
-29
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: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5078,6 +5078,42 @@ ClangDirectLookupRequest::evaluate(Evaluator &evaluator,
50785078
return filteredDecls;
50795079
}
50805080

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

50895125
TinyPtrVector<ValueDecl *> result;
5126+
CollectLookupResults collector(name, result);
5127+
50905128
llvm::SmallPtrSet<clang::NamedDecl *, 8> importedDecls;
50915129
for (auto redecl : clangNamespaceDecl->redecls()) {
50925130
auto allResults = evaluateOrDefault(
@@ -5102,7 +5140,7 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
51025140
continue;
51035141
if (auto import =
51045142
ctx.getClangModuleLoader()->importDeclDirectly(clangMember))
5105-
result.push_back(cast<ValueDecl>(import));
5143+
collector.add(cast<ValueDecl>(import));
51065144
}
51075145
}
51085146

@@ -6202,28 +6240,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62026240

62036241
// The set of declarations we found.
62046242
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-
};
6243+
CollectLookupResults collector(name, result);
62276244

62286245
// Find the results that are actually a member of "recordDecl".
62296246
ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader();
@@ -6261,7 +6278,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62616278
continue;
62626279
}
62636280

6264-
addResult(cast<ValueDecl>(imported));
6281+
collector.add(cast<ValueDecl>(imported));
62656282
}
62666283

62676284
if (inheritance) {
@@ -6280,7 +6297,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
62806297
if (!imported)
62816298
continue;
62826299

6283-
addResult(imported);
6300+
collector.add(imported);
62846301
}
62856302
}
62866303

@@ -6329,7 +6346,7 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
63296346
if (foundNameArities.count(getArity(foundInBase)))
63306347
continue;
63316348

6332-
addResult(foundInBase);
6349+
collector.add(foundInBase);
63336350
}
63346351
}
63356352
}

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+
}

test/Interop/Cxx/swiftify-import/counted-by-method.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
// RUN: rm -rf %t
44
// 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
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
66
// 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
77

88
// CHECK: @_alwaysEmitIntoClient
9-
// CHECK: public mutating func bar(_ p: UnsafeMutableBufferPointer<Int32>)
9+
// CHECK-SAME: public mutating func bar(_ p: UnsafeMutableBufferPointer<Float>)
1010

1111
//--- Inputs/module.modulemap
1212
module Method {

0 commit comments

Comments
 (0)