Skip to content

Commit 64d8b70

Browse files
committed
Make DeclNameRef able to store a module selector
In this commit, this change affects certain diagnostics but doesn’t actually alter name lookup behavior yet.
1 parent 4991bf9 commit 64d8b70

File tree

8 files changed

+137
-47
lines changed

8 files changed

+137
-47
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,13 @@ BridgedDeclNameRef_createParsed(BridgedASTContext cContext,
164164

165165
class BridgedDeclNameLoc {
166166
const void *_Nullable LocationInfo;
167-
size_t NumArgumentLabels;
167+
uint32_t NumArgumentLabels;
168+
bool HasModuleSelectorLoc;
168169

169170
public:
170-
BridgedDeclNameLoc() : LocationInfo(nullptr), NumArgumentLabels(0) {}
171+
BridgedDeclNameLoc()
172+
: LocationInfo(nullptr), NumArgumentLabels(0), HasModuleSelectorLoc(false)
173+
{}
171174

172175
BRIDGED_INLINE BridgedDeclNameLoc(swift::DeclNameLoc loc);
173176

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: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -738,39 +738,75 @@ 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+
friend struct llvm::PointerLikeTypeTraits<DeclNameRef>;
743+
744+
/// Contains the name and module for a DeclNameRef with a module selector.
745+
struct alignas(Identifier) SelectiveDeclNameRef : llvm::FoldingSetNode {
746+
Identifier moduleSelector; // Note: currently can never be empty().
747+
DeclName fullName;
748+
749+
SelectiveDeclNameRef(Identifier moduleSelector, DeclName fullName)
750+
: moduleSelector(moduleSelector), fullName(fullName) { }
751+
752+
/// Uniquing for the ASTContext.
753+
static void Profile(llvm::FoldingSetNodeID &id, Identifier moduleSelector,
754+
DeclName fullName);
755+
756+
void Profile(llvm::FoldingSetNodeID &id) {
757+
Profile(id, moduleSelector, fullName);
758+
}
759+
};
760+
761+
using Storage = llvm::PointerUnion<DeclName, SelectiveDeclNameRef *>;
762+
Storage storage;
763+
764+
explicit DeclNameRef(void *_Nullable Opaque)
765+
: storage(decltype(storage)::getFromOpaqueValue(Opaque)) { }
766+
767+
void initialize(ASTContext &C, Identifier moduleScope, DeclName fullName);
742768

743769
public:
744770
static DeclNameRef createSubscript();
745771
static DeclNameRef createConstructor();
746772

747-
DeclNameRef() : FullName() { }
773+
DeclNameRef() : storage(DeclName()) { }
748774

749-
void *_Nullable getOpaqueValue() const { return FullName.getOpaqueValue(); }
775+
void *_Nullable getOpaqueValue() const {
776+
return storage.getOpaqueValue();
777+
}
750778
static DeclNameRef getFromOpaqueValue(void *_Nullable p);
751779

752780
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
753-
DeclName fullName)
754-
: FullName(fullName) { }
781+
DeclName fullName) {
782+
initialize(C, moduleSelector, fullName);
783+
}
755784

756785
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
757-
DeclBaseName baseName, ArrayRef<Identifier> argLabels)
758-
: FullName(C, baseName, argLabels) { }
786+
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
787+
initialize(C, moduleSelector, DeclName(C, baseName, argLabels));
788+
}
759789

760790
explicit DeclNameRef(DeclName FullName)
761-
: FullName(FullName) { }
791+
: storage(FullName) { }
762792

763793
bool hasModuleSelector() const {
764-
return false;
794+
return isa<SelectiveDeclNameRef *>(storage);
765795
}
766796

767797
Identifier getModuleSelector() const {
768-
return Identifier();
798+
if (!hasModuleSelector())
799+
return Identifier();
800+
801+
return cast<SelectiveDeclNameRef *>(storage)->moduleSelector;
769802
}
770803

771804
/// The name of the declaration being referenced.
772805
DeclName getFullName() const {
773-
return FullName;
806+
if (!hasModuleSelector())
807+
return cast<DeclName>(storage);
808+
809+
return cast<SelectiveDeclNameRef *>(storage)->fullName;
774810
}
775811

776812
/// The base name of the declaration being referenced.
@@ -885,7 +921,7 @@ class DeclNameRef {
885921
};
886922

887923
inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *_Nullable p) {
888-
return DeclNameRef(DeclName::getFromOpaqueValue(p));
924+
return DeclNameRef(p);
889925
}
890926

891927
inline DeclNameRef DeclNameRef::withoutArgumentLabels(ASTContext &C) const {
@@ -1059,7 +1095,6 @@ namespace llvm {
10591095
};
10601096

10611097
// A DeclNameRef is "pointer like" just like DeclNames.
1062-
template<typename T> struct PointerLikeTypeTraits;
10631098
template<>
10641099
struct PointerLikeTypeTraits<swift::DeclNameRef> {
10651100
public:
@@ -1069,7 +1104,7 @@ namespace llvm {
10691104
static inline swift::DeclNameRef getFromVoidPointer(void *_Nullable ptr) {
10701105
return swift::DeclNameRef::getFromOpaqueValue(ptr);
10711106
}
1072-
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable };
1107+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclNameRef::Storage>::NumLowBitsAvailable };
10731108
};
10741109

10751110
// DeclNameRefs hash just like DeclNames.

lib/AST/ASTContext.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ struct ASTContext::Implementation {
641641
llvm::DenseMap<unsigned, BuiltinUnboundGenericType*> BuiltinUnboundGenericTypes;
642642
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
643643
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
644+
llvm::FoldingSet<DeclNameRef::SelectiveDeclNameRef> SelectiveNameRefs;
644645
llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
645646
llvm::FoldingSet<IndexSubset> IndexSubsets;
646647
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -6233,6 +6234,39 @@ DeclName::DeclName(ASTContext &C, DeclBaseName baseName,
62336234
initialize(C, baseName, names);
62346235
}
62356236

6237+
void DeclNameRef::SelectiveDeclNameRef::Profile(llvm::FoldingSetNodeID &id,
6238+
Identifier moduleSelector,
6239+
DeclName fullName) {
6240+
ASSERT(!moduleSelector.empty() &&
6241+
"Looking up SelectiveDeclNameRef with empty module?");
6242+
id.AddPointer(moduleSelector.getAsOpaquePointer());
6243+
id.AddPointer(fullName.getOpaqueValue());
6244+
}
6245+
6246+
void DeclNameRef::initialize(ASTContext &C, Identifier moduleSelector,
6247+
DeclName fullName) {
6248+
if (moduleSelector.empty()) {
6249+
storage = fullName;
6250+
return;
6251+
}
6252+
6253+
llvm::FoldingSetNodeID id;
6254+
SelectiveDeclNameRef::Profile(id, moduleSelector, fullName);
6255+
6256+
void *insert = nullptr;
6257+
if (SelectiveDeclNameRef *selectiveRef
6258+
= C.getImpl().SelectiveNameRefs.FindNodeOrInsertPos(id, insert)) {
6259+
storage = selectiveRef;
6260+
return;
6261+
}
6262+
6263+
auto buf = C.Allocate(sizeof(SelectiveDeclNameRef),
6264+
alignof(SelectiveDeclNameRef));
6265+
auto selectiveRef = new (buf) SelectiveDeclNameRef(moduleSelector, fullName);
6266+
storage = selectiveRef;
6267+
C.getImpl().SelectiveNameRefs.InsertNode(selectiveRef, insert);
6268+
}
6269+
62366270
/// Find the implementation of the named type in the given module.
62376271
static NominalTypeDecl *findUnderlyingTypeInModule(ASTContext &ctx,
62386272
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
@@ -10278,8 +10278,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1027810278
// high.
1027910279
if (auto *args = getArgumentList(memberLocator)) {
1028010280
SmallVector<Identifier, 4> scratch;
10281-
memberName.getFullName() = DeclName(ctx, memberName.getBaseName(),
10282-
args->getArgumentLabels(scratch));
10281+
memberName = memberName.withArgumentLabels(
10282+
ctx, args->getArgumentLabels(scratch));
1028310283
}
1028410284
}
1028510285

test/NameLookup/module_selector.swift

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

205205
func localVarsCantBeAccessedByModuleSelector() {
206206
let mag: Int.Swift::Magnitude = main::mag
207-
// expected-error@-1 {{use of local variable 'mag' before its declaration}}
207+
// expected-error@-1 {{use of local variable 'main::mag' before its declaration}}
208208
// expected-note@-2 {{'mag' declared here}}
209209

210210
let mog: Never = main::mog
@@ -267,8 +267,9 @@ func badModuleNames() {
267267
_ = "foo".NonexistentModule::count
268268

269269
let x: NonexistentModule::MyType = NonexistentModule::MyType()
270-
// expected-error@-1 {{cannot find type 'MyType' in scope}}
270+
// expected-error@-1 {{cannot find type 'NonexistentModule::MyType' in scope}}
271+
// expected-error@-2 {{cannot find 'NonexistentModule::MyType' in scope}}
271272

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

0 commit comments

Comments
 (0)