diff options
author | Momchil Velikov <momchil.velikov@arm.com> | 2018-02-12 16:10:09 +0000 |
---|---|---|
committer | Momchil Velikov <momchil.velikov@arm.com> | 2018-02-12 16:10:09 +0000 |
commit | 08dc66eff0c7ad594584a8a6925ef830cd6873a1 (patch) | |
tree | 36a9dc79a29945f66faf9ac868a413e9733cc037 /llvm/lib/AsmParser | |
parent | b941f5dc5f36daf6fac61b5bb2faf9e461a6cc91 (diff) | |
download | bcm5719-llvm-08dc66eff0c7ad594584a8a6925ef830cd6873a1.tar.gz bcm5719-llvm-08dc66eff0c7ad594584a8a6925ef830cd6873a1.zip |
Re-commit r324489: [DebugInfo] Improvements to representation of enumeration types (PR36168)
Differential Revision: https://reviews.llvm.org/D42734
llvm-svn: 324899
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 52 |
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; } |