Skip to content

Commit e6e7bd0

Browse files
authored
Merge pull request #63296 from hyp/eng/print-ns-interface-quick
[interop] AST printer should only visit one original namespace decl t…
2 parents 8d49757 + da30593 commit e6e7bd0

File tree

5 files changed

+103
-5
lines changed

5 files changed

+103
-5
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
// ambiguities with type names, in AliasModuleNames mode.
2929
#define MODULE_DISAMBIGUATING_PREFIX "Module___"
3030

31+
namespace clang {
32+
class Decl;
33+
}
34+
3135
namespace swift {
3236
class Decl;
3337
class DeclContext;
@@ -111,6 +115,7 @@ class ASTPrinter {
111115
unsigned CurrentIndentation = 0;
112116
unsigned PendingNewlines = 0;
113117
TypeOrExtensionDecl SynthesizeTarget;
118+
llvm::SmallPtrSet<const clang::Decl *, 8> printedClangDecl;
114119

115120
void printTextImpl(StringRef Text);
116121

@@ -331,6 +336,12 @@ class ASTPrinter {
331336
printStructurePre(Kind, D);
332337
}
333338

339+
/// Return true when the given redeclared clang decl is being printed for the
340+
/// first time.
341+
bool shouldPrintRedeclaredClangDecl(const clang::Decl *d) {
342+
return printedClangDecl.insert(d).second;
343+
}
344+
334345
private:
335346
virtual void anchor();
336347
};

lib/AST/ASTPrinter.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "InlinableText.h"
1817
#include "swift/AST/ASTPrinter.h"
18+
#include "InlinableText.h"
1919
#include "swift/AST/ASTContext.h"
2020
#include "swift/AST/ASTMangler.h"
2121
#include "swift/AST/ASTVisitor.h"
@@ -61,6 +61,7 @@
6161
#include "clang/AST/DeclObjC.h"
6262
#include "clang/Basic/Module.h"
6363
#include "clang/Basic/SourceManager.h"
64+
#include "clang/Lex/MacroInfo.h"
6465
#include "llvm/ADT/STLExtras.h"
6566
#include "llvm/ADT/StringSwitch.h"
6667
#include "llvm/Support/Compiler.h"
@@ -2299,7 +2300,15 @@ static void addNamespaceMembers(Decl *decl,
22992300

23002301
// This is only to keep track of the members we've already seen.
23012302
llvm::SmallPtrSet<Decl *, 16> addedMembers;
2303+
const auto *declOwner = namespaceDecl->getOwningModule();
2304+
if (declOwner)
2305+
declOwner = declOwner->getTopLevelModule();
23022306
for (auto redecl : namespaceDecl->redecls()) {
2307+
// Skip namespace declarations that come from other top-level modules.
2308+
if (const auto *redeclOwner = redecl->getOwningModule()) {
2309+
if (declOwner && declOwner != redeclOwner->getTopLevelModule())
2310+
continue;
2311+
}
23032312
for (auto member : redecl->decls()) {
23042313
if (auto classTemplate = dyn_cast<clang::ClassTemplateDecl>(member)) {
23052314
// Add all specializations to a worklist so we don't accidently mutate
@@ -2323,10 +2332,16 @@ static void addNamespaceMembers(Decl *decl,
23232332
if (!name)
23242333
continue;
23252334

2326-
CXXNamespaceMemberLookup lookupRequest({cast<EnumDecl>(decl), name});
2327-
for (auto found : evaluateOrDefault(ctx.evaluator, lookupRequest, {})) {
2328-
if (addedMembers.insert(found).second)
2329-
members.push_back(found);
2335+
auto allResults = evaluateOrDefault(
2336+
ctx.evaluator, ClangDirectLookupRequest({decl, redecl, name}), {});
2337+
2338+
for (auto found : allResults) {
2339+
auto clangMember = found.get<clang::NamedDecl *>();
2340+
if (auto importedDecl =
2341+
ctx.getClangModuleLoader()->importDeclDirectly(clangMember)) {
2342+
if (addedMembers.insert(importedDecl).second)
2343+
members.push_back(importedDecl);
2344+
}
23302345
}
23312346
}
23322347
}
@@ -3593,6 +3608,13 @@ void PrintAST::visitAssociatedTypeDecl(AssociatedTypeDecl *decl) {
35933608
}
35943609

35953610
void PrintAST::visitEnumDecl(EnumDecl *decl) {
3611+
if (const auto *namespaceDecl =
3612+
dyn_cast_or_null<clang::NamespaceDecl>(decl->getClangDecl())) {
3613+
// Enum that correponds to the C++ namespace should only be printed once.
3614+
if (!Printer.shouldPrintRedeclaredClangDecl(
3615+
namespaceDecl->getOriginalNamespace()))
3616+
return;
3617+
}
35963618
printDocumentationComment(decl);
35973619
printAttributes(decl);
35983620
printAccess(decl);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-ide-test -print-module -module-to-print=ModuleB -I %t/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck --check-prefix=CHECKB %s
4+
// RUN: %target-swift-ide-test -print-module -module-to-print=ModuleA -I %t/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck --check-prefix=CHECKA %s
5+
6+
//--- Inputs/module.modulemap
7+
module ModuleA {
8+
header "headerA.h"
9+
requires cplusplus
10+
}
11+
12+
module ModuleB {
13+
header "headerB.h"
14+
requires cplusplus
15+
}
16+
17+
//--- Inputs/headerA.h
18+
19+
namespace ns {
20+
struct A {
21+
int x;
22+
};
23+
}
24+
25+
//--- Inputs/headerB.h
26+
27+
#include "headerA.h"
28+
29+
namespace ns {
30+
struct B {
31+
int y;
32+
};
33+
}
34+
35+
// CHECKB: enum ns {
36+
// CHECKB-NEXT: struct B {
37+
// CHECKB-NEXT: init()
38+
// CHECKB-NEXT: init(y: Int32)
39+
// CHECKB-NEXT: var y: Int32
40+
// CHECKB-NEXT: }
41+
// CHECKB-NEXT: }
42+
43+
// CHECKA: enum ns {
44+
// CHECKA-NEXT: struct A {
45+
// CHECKA-NEXT: init()
46+
// CHECKA-NEXT: init(x: Int32)
47+
// CHECKA-NEXT: var x: Int32
48+
// CHECKA-NEXT: }
49+
// CHECKA-NEXT: }
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=CxxStdlib -source-filename=x -enable-experimental-cxx-interop -enable-objc-interop -module-print-submodules | %FileCheck %s
2+
3+
// REQUIRES: OS=macosx
4+
// REQUIRES: libcxx-in-sdk
5+
6+
// CHECK: enum std {
7+
// CHECK-NEXT: enum __1 {
8+
9+
// CHECK: typealias string =
10+
11+
// CHECK-NOT: enum std

test/Interop/lit.local.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ clang_opt = clang_compile_opt
1212
is_cf_options_interop_updated = True
1313

1414
if config.variant_sdk and config.variant_sdk != "":
15+
# Check if libc++ is present in the SDK or not.
16+
if config.target_sdk_libcxx_path and os.path.exists(config.target_sdk_libcxx_path):
17+
config.available_features.add('libcxx-in-sdk')
18+
config.substitutions.insert(0, ('%libcxx-in-sdk-path', config.target_sdk_libcxx_path))
19+
1520
# Check if CF_OPTIONS macro has been updated to be imported into Swift in C++ mode correctly.
1621
cf_avail_path = os.path.join(config.variant_sdk, 'System', 'Library', 'Frameworks', 'CoreFoundation.framework', 'Versions', 'A', 'Headers', 'CFAvailability.h')
1722
if os.path.exists(cf_avail_path):

0 commit comments

Comments
 (0)