Skip to content

Commit bbfe7bb

Browse files
committed
[NFC] Add representations for DeclNameRef/Loc with module selector
1 parent cc75d6d commit bbfe7bb

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
@@ -162,10 +162,13 @@ BridgedDeclNameRef_createParsed(BridgedASTContext cContext,
162162

163163
class BridgedDeclNameLoc {
164164
const void *_Nullable LocationInfo;
165-
size_t NumArgumentLabels;
165+
uint32_t NumArgumentLabels;
166+
bool HasModuleSelectorLoc;
166167

167168
public:
168-
BridgedDeclNameLoc() : LocationInfo(nullptr), NumArgumentLabels(0) {}
169+
BridgedDeclNameLoc()
170+
: LocationInfo(nullptr), NumArgumentLabels(0), HasModuleSelectorLoc(false)
171+
{}
169172

170173
BRIDGED_INLINE BridgedDeclNameLoc(swift::DeclNameLoc loc);
171174

include/swift/AST/ASTBridgingImpl.h

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

6161
BridgedDeclNameLoc::BridgedDeclNameLoc(swift::DeclNameLoc loc)
6262
: LocationInfo(loc.LocationInfo),
63-
NumArgumentLabels(loc.NumArgumentLabels) {}
63+
NumArgumentLabels(loc.NumArgumentLabels),
64+
HasModuleSelectorLoc(loc.HasModuleSelectorLoc) {}
6465

6566
swift::DeclNameLoc BridgedDeclNameLoc::unbridged() const {
66-
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels);
67+
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels,
68+
HasModuleSelectorLoc);
6769
}
6870

6971
//===----------------------------------------------------------------------===//

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
@@ -738,39 +738,86 @@ void simple_display(llvm::raw_ostream &out, DeclName name);
738738
/// An in-source reference to another declaration, including qualification
739739
/// information.
740740
class DeclNameRef {
741-
DeclName FullName;
741+
friend class ASTContext;
742+
743+
/// Contains the name and module for a DeclNameRef with a module selector.
744+
struct alignas(Identifier) SelectiveDeclNameRef : llvm::FoldingSetNode {
745+
Identifier moduleSelector; // Note: currently can never be empty().
746+
DeclName fullName;
747+
748+
SelectiveDeclNameRef(Identifier moduleSelector, DeclName fullName)
749+
: moduleSelector(moduleSelector), fullName(fullName) { }
750+
751+
/// Uniquing for the ASTContext.
752+
static void Profile(llvm::FoldingSetNodeID &id, Identifier moduleSelector,
753+
DeclName fullName);
754+
755+
void Profile(llvm::FoldingSetNodeID &id) {
756+
Profile(id, moduleSelector, fullName);
757+
}
758+
759+
// Make vanilla new/delete illegal for SelectiveDeclNameRef.
760+
void * _Nullable operator new(size_t Bytes) = delete;
761+
void operator delete(void *_Nonnull Data) = delete;
762+
763+
// Only allow allocation of SelectiveDeclNameRef using the allocator
764+
// in ASTContext or by doing a placement new.
765+
void *_Nullable operator new(size_t Bytes, const ASTContext &C,
766+
unsigned Alignment = alignof(SelectiveDeclNameRef));
767+
void *_Nullable operator new(size_t Bytes, void *_Nonnull Mem) {
768+
assert(Mem);
769+
return Mem;
770+
}
771+
};
772+
773+
llvm::PointerUnion<DeclName, SelectiveDeclNameRef *> storage;
774+
775+
explicit DeclNameRef(void *_Nullable Opaque)
776+
: storage(decltype(storage)::getFromOpaqueValue(Opaque)) { }
777+
778+
void initialize(ASTContext &C, Identifier moduleScope, DeclName fullName);
742779

743780
public:
744781
static DeclNameRef createSubscript();
745782
static DeclNameRef createConstructor();
746783

747-
DeclNameRef() : FullName() { }
784+
DeclNameRef() : storage(DeclName()) { }
748785

749-
void *_Nullable getOpaqueValue() const { return FullName.getOpaqueValue(); }
786+
void *_Nullable getOpaqueValue() const {
787+
return storage.getOpaqueValue();
788+
}
750789
static DeclNameRef getFromOpaqueValue(void *_Nullable p);
751790

752791
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
753-
DeclName fullName)
754-
: FullName(fullName) { }
792+
DeclName fullName) {
793+
initialize(C, moduleSelector, fullName);
794+
}
755795

756796
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
757-
DeclBaseName baseName, ArrayRef<Identifier> argLabels)
758-
: FullName(C, baseName, argLabels) { }
797+
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
798+
initialize(C, moduleSelector, DeclName(C, baseName, argLabels));
799+
}
759800

760801
explicit DeclNameRef(DeclName FullName)
761-
: FullName(FullName) { }
802+
: storage(FullName) { }
762803

763804
bool hasModuleSelector() const {
764-
return false;
805+
return storage.is<SelectiveDeclNameRef *>();
765806
}
766807

767808
Identifier getModuleSelector() const {
768-
return Identifier();
809+
if (!hasModuleSelector())
810+
return Identifier();
811+
812+
return storage.get<SelectiveDeclNameRef *>()->moduleSelector;
769813
}
770814

771815
/// The name of the declaration being referenced.
772816
DeclName getFullName() const {
773-
return FullName;
817+
if (!hasModuleSelector())
818+
return storage.get<DeclName>();
819+
820+
return storage.get<SelectiveDeclNameRef *>()->fullName;
774821
}
775822

776823
/// The base name of the declaration being referenced.
@@ -885,7 +932,7 @@ class DeclNameRef {
885932
};
886933

887934
inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *_Nullable p) {
888-
return DeclNameRef(DeclName::getFromOpaqueValue(p));
935+
return DeclNameRef(p);
889936
}
890937

891938
inline DeclNameRef DeclNameRef::withoutArgumentLabels(ASTContext &C) const {
@@ -1069,7 +1116,7 @@ namespace llvm {
10691116
static inline swift::DeclNameRef getFromVoidPointer(void *_Nullable ptr) {
10701117
return swift::DeclNameRef::getFromOpaqueValue(ptr);
10711118
}
1072-
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable };
1119+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable - 1 };
10731120
};
10741121

10751122
// 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::DenseMap<unsigned, BuiltinUnboundGenericType*> BuiltinUnboundGenericTypes;
635635
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
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>
@@ -6183,6 +6184,44 @@ DeclName::DeclName(ASTContext &C, DeclBaseName baseName,
61836184
initialize(C, baseName, names);
61846185
}
61856186

6187+
// Only allow allocation of SelectiveDeclNameRefs using the allocator in
6188+
// ASTContext.
6189+
void *DeclNameRef::SelectiveDeclNameRef::
6190+
operator new(size_t Bytes, const ASTContext &C, unsigned Alignment) {
6191+
return C.Allocate(Bytes, Alignment);
6192+
}
6193+
6194+
void DeclNameRef::SelectiveDeclNameRef::Profile(llvm::FoldingSetNodeID &id,
6195+
Identifier moduleSelector,
6196+
DeclName fullName) {
6197+
assert(!moduleSelector.empty() &&
6198+
"Looking up SelectiveDeclNameRef with empty module?");
6199+
id.AddPointer(moduleSelector.getAsOpaquePointer());
6200+
id.AddPointer(fullName.getOpaqueValue());
6201+
}
6202+
6203+
void DeclNameRef::initialize(ASTContext &C, Identifier moduleSelector,
6204+
DeclName fullName) {
6205+
if (moduleSelector.empty()) {
6206+
storage = fullName;
6207+
return;
6208+
}
6209+
6210+
llvm::FoldingSetNodeID id;
6211+
SelectiveDeclNameRef::Profile(id, moduleSelector, fullName);
6212+
6213+
void *insert = nullptr;
6214+
if (SelectiveDeclNameRef *selectiveRef
6215+
= C.getImpl().SelectiveNameRefs.FindNodeOrInsertPos(id, insert)) {
6216+
storage = selectiveRef;
6217+
return;
6218+
}
6219+
6220+
auto selectiveRef = new (C) SelectiveDeclNameRef(moduleSelector, fullName);
6221+
storage = selectiveRef;
6222+
C.getImpl().SelectiveNameRefs.InsertNode(selectiveRef, insert);
6223+
}
6224+
61866225
/// Find the implementation of the named type in the given module.
61876226
static NominalTypeDecl *findUnderlyingTypeInModule(ASTContext &ctx,
61886227
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
@@ -10190,8 +10190,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1019010190
// high.
1019110191
if (auto *args = getArgumentList(memberLocator)) {
1019210192
SmallVector<Identifier, 4> scratch;
10193-
memberName.getFullName() = DeclName(ctx, memberName.getBaseName(),
10194-
args->getArgumentLabels(scratch));
10193+
memberName = memberName.withArgumentLabels(
10194+
ctx, args->getArgumentLabels(scratch));
1019510195
}
1019610196
}
1019710197

test/NameLookup/module_selector.swift

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

194194
func localVarsCantBeAccessedByModuleSelector() {
195195
let mag: Int.Swift::Magnitude = main::mag
196-
// expected-error@-1 {{use of local variable 'mag' before its declaration}}
196+
// expected-error@-1 {{use of local variable 'main::mag' before its declaration}}
197197
// expected-note@-2 {{'mag' declared here}}
198198

199199
let mog: Never = main::mog
@@ -256,8 +256,8 @@ func badModuleNames() {
256256
_ = "foo".NonexistentModule::count
257257

258258
let x: NonexistentModule::MyType = NonexistentModule::MyType()
259-
// expected-error@-1 {{cannot find type 'MyType' in scope}}
259+
// expected-error@-1 {{cannot find type 'NonexistentModule::MyType' in scope}}
260260

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

0 commit comments

Comments
 (0)