summaryrefslogtreecommitdiffstats
path: root/llvm/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2018-02-07 16:46:33 +0000
committerMomchil Velikov <momchil.velikov@arm.com>2018-02-07 16:46:33 +0000
commitc502027efdf0361d5f8f57af6ad62d8096f0b6da (patch)
tree129c60d419acb0de03aa68b89df1e9d166646a9e /llvm/lib/AsmParser/LLParser.cpp
parent466396592d7a5440379b0e606e7e8674c6d348fd (diff)
downloadbcm5719-llvm-c502027efdf0361d5f8f57af6ad62d8096f0b6da.tar.gz
bcm5719-llvm-c502027efdf0361d5f8f57af6ad62d8096f0b6da.zip
[DebugInfo] Improvements to representation of enumeration types (PR36168)
This patch is the LLVM part of fixing the issues, described in https://bugs.llvm.org/show_bug.cgi?id=36168 * The representation of enumerator values in the debug info metadata now contains a boolean flag isUnsigned, which determines how the bits of the value are interpreted. * The DW_TAG_enumeration type DIE now always (for DWARF version >= 3) includes a DW_AT_type attribute, which refers to the underlying integer type, as suggested in DWARFv4 (5.7 Enumeration Type Entries). * The debug info metadata for enumeration type contains (in flags) indication whether this is a C++11 "fixed enum". * For C++11 enumeration with a fixed underlying type, the DIE also includes the DW_AT_enum_class attribute (for DWARF version >= 4). * Encoding of enumerator constants uses DW_FORM_sdata for signed values and DW_FORM_udata for unsigned values, as suggested by DWARFv4 (7.5.4 Attribute Encodings). The changes should be backwards compatible: * the isUnsigned attribute is optional and defaults to false. * if the underlying type for the enumeration is not available, the enumerator values are considered signed. * the FixedEnum flag defaults to clear. * the bitcode format for DIEnumerator stores the unsigned flag bit #1 of the first record element, so the format does not change and the zero previously stored there is consistent with the false default for IsUnsigned. Differential Revision: https://reviews.llvm.org/D42734 llvm-svn: 324489
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 2833ef44fe9..209a834fed1 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3636,6 +3636,22 @@ struct MDSignedOrMDField : MDEitherFieldImpl<MDSignedField, MDField> {
}
};
+struct MDSignedOrUnsignedField
+ : MDEitherFieldImpl<MDSignedField, MDUnsignedField> {
+ MDSignedOrUnsignedField() : ImplTy(MDSignedField(0), MDUnsignedField(0)) {}
+
+ bool isMDSignedField() const { return WhatIs == IsTypeA; }
+ bool isMDUnsignedField() const { return WhatIs == IsTypeB; }
+ int64_t getMDSignedValue() const {
+ assert(isMDSignedField() && "Wrong field type");
+ return A.Val;
+ }
+ uint64_t getMDUnsignedValue() const {
+ assert(isMDUnsignedField() && "Wrong field type");
+ return B.Val;
+ }
+};
+
} // end anonymous namespace
namespace llvm {
@@ -3913,6 +3929,27 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
}
template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+ MDSignedOrUnsignedField &Result) {
+ if (Lex.getKind() != lltok::APSInt)
+ return false;
+
+ if (Lex.getAPSIntVal().isSigned()) {
+ MDSignedField Res = Result.A;
+ if (ParseMDField(Loc, Name, Res))
+ return true;
+ Result.assign(Res);
+ return false;
+ }
+
+ MDUnsignedField Res = Result.B;
+ if (ParseMDField(Loc, Name, Res))
+ return true;
+ Result.assign(Res);
+ return false;
+}
+
+template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
LocTy ValueLoc = Lex.getLoc();
std::string S;
@@ -4077,15 +4114,24 @@ bool LLParser::ParseDISubrange(MDNode *&Result, bool IsDistinct) {
}
/// ParseDIEnumerator:
-/// ::= !DIEnumerator(value: 30, name: "SomeKind")
+/// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind")
bool LLParser::ParseDIEnumerator(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(name, MDStringField, ); \
- REQUIRED(value, MDSignedField, );
+ REQUIRED(value, MDSignedOrUnsignedField, ); \
+ OPTIONAL(isUnsigned, MDBoolField, (false));
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
- Result = GET_OR_DISTINCT(DIEnumerator, (Context, value.Val, name.Val));
+ if (isUnsigned.Val && value.isMDSignedField())
+ return TokError("unsigned enumerator with negative value");
+
+ int64_t Value = value.isMDSignedField()
+ ? value.getMDSignedValue()
+ : static_cast<int64_t>(value.getMDUnsignedValue());
+ Result =
+ GET_OR_DISTINCT(DIEnumerator, (Context, Value, isUnsigned.Val, name.Val));
+
return false;
}
OpenPOWER on IntegriCloud