mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
Reapply "AsmPrinter: Change DIEValue to be stored by value"
This reverts commit r238350, effectively reapplying r238349 after fixing (all?) the problems, all somehow related to how I was using `AlignedArrayCharUnion<>` inside `DIEValue`: - MSVC can only handle `sizeof()` on types, not values. Change the assert. - GCC doesn't know the `is_trivially_copyable` type trait. Instead of asserting it, add destructors. - Call placement new even when constructing POD (i.e., the pointers). - Instead of copying the char buffer, copy the casted classes. I've left in a couple of `static_assert`s that I think both MSVC and GCC know how to handle. If the bots disagree with me, I'll remove them. - Check that the constructed type is either standard layout or a pointer. This protects against a programming error: we really want the "small" `DIEValue`s to be small and simple, so don't accidentally change them not to be. - Similarly, check that the size of the buffer is no bigger than a `uint64_t` or a pointer. (I thought checking against `sizeof(uint64_t)` would be good enough, but Chandler suggested that pointers might sometimes be bigger than that in the context of sanitizers.) I've also committed r238359 in the meantime, which introduces a DIEValue.def to simplify dispatching between the various types (thanks to a review comment by David Blaikie). Without that, this commit would be almost unintelligible. Here's the original commit message: -- Change `DIEValue` to be stored/passed/etc. by value, instead of reference. It's now a discriminated union, with a `Val` field storing the actual type. The classes that used to inherit from `DIEValue` no longer do. There are two categories of these: - Small values fit in a single pointer and are stored by value. - Large values require auxiliary storage, and are stored by reference. The only non-mechanical change is to tools/dsymutil/DwarfLinker.cpp. It was relying on `DIEInteger`s being passed around by reference, so I replaced that assumption with a `PatchLocation` type that stores a safe reference to where the `DIEInteger` lives instead. This commit causes a temporary regression in memory usage, since I've left merging `DIEAbbrevData` into `DIEValue` for a follow-up commit. I measured an increase from 845 MB to 879 MB, around 3.9%. The follow-up drops it lower than the starting point, and I've only recently brought the memory this low anyway, so I'm committing these changes separately to keep them incremental. (I also considered swapping the commits, but the other one first would cause a lot more code churn.) (I'm looking at `llc` memory usage on `verify-uselistorder.lto.opt.bc`; see r236629 for details.) -- git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238362 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -104,54 +104,14 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEValue - A debug information entry value. Some of these roughly correlate
|
||||
/// to DWARF attribute classes.
|
||||
///
|
||||
class DIEValue {
|
||||
public:
|
||||
enum Type {
|
||||
#define HANDLE_DIEVALUE(T) is##T,
|
||||
#include "llvm/CodeGen/DIEValue.def"
|
||||
};
|
||||
|
||||
private:
|
||||
/// Ty - Type of data stored in the value.
|
||||
///
|
||||
Type Ty;
|
||||
|
||||
protected:
|
||||
explicit DIEValue(Type T) : Ty(T) {}
|
||||
~DIEValue() {}
|
||||
|
||||
public:
|
||||
// Accessors
|
||||
Type getType() const { return Ty; }
|
||||
|
||||
/// EmitValue - Emit value via the Dwarf writer.
|
||||
///
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
/// SizeOf - Return the size of a value in bytes.
|
||||
///
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void print(raw_ostream &O) const;
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEInteger - An integer value DIE.
|
||||
///
|
||||
class DIEInteger : public DIEValue {
|
||||
friend DIEValue;
|
||||
|
||||
class DIEInteger {
|
||||
uint64_t Integer;
|
||||
|
||||
public:
|
||||
explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
|
||||
explicit DIEInteger(uint64_t I) : Integer(I) {}
|
||||
|
||||
/// BestForm - Choose the best form for integer.
|
||||
///
|
||||
@@ -178,120 +138,91 @@ public:
|
||||
uint64_t getValue() const { return Integer; }
|
||||
void setValue(uint64_t Val) { Integer = Val; }
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEExpr - An expression DIE.
|
||||
//
|
||||
class DIEExpr : public DIEValue {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIEExpr {
|
||||
const MCExpr *Expr;
|
||||
|
||||
public:
|
||||
explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {}
|
||||
explicit DIEExpr(const MCExpr *E) : Expr(E) {}
|
||||
|
||||
/// getValue - Get MCExpr.
|
||||
///
|
||||
const MCExpr *getValue() const { return Expr; }
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isExpr; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIELabel - A label DIE.
|
||||
//
|
||||
class DIELabel : public DIEValue {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIELabel {
|
||||
const MCSymbol *Label;
|
||||
|
||||
public:
|
||||
explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
|
||||
explicit DIELabel(const MCSymbol *L) : Label(L) {}
|
||||
|
||||
/// getValue - Get MCSymbol.
|
||||
///
|
||||
const MCSymbol *getValue() const { return Label; }
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEDelta - A simple label difference DIE.
|
||||
///
|
||||
class DIEDelta : public DIEValue {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIEDelta {
|
||||
const MCSymbol *LabelHi;
|
||||
const MCSymbol *LabelLo;
|
||||
|
||||
public:
|
||||
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
|
||||
: DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
|
||||
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEString - A container for string values.
|
||||
///
|
||||
class DIEString : public DIEValue {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIEString {
|
||||
DwarfStringPoolEntryRef S;
|
||||
|
||||
public:
|
||||
DIEString(DwarfStringPoolEntryRef S) : DIEValue(isString), S(S) {}
|
||||
DIEString(DwarfStringPoolEntryRef S) : S(S) {}
|
||||
|
||||
/// getString - Grab the string out of the object.
|
||||
StringRef getString() const { return S.getString(); }
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *D) { return D->getType() == isString; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -300,60 +231,48 @@ private:
|
||||
/// this class can also be used as a proxy for a debug information entry not
|
||||
/// yet defined (ie. types.)
|
||||
class DIE;
|
||||
class DIEEntry : public DIEValue {
|
||||
friend class DIEValue;
|
||||
class DIEEntry {
|
||||
DIE *Entry;
|
||||
|
||||
DIE &Entry;
|
||||
DIEEntry() = delete;
|
||||
|
||||
public:
|
||||
explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) {
|
||||
}
|
||||
explicit DIEEntry(DIE &E) : Entry(&E) {}
|
||||
|
||||
DIE &getEntry() const { return Entry; }
|
||||
DIE &getEntry() const { return *Entry; }
|
||||
|
||||
/// Returns size of a ref_addr entry.
|
||||
static unsigned getRefAddrSize(const AsmPrinter *AP);
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
|
||||
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
|
||||
: sizeof(int32_t);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// \brief A signature reference to a type unit.
|
||||
class DIETypeSignature : public DIEValue {
|
||||
friend class DIEValue;
|
||||
class DIETypeSignature {
|
||||
const DwarfTypeUnit *Unit;
|
||||
|
||||
const DwarfTypeUnit &Unit;
|
||||
DIETypeSignature() = delete;
|
||||
|
||||
public:
|
||||
explicit DIETypeSignature(const DwarfTypeUnit &Unit)
|
||||
: DIEValue(isTypeSignature), Unit(Unit) {}
|
||||
explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {}
|
||||
|
||||
// \brief Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *E) {
|
||||
return E->getType() == isTypeSignature;
|
||||
}
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const {
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
|
||||
assert(Form == dwarf::DW_FORM_ref_sig8);
|
||||
return 8;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -361,27 +280,159 @@ private:
|
||||
/// DIELocList - Represents a pointer to a location list in the debug_loc
|
||||
/// section.
|
||||
//
|
||||
class DIELocList : public DIEValue {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIELocList {
|
||||
// Index into the .debug_loc vector.
|
||||
size_t Index;
|
||||
|
||||
public:
|
||||
DIELocList(size_t I) : DIEValue(isLocList), Index(I) {}
|
||||
DIELocList(size_t I) : Index(I) {}
|
||||
|
||||
/// getValue - Grab the current index out.
|
||||
size_t getValue() const { return Index; }
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isLocList; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEValue - A debug information entry value. Some of these roughly correlate
|
||||
/// to DWARF attribute classes.
|
||||
///
|
||||
class DIEBlock;
|
||||
class DIELoc;
|
||||
class DIEValue {
|
||||
public:
|
||||
enum Type {
|
||||
isNone,
|
||||
#define HANDLE_DIEVALUE(T) is##T,
|
||||
#include "llvm/CodeGen/DIEValue.def"
|
||||
};
|
||||
|
||||
private:
|
||||
/// Ty - Type of data stored in the value.
|
||||
///
|
||||
Type Ty;
|
||||
|
||||
/// Storage for the value.
|
||||
///
|
||||
/// All values that aren't standard layout (or are larger than 8 bytes)
|
||||
/// should be stored by reference instead of by value.
|
||||
typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
|
||||
DIEDelta *, DIEEntry, DIETypeSignature,
|
||||
DIEBlock *, DIELoc *, DIELocList> ValTy;
|
||||
static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
|
||||
sizeof(ValTy) <= sizeof(void *),
|
||||
"Expected all large types to be stored via pointer");
|
||||
|
||||
/// Underlying stored value.
|
||||
ValTy Val;
|
||||
|
||||
template <class T> void construct(T V) {
|
||||
static_assert(std::is_standard_layout<T>::value ||
|
||||
std::is_pointer<T>::value,
|
||||
"Expected standard layout or pointer");
|
||||
new (reinterpret_cast<void *>(Val.buffer)) T(V);
|
||||
}
|
||||
|
||||
template <class T> T &get() { return *reinterpret_cast<T *>(Val.buffer); }
|
||||
template <class T> const T &get() const {
|
||||
return *reinterpret_cast<const T *>(Val.buffer);
|
||||
}
|
||||
template <class T> void destruct() { get<T>().~T(); }
|
||||
|
||||
/// Destroy the underlying value.
|
||||
///
|
||||
/// This should get optimized down to a no-op. We could skip it if we could
|
||||
/// add a static assert on \a std::is_trivially_copyable(), but we currently
|
||||
/// support versions of GCC that don't understand that.
|
||||
void destroyVal() {
|
||||
switch (Ty) {
|
||||
case isNone:
|
||||
return;
|
||||
#define HANDLE_DIEVALUE_SMALL(T) \
|
||||
case is##T: \
|
||||
destruct<DIE##T>();
|
||||
return;
|
||||
#define HANDLE_DIEVALUE_LARGE(T) \
|
||||
case is##T: \
|
||||
destruct<const DIE##T *>();
|
||||
return;
|
||||
#include "llvm/CodeGen/DIEValue.def"
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy the underlying value.
|
||||
///
|
||||
/// This should get optimized down to a simple copy. We need to actually
|
||||
/// construct the value, rather than calling memcpy, to satisfy strict
|
||||
/// aliasing rules.
|
||||
void copyVal(const DIEValue &X) {
|
||||
switch (Ty) {
|
||||
case isNone:
|
||||
return;
|
||||
#define HANDLE_DIEVALUE_SMALL(T) \
|
||||
case is##T: \
|
||||
construct<DIE##T>(X.get<DIE##T>()); \
|
||||
return;
|
||||
#define HANDLE_DIEVALUE_LARGE(T) \
|
||||
case is##T: \
|
||||
construct<const DIE##T *>(X.get<const DIE##T *>()); \
|
||||
return;
|
||||
#include "llvm/CodeGen/DIEValue.def"
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
DIEValue() : Ty(isNone) {}
|
||||
DIEValue(const DIEValue &X) : Ty(X.Ty) { copyVal(X); }
|
||||
DIEValue &operator=(const DIEValue &X) {
|
||||
destroyVal();
|
||||
Ty = X.Ty;
|
||||
copyVal(X);
|
||||
return *this;
|
||||
}
|
||||
~DIEValue() { destroyVal(); }
|
||||
|
||||
#define HANDLE_DIEVALUE_SMALL(T) \
|
||||
DIEValue(const DIE##T &V) : Ty(is##T) { construct<DIE##T>(V); }
|
||||
#define HANDLE_DIEVALUE_LARGE(T) \
|
||||
DIEValue(const DIE##T *V) : Ty(is##T) { \
|
||||
assert(V && "Expected valid value"); \
|
||||
construct<const DIE##T *>(V); \
|
||||
}
|
||||
#include "llvm/CodeGen/DIEValue.def"
|
||||
|
||||
// Accessors
|
||||
Type getType() const { return Ty; }
|
||||
explicit operator bool() const { return Ty; }
|
||||
|
||||
#define HANDLE_DIEVALUE_SMALL(T) \
|
||||
const DIE##T &getDIE##T() const { \
|
||||
assert(getType() == is##T && "Expected " #T); \
|
||||
return get<DIE##T>(); \
|
||||
}
|
||||
#define HANDLE_DIEVALUE_LARGE(T) \
|
||||
const DIE##T &getDIE##T() const { \
|
||||
assert(getType() == is##T && "Expected " #T); \
|
||||
return *get<const DIE##T *>(); \
|
||||
}
|
||||
#include "llvm/CodeGen/DIEValue.def"
|
||||
|
||||
/// EmitValue - Emit value via the Dwarf writer.
|
||||
///
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
/// SizeOf - Return the size of a value in bytes.
|
||||
///
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void print(raw_ostream &O) const;
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -416,7 +467,7 @@ protected:
|
||||
|
||||
/// Attribute values.
|
||||
///
|
||||
SmallVector<DIEValue *, 12> Values;
|
||||
SmallVector<DIEValue, 12> Values;
|
||||
|
||||
protected:
|
||||
DIE()
|
||||
@@ -438,7 +489,11 @@ public:
|
||||
const std::vector<std::unique_ptr<DIE>> &getChildren() const {
|
||||
return Children;
|
||||
}
|
||||
const SmallVectorImpl<DIEValue *> &getValues() const { return Values; }
|
||||
const SmallVectorImpl<DIEValue> &getValues() const { return Values; }
|
||||
void setValue(unsigned I, DIEValue New) {
|
||||
assert(I < Values.size());
|
||||
Values[I] = New;
|
||||
}
|
||||
DIE *getParent() const { return Parent; }
|
||||
/// Climb up the parent chain to get the compile or type unit DIE this DIE
|
||||
/// belongs to.
|
||||
@@ -451,7 +506,7 @@ public:
|
||||
|
||||
/// addValue - Add a value and attributes to a DIE.
|
||||
///
|
||||
void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue *Value) {
|
||||
void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue Value) {
|
||||
Abbrev.AddAttribute(Attribute, Form);
|
||||
Values.push_back(Value);
|
||||
}
|
||||
@@ -465,9 +520,11 @@ public:
|
||||
Children.push_back(std::move(Child));
|
||||
}
|
||||
|
||||
/// findAttribute - Find a value in the DIE with the attribute given,
|
||||
/// returns NULL if no such attribute exists.
|
||||
DIEValue *findAttribute(dwarf::Attribute Attribute) const;
|
||||
/// Find a value in the DIE with the attribute given.
|
||||
///
|
||||
/// Returns a default-constructed DIEValue (where \a DIEValue::getType()
|
||||
/// gives \a DIEValue::isNone) if no such attribute exists.
|
||||
DIEValue findAttribute(dwarf::Attribute Attribute) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void print(raw_ostream &O, unsigned IndentCount = 0) const;
|
||||
@@ -478,12 +535,11 @@ public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIELoc - Represents an expression location.
|
||||
//
|
||||
class DIELoc : public DIEValue, public DIE {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIELoc : public DIE {
|
||||
mutable unsigned Size; // Size in bytes excluding size header.
|
||||
|
||||
public:
|
||||
DIELoc() : DIEValue(isLoc), Size(0) {}
|
||||
DIELoc() : Size(0) {}
|
||||
|
||||
/// ComputeSize - Calculate the size of the location expression.
|
||||
///
|
||||
@@ -504,27 +560,22 @@ public:
|
||||
return dwarf::DW_FORM_block;
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isLoc; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIEBlock - Represents a block of values.
|
||||
//
|
||||
class DIEBlock : public DIEValue, public DIE {
|
||||
friend class DIEValue;
|
||||
|
||||
class DIEBlock : public DIE {
|
||||
mutable unsigned Size; // Size in bytes excluding size header.
|
||||
|
||||
public:
|
||||
DIEBlock() : DIEValue(isBlock), Size(0) {}
|
||||
DIEBlock() : Size(0) {}
|
||||
|
||||
/// ComputeSize - Calculate the size of the location expression.
|
||||
///
|
||||
@@ -542,15 +593,11 @@ public:
|
||||
return dwarf::DW_FORM_block;
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast.
|
||||
static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
|
||||
|
||||
private:
|
||||
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void printImpl(raw_ostream &O) const;
|
||||
void print(raw_ostream &O) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user