//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dwarfdebug"
-
+#include "ByteStreamer.h"
#include "DIEHash.h"
#include "DIE.h"
+#include "DwarfDebug.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/AsmPrinter.h"
using namespace llvm;
+#define DEBUG_TYPE "dwarfdebug"
+
/// \brief Grabs the string in whichever attribute is passed in and returns
/// a reference to it.
static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) {
Hash.update((uint64_t)cast<DIEInteger>(*I)->getValue());
}
+// Hash the contents of a loclistptr class.
+void DIEHash::hashLocList(const DIELocList &LocList) {
+ HashingByteStreamer Streamer(*this);
+ DwarfDebug &DD = *AP->getDwarfDebug();
+ for (const auto &Entry :
+ DD.getDebugLocEntries()[LocList.getValue()].List)
+ DD.emitDebugLocEntry(Streamer, Entry);
+}
+
// Hash an individual attribute \param Attr based on the type of attribute and
// the form.
void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
const DIEAbbrevData *Desc = Attr.Desc;
dwarf::Attribute Attribute = Desc->getAttribute();
- // 7.27 Step 3
- // ... An attribute that refers to another type entry T is processed as
- // follows:
- if (const DIEEntry *EntryAttr = dyn_cast<DIEEntry>(Value)) {
- hashDIEEntry(Attribute, Tag, *EntryAttr->getEntry());
- return;
- }
-
// Other attribute values use the letter 'A' as the marker, and the value
// consists of the form code (encoded as an unsigned LEB128 value) followed by
// the encoding of the value according to the form code. To ensure
// DW_FORM_string, and DW_FORM_block.
switch (Value->getType()) {
+ // 7.27 Step 3
+ // ... An attribute that refers to another type entry T is processed as
+ // follows:
+ case DIEValue::isEntry:
+ hashDIEEntry(Attribute, Tag, cast<DIEEntry>(Value)->getEntry());
+ break;
case DIEValue::isInteger: {
addULEB128('A');
addULEB128(Attribute);
break;
case DIEValue::isBlock:
case DIEValue::isLoc:
+ case DIEValue::isLocList:
addULEB128('A');
addULEB128(Attribute);
addULEB128(dwarf::DW_FORM_block);
if (isa<DIEBlock>(Value)) {
addULEB128(cast<DIEBlock>(Value)->ComputeSize(AP));
hashBlockData(cast<DIEBlock>(Value)->getValues());
- } else {
+ } else if (isa<DIELoc>(Value)) {
addULEB128(cast<DIELoc>(Value)->ComputeSize(AP));
hashBlockData(cast<DIELoc>(Value)->getValues());
+ } else {
+ // We could add the block length, but that would take
+ // a bit of work and not add a lot of uniqueness
+ // to the hash in some way we could test.
+ hashLocList(*cast<DIELocList>(Value));
}
break;
- // FIXME: Handle loclistptr.
- case DIEValue::isLocList:
// FIXME: It's uncertain whether or not we should handle this at the moment.
case DIEValue::isExpr:
case DIEValue::isLabel:
case DIEValue::isDelta:
- // These two were handled above.
- case DIEValue::isEntry:
case DIEValue::isTypeSignature:
llvm_unreachable("Add support for additional value types.");
}
addAttributes(Die);
// Then hash each of the children of the DIE.
- for (std::vector<DIE *>::const_iterator I = Die.getChildren().begin(),
- E = Die.getChildren().end();
- I != E; ++I) {
+ for (auto &C : Die.getChildren()) {
// 7.27 Step 7
// If C is a nested type entry or a member function entry, ...
- if (isType((*I)->getTag()) || (*I)->getTag() == dwarf::DW_TAG_subprogram) {
- StringRef Name = getDIEStringAttr(**I, dwarf::DW_AT_name);
+ if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) {
+ StringRef Name = getDIEStringAttr(*C, dwarf::DW_AT_name);
// ... and has a DW_AT_name attribute
if (!Name.empty()) {
- hashNestedType(**I, Name);
+ hashNestedType(*C, Name);
continue;
}
}
- computeHash(**I);
+ computeHash(*C);
}
// Following the last (or if there are no children), append a zero byte.