Skip to content

Commit 7aa9839

Browse files
authored
Merge pull request swiftlang#12351 from adrian-prantl/18296829
2 parents 2c8393a + 44aa482 commit 7aa9839

File tree

5 files changed

+97
-39
lines changed

5 files changed

+97
-39
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,6 +2209,9 @@ class ValueDecl : public Decl {
22092209
return result;
22102210
}
22112211

2212+
/// Determine whether this Decl has either Private or FilePrivate access.
2213+
bool isOutermostPrivateOrFilePrivateScope() const;
2214+
22122215
/// Returns the outermost DeclContext from which this declaration can be
22132216
/// accessed, or null if the declaration is public.
22142217
///

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -533,25 +533,6 @@ void ASTMangler::appendSymbolKind(SymbolKind SKind) {
533533
}
534534
}
535535

536-
/// Returns true if one of the ancestor DeclContexts of \p D is either marked
537-
/// private or is a local context.
538-
static bool isInPrivateOrLocalContext(const ValueDecl *D) {
539-
const DeclContext *DC = D->getDeclContext();
540-
if (!DC->isTypeContext()) {
541-
assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
542-
"unexpected context kind");
543-
return DC->isLocalContext();
544-
}
545-
546-
auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
547-
if (nominal == nullptr)
548-
return false;
549-
550-
if (nominal->getFormalAccess() <= AccessLevel::FilePrivate)
551-
return true;
552-
return isInPrivateOrLocalContext(nominal);
553-
}
554-
555536
static bool getUnnamedParamIndex(const ParameterList *ParamList,
556537
const ParamDecl *D,
557538
unsigned &UnnamedIndex) {
@@ -593,11 +574,8 @@ static unsigned getUnnamedParamIndex(const ParamDecl *D) {
593574
}
594575

595576
static StringRef getPrivateDiscriminatorIfNecessary(const ValueDecl *decl) {
596-
if (!decl->hasAccess() ||
597-
decl->getFormalAccess() > AccessLevel::FilePrivate ||
598-
isInPrivateOrLocalContext(decl)) {
577+
if (!decl->isOutermostPrivateOrFilePrivateScope())
599578
return StringRef();
600-
}
601579

602580
// Mangle non-local private declarations with a textual discriminator
603581
// based on their enclosing file.

lib/AST/Decl.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,34 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
14331433
llvm_unreachable("bad access semantics");
14341434
}
14351435

1436+
static bool hasPrivateOrFilePrivateFormalAccess(const ValueDecl *D) {
1437+
return D->hasAccess() && D->getFormalAccess() <= AccessLevel::FilePrivate;
1438+
}
1439+
1440+
/// Returns true if one of the ancestor DeclContexts of this ValueDecl is either
1441+
/// marked private or fileprivate or is a local context.
1442+
static bool isInPrivateOrLocalContext(const ValueDecl *D) {
1443+
const DeclContext *DC = D->getDeclContext();
1444+
if (!DC->isTypeContext()) {
1445+
assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
1446+
"unexpected context kind");
1447+
return DC->isLocalContext();
1448+
}
1449+
1450+
auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
1451+
if (nominal == nullptr)
1452+
return false;
1453+
1454+
if (hasPrivateOrFilePrivateFormalAccess(nominal))
1455+
return true;
1456+
return isInPrivateOrLocalContext(nominal);
1457+
}
1458+
1459+
bool ValueDecl::isOutermostPrivateOrFilePrivateScope() const {
1460+
return hasPrivateOrFilePrivateFormalAccess(this) &&
1461+
!isInPrivateOrLocalContext(this);
1462+
}
1463+
14361464
bool AbstractStorageDecl::hasFixedLayout() const {
14371465
// If we're in a nominal type, just query the type.
14381466
auto *dc = getDeclContext();

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13951395
return nullptr;
13961396
}
13971397

1398+
/// The private discriminator is represented as an inline namespace.
1399+
llvm::DIScope *getFilePrivateScope(llvm::DIScope *Parent, TypeDecl *Decl) {
1400+
// Retrieve the private discriminator.
1401+
auto *MSC = Decl->getDeclContext()->getModuleScopeContext();
1402+
auto *FU = cast<FileUnit>(MSC);
1403+
Identifier PD = FU->getDiscriminatorForPrivateValue(Decl);
1404+
bool ExportSymbols = true;
1405+
return DBuilder.createNameSpace(Parent, PD.str(), ExportSymbols);
1406+
}
1407+
13981408
llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
13991409
// Is this an empty type?
14001410
if (DbgTy.isNull())
@@ -1438,6 +1448,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14381448
}
14391449
if (!Scope)
14401450
Scope = getOrCreateContext(Context);
1451+
1452+
// Scope outermost fileprivate decls in an inline private discriminator
1453+
// namespace.
1454+
if (auto *Decl = DbgTy.getDecl())
1455+
if (Decl->isOutermostPrivateOrFilePrivateScope())
1456+
Scope = getFilePrivateScope(Scope, Decl);
1457+
14411458
llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));
14421459

14431460
// Incrementally build the DIRefMap.
@@ -1518,9 +1535,9 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
15181535
CU_Nodes->addOperand(*CU);
15191536

15201537
// Create a module for the current compile unit.
1538+
auto *MDecl = IGM.getSwiftModule();
15211539
llvm::sys::path::remove_filename(AbsMainFile);
1522-
MainModule = getOrCreateModule(IGM.getSwiftModule(), TheCU, Opts.ModuleName,
1523-
AbsMainFile);
1540+
MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, AbsMainFile);
15241541
DBuilder.createImportedModule(MainFile, MainModule, MainFile, 0);
15251542

15261543
// Macro definitions that were defined by the user with "-Xcc -D" on the
Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,57 @@
11
// Private discriminators should only be emitted for multi-file projects.
22

3-
// RUN: %target-swift-frontend -emit-ir %s -g -o - | %FileCheck --check-prefix=SINGLE %s
3+
// RUN: %target-swift-frontend -emit-ir %s -g -o - \
4+
// RUN: | %FileCheck --check-prefix=SINGLE %s
45
// SINGLE-NOT: !DICompileUnit({{.*}}-private-discriminator
56

6-
// RUN: %target-swift-frontend %S/../Inputs/empty.swift -primary-file %s -emit-ir -g | %FileCheck %s
7+
// RUN: %target-swift-frontend %S/../Inputs/empty.swift -primary-file %s \
8+
// RUN: -emit-ir -g | %FileCheck %s
79
// CHECK: !DICompileUnit({{.*}}flags: {{[^,]*}}-private-discriminator [[DISCRIMINATOR:_[A-Z0-9]+]]
10+
// CHECK: ![[MOD:.*]] = !DIModule(scope: null,
11+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "InA",
12+
// CHECK-SAME: scope: ![[A:[0-9]+]],
13+
// CHECK: ![[A]] = !DICompositeType(tag: DW_TAG_structure_type, name: "A",
14+
// CHECK-SAME: scope: ![[NS:[0-9]+]]
15+
// CHECK: !DINamespace(name: "[[DISCRIMINATOR]]",
16+
// CHECK-SAME: scope: ![[OUTER:[0-9]+]], exportSymbols: true)
17+
// CHECK: ![[OUTER]] = !DICompositeType(tag: DW_TAG_structure_type,
18+
// CHECK-SAME: name: "Outer",
19+
// CHECK-SAME: scope: ![[MOD]],
820

921
func markUsed<T>(_ t: T) {}
1022

11-
private class A {
12-
init(val : Int64) { member = val }
13-
private let member : Int64
14-
// CHECK: !DISubprogram(name: "getMember"
15-
// CHECK-SAME: linkageName: "{{[^"]*}}[[DISCRIMINATOR]]
16-
// CHECK-SAME: line: [[@LINE+2]]
17-
// CHECK-SAME: isLocal: true, isDefinition: true
18-
private func getMember() -> Int64 { return member }
19-
func getVal() -> Int64 { return getMember() }
23+
public class Outer {
24+
fileprivate class A {
25+
fileprivate struct InA {
26+
let i : Int64
27+
init(_ val : Int64) { i = val }
28+
}
29+
30+
init(val : Int64) { member = InA(val) }
31+
fileprivate let member : InA
32+
// CHECK: !DISubprogram(name: "getMember"
33+
// CHECK-SAME: linkageName: "{{[^"]*}}[[DISCRIMINATOR]]
34+
// CHECK-SAME: line: [[@LINE+2]]
35+
// CHECK-SAME: isLocal: true, isDefinition: true
36+
fileprivate func getMember() -> Int64 { return member.i }
37+
}
2038
}
2139

22-
func f() {
23-
let a = A(val: 42)
24-
markUsed(a.getVal())
40+
// CHECK: ![[G:[0-9]+]] = distinct !DISubprogram(name: "g",
41+
// CHECK-SAME: scope: ![[MOD]]
42+
fileprivate func g() -> Int64 {
43+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "InG",
44+
// CHECK-SAME: scope: ![[G]],
45+
struct InG {
46+
let i : Int64
47+
init(_ val : Int64) { i = val }
48+
}
49+
50+
return InG(42).i
51+
}
52+
53+
// CHECK: distinct !DISubprogram(name: "f", {{.*}}, scope: ![[MOD]]
54+
public func f() {
55+
let a = Outer.A(val: g())
56+
markUsed(a)
2557
}

0 commit comments

Comments
 (0)