summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AsmParser/LLLexer.cpp6
-rw-r--r--lib/AsmParser/LLParser.cpp25
-rw-r--r--lib/AsmParser/LLParser.h4
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/IR/AsmWriter.cpp7
-rw-r--r--test/Assembler/generic-debug-node.ll13
-rw-r--r--test/Assembler/invalid-generic-debug-node-tag-bad.ll4
-rw-r--r--test/Assembler/invalid-generic-debug-node-tag-wrong-type.ll4
-rw-r--r--utils/vim/llvm.vim1
9 files changed, 57 insertions, 8 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 1a85852d5f8..eb16608ad1e 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -738,6 +738,12 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(landingpad, LandingPad);
#undef INSTKEYWORD
+ if (Len >= strlen("DW_TAG_") &&
+ !memcmp(StartChar, "DW_TAG_", strlen("DW_TAG_"))) {
+ StrVal.assign(StartChar, CurPtr);
+ return lltok::DwarfTag;
+ }
+
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
// the CFE to avoid forcing it to deal with 64-bit numbers.
if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 8ef8d664457..1f5087c152c 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -24,6 +24,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
@@ -2936,6 +2937,28 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
return false;
}
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
+ if (Lex.getKind() == lltok::APSInt)
+ return ParseMDField(Loc, Name,
+ static_cast<MDUnsignedField<uint32_t> &>(Result));
+
+ if (Result.Seen)
+ return Error(Loc,
+ "field '" + Name + "' cannot be specified more than once");
+
+ if (Lex.getKind() != lltok::DwarfTag)
+ return TokError("expected DWARF tag");
+
+ unsigned Tag = dwarf::getTag(Lex.getStrVal());
+ if (Tag == dwarf::DW_TAG_invalid)
+ return TokError("invalid DWARF tag" + Twine(" '") + Lex.getStrVal() + "'");
+ assert(Tag < 1u << 16 && "Expected valid DWARF tag");
+
+ Result.assign(Tag);
+ Lex.Lex();
+ return false;
+}
+
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
Metadata *MD;
if (ParseMetadata(MD, nullptr))
@@ -3056,7 +3079,7 @@ bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) {
/// ::= !GenericDebugNode(tag: 15, header: "...", operands: {...})
bool LLParser::ParseGenericDebugNode(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(tag, MDUnsignedField<uint32_t>, (0, ~0u >> 16)); \
+ REQUIRED(tag, DwarfTagField, ); \
OPTIONAL(header, MDStringField, ); \
OPTIONAL(operands, MDFieldList, );
PARSE_MD_FIELDS();
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 6e410d05cd2..240fb608138 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -102,6 +102,9 @@ namespace llvm {
NumTy Max = std::numeric_limits<NumTy>::max())
: ImplTy(Default), Max(Max) {}
};
+ struct DwarfTagField : public MDUnsignedField<uint32_t> {
+ DwarfTagField() : MDUnsignedField<uint32_t>(0, ~0u >> 16) {}
+ };
struct MDField : public MDFieldImpl<Metadata *> {
MDField() : ImplTy(nullptr) {}
};
@@ -427,6 +430,7 @@ namespace llvm {
bool ParseMDField(LocTy Loc, StringRef Name,
MDUnsignedField<uint32_t> &Result);
+ bool ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result);
bool ParseMDField(LocTy Loc, StringRef Name, MDField &Result);
bool ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result);
bool ParseMDField(LocTy Loc, StringRef Name, MDFieldList &Result);
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 5b3463bf4ab..4e5af1e89bd 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -198,6 +198,7 @@ namespace lltok {
LocalVar, // %foo %"foo"
MetadataVar, // !foo
StringConstant, // "foo"
+ DwarfTag, // DW_TAG_foo (includes "DW_TAG_")
// Type valued tokens (TyVal).
Type,
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index ba1c5260074..46f26c579ac 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -1291,8 +1291,11 @@ static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
SlotTracker *Machine, const Module *Context) {
Out << "!GenericDebugNode(";
FieldSeparator FS;
- // Always output the line, since 0 is a relevant and important value for it.
- Out << FS << "tag: " << N->getTag();
+ Out << FS << "tag: ";
+ if (const char *Tag = dwarf::TagString(N->getTag()))
+ Out << Tag;
+ else
+ Out << N->getTag();
if (!N->getHeader().empty()) {
Out << FS << "header: \"";
PrintEscapedString(N->getHeader(), Out);
diff --git a/test/Assembler/generic-debug-node.ll b/test/Assembler/generic-debug-node.ll
index e8b169170ac..cb7222b043d 100644
--- a/test/Assembler/generic-debug-node.ll
+++ b/test/Assembler/generic-debug-node.ll
@@ -1,24 +1,27 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; RUN: verify-uselistorder %s
-; CHECK: !named = !{!0, !1, !1, !2, !2, !2, !2, !3, !4}
-!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
+; CHECK: !named = !{!0, !1, !1, !2, !2, !2, !2, !3, !4, !2}
+!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
; CHECK: !0 = !{}
!0 = !{}
-; CHECK-NEXT: !1 = !GenericDebugNode(tag: 3, header: "some\00header", operands: {!0, !2, !2})
+; CHECK-NEXT: !1 = !GenericDebugNode(tag: DW_TAG_entry_point, header: "some\00header", operands: {!0, !2, !2})
!1 = !GenericDebugNode(tag: 3, header: "some\00header", operands: {!0, !3, !4})
!2 = !GenericDebugNode(tag: 3, header: "some\00header", operands: {!{}, !3, !4})
-; CHECK-NEXT: !2 = !GenericDebugNode(tag: 3)
+; CHECK-NEXT: !2 = !GenericDebugNode(tag: DW_TAG_entry_point)
!3 = !GenericDebugNode(tag: 3)
!4 = !GenericDebugNode(tag: 3, header: "")
!5 = !GenericDebugNode(tag: 3, operands: {})
!6 = !GenericDebugNode(tag: 3, header: "", operands: {})
-; CHECK-NEXT: !3 = distinct !GenericDebugNode(tag: 3)
+; CHECK-NEXT: !3 = distinct !GenericDebugNode(tag: DW_TAG_entry_point)
!7 = distinct !GenericDebugNode(tag: 3)
; CHECK-NEXT: !4 = !GenericDebugNode(tag: 65535)
!8 = !GenericDebugNode(tag: 65535)
+
+; CHECK-NOT: !
+!9 = !GenericDebugNode(tag: DW_TAG_entry_point)
diff --git a/test/Assembler/invalid-generic-debug-node-tag-bad.ll b/test/Assembler/invalid-generic-debug-node-tag-bad.ll
new file mode 100644
index 00000000000..98c10b6a878
--- /dev/null
+++ b/test/Assembler/invalid-generic-debug-node-tag-bad.ll
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:29: error: invalid DWARF tag 'DW_TAG_badtag'
+!0 = !GenericDebugNode(tag: DW_TAG_badtag)
diff --git a/test/Assembler/invalid-generic-debug-node-tag-wrong-type.ll b/test/Assembler/invalid-generic-debug-node-tag-wrong-type.ll
new file mode 100644
index 00000000000..fca24a70bf0
--- /dev/null
+++ b/test/Assembler/invalid-generic-debug-node-tag-wrong-type.ll
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:29: error: expected DWARF tag
+!0 = !GenericDebugNode(tag: "string")
diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim
index b7411c3cd31..57c71331105 100644
--- a/utils/vim/llvm.vim
+++ b/utils/vim/llvm.vim
@@ -77,6 +77,7 @@ syn match llvmIdentifier /[%@][-a-zA-Z$._][-a-zA-Z$._0-9]*/
syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*$/
syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*[=!]/
syn match llvmType /!\zs\a\+\ze\s*(/
+syn match llvmConstant /\<DW_TAG_[a-z_]\+\>/
" Syntax-highlight dejagnu test commands.
syn match llvmSpecialComment /;\s*RUN:.*$/