Revert "AsmPrinter: Change DIEValue to be stored by value"

This reverts commit r238349, since it caused some errors on bots:
  - std::is_trivially_copyable isn't available until GCC 5.0.
  - It was complaining about strict aliasing with my use of
    ArrayCharUnion.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2015-05-27 19:30:27 +00:00
parent b9d92c6a8d
commit 3c41ae83f2
12 changed files with 542 additions and 512 deletions

View File

@ -104,14 +104,62 @@ public:
#endif
};
//===--------------------------------------------------------------------===//
/// DIEValue - A debug information entry value. Some of these roughly correlate
/// to DWARF attribute classes.
///
class DIEValue {
public:
enum Type {
isInteger,
isString,
isExpr,
isLabel,
isDelta,
isEntry,
isTypeSignature,
isBlock,
isLoc,
isLocList,
};
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 {
class DIEInteger : public DIEValue {
friend DIEValue;
uint64_t Integer;
public:
explicit DIEInteger(uint64_t I) : Integer(I) {}
explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
/// BestForm - Choose the best form for integer.
///
@ -138,91 +186,120 @@ public:
uint64_t getValue() const { return Integer; }
void setValue(uint64_t Val) { Integer = Val; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEExpr - An expression DIE.
//
class DIEExpr {
class DIEExpr : public DIEValue {
friend class DIEValue;
const MCExpr *Expr;
public:
explicit DIEExpr(const MCExpr *E) : Expr(E) {}
explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {}
/// getValue - Get MCExpr.
///
const MCExpr *getValue() const { return Expr; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIELabel - A label DIE.
//
class DIELabel {
class DIELabel : public DIEValue {
friend class DIEValue;
const MCSymbol *Label;
public:
explicit DIELabel(const MCSymbol *L) : Label(L) {}
explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
/// getValue - Get MCSymbol.
///
const MCSymbol *getValue() const { return Label; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEDelta - A simple label difference DIE.
///
class DIEDelta {
class DIEDelta : public DIEValue {
friend class DIEValue;
const MCSymbol *LabelHi;
const MCSymbol *LabelLo;
public:
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
: DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEString - A container for string values.
///
class DIEString {
class DIEString : public DIEValue {
friend class DIEValue;
DwarfStringPoolEntryRef S;
public:
DIEString(DwarfStringPoolEntryRef S) : S(S) {}
DIEString(DwarfStringPoolEntryRef S) : DIEValue(isString), S(S) {}
/// getString - Grab the string out of the object.
StringRef getString() const { return S.getString(); }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
@ -231,48 +308,60 @@ public:
/// this class can also be used as a proxy for a debug information entry not
/// yet defined (ie. types.)
class DIE;
class DIEEntry {
DIE *Entry;
class DIEEntry : public DIEValue {
friend class DIEValue;
DIEEntry() = delete;
DIE &Entry;
public:
explicit DIEEntry(DIE &E) : Entry(&E) {}
explicit DIEEntry(DIE &E) : DIEValue(isEntry), 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);
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
// 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 {
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
: sizeof(int32_t);
}
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// \brief A signature reference to a type unit.
class DIETypeSignature {
const DwarfTypeUnit *Unit;
class DIETypeSignature : public DIEValue {
friend class DIEValue;
DIETypeSignature() = delete;
const DwarfTypeUnit &Unit;
public:
explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {}
explicit DIETypeSignature(const DwarfTypeUnit &Unit)
: DIEValue(isTypeSignature), Unit(Unit) {}
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
// \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 {
assert(Form == dwarf::DW_FORM_ref_sig8);
return 8;
}
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
@ -280,125 +369,27 @@ public:
/// DIELocList - Represents a pointer to a location list in the debug_loc
/// section.
//
class DIELocList {
class DIELocList : public DIEValue {
friend class DIEValue;
// Index into the .debug_loc vector.
size_t Index;
public:
DIELocList(size_t I) : Index(I) {}
DIELocList(size_t I) : DIEValue(isLocList), Index(I) {}
/// getValue - Grab the current index out.
size_t getValue() const { return Index; }
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
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,
isInteger,
isString,
isExpr,
isLabel,
isDelta,
isEntry,
isTypeSignature,
isBlock,
isLoc,
isLocList,
};
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isLocList; }
private:
/// Ty - Type of data stored in the value.
///
Type Ty;
AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel, DIEDelta *,
DIEEntry, DIETypeSignature, DIEBlock *, DIELoc *,
DIELocList> Val;
static_assert(sizeof(Val) == sizeof(uint64_t),
"Only small values should be allocated locally");
public:
DIEValue() : Ty(isNone) {}
DIEValue(const DIEValue &X) = default;
DIEValue &operator=(const DIEValue &X) = default;
explicit operator bool() const { return Ty; }
#define CONSTRUCT_FROM_SMALL(Kind) \
DIEValue(const DIE##Kind &V) : Ty(is##Kind) { \
static_assert(std::is_trivially_copyable<DIE##Kind>::value, \
"Expected trivial type"); \
new (reinterpret_cast<void *>(Val.buffer)) DIE##Kind(V); \
}
#define CONSTRUCT_FROM_LARGE(Kind) \
DIEValue(const DIE##Kind *V) : Ty(is##Kind) { \
assert(V && "Expected valid value"); \
*reinterpret_cast<const DIE##Kind **>(Val.buffer) = V; \
}
CONSTRUCT_FROM_SMALL(Integer)
CONSTRUCT_FROM_SMALL(Expr)
CONSTRUCT_FROM_SMALL(Label)
CONSTRUCT_FROM_SMALL(Entry)
CONSTRUCT_FROM_SMALL(TypeSignature)
CONSTRUCT_FROM_SMALL(LocList)
CONSTRUCT_FROM_SMALL(String)
CONSTRUCT_FROM_LARGE(Delta)
CONSTRUCT_FROM_LARGE(Block)
CONSTRUCT_FROM_LARGE(Loc)
#undef CONSTRUCT_FROM_SMALL
#undef CONSTRUCT_FROM_LARGE
// Accessors
Type getType() const { return Ty; }
#define GET_VALUE_REF_SMALL(Kind) \
const DIE##Kind &getDIE##Kind() const { \
assert(getType() == is##Kind && "Expected " #Kind); \
return *reinterpret_cast<const DIE##Kind *>(Val.buffer); \
}
#define GET_VALUE_REF_LARGE(Kind) \
const DIE##Kind &getDIE##Kind() const { \
assert(getType() == is##Kind && "Expected " #Kind); \
return **reinterpret_cast<const DIE##Kind *const *>(Val.buffer); \
}
GET_VALUE_REF_SMALL(Integer)
GET_VALUE_REF_SMALL(Expr)
GET_VALUE_REF_SMALL(Label)
GET_VALUE_REF_SMALL(Entry)
GET_VALUE_REF_SMALL(TypeSignature)
GET_VALUE_REF_SMALL(LocList)
GET_VALUE_REF_SMALL(String)
GET_VALUE_REF_LARGE(Delta)
GET_VALUE_REF_LARGE(Block)
GET_VALUE_REF_LARGE(Loc)
#undef GET_VALUE_REF_SMALL
#undef GET_VALUE_REF_LARGE
/// 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;
void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void dump() const;
void printImpl(raw_ostream &O) const;
#endif
};
@ -433,7 +424,7 @@ protected:
/// Attribute values.
///
SmallVector<DIEValue, 12> Values;
SmallVector<DIEValue *, 12> Values;
protected:
DIE()
@ -455,11 +446,7 @@ public:
const std::vector<std::unique_ptr<DIE>> &getChildren() const {
return Children;
}
const SmallVectorImpl<DIEValue> &getValues() const { return Values; }
void setValue(unsigned I, DIEValue New) {
assert(I < Values.size());
Values[I] = New;
}
const SmallVectorImpl<DIEValue *> &getValues() const { return Values; }
DIE *getParent() const { return Parent; }
/// Climb up the parent chain to get the compile or type unit DIE this DIE
/// belongs to.
@ -472,7 +459,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);
}
@ -486,11 +473,9 @@ public:
Children.push_back(std::move(Child));
}
/// 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;
/// findAttribute - Find a value in the DIE with the attribute given,
/// returns NULL if no such attribute exists.
DIEValue *findAttribute(dwarf::Attribute Attribute) const;
#ifndef NDEBUG
void print(raw_ostream &O, unsigned IndentCount = 0) const;
@ -501,11 +486,12 @@ public:
//===--------------------------------------------------------------------===//
/// DIELoc - Represents an expression location.
//
class DIELoc : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
class DIELoc : public DIEValue, public DIE {
friend class DIEValue;
mutable unsigned Size; // Size in bytes excluding size header.
public:
DIELoc() : Size(0) {}
DIELoc() : DIEValue(isLoc), Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@ -526,22 +512,27 @@ public:
return dwarf::DW_FORM_block;
}
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};
//===--------------------------------------------------------------------===//
/// DIEBlock - Represents a block of values.
//
class DIEBlock : public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
class DIEBlock : public DIEValue, public DIE {
friend class DIEValue;
mutable unsigned Size; // Size in bytes excluding size header.
public:
DIEBlock() : Size(0) {}
DIEBlock() : DIEValue(isBlock), Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@ -559,11 +550,15 @@ public:
return dwarf::DW_FORM_block;
}
void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
// 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;
#ifndef NDEBUG
void print(raw_ostream &O) const;
void printImpl(raw_ostream &O) const;
#endif
};