mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Separate underlying storage and location kind in SILLocation and
remove the mixed concept that was SILFileLocation. Also add support for a third type of underlying storage that will be used for deserialized debug lcoations from textual SIL. NFC <rdar://problem/22706994>
This commit is contained in:
@@ -65,7 +65,7 @@ private:
|
||||
typedef llvm::PointerUnion4<Stmt*, Expr*, Decl*, Pattern*> ASTNodeTy;
|
||||
|
||||
public:
|
||||
enum LocationKind {
|
||||
enum LocationKind : unsigned {
|
||||
// FIXME: NoneKind is to be removed.
|
||||
NoneKind = 0,
|
||||
RegularKind = 1,
|
||||
@@ -74,29 +74,53 @@ public:
|
||||
InlinedKind = 4,
|
||||
MandatoryInlinedKind = 5,
|
||||
CleanupKind = 6,
|
||||
ArtificialUnreachableKind = 7,
|
||||
SILFileKind = 8
|
||||
ArtificialUnreachableKind = 7
|
||||
};
|
||||
|
||||
protected:
|
||||
/// Primary AST location, always used for diagnostics.
|
||||
ASTNodeTy ASTNode;
|
||||
enum StorageKind : unsigned {
|
||||
UnknownKind = 0,
|
||||
ASTNodeKind = 1 << 3,
|
||||
SILFileKind = 1 << 4,
|
||||
DebugInfoKind = 1 << 3 | 1 << 4
|
||||
};
|
||||
|
||||
union SpecificLoc {
|
||||
SpecificLoc() : DebugLoc() {}
|
||||
/// If coming from a .sil file, this is the location in the .sil file.
|
||||
SourceLoc SILFileSourceLoc;
|
||||
typedef struct {
|
||||
unsigned Line = 0, Col = 0;
|
||||
const char *Filename = nullptr;
|
||||
} DebugLoc;
|
||||
|
||||
protected:
|
||||
union UnderlyingLocation {
|
||||
UnderlyingLocation() : DebugInfoLoc({}) {}
|
||||
UnderlyingLocation(ASTNodeTy N) : ASTNode(N) {}
|
||||
UnderlyingLocation(SourceLoc L) : SILFileLoc(L) {}
|
||||
struct ASTNodeLoc {
|
||||
ASTNodeLoc(ASTNodeTy N) : Primary(N) {}
|
||||
/// Primary AST location, always used for diagnostics.
|
||||
ASTNodeTy Primary;
|
||||
/// Sometimes the location for diagnostics needs to be
|
||||
/// different than the one used to emit the line table. If
|
||||
/// HasDebugLoc is set, this is used for the debug info.
|
||||
ASTNodeTy DebugLoc;
|
||||
} SpecificLoc;
|
||||
ASTNodeTy ForDebugger;
|
||||
} ASTNode;
|
||||
|
||||
/// A location inside a textual .sil file.
|
||||
SourceLoc SILFileLoc;
|
||||
|
||||
/// A deserialized source location.
|
||||
DebugLoc DebugInfoLoc;
|
||||
} Loc;
|
||||
|
||||
/// The kind of this SIL location.
|
||||
unsigned KindData;
|
||||
|
||||
enum {
|
||||
BaseBits = 4, BaseMask = 0xF,
|
||||
LocationKindBits = 3,
|
||||
LocationKindMask = 7,
|
||||
|
||||
StorageKindBits = 2,
|
||||
StorageKindMask = (1 << 3) | (1 << 4),
|
||||
SpecialFlagsMask = ~ (LocationKindMask | StorageKindMask),
|
||||
|
||||
/// Used to mark this instruction as part of auto-generated
|
||||
/// code block.
|
||||
@@ -106,7 +130,8 @@ protected:
|
||||
/// represent this SILLocation. For example, when the host instruction
|
||||
/// is known to correspond to the beginning or the end of the source
|
||||
/// range of the ASTNode.
|
||||
PointsToStartBit = 6, PointsToEndBit = 7,
|
||||
PointsToStartBit = 6,
|
||||
PointsToEndBit = 7,
|
||||
|
||||
/// Used to notify that this instruction belongs to the top-
|
||||
/// level (module) scope.
|
||||
@@ -115,14 +140,7 @@ protected:
|
||||
IsInTopLevel = 8,
|
||||
|
||||
/// Marks this instruction as belonging to the function prologue.
|
||||
IsInPrologue = 9,
|
||||
|
||||
/// Indicates that SILFileSourceLoc is present.
|
||||
HasSILFileSourceLoc = 10,
|
||||
|
||||
/// Indicates that DebugLoc should be used for emitting debug info.
|
||||
HasDebugLoc = 11
|
||||
|
||||
IsInPrologue = 9
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -133,7 +151,8 @@ protected:
|
||||
|
||||
template <typename T>
|
||||
bool isNode(ASTNodeTy Node) const {
|
||||
if (ASTNode.is<typename base_type<T>::type*>())
|
||||
assert(isASTNode());
|
||||
if (Loc.ASTNode.Primary.is<typename base_type<T>::type*>())
|
||||
return isa<T>(Node.get<typename base_type<T>::type*>());
|
||||
return false;
|
||||
}
|
||||
@@ -147,22 +166,40 @@ protected:
|
||||
/// @{
|
||||
|
||||
/// This constructor is used to support getAs operation.
|
||||
SILLocation() {}
|
||||
|
||||
SILLocation(LocationKind K, unsigned Flags = 0)
|
||||
: KindData(unsigned(K) | Flags) {}
|
||||
SILLocation() { assert(Loc.DebugInfoLoc.Line == 0); }
|
||||
SILLocation(LocationKind K, unsigned Flags = 0) : KindData(K | Flags) {
|
||||
assert(Loc.DebugInfoLoc.Line == 0);
|
||||
}
|
||||
|
||||
SILLocation(Stmt *S, LocationKind K, unsigned Flags = 0)
|
||||
: ASTNode(S), KindData(unsigned(K) | Flags) {}
|
||||
: Loc(S), KindData(K | Flags) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
|
||||
SILLocation(Expr *E, LocationKind K, unsigned Flags = 0)
|
||||
: ASTNode(E), KindData(unsigned(K) | Flags) {}
|
||||
: Loc(E), KindData(K | Flags) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
|
||||
SILLocation(Decl *D, LocationKind K, unsigned Flags = 0)
|
||||
: ASTNode(D), KindData(unsigned(K) | Flags) {}
|
||||
: Loc(D), KindData(K | Flags) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
|
||||
SILLocation(Pattern *P, LocationKind K, unsigned Flags = 0)
|
||||
: ASTNode(P), KindData(unsigned(K) | Flags) {}
|
||||
: Loc(P), KindData(K | Flags) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
|
||||
SILLocation(SourceLoc L, LocationKind K, unsigned Flags = 0)
|
||||
: Loc(L), KindData(K | Flags) {
|
||||
setStorageKind(SILFileKind);
|
||||
assert(isSILFile());
|
||||
}
|
||||
/// @}
|
||||
|
||||
private:
|
||||
@@ -171,9 +208,12 @@ private:
|
||||
friend class InlinedLocation;
|
||||
friend class CleanupLocation;
|
||||
|
||||
void setKind(LocationKind K) { KindData |= (K & BaseMask); }
|
||||
unsigned getSpecialFlags() const { return unsigned(KindData) & ~BaseMask; }
|
||||
void setSpecialFlags(unsigned Flags) { KindData |= (Flags & ~BaseMask); }
|
||||
void setLocationKind(LocationKind K) { KindData |= (K & LocationKindMask); }
|
||||
void setStorageKind(StorageKind K) { KindData |= (K & StorageKindMask); }
|
||||
unsigned getSpecialFlags() const { return KindData & SpecialFlagsMask; }
|
||||
void setSpecialFlags(unsigned Flags) {
|
||||
KindData |= (Flags & SpecialFlagsMask);
|
||||
}
|
||||
|
||||
SourceLoc getSourceLoc(ASTNodeTy N) const;
|
||||
SourceLoc getStartSourceLoc(ASTNodeTy N) const;
|
||||
@@ -184,22 +224,43 @@ public:
|
||||
/// When an ASTNode gets implicitly converted into a SILLocation we
|
||||
/// construct a RegularLocation. Since RegularLocations represent the majority
|
||||
/// of locations, this greatly simplifies the user code.
|
||||
SILLocation(Stmt *S) : ASTNode(S), KindData(RegularKind) {}
|
||||
SILLocation(Expr *E) : ASTNode(E), KindData(RegularKind) {}
|
||||
SILLocation(Decl *D) : ASTNode(D), KindData(RegularKind) {}
|
||||
SILLocation(Pattern *P) : ASTNode(P), KindData(RegularKind) {}
|
||||
SILLocation(Stmt *S) : Loc(S), KindData(RegularKind) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
SILLocation(Expr *E) : Loc(E), KindData(RegularKind) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
SILLocation(Decl *D) : Loc(D), KindData(RegularKind) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
SILLocation(Pattern *P) : Loc(P), KindData(RegularKind) {
|
||||
setStorageKind(ASTNodeKind);
|
||||
assert(isASTNode());
|
||||
}
|
||||
|
||||
/// Check if the location wraps an AST node or a valid SIL file
|
||||
/// location.
|
||||
///
|
||||
/// Artificial locations and the top-level module locations will be null.
|
||||
bool isNull() const {
|
||||
if (hasSILFileSourceLoc())
|
||||
return SpecificLoc.SILFileSourceLoc.isInvalid();
|
||||
return ASTNode.isNull();
|
||||
switch (getStorageKind()) {
|
||||
case ASTNodeKind: return Loc.ASTNode.Primary.isNull();
|
||||
case DebugInfoKind: return Loc.DebugInfoLoc.Filename;
|
||||
case SILFileKind: return Loc.SILFileLoc.isInvalid();
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
explicit operator bool() const { return !isNull(); }
|
||||
|
||||
/// Return whether this location is backed by an AST node.
|
||||
bool isASTNode() const { return getStorageKind() == ASTNodeKind; }
|
||||
|
||||
/// Return whether this location came from a SIL file.
|
||||
bool isSILFile() const { return getStorageKind() == SILFileKind; }
|
||||
|
||||
/// Marks the location as coming from auto-generated body.
|
||||
void markAutoGenerated() { KindData |= (1 << AutoGeneratedBit); }
|
||||
|
||||
@@ -235,37 +296,19 @@ public:
|
||||
/// Check is this location is part of a function's implicit prologue.
|
||||
bool isInPrologue() const { return KindData & (1 << IsInPrologue); }
|
||||
|
||||
void setHasSILFileSourceLoc() {
|
||||
assert(!hasDebugLoc() &&
|
||||
"SILFileSourceLoc and DebugLoc are mutually exclusive");
|
||||
KindData |= (1 << HasSILFileSourceLoc);
|
||||
}
|
||||
bool hasSILFileSourceLoc() const {
|
||||
return KindData & (1 << HasSILFileSourceLoc);
|
||||
}
|
||||
|
||||
SourceLoc getSILFileSourceLoc() const {
|
||||
assert(hasSILFileSourceLoc() && "no SILFileSourceLoc");
|
||||
return SpecificLoc.SILFileSourceLoc;
|
||||
}
|
||||
|
||||
/// Add an ASTNode to use as the location for debugging
|
||||
/// purposes if this location is different from the location used
|
||||
/// for diagnostics.
|
||||
template <typename T>
|
||||
void setDebugLoc(T *ASTNodeForDebugging) {
|
||||
assert(!hasDebugLoc() && "DebugLoc already present");
|
||||
assert(!hasSILFileSourceLoc() &&
|
||||
"SILFileSourceLoc and DebugLoc are mutually exclusive");
|
||||
KindData |= (1 << HasDebugLoc);
|
||||
SpecificLoc.DebugLoc = ASTNodeForDebugging;
|
||||
assert(isASTNode() && "not an AST location");
|
||||
Loc.ASTNode.ForDebugger = ASTNodeForDebugging;
|
||||
}
|
||||
bool hasDebugLoc() const {
|
||||
return KindData & (1 << HasDebugLoc);
|
||||
return isASTNode() && !Loc.ASTNode.ForDebugger.isNull();
|
||||
}
|
||||
|
||||
bool hasASTLocation() const { return !ASTNode.isNull(); }
|
||||
|
||||
/// Check if the corresponding source code location definitely points
|
||||
/// to the start of the AST node.
|
||||
bool alwaysPointsToStart() const { return KindData & (1 << PointsToStartBit);}
|
||||
@@ -274,7 +317,12 @@ public:
|
||||
/// to the end of the AST node.
|
||||
bool alwaysPointsToEnd() const { return KindData & (1 << PointsToEndBit); }
|
||||
|
||||
LocationKind getKind() const { return (LocationKind)(KindData & BaseMask); }
|
||||
LocationKind getKind() const {
|
||||
return LocationKind(KindData & LocationKindMask);
|
||||
}
|
||||
StorageKind getStorageKind() const {
|
||||
return StorageKind(KindData & StorageKindMask);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
@@ -302,25 +350,28 @@ public:
|
||||
|
||||
/// If the current value is of the specified AST unit type T,
|
||||
/// return it, otherwise return null.
|
||||
template <typename T>
|
||||
T *getAsASTNode() const { return getNodeAs<T>(ASTNode); }
|
||||
template <typename T> T *getAsASTNode() const {
|
||||
return isASTNode() ? getNodeAs<T>(Loc.ASTNode.Primary) : nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if the Location currently points to the AST node
|
||||
/// matching type T.
|
||||
template <typename T>
|
||||
bool isASTNode() const { return isNode<T>(ASTNode); }
|
||||
template <typename T> bool isASTNode() const {
|
||||
return isASTNode() && isNode<T>(Loc.ASTNode.Primary);
|
||||
}
|
||||
|
||||
/// Returns the primary value as the specified AST node type. If the
|
||||
/// specified type is incorrect, asserts.
|
||||
template <typename T>
|
||||
T *castToASTNode() const { return castNodeTo<T>(ASTNode); }
|
||||
template <typename T> T *castToASTNode() const {
|
||||
assert(isASTNode());
|
||||
return castNodeTo<T>(Loc.ASTNode.Primary);
|
||||
}
|
||||
|
||||
/// If the DebugLoc is of the specified AST unit type T,
|
||||
/// return it, otherwise return null.
|
||||
template <typename T>
|
||||
T *getDebugLocAsASTNode() const {
|
||||
template <typename T> T *getDebugLocAsASTNode() const {
|
||||
assert(hasDebugLoc() && "no debug location");
|
||||
return getNodeAs<T>(SpecificLoc.DebugLoc);
|
||||
return getNodeAs<T>(Loc.ASTNode.ForDebugger);
|
||||
}
|
||||
|
||||
SourceLoc getDebugSourceLoc() const;
|
||||
@@ -332,10 +383,11 @@ public:
|
||||
return { getStartSourceLoc(), getEndSourceLoc() };
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned Line = 0, Col = 0;
|
||||
const char *Filename = nullptr;
|
||||
} DebugLoc;
|
||||
/// Fingerprint a DebugLoc for use in a DenseMap.
|
||||
typedef std::pair<std::pair<unsigned, unsigned>, const void *> DebugLocKey;
|
||||
struct DebugLocHash : public DebugLocKey {
|
||||
DebugLocHash(DebugLoc L) : DebugLocKey({{L.Line, L.Col}, L.Filename}) {}
|
||||
};
|
||||
|
||||
/// Extract the line, column, and filename.
|
||||
static DebugLoc decode(SourceLoc Loc, const SourceManager &SM);
|
||||
@@ -352,17 +404,21 @@ public:
|
||||
/// Returns an opaque pointer value for the debug location that may
|
||||
/// be used to unique debug locations.
|
||||
const void *getOpaquePointerValue() const {
|
||||
if (hasSILFileSourceLoc())
|
||||
return getSILFileSourceLoc().getOpaquePointerValue();
|
||||
return ASTNode.getOpaqueValue();
|
||||
if (isSILFile())
|
||||
return Loc.SILFileLoc.getOpaquePointerValue();
|
||||
if (isASTNode())
|
||||
return Loc.ASTNode.Primary.getOpaqueValue();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
unsigned getOpaqueKind() const { return KindData; }
|
||||
|
||||
inline bool operator==(const SILLocation& R) const {
|
||||
return KindData == R.KindData &&
|
||||
ASTNode.getOpaqueValue() == R.ASTNode.getOpaqueValue() &&
|
||||
SpecificLoc.DebugLoc.getOpaqueValue() ==
|
||||
R.SpecificLoc.DebugLoc.getOpaqueValue();
|
||||
Loc.ASTNode.Primary.getOpaqueValue() ==
|
||||
R.Loc.ASTNode.Primary.getOpaqueValue() &&
|
||||
Loc.ASTNode.ForDebugger.getOpaqueValue() ==
|
||||
R.Loc.ASTNode.ForDebugger.getOpaqueValue();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -373,6 +429,7 @@ public:
|
||||
RegularLocation(Expr *E) : SILLocation(E, RegularKind) {}
|
||||
RegularLocation(Decl *D) : SILLocation(D, RegularKind) {}
|
||||
RegularLocation(Pattern *P) : SILLocation(P, RegularKind) {}
|
||||
RegularLocation(SourceLoc L) : SILLocation(L, RegularKind) {}
|
||||
|
||||
/// Returns a location representing the module.
|
||||
static RegularLocation getModuleLocation() {
|
||||
@@ -383,18 +440,15 @@ public:
|
||||
|
||||
/// If the current value is of the specified AST unit type T,
|
||||
/// return it, otherwise return null.
|
||||
template <typename T>
|
||||
T *getAs() const { return getNodeAs<T>(ASTNode); }
|
||||
template <typename T> T *getAs() const { return getNodeAs<T>(Loc.ASTNode); }
|
||||
|
||||
/// Returns true if the Location currently points to the AST node
|
||||
/// matching type T.
|
||||
template <typename T>
|
||||
bool is() const { return isNode<T>(ASTNode); }
|
||||
template <typename T> bool is() const { return isNode<T>(Loc.ASTNode); }
|
||||
|
||||
/// Returns the primary value as the specified AST node type. If the
|
||||
/// specified type is incorrect, asserts.
|
||||
template <typename T>
|
||||
T *castTo() const { return castNodeTo<T>(ASTNode); }
|
||||
template <typename T> T *castTo() const { return castNodeTo<T>(Loc.ASTNode); }
|
||||
|
||||
static RegularLocation getAutoGeneratedLocation() {
|
||||
RegularLocation AL;
|
||||
@@ -425,13 +479,11 @@ public:
|
||||
ReturnStmt *get() {
|
||||
return castToASTNode<ReturnStmt>();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SILLocation;
|
||||
static bool isKind(const SILLocation& L) {
|
||||
return L.getKind() == ReturnKind;
|
||||
}
|
||||
ReturnLocation() : SILLocation(ReturnKind) {}
|
||||
};
|
||||
|
||||
/// Used on the instruction that was generated to represent an implicit
|
||||
@@ -459,7 +511,7 @@ public:
|
||||
L.isASTNode<ValueDecl>() ||
|
||||
L.isASTNode<PatternBindingDecl>() ||
|
||||
(L.isNull() && L.isInTopLevel()));
|
||||
L.setKind(ImplicitReturnKind);
|
||||
L.setLocationKind(ImplicitReturnKind);
|
||||
return L;
|
||||
}
|
||||
|
||||
@@ -492,8 +544,8 @@ public:
|
||||
/// Constructs an inlined location when the call site is represented by a
|
||||
/// SILFile location.
|
||||
InlinedLocation(SourceLoc L) : SILLocation(InlinedKind) {
|
||||
setHasSILFileSourceLoc();
|
||||
SpecificLoc.SILFileSourceLoc = L;
|
||||
setStorageKind(SILFileKind);
|
||||
Loc.SILFileLoc = L;
|
||||
}
|
||||
|
||||
static InlinedLocation getInlinedLocation(SILLocation L);
|
||||
@@ -509,10 +561,7 @@ private:
|
||||
InlinedLocation(Stmt *S, unsigned F) : SILLocation(S, InlinedKind, F) {}
|
||||
InlinedLocation(Pattern *P, unsigned F) : SILLocation(P, InlinedKind, F) {}
|
||||
InlinedLocation(Decl *D, unsigned F) : SILLocation(D, InlinedKind, F) {}
|
||||
InlinedLocation(SourceLoc L, unsigned F) : SILLocation(InlinedKind, F) {
|
||||
setHasSILFileSourceLoc();
|
||||
SpecificLoc.SILFileSourceLoc = L;
|
||||
}
|
||||
InlinedLocation(SourceLoc L, unsigned F) : SILLocation(L, InlinedKind, F) {}
|
||||
|
||||
static InlinedLocation getModuleLocation(unsigned Flags) {
|
||||
auto L = InlinedLocation();
|
||||
@@ -539,10 +588,8 @@ public:
|
||||
|
||||
/// Constructs an inlined location when the call site is represented by a
|
||||
/// SILFile location.
|
||||
MandatoryInlinedLocation(SourceLoc L) : SILLocation(MandatoryInlinedKind) {
|
||||
setHasSILFileSourceLoc();
|
||||
SpecificLoc.SILFileSourceLoc = L;
|
||||
}
|
||||
MandatoryInlinedLocation(SourceLoc L)
|
||||
: SILLocation(L, MandatoryInlinedKind) {}
|
||||
|
||||
static MandatoryInlinedLocation getMandatoryInlinedLocation(SILLocation L);
|
||||
|
||||
@@ -558,23 +605,16 @@ private:
|
||||
return L.getKind() == MandatoryInlinedKind;
|
||||
}
|
||||
MandatoryInlinedLocation() : SILLocation(MandatoryInlinedKind) {}
|
||||
MandatoryInlinedLocation(Expr *E,
|
||||
unsigned F) : SILLocation(E, MandatoryInlinedKind,
|
||||
F) {}
|
||||
MandatoryInlinedLocation(Stmt *S,
|
||||
unsigned F) : SILLocation(S, MandatoryInlinedKind,
|
||||
F) {}
|
||||
MandatoryInlinedLocation(Pattern *P,
|
||||
unsigned F) : SILLocation(P, MandatoryInlinedKind,
|
||||
F) {}
|
||||
MandatoryInlinedLocation(Decl *D,
|
||||
unsigned F) : SILLocation(D, MandatoryInlinedKind,
|
||||
F) {}
|
||||
MandatoryInlinedLocation(SourceLoc L,
|
||||
unsigned F) : SILLocation(MandatoryInlinedKind, F) {
|
||||
setHasSILFileSourceLoc();
|
||||
SpecificLoc.SILFileSourceLoc = L;
|
||||
}
|
||||
MandatoryInlinedLocation(Expr *E, unsigned F)
|
||||
: SILLocation(E, MandatoryInlinedKind, F) {}
|
||||
MandatoryInlinedLocation(Stmt *S, unsigned F)
|
||||
: SILLocation(S, MandatoryInlinedKind, F) {}
|
||||
MandatoryInlinedLocation(Pattern *P, unsigned F)
|
||||
: SILLocation(P, MandatoryInlinedKind, F) {}
|
||||
MandatoryInlinedLocation(Decl *D, unsigned F)
|
||||
: SILLocation(D, MandatoryInlinedKind, F) {}
|
||||
MandatoryInlinedLocation(SourceLoc L, unsigned F)
|
||||
: SILLocation(L, MandatoryInlinedKind, F) {}
|
||||
};
|
||||
|
||||
/// Used on the instruction performing auto-generated cleanup such as
|
||||
@@ -627,7 +667,6 @@ private:
|
||||
class ArtificialUnreachableLocation : public SILLocation {
|
||||
public:
|
||||
ArtificialUnreachableLocation() : SILLocation(ArtificialUnreachableKind) {}
|
||||
|
||||
private:
|
||||
friend class SILLocation;
|
||||
static bool isKind(const SILLocation& L) {
|
||||
@@ -635,27 +674,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
/// Used to represent locations coming from a parsed SIL file.
|
||||
///
|
||||
/// Allowed on any SILInstruction.
|
||||
class SILFileLocation : public SILLocation {
|
||||
public:
|
||||
SILFileLocation(SourceLoc L) : SILLocation(SILFileKind) {
|
||||
setHasSILFileSourceLoc();
|
||||
SpecificLoc.SILFileSourceLoc = L;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SILLocation;
|
||||
static bool isKind(const SILLocation& L) {
|
||||
return L.getKind() == SILFileKind;
|
||||
}
|
||||
SILFileLocation() : SILLocation(SILFileKind) {
|
||||
setHasSILFileSourceLoc();
|
||||
SpecificLoc.SILFileSourceLoc = SourceLoc();
|
||||
}
|
||||
};
|
||||
|
||||
} // end swift namespace
|
||||
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ void IRGenDebugInfo::setCurrentLoc(IRBuilder &Builder, const SILDebugScope *DS,
|
||||
//
|
||||
// The actual closure has a closure expression as scope.
|
||||
if (Loc && isAbstractClosure(*Loc) && DS && !isAbstractClosure(DS->Loc)
|
||||
&& Loc->getKind() != SILLocation::ImplicitReturnKind)
|
||||
&& !Loc->is<ImplicitReturnLocation>())
|
||||
return;
|
||||
|
||||
if (L.Line == 0 && DS == LastScope) {
|
||||
@@ -660,7 +660,7 @@ llvm::DISubprogram *IRGenDebugInfo::emitFunction(
|
||||
|
||||
StringRef Name;
|
||||
if (DS) {
|
||||
if (DS->Loc.getKind() == SILLocation::SILFileKind)
|
||||
if (DS->Loc.isSILFile())
|
||||
Name = SILFn->getName();
|
||||
else
|
||||
Name = getName(DS->Loc);
|
||||
|
||||
@@ -1547,7 +1547,7 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
|
||||
SILLocation ILoc = I.getLoc();
|
||||
auto DS = I.getDebugScope();
|
||||
// Handle cleanup locations.
|
||||
if (ILoc.getKind() == SILLocation::CleanupKind) {
|
||||
if (ILoc.is<CleanupLocation>()) {
|
||||
// Cleanup locations point to the decl of the value that is
|
||||
// being destroyed (for diagnostic generation). As far as
|
||||
// the linetable is concerned, cleanups at the end of a
|
||||
@@ -1559,7 +1559,7 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
|
||||
// this basic block.
|
||||
auto It = InsnIter;
|
||||
do ++It; while (It != BB->end() &&
|
||||
It->getLoc().getKind() == SILLocation::CleanupKind);
|
||||
It->getLoc().is<CleanupLocation>());
|
||||
// We are still in the middle of a basic block?
|
||||
if (It != BB->end() && !isa<TermInst>(It))
|
||||
KeepCurrentLocation = true;
|
||||
|
||||
@@ -366,7 +366,7 @@ SILFunction *SILParser::getGlobalNameForDefinition(Identifier Name,
|
||||
P.diagnose(Loc, diag::sil_value_use_type_mismatch, Name.str(),
|
||||
Fn->getLoweredFunctionType(), Ty);
|
||||
P.diagnose(It->second.second, diag::sil_prior_reference);
|
||||
auto loc = SILFileLocation(Loc);
|
||||
auto loc = RegularLocation(Loc);
|
||||
Fn =
|
||||
SILMod.getOrCreateFunction(SILLinkage::Private, "", Ty, nullptr, loc,
|
||||
IsNotBare, IsNotTransparent, IsNotFragile);
|
||||
@@ -383,7 +383,7 @@ SILFunction *SILParser::getGlobalNameForDefinition(Identifier Name,
|
||||
return Fn;
|
||||
}
|
||||
|
||||
auto loc = SILFileLocation(Loc);
|
||||
auto loc = RegularLocation(Loc);
|
||||
// If we don't have a forward reference, make sure the function hasn't been
|
||||
// defined already.
|
||||
if (SILMod.lookUpFunction(Name.str()) != nullptr) {
|
||||
@@ -410,7 +410,7 @@ SILFunction *SILParser::getGlobalNameForDefinition(Identifier Name,
|
||||
SILFunction *SILParser::getGlobalNameForReference(Identifier Name,
|
||||
CanSILFunctionType Ty,
|
||||
SourceLoc Loc) {
|
||||
auto loc = SILFileLocation(Loc);
|
||||
auto loc = RegularLocation(Loc);
|
||||
|
||||
// Check to see if we have a function by this name already.
|
||||
if (SILFunction *FnRef = SILMod.lookUpFunction(Name.str())) {
|
||||
@@ -1042,7 +1042,7 @@ bool SILParser::parseTypedValueRef(SILValue &Result, SourceLoc &Loc,
|
||||
parseSILType(Ty))
|
||||
return true;
|
||||
|
||||
Result = getLocalValue(Name, Ty, SILFileLocation(Loc), B);
|
||||
Result = getLocalValue(Name, Ty, RegularLocation(Loc), B);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1443,7 +1443,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
SmallVector<SILValue, 4> OpList;
|
||||
SILValue Val;
|
||||
|
||||
SILLocation InstLoc = SILFileLocation(OpcodeLoc);
|
||||
SILLocation InstLoc = RegularLocation(OpcodeLoc);
|
||||
|
||||
auto parseCastConsumptionKind = [&](Identifier name, SourceLoc loc,
|
||||
CastConsumptionKind &out) -> bool {
|
||||
@@ -2337,7 +2337,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
Type EltTy = TT->getElement(TypeElts.size()).getType();
|
||||
if (parseValueRef(Val,
|
||||
SILType::getPrimitiveObjectType(EltTy->getCanonicalType()),
|
||||
SILFileLocation(P.Tok.getLoc()), B))
|
||||
RegularLocation(P.Tok.getLoc()), B))
|
||||
return true;
|
||||
OpList.push_back(Val);
|
||||
TypeElts.push_back(Val->getType().getSwiftRValueType());
|
||||
@@ -2930,7 +2930,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
// Parse 'case' value-ref ':' sil-identifier.
|
||||
if (P.consumeIf(tok::kw_case)) {
|
||||
if (parseValueRef(CaseVal, Val->getType(),
|
||||
SILFileLocation(P.Tok.getLoc()), B)) {
|
||||
RegularLocation(P.Tok.getLoc()), B)) {
|
||||
// TODO: Issue a proper error message here
|
||||
P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "reference to a value");
|
||||
return true;
|
||||
@@ -3618,7 +3618,7 @@ bool Parser::parseSILGlobal() {
|
||||
auto *GV = SILGlobalVariable::create(*SIL->M, GlobalLinkage.getValue(),
|
||||
(IsFragile_t)isFragile,
|
||||
GlobalName.str(),GlobalType,
|
||||
SILFileLocation(NameLoc));
|
||||
RegularLocation(NameLoc));
|
||||
|
||||
GV->setLet(isLet);
|
||||
// Parse static initializer if exists.
|
||||
|
||||
@@ -27,7 +27,7 @@ void swift::printSILLocationDescription(llvm::raw_ostream &out,
|
||||
ASTContext &Context) {
|
||||
if (loc.isNull()) {
|
||||
out << "<<invalid location>>";
|
||||
} else if (!loc.hasASTLocation()) {
|
||||
} else if (loc.isSILFile()) {
|
||||
printSourceLocDescription(out, loc.getSourceLoc(), Context);
|
||||
} else if (auto decl = loc.getAsASTNode<Decl>()) {
|
||||
printDeclDescription(out, decl, Context);
|
||||
@@ -35,8 +35,7 @@ void swift::printSILLocationDescription(llvm::raw_ostream &out,
|
||||
printExprDescription(out, expr, Context);
|
||||
} else if (auto stmt = loc.getAsASTNode<Stmt>()) {
|
||||
printStmtDescription(out, stmt, Context);
|
||||
} else {
|
||||
auto pattern = loc.castToASTNode<Pattern>();
|
||||
} else if (auto pattern = loc.castToASTNode<Pattern>()) {
|
||||
printPatternDescription(out, pattern, Context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ using namespace swift;
|
||||
|
||||
|
||||
SourceLoc SILLocation::getSourceLoc() const {
|
||||
if (hasSILFileSourceLoc())
|
||||
return getSILFileSourceLoc();
|
||||
if (isSILFile())
|
||||
return Loc.SILFileLoc;
|
||||
|
||||
return getSourceLoc(ASTNode);
|
||||
return getSourceLoc(Loc.ASTNode.Primary);
|
||||
}
|
||||
|
||||
SourceLoc SILLocation::getSourceLoc(ASTNodeTy N) const {
|
||||
@@ -34,12 +34,12 @@ SourceLoc SILLocation::getSourceLoc(ASTNodeTy N) const {
|
||||
|
||||
if (alwaysPointsToStart() ||
|
||||
alwaysPointsToEnd() ||
|
||||
getKind() == CleanupKind ||
|
||||
getKind() == ImplicitReturnKind)
|
||||
is<CleanupLocation>() ||
|
||||
is<ImplicitReturnLocation>())
|
||||
return getEndSourceLoc(N);
|
||||
|
||||
// Use the start location for the ReturnKind.
|
||||
if (getKind() == ReturnKind)
|
||||
if (is<ReturnLocation>())
|
||||
return getStartSourceLoc(N);
|
||||
|
||||
if (auto *decl = N.dyn_cast<Decl*>())
|
||||
@@ -54,13 +54,13 @@ SourceLoc SILLocation::getSourceLoc(ASTNodeTy N) const {
|
||||
}
|
||||
|
||||
SourceLoc SILLocation::getDebugSourceLoc() const {
|
||||
if (hasSILFileSourceLoc())
|
||||
return getSILFileSourceLoc();
|
||||
if (isSILFile())
|
||||
return Loc.SILFileLoc;
|
||||
|
||||
if (isAutoGenerated())
|
||||
return SourceLoc();
|
||||
|
||||
if (auto *expr = ASTNode.dyn_cast<Expr*>()) {
|
||||
if (auto *expr = Loc.ASTNode.Primary.dyn_cast<Expr*>()) {
|
||||
if (isa<CallExpr>(expr))
|
||||
return expr->getEndLoc();
|
||||
// Code that has an autoclosure as location should not show up in
|
||||
@@ -73,19 +73,18 @@ SourceLoc SILLocation::getDebugSourceLoc() const {
|
||||
return SourceLoc();
|
||||
}
|
||||
|
||||
if (!hasDebugLoc())
|
||||
return getSourceLoc(ASTNode);
|
||||
if (Loc.ASTNode.ForDebugger)
|
||||
return getSourceLoc(Loc.ASTNode.ForDebugger);
|
||||
|
||||
assert(!SpecificLoc.DebugLoc.isNull() && "empty debug location");
|
||||
return getSourceLoc(SpecificLoc.DebugLoc);
|
||||
return getSourceLoc(Loc.ASTNode.Primary);
|
||||
}
|
||||
|
||||
SourceLoc SILLocation::getStartSourceLoc() const {
|
||||
if (isAutoGenerated())
|
||||
return SourceLoc();
|
||||
if (ASTNode.isNull())
|
||||
return getSILFileSourceLoc();
|
||||
return getStartSourceLoc(ASTNode);
|
||||
if (isSILFile())
|
||||
return Loc.SILFileLoc;
|
||||
return getStartSourceLoc(Loc.ASTNode.Primary);
|
||||
}
|
||||
|
||||
SourceLoc SILLocation::getStartSourceLoc(ASTNodeTy N) const {
|
||||
@@ -103,9 +102,9 @@ SourceLoc SILLocation::getStartSourceLoc(ASTNodeTy N) const {
|
||||
SourceLoc SILLocation::getEndSourceLoc() const {
|
||||
if (isAutoGenerated())
|
||||
return SourceLoc();
|
||||
if (ASTNode.isNull())
|
||||
return getSILFileSourceLoc();
|
||||
return getEndSourceLoc(ASTNode);
|
||||
if (isSILFile())
|
||||
return Loc.SILFileLoc;
|
||||
return getEndSourceLoc(Loc.ASTNode.Primary);
|
||||
}
|
||||
|
||||
SourceLoc SILLocation::getEndSourceLoc(ASTNodeTy N) const {
|
||||
@@ -131,13 +130,13 @@ SILLocation::DebugLoc SILLocation::decode(SourceLoc Loc,
|
||||
}
|
||||
|
||||
void SILLocation::dump(const SourceManager &SM) const {
|
||||
if (auto D = ASTNode.dyn_cast<Decl *>())
|
||||
if (auto D = getAsASTNode<Decl>())
|
||||
llvm::errs() << Decl::getKindName(D->getKind()) << "Decl @ ";
|
||||
if (auto E = ASTNode.dyn_cast<Expr *>())
|
||||
if (auto E = getAsASTNode<Expr>())
|
||||
llvm::errs() << Expr::getKindName(E->getKind()) << "Expr @ ";
|
||||
if (auto S = ASTNode.dyn_cast<Stmt *>())
|
||||
if (auto S = getAsASTNode<Stmt>())
|
||||
llvm::errs() << Stmt::getKindName(S->getKind()) << "Stmt @ ";
|
||||
if (auto P = ASTNode.dyn_cast<Pattern *>())
|
||||
if (auto P = getAsASTNode<Pattern>())
|
||||
llvm::errs() << Pattern::getKindName(P->getKind()) << "Pattern @ ";
|
||||
|
||||
print(llvm::errs(), SM);
|
||||
@@ -147,7 +146,7 @@ void SILLocation::dump(const SourceManager &SM) const {
|
||||
if (alwaysPointsToEnd()) llvm::errs() << ":end";
|
||||
if (isInTopLevel()) llvm::errs() << ":toplevel";
|
||||
if (isInPrologue()) llvm::errs() << ":prologue";
|
||||
if (hasSILFileSourceLoc()) llvm::errs() << ":sil";
|
||||
if (isSILFile()) llvm::errs() << ":sil";
|
||||
if (hasDebugLoc()) {
|
||||
llvm::errs() << ":debug[";
|
||||
getDebugSourceLoc().print(llvm::errs(), SM);
|
||||
@@ -171,8 +170,8 @@ InlinedLocation InlinedLocation::getInlinedLocation(SILLocation L) {
|
||||
if (Decl *D = L.getAsASTNode<Decl>())
|
||||
return InlinedLocation(D, L.getSpecialFlags());
|
||||
|
||||
if (L.hasSILFileSourceLoc())
|
||||
return InlinedLocation(L.getSILFileSourceLoc(), L.getSpecialFlags());
|
||||
if (L.isSILFile())
|
||||
return InlinedLocation(L.Loc.SILFileLoc, L.getSpecialFlags());
|
||||
|
||||
if (L.isInTopLevel())
|
||||
return InlinedLocation::getModuleLocation(L.getSpecialFlags());
|
||||
@@ -196,9 +195,8 @@ MandatoryInlinedLocation::getMandatoryInlinedLocation(SILLocation L) {
|
||||
if (Decl *D = L.getAsASTNode<Decl>())
|
||||
return MandatoryInlinedLocation(D, L.getSpecialFlags());
|
||||
|
||||
if (L.hasSILFileSourceLoc())
|
||||
return MandatoryInlinedLocation(L.getSILFileSourceLoc(),
|
||||
L.getSpecialFlags());
|
||||
if (L.isSILFile())
|
||||
return MandatoryInlinedLocation(L.Loc.SILFileLoc, L.getSpecialFlags());
|
||||
|
||||
if (L.isInTopLevel())
|
||||
return MandatoryInlinedLocation::getModuleLocation(L.getSpecialFlags());
|
||||
@@ -217,7 +215,7 @@ CleanupLocation CleanupLocation::get(SILLocation L) {
|
||||
return CleanupLocation(D, L.getSpecialFlags());
|
||||
if (L.isNull())
|
||||
return CleanupLocation();
|
||||
if (L.getAs<SILFileLocation>())
|
||||
if (L.isSILFile())
|
||||
return CleanupLocation();
|
||||
llvm_unreachable("Cannot construct Cleanup loc from the "
|
||||
"given location.");
|
||||
|
||||
@@ -597,10 +597,9 @@ public:
|
||||
case SILLocation::ArtificialUnreachableKind:
|
||||
*this << ":art_unreach";
|
||||
break;
|
||||
case SILLocation::SILFileKind:
|
||||
*this << ":sil";
|
||||
break;
|
||||
}
|
||||
if (L.isSILFile())
|
||||
*this << ":sil";
|
||||
if (L.isAutoGenerated())
|
||||
*this << ":auto_gen";
|
||||
if (L.isInPrologue())
|
||||
|
||||
@@ -531,9 +531,8 @@ public:
|
||||
SILLocation::LocationKind LocKind = L.getKind();
|
||||
ValueKind InstKind = I->getKind();
|
||||
|
||||
// Regular locations and SIL file locations are allowed on all instructions.
|
||||
if (LocKind == SILLocation::RegularKind ||
|
||||
LocKind == SILLocation::SILFileKind)
|
||||
// Regular locations are allowed on all instructions.
|
||||
if (LocKind == SILLocation::RegularKind)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -51,7 +51,7 @@ llvm::cl::opt<bool> EnableLoopARC("enable-loop-arc", llvm::cl::init(true));
|
||||
static SILInstruction *createIncrement(SILValue Ptr, SILInstruction *InsertPt) {
|
||||
// Set up the builder we use to insert at our insertion point.
|
||||
SILBuilder B(InsertPt);
|
||||
auto Loc = SILFileLocation(SourceLoc());
|
||||
auto Loc = RegularLocation(SourceLoc());
|
||||
|
||||
// If Ptr is refcounted itself, create the strong_retain and
|
||||
// return.
|
||||
@@ -68,7 +68,7 @@ static SILInstruction *createIncrement(SILValue Ptr, SILInstruction *InsertPt) {
|
||||
static SILInstruction *createDecrement(SILValue Ptr, SILInstruction *InsertPt) {
|
||||
// Setup the builder we will use to insert at our insertion point.
|
||||
SILBuilder B(InsertPt);
|
||||
auto Loc = SILFileLocation(SourceLoc());
|
||||
auto Loc = RegularLocation(SourceLoc());
|
||||
|
||||
// If Ptr has reference semantics itself, create a strong_release.
|
||||
if (Ptr->getType().isReferenceCounted(B.getModule()))
|
||||
|
||||
@@ -1031,7 +1031,7 @@ static SILInstruction *isSuperInitUse(UpcastInst *Inst) {
|
||||
// If we're reading a .sil file, treat a call to "superinit" as a
|
||||
// super.init call as a hack to allow us to write testcases.
|
||||
auto *AI = dyn_cast<ApplyInst>(inst);
|
||||
if (AI && inst->getLoc().is<SILFileLocation>())
|
||||
if (AI && inst->getLoc().isSILFile())
|
||||
if (auto *Fn = AI->getCalleeFunction())
|
||||
if (Fn->getName() == "superinit")
|
||||
return inst;
|
||||
@@ -1070,7 +1070,7 @@ static SILInstruction *isSuperInitUse(UpcastInst *Inst) {
|
||||
static bool isSelfInitUse(SILInstruction *I) {
|
||||
// If we're reading a .sil file, treat a call to "selfinit" as a
|
||||
// self.init call as a hack to allow us to write testcases.
|
||||
if (I->getLoc().is<SILFileLocation>()) {
|
||||
if (I->getLoc().isSILFile()) {
|
||||
if (auto *AI = dyn_cast<ApplyInst>(I))
|
||||
if (auto *Fn = AI->getCalleeFunction())
|
||||
if (Fn->getName().startswith("selfinit"))
|
||||
|
||||
@@ -75,7 +75,7 @@ static void diagnoseUnreachable(const SILInstruction *I,
|
||||
// transparently inlined. We should have already emitted these
|
||||
// diagnostics when we process the callee function prior to
|
||||
// inlining it.
|
||||
if (!L.hasASTLocation() || L.is<MandatoryInlinedLocation>())
|
||||
if (!L || L.is<MandatoryInlinedLocation>())
|
||||
return;
|
||||
|
||||
// The most common case of getting an unreachable instruction is a
|
||||
|
||||
@@ -183,7 +183,7 @@ static void analyzeUseOfInOut(Operand *UI, StackSlotState &state) {
|
||||
// We only look at autogenerated copy_addr's. We don't want to muck with
|
||||
// user variables, as in:
|
||||
// func f(inout a : Int) { var b = a }
|
||||
if (!CAI->getLoc().isAutoGenerated() && !CAI->getLoc().is<SILFileLocation>())
|
||||
if (!CAI->getLoc().isAutoGenerated() && !CAI->getLoc().isSILFile())
|
||||
return;
|
||||
|
||||
// Get a stack slot, looking through mark_uninitialized if necessary.
|
||||
|
||||
@@ -34,8 +34,8 @@ static SILBasicBlock *createInitialPreheader(SILBasicBlock *Header) {
|
||||
}
|
||||
|
||||
// Create the branch to the header.
|
||||
SILBuilder(Preheader)
|
||||
.createBranch(SILFileLocation(SourceLoc()), Header, Args);
|
||||
SILBuilder(Preheader).createBranch(RegularLocation(SourceLoc()), Header,
|
||||
Args);
|
||||
|
||||
return Preheader;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ static SILFunction *createBogusSILFunction(SILModule &M,
|
||||
SourceLoc loc;
|
||||
return M.getOrCreateFunction(
|
||||
SILLinkage::Private, name, type.castTo<SILFunctionType>(), nullptr,
|
||||
SILFileLocation(loc), IsNotBare, IsNotTransparent, IsNotFragile,
|
||||
RegularLocation(loc), IsNotBare, IsNotTransparent, IsNotFragile,
|
||||
IsNotThunk, SILFunction::NotRelevant);
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID,
|
||||
auto fn = existingFn;
|
||||
|
||||
// TODO: use the correct SILLocation from module.
|
||||
SILLocation loc = SILFileLocation(SourceLoc());
|
||||
SILLocation loc = RegularLocation(SourceLoc());
|
||||
|
||||
// If we have an existing function, verify that the types match up.
|
||||
if (fn) {
|
||||
@@ -624,7 +624,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||
ModuleID OwningModuleID;
|
||||
SourceLoc SLoc;
|
||||
ArrayRef<uint64_t> ListOfValues;
|
||||
SILLocation Loc = SILFileLocation(SLoc);
|
||||
SILLocation Loc = RegularLocation(SLoc);
|
||||
|
||||
switch (RecordKind) {
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user