Skip to content

Commit 7e81332

Browse files
committed
[NFC] Add representations for DeclNameRef/Loc with module selector
1 parent 6a7b1d3 commit 7e81332

File tree

8 files changed

+152
-46
lines changed

8 files changed

+152
-46
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,13 @@ BridgedDeclNameRef_createParsed(BridgedDeclBaseName cBaseName);
198198

199199
class BridgedDeclNameLoc {
200200
const void *_Nullable LocationInfo;
201-
size_t NumArgumentLabels;
201+
uint32_t NumArgumentLabels;
202+
bool HasModuleSelectorLoc;
202203

203204
public:
204-
BridgedDeclNameLoc() : LocationInfo(nullptr), NumArgumentLabels(0) {}
205+
BridgedDeclNameLoc()
206+
: LocationInfo(nullptr), NumArgumentLabels(0), HasModuleSelectorLoc(false)
207+
{}
205208

206209
BRIDGED_INLINE BridgedDeclNameLoc(swift::DeclNameLoc loc);
207210

include/swift/AST/ASTBridgingImpl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,12 @@ swift::DeclNameRef BridgedDeclNameRef::unbridged() const {
8787

8888
BridgedDeclNameLoc::BridgedDeclNameLoc(swift::DeclNameLoc loc)
8989
: LocationInfo(loc.LocationInfo),
90-
NumArgumentLabels(loc.NumArgumentLabels) {}
90+
NumArgumentLabels(loc.NumArgumentLabels),
91+
HasModuleSelectorLoc(loc.HasModuleSelectorLoc) {}
9192

9293
swift::DeclNameLoc BridgedDeclNameLoc::unbridged() const {
93-
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels);
94+
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels,
95+
HasModuleSelectorLoc);
9496
}
9597

9698
//===----------------------------------------------------------------------===//

include/swift/AST/DeclNameLoc.h

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,61 +35,69 @@ class DeclNameLoc {
3535

3636
/// Source location information.
3737
///
38-
/// If \c NumArgumentLabels == 0, this is the SourceLoc for the base name.
39-
/// Otherwise, it points to an array of SourceLocs, which contains:
38+
/// If \c NumArgumentLabels == 0 and \c !HasModuleSelectorLoc, this is the
39+
/// SourceLoc for the base name. Otherwise, it points to an array of
40+
/// SourceLocs, which contains:
4041
/// * The base name location
42+
/// * The module selector location
4143
/// * The left parentheses location
4244
/// * The right parentheses location
4345
/// * The locations of each of the argument labels.
4446
const void *LocationInfo;
4547

4648
/// The number of argument labels stored in the name.
47-
unsigned NumArgumentLabels;
49+
uint32_t NumArgumentLabels;
50+
bool HasModuleSelectorLoc;
4851

4952
enum {
5053
BaseNameIndex = 0,
51-
LParenIndex = 1,
52-
RParenIndex = 2,
53-
FirstArgumentLabelIndex = 3,
54+
ModuleSelectorIndex = 1,
55+
LParenIndex = 2,
56+
RParenIndex = 3,
57+
FirstArgumentLabelIndex = 4,
5458
};
5559

5660
/// Retrieve a pointer to either the only source location that was
5761
/// stored or to the array of source locations that was stored.
5862
SourceLoc const * getSourceLocs() const {
59-
if (NumArgumentLabels == 0)
63+
if (NumArgumentLabels == 0 && !HasModuleSelectorLoc)
6064
return reinterpret_cast<SourceLoc const *>(&LocationInfo);
6165

6266
return reinterpret_cast<SourceLoc const *>(LocationInfo);
6367
}
6468

65-
DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels)
66-
: LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels) {}
69+
DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels,
70+
bool HasModuleSelectorLoc)
71+
: LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels),
72+
HasModuleSelectorLoc(HasModuleSelectorLoc) {}
6773

6874
public:
6975
/// Create an invalid declaration name location.
70-
DeclNameLoc() : DeclNameLoc(nullptr, 0) {}
76+
DeclNameLoc() : DeclNameLoc(nullptr, 0, false) {}
7177

7278
/// Create declaration name location information for a base name.
7379
explicit DeclNameLoc(SourceLoc baseNameLoc)
74-
: DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0) {}
80+
: DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0, false) {}
7581

7682
explicit DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
7783
SourceLoc baseNameLoc)
78-
: DeclNameLoc(baseNameLoc) { }
84+
: DeclNameLoc(ctx, moduleSelectorLoc, baseNameLoc,
85+
SourceLoc(), {}, SourceLoc()) { }
7986

8087
/// Create declaration name location information for a compound
8188
/// name.
8289
DeclNameLoc(ASTContext &ctx, SourceLoc baseNameLoc,
8390
SourceLoc lParenLoc,
8491
ArrayRef<SourceLoc> argumentLabelLocs,
85-
SourceLoc rParenLoc);
92+
SourceLoc rParenLoc)
93+
: DeclNameLoc(ctx, SourceLoc(), baseNameLoc,
94+
lParenLoc, argumentLabelLocs, rParenLoc) { }
8695

8796
DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
8897
SourceLoc baseNameLoc,
8998
SourceLoc lParenLoc,
9099
ArrayRef<SourceLoc> argumentLabelLocs,
91-
SourceLoc rParenLoc)
92-
: DeclNameLoc(ctx, baseNameLoc, lParenLoc, argumentLabelLocs, rParenLoc) { }
100+
SourceLoc rParenLoc);
93101

94102
/// Whether the location information is valid.
95103
bool isValid() const { return getBaseNameLoc().isValid(); }
@@ -125,11 +133,12 @@ class DeclNameLoc {
125133
}
126134

127135
SourceLoc getModuleSelectorLoc() const {
128-
return SourceLoc();
136+
if (!HasModuleSelectorLoc) return SourceLoc();
137+
return getSourceLocs()[ModuleSelectorIndex];
129138
}
130139

131140
SourceLoc getStartLoc() const {
132-
return getBaseNameLoc();
141+
return HasModuleSelectorLoc ? getModuleSelectorLoc() : getBaseNameLoc();
133142
}
134143

135144
SourceLoc getEndLoc() const {
@@ -138,9 +147,7 @@ class DeclNameLoc {
138147

139148
/// Retrieve the complete source range for this declaration name.
140149
SourceRange getSourceRange() const {
141-
if (NumArgumentLabels == 0) return getBaseNameLoc();
142-
143-
return SourceRange(getBaseNameLoc(), getRParenLoc());
150+
return SourceRange(getStartLoc(), getEndLoc());
144151
}
145152
};
146153

include/swift/AST/Identifier.h

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -682,39 +682,86 @@ void simple_display(llvm::raw_ostream &out, DeclName name);
682682
/// An in-source reference to another declaration, including qualification
683683
/// information.
684684
class DeclNameRef {
685-
DeclName FullName;
685+
friend class ASTContext;
686+
687+
/// Contains the name and module for a DeclNameRef with a module selector.
688+
struct alignas(Identifier) SelectiveDeclNameRef : llvm::FoldingSetNode {
689+
Identifier moduleSelector; // Note: currently can never be empty().
690+
DeclName fullName;
691+
692+
SelectiveDeclNameRef(Identifier moduleSelector, DeclName fullName)
693+
: moduleSelector(moduleSelector), fullName(fullName) { }
694+
695+
/// Uniquing for the ASTContext.
696+
static void Profile(llvm::FoldingSetNodeID &id, Identifier moduleSelector,
697+
DeclName fullName);
698+
699+
void Profile(llvm::FoldingSetNodeID &id) {
700+
Profile(id, moduleSelector, fullName);
701+
}
702+
703+
// Make vanilla new/delete illegal for SelectiveDeclNameRef.
704+
void *operator new(size_t Bytes) = delete;
705+
void operator delete(void *Data) = delete;
706+
707+
// Only allow allocation of SelectiveDeclNameRef using the allocator
708+
// in ASTContext or by doing a placement new.
709+
void *operator new(size_t Bytes, const ASTContext &C,
710+
unsigned Alignment = alignof(SelectiveDeclNameRef));
711+
void *operator new(size_t Bytes, void *Mem) {
712+
assert(Mem);
713+
return Mem;
714+
}
715+
};
716+
717+
llvm::PointerUnion<DeclName, SelectiveDeclNameRef *> storage;
718+
719+
explicit DeclNameRef(void *Opaque)
720+
: storage(decltype(storage)::getFromOpaqueValue(Opaque)) { }
721+
722+
void initialize(ASTContext &C, Identifier moduleScope, DeclName fullName);
686723

687724
public:
688725
static DeclNameRef createSubscript();
689726
static DeclNameRef createConstructor();
690727

691-
DeclNameRef() : FullName() { }
728+
DeclNameRef() : storage(DeclName()) { }
692729

693-
void *getOpaqueValue() const { return FullName.getOpaqueValue(); }
730+
void *getOpaqueValue() const {
731+
return storage.getOpaqueValue();
732+
}
694733
static DeclNameRef getFromOpaqueValue(void *p);
695734

696735
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
697-
DeclName fullName)
698-
: FullName(fullName) { }
736+
DeclName fullName) {
737+
initialize(C, moduleSelector, fullName);
738+
}
699739

700740
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
701-
DeclBaseName baseName, ArrayRef<Identifier> argLabels)
702-
: FullName(C, baseName, argLabels) { }
741+
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
742+
initialize(C, moduleSelector, DeclName(C, baseName, argLabels));
743+
}
703744

704745
explicit DeclNameRef(DeclName FullName)
705-
: FullName(FullName) { }
746+
: storage(FullName) { }
706747

707748
bool hasModuleSelector() const {
708-
return false;
749+
return storage.is<SelectiveDeclNameRef *>();
709750
}
710751

711752
Identifier getModuleSelector() const {
712-
return Identifier();
753+
if (!hasModuleSelector())
754+
return Identifier();
755+
756+
return storage.get<SelectiveDeclNameRef *>()->moduleSelector;
713757
}
714758

715759
/// The name of the declaration being referenced.
716760
DeclName getFullName() const {
717-
return FullName;
761+
if (!hasModuleSelector())
762+
return storage.get<DeclName>();
763+
764+
return storage.get<SelectiveDeclNameRef *>()->fullName;
718765
}
719766

720767
/// The base name of the declaration being referenced.
@@ -829,7 +876,7 @@ class DeclNameRef {
829876
};
830877

831878
inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *p) {
832-
return DeclNameRef(DeclName::getFromOpaqueValue(p));
879+
return DeclNameRef(p);
833880
}
834881

835882
inline DeclNameRef DeclNameRef::withoutArgumentLabels(ASTContext &C) const {
@@ -1013,7 +1060,7 @@ namespace llvm {
10131060
static inline swift::DeclNameRef getFromVoidPointer(void *ptr) {
10141061
return swift::DeclNameRef::getFromOpaqueValue(ptr);
10151062
}
1016-
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable };
1063+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable - 1 };
10171064
};
10181065

10191066
// DeclNameRefs hash just like DeclNames.

lib/AST/ASTContext.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ struct ASTContext::Implementation {
634634
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
635635
llvm::FoldingSet<BuiltinFixedArrayType> BuiltinFixedArrayTypes;
636636
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
637+
llvm::FoldingSet<DeclNameRef::SelectiveDeclNameRef> SelectiveNameRefs;
637638
llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
638639
llvm::FoldingSet<IndexSubset> IndexSubsets;
639640
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -6148,6 +6149,44 @@ DeclName::DeclName(ASTContext &C, DeclBaseName baseName,
61486149
initialize(C, baseName, names);
61496150
}
61506151

6152+
// Only allow allocation of SelectiveDeclNameRefs using the allocator in
6153+
// ASTContext.
6154+
void *DeclNameRef::SelectiveDeclNameRef::
6155+
operator new(size_t Bytes, const ASTContext &C, unsigned Alignment) {
6156+
return C.Allocate(Bytes, Alignment);
6157+
}
6158+
6159+
void DeclNameRef::SelectiveDeclNameRef::Profile(llvm::FoldingSetNodeID &id,
6160+
Identifier moduleSelector,
6161+
DeclName fullName) {
6162+
assert(!moduleSelector.empty() &&
6163+
"Looking up SelectiveDeclNameRef with empty module?");
6164+
id.AddPointer(moduleSelector.getAsOpaquePointer());
6165+
id.AddPointer(fullName.getOpaqueValue());
6166+
}
6167+
6168+
void DeclNameRef::initialize(ASTContext &C, Identifier moduleSelector,
6169+
DeclName fullName) {
6170+
if (moduleSelector.empty()) {
6171+
storage = fullName;
6172+
return;
6173+
}
6174+
6175+
llvm::FoldingSetNodeID id;
6176+
SelectiveDeclNameRef::Profile(id, moduleSelector, fullName);
6177+
6178+
void *insert = nullptr;
6179+
if (SelectiveDeclNameRef *selectiveRef
6180+
= C.getImpl().SelectiveNameRefs.FindNodeOrInsertPos(id, insert)) {
6181+
storage = selectiveRef;
6182+
return;
6183+
}
6184+
6185+
auto selectiveRef = new (C) SelectiveDeclNameRef(moduleSelector, fullName);
6186+
storage = selectiveRef;
6187+
C.getImpl().SelectiveNameRefs.InsertNode(selectiveRef, insert);
6188+
}
6189+
61516190
/// Find the implementation of the named type in the given module.
61526191
static NominalTypeDecl *findUnderlyingTypeInModule(ASTContext &ctx,
61536192
Identifier name,

lib/AST/DeclNameLoc.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,24 @@
2020

2121
using namespace swift;
2222

23-
DeclNameLoc::DeclNameLoc(ASTContext &ctx, SourceLoc baseNameLoc,
23+
DeclNameLoc::DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
24+
SourceLoc baseNameLoc,
2425
SourceLoc lParenLoc,
2526
ArrayRef<SourceLoc> argumentLabelLocs,
2627
SourceLoc rParenLoc)
27-
: NumArgumentLabels(argumentLabelLocs.size()) {
28-
assert(NumArgumentLabels > 0 && "Use other constructor");
28+
: NumArgumentLabels(argumentLabelLocs.size()),
29+
HasModuleSelectorLoc(moduleSelectorLoc.isValid())
30+
{
31+
if (NumArgumentLabels == 0 && !HasModuleSelectorLoc) {
32+
LocationInfo = baseNameLoc.getOpaquePointerValue();
33+
return;
34+
}
2935

3036
// Copy the location information into permanent storage.
31-
auto storedLocs = ctx.Allocate<SourceLoc>(NumArgumentLabels + 3);
37+
auto storedLocs =
38+
ctx.Allocate<SourceLoc>(FirstArgumentLabelIndex + NumArgumentLabels);
3239
storedLocs[BaseNameIndex] = baseNameLoc;
40+
storedLocs[ModuleSelectorIndex] = moduleSelectorLoc;
3341
storedLocs[LParenIndex] = lParenLoc;
3442
storedLocs[RParenIndex] = rParenLoc;
3543
std::memcpy(storedLocs.data() + FirstArgumentLabelIndex,

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10109,8 +10109,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1010910109
// high.
1011010110
if (auto *args = getArgumentList(memberLocator)) {
1011110111
SmallVector<Identifier, 4> scratch;
10112-
memberName.getFullName() = DeclName(ctx, memberName.getBaseName(),
10113-
args->getArgumentLabels(scratch));
10112+
memberName = memberName.withArgumentLabels(
10113+
ctx, args->getArgumentLabels(scratch));
1011410114
}
1011510115
}
1011610116

test/NameLookup/module_selector.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ let mog: Never = fatalError()
199199

200200
func localVarsCantBeAccessedByModuleSelector() {
201201
let mag: Int.Swift::Magnitude = main::mag
202-
// expected-error@-1 {{use of local variable 'mag' before its declaration}}
202+
// expected-error@-1 {{use of local variable 'main::mag' before its declaration}}
203203
// expected-note@-2 {{'mag' declared here}}
204204

205205
let mog: Never = main::mog
@@ -399,10 +399,10 @@ func badModuleNames() {
399399
_ = "foo".NonexistentModule::count
400400

401401
let x: NonexistentModule::MyType = NonexistentModule::MyType()
402-
// expected-error@-1 {{cannot find type 'MyType' in scope}}
402+
// expected-error@-1 {{cannot find type 'NonexistentModule::MyType' in scope}}
403403

404404
let y: A.NonexistentModule::MyChildType = fatalError()
405-
// expected-error@-1 {{'MyChildType' is not a member type of struct 'ModuleSelectorTestingKit.A'}}
405+
// expected-error@-1 {{'NonexistentModule::MyChildType' is not a member type of struct 'ModuleSelectorTestingKit.A'}}
406406
}
407407

408408
struct BadModuleSelectorSyntax { // expected-note {{in declaration of 'BadModuleSelectorSyntax'}}

0 commit comments

Comments
 (0)