Skip to content

Commit 4b9a219

Browse files
committed
[NFC] Add DeclNameRef type to the compiler
This type wraps a DeclName, indicating that it is a reference to a declaration that exists somewhere else and it requires slightly “fuzzy” comparison (i.e. if it’s not compound, only the base names should be compared). DeclName::matchesRef() and MemberLookupTable::find() both now take a DeclNameRef instead of a DeclName. This commit temporarily allows implicit conversion from DeclName; I’ll flip the switch on that in a later commit.
1 parent 36b949c commit 4b9a219

File tree

8 files changed

+314
-12
lines changed

8 files changed

+314
-12
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,10 @@ class ASTPrinter {
188188
ASTPrinter &operator<<(unsigned long long N);
189189
ASTPrinter &operator<<(UUID UU);
190190

191+
ASTPrinter &operator<<(Identifier name);
192+
ASTPrinter &operator<<(DeclBaseName name);
191193
ASTPrinter &operator<<(DeclName name);
194+
ASTPrinter &operator<<(DeclNameRef name);
192195

193196
// Special case for 'char', but not arbitrary things that convert to 'char'.
194197
template <typename T>

include/swift/AST/Decl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,6 +2459,12 @@ class ValueDecl : public Decl {
24592459
/// names.
24602460
DeclBaseName getBaseName() const { return Name.getBaseName(); }
24612461

2462+
/// Generates a DeclNameRef referring to this declaration with as much
2463+
/// specificity as possible.
2464+
DeclNameRef createNameRef() const {
2465+
return DeclNameRef_(getFullName());
2466+
}
2467+
24622468
/// Retrieve the name to use for this declaration when interoperating
24632469
/// with the Objective-C runtime.
24642470
///

include/swift/AST/DiagnosticEngine.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ namespace swift {
105105
int IntegerVal;
106106
unsigned UnsignedVal;
107107
StringRef StringVal;
108-
DeclName IdentifierVal;
108+
DeclNameRef IdentifierVal;
109109
ObjCSelector ObjCSelectorVal;
110110
ValueDecl *TheValueDecl;
111111
Type TypeVal;
@@ -133,14 +133,20 @@ namespace swift {
133133
: Kind(DiagnosticArgumentKind::Unsigned), UnsignedVal(I) {
134134
}
135135

136+
DiagnosticArgument(DeclNameRef R)
137+
: Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(R) {}
138+
136139
DiagnosticArgument(DeclName D)
137-
: Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(D) {}
140+
: Kind(DiagnosticArgumentKind::Identifier),
141+
IdentifierVal(DeclNameRef_(D)) {}
138142

139143
DiagnosticArgument(DeclBaseName D)
140-
: Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(D) {}
144+
: Kind(DiagnosticArgumentKind::Identifier),
145+
IdentifierVal(DeclNameRef_(D)) {}
141146

142147
DiagnosticArgument(Identifier I)
143-
: Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(I) {
148+
: Kind(DiagnosticArgumentKind::Identifier),
149+
IdentifierVal(DeclNameRef_(I)) {
144150
}
145151

146152
DiagnosticArgument(ObjCSelector S)
@@ -225,7 +231,7 @@ namespace swift {
225231
return UnsignedVal;
226232
}
227233

228-
DeclName getAsIdentifier() const {
234+
DeclNameRef getAsIdentifier() const {
229235
assert(Kind == DiagnosticArgumentKind::Identifier);
230236
return IdentifierVal;
231237
}

include/swift/AST/Identifier.h

Lines changed: 221 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,15 @@ class Identifier {
188188
};
189189

190190
class DeclName;
191+
class DeclNameRef;
191192
class ObjCSelector;
192193

193194
} // end namespace swift
194195

195196
namespace llvm {
196197
raw_ostream &operator<<(raw_ostream &OS, swift::Identifier I);
197198
raw_ostream &operator<<(raw_ostream &OS, swift::DeclName I);
199+
raw_ostream &operator<<(raw_ostream &OS, swift::DeclNameRef I);
198200
raw_ostream &operator<<(raw_ostream &OS, swift::ObjCSelector S);
199201

200202
// Identifiers hash just like pointers.
@@ -546,7 +548,7 @@ class DeclName {
546548
// The names don't match.
547549
return false;
548550
}
549-
551+
550552
/// Add a DeclName to a lookup table so that it can be found by its simple
551553
/// name or its compound name.
552554
template<typename LookupTable, typename Element>
@@ -622,6 +624,193 @@ class DeclName {
622624

623625
void simple_display(llvm::raw_ostream &out, DeclName name);
624626

627+
/// An in-source reference to another declaration, including qualification
628+
/// information.
629+
class DeclNameRef {
630+
DeclName FullName;
631+
632+
public:
633+
static DeclNameRef createSubscript();
634+
static DeclNameRef createConstructor();
635+
636+
DeclNameRef() : FullName() { }
637+
638+
void *getOpaqueValue() const { return FullName.getOpaqueValue(); }
639+
static DeclNameRef getFromOpaqueValue(void *p);
640+
641+
// *** TRANSITIONAL CODE STARTS HERE ***
642+
643+
// We want all DeclNameRef constructions to be explicit, but they need to be
644+
// threaded through large portions of the compiler, so that would be
645+
// difficult. Instead, we will make uses of DeclNameRef(...) implicit but
646+
// deprecated, and use DeclNameRef_(...) as a stand-in for intentional calls
647+
// to the constructors. The deprecations and DeclNameRef_ function will go
648+
// away before we merge any of this into master.
649+
650+
[[deprecated]] DeclNameRef(DeclName FullName)
651+
: FullName(FullName) { }
652+
653+
[[deprecated]] DeclNameRef(DeclBaseName BaseName)
654+
: FullName(BaseName) { }
655+
656+
[[deprecated]] DeclNameRef(Identifier BaseName)
657+
: FullName(BaseName) { }
658+
659+
// *** TRANSITIONAL CODE ENDS HERE ***
660+
661+
/// The name of the declaration being referenced.
662+
DeclName getFullName() const {
663+
return FullName;
664+
}
665+
666+
DeclName &getFullName() {
667+
return FullName;
668+
}
669+
670+
/// The base name of the declaration being referenced.
671+
DeclBaseName getBaseName() const {
672+
return FullName.getBaseName();
673+
}
674+
675+
Identifier getBaseIdentifier() const {
676+
return FullName.getBaseIdentifier();
677+
}
678+
679+
ArrayRef<Identifier> getArgumentNames() const {
680+
return FullName.getArgumentNames();
681+
}
682+
683+
bool isSimpleName() const {
684+
return FullName.isSimpleName();
685+
}
686+
687+
bool isSimpleName(DeclBaseName name) const {
688+
return FullName.isSimpleName(name);
689+
}
690+
691+
bool isSimpleName(StringRef name) const {
692+
return FullName.isSimpleName(name);
693+
}
694+
695+
bool isSpecial() const {
696+
return FullName.isSpecial();
697+
}
698+
699+
bool isOperator() const {
700+
return FullName.isOperator();
701+
}
702+
703+
bool isCompoundName() const {
704+
return FullName.isCompoundName();
705+
}
706+
707+
explicit operator bool() const {
708+
return (bool)FullName;
709+
}
710+
711+
/// Compare two declaration names, producing -1 if \c *this comes before
712+
/// \c other, 1 if \c *this comes after \c other, and 0 if they are equal.
713+
///
714+
/// Null declaration names come after all other declaration names.
715+
int compare(DeclNameRef other) const {
716+
return getFullName().compare(other.getFullName());
717+
}
718+
719+
friend bool operator==(DeclNameRef lhs, DeclNameRef rhs) {
720+
return lhs.getOpaqueValue() == rhs.getOpaqueValue();
721+
}
722+
723+
friend bool operator!=(DeclNameRef lhs, DeclNameRef rhs) {
724+
return !(lhs == rhs);
725+
}
726+
727+
friend llvm::hash_code hash_value(DeclNameRef name) {
728+
using llvm::hash_value;
729+
return hash_value(name.getFullName().getOpaqueValue());
730+
}
731+
732+
friend bool operator<(DeclNameRef lhs, DeclNameRef rhs) {
733+
return lhs.compare(rhs) < 0;
734+
}
735+
736+
friend bool operator<=(DeclNameRef lhs, DeclNameRef rhs) {
737+
return lhs.compare(rhs) <= 0;
738+
}
739+
740+
friend bool operator>(DeclNameRef lhs, DeclNameRef rhs) {
741+
return lhs.compare(rhs) > 0;
742+
}
743+
744+
friend bool operator>=(DeclNameRef lhs, DeclNameRef rhs) {
745+
return lhs.compare(rhs) >= 0;
746+
}
747+
748+
DeclNameRef withoutArgumentLabels() const;
749+
DeclNameRef withArgumentLabels(ASTContext &C,
750+
ArrayRef<Identifier> argumentNames) const;
751+
752+
/// Get a string representation of the name,
753+
///
754+
/// \param scratch Scratch space to use.
755+
StringRef getString(llvm::SmallVectorImpl<char> &scratch,
756+
bool skipEmptyArgumentNames = false) const;
757+
758+
/// Print the representation of this declaration name to the given
759+
/// stream.
760+
///
761+
/// \param skipEmptyArgumentNames When true, don't print the argument labels
762+
/// if they are all empty.
763+
llvm::raw_ostream &print(llvm::raw_ostream &os,
764+
bool skipEmptyArgumentNames = false) const;
765+
766+
/// Print a "pretty" representation of this declaration name to the given
767+
/// stream.
768+
///
769+
/// This is the name used for diagnostics; it is not necessarily the
770+
/// fully-specified name that would be written in the source.
771+
llvm::raw_ostream &printPretty(llvm::raw_ostream &os) const;
772+
773+
/// Dump this name to standard error.
774+
LLVM_ATTRIBUTE_DEPRECATED(void dump() const LLVM_ATTRIBUTE_USED,
775+
"only for use within the debugger");
776+
};
777+
778+
// *** TRANSITIONAL CODE STARTS HERE ***
779+
780+
template<typename T>
781+
static DeclNameRef DeclNameRef_(T name) {
782+
#pragma clang diagnostic push
783+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
784+
return DeclNameRef(name);
785+
#pragma clang diagnostic pop
786+
}
787+
788+
// *** TRANSITIONAL CODE ENDS HERE ***
789+
790+
inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *p) {
791+
return DeclNameRef_(DeclName::getFromOpaqueValue(p));
792+
}
793+
794+
inline DeclNameRef DeclNameRef::withoutArgumentLabels() const {
795+
return DeclNameRef_(getBaseName());
796+
}
797+
798+
inline DeclNameRef DeclNameRef::withArgumentLabels(
799+
ASTContext &C, ArrayRef<Identifier> argumentNames) const {
800+
return DeclNameRef_(DeclName(C, getBaseName(), argumentNames));
801+
}
802+
803+
804+
inline DeclNameRef DeclNameRef::createSubscript() {
805+
return DeclNameRef_(DeclBaseName::createSubscript());
806+
}
807+
808+
inline DeclNameRef DeclNameRef::createConstructor() {
809+
return DeclNameRef_(DeclBaseName::createConstructor());
810+
}
811+
812+
void simple_display(llvm::raw_ostream &out, DeclNameRef name);
813+
625814
enum class ObjCSelectorFamily : unsigned {
626815
None,
627816
#define OBJC_SELECTOR_FAMILY(LABEL, PREFIX) LABEL,
@@ -766,6 +955,37 @@ namespace llvm {
766955
}
767956
};
768957

958+
// A DeclNameRef is "pointer like" just like DeclNames.
959+
template<typename T> struct PointerLikeTypeTraits;
960+
template<>
961+
struct PointerLikeTypeTraits<swift::DeclNameRef> {
962+
public:
963+
static inline void *getAsVoidPointer(swift::DeclNameRef name) {
964+
return name.getOpaqueValue();
965+
}
966+
static inline swift::DeclNameRef getFromVoidPointer(void *ptr) {
967+
return swift::DeclNameRef::getFromOpaqueValue(ptr);
968+
}
969+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable };
970+
};
971+
972+
// DeclNameRefs hash just like DeclNames.
973+
template<> struct DenseMapInfo<swift::DeclNameRef> {
974+
static swift::DeclNameRef getEmptyKey() {
975+
return DeclNameRef_(DenseMapInfo<swift::DeclName>::getEmptyKey());
976+
}
977+
static swift::DeclNameRef getTombstoneKey() {
978+
return DeclNameRef_(DenseMapInfo<swift::DeclName>::getTombstoneKey());
979+
}
980+
static unsigned getHashValue(swift::DeclNameRef Val) {
981+
return DenseMapInfo<swift::DeclName>::getHashValue(Val.getFullName());
982+
}
983+
static bool isEqual(swift::DeclNameRef LHS, swift::DeclNameRef RHS) {
984+
return DenseMapInfo<swift::DeclName>::isEqual(LHS.getFullName(),
985+
RHS.getFullName());
986+
}
987+
};
988+
769989
// An ObjCSelector is "pointer like".
770990
template<typename T> struct PointerLikeTypeTraits;
771991
template<>

include/swift/Parse/Parser.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,9 @@ struct ParsedDeclName {
16611661

16621662
/// Form a declaration name from this parsed declaration name.
16631663
DeclName formDeclName(ASTContext &ctx) const;
1664+
1665+
/// Form a declaration name from this parsed declaration name.
1666+
DeclNameRef formDeclNameRef(ASTContext &ctx) const;
16641667
};
16651668

16661669
/// Parse a stringified Swift declaration name,
@@ -1674,6 +1677,13 @@ DeclName formDeclName(ASTContext &ctx,
16741677
bool isFunctionName,
16751678
bool isInitializer);
16761679

1680+
/// Form a Swift declaration name referemce from its constituent parts.
1681+
DeclNameRef formDeclNameRef(ASTContext &ctx,
1682+
StringRef baseName,
1683+
ArrayRef<StringRef> argumentLabels,
1684+
bool isFunctionName,
1685+
bool isInitializer);
1686+
16771687
/// Parse a stringified Swift declaration name, e.g. "init(frame:)".
16781688
DeclName parseDeclName(ASTContext &ctx, StringRef name);
16791689

lib/AST/ASTPrinter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,14 @@ ASTPrinter &ASTPrinter::operator<<(UUID UU) {
334334
return *this;
335335
}
336336

337+
ASTPrinter &ASTPrinter::operator<<(Identifier name) {
338+
return *this << DeclName(name);
339+
}
340+
341+
ASTPrinter &ASTPrinter::operator<<(DeclBaseName name) {
342+
return *this << DeclName(name);
343+
}
344+
337345
ASTPrinter &ASTPrinter::operator<<(DeclName name) {
338346
llvm::SmallString<32> str;
339347
llvm::raw_svector_ostream os(str);
@@ -342,6 +350,14 @@ ASTPrinter &ASTPrinter::operator<<(DeclName name) {
342350
return *this;
343351
}
344352

353+
ASTPrinter &ASTPrinter::operator<<(DeclNameRef ref) {
354+
llvm::SmallString<32> str;
355+
llvm::raw_svector_ostream os(str);
356+
ref.print(os);
357+
printTextImpl(os.str());
358+
return *this;
359+
}
360+
345361
llvm::raw_ostream &swift::
346362
operator<<(llvm::raw_ostream &OS, tok keyword) {
347363
switch (keyword) {

0 commit comments

Comments
 (0)