From: Duncan P. N. Exon Smith Date: Fri, 13 Feb 2015 01:42:09 +0000 (+0000) Subject: AsmWriter/Bitcode: MDExpression X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=a034e076c2aef0be2c816fbe5342f1f0d5798352 AsmWriter/Bitcode: MDExpression git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229023 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index dff1c28591d..98b40d2a033 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -163,7 +163,8 @@ namespace bitc { METADATA_TEMPLATE_TYPE = 25, // [distinct, scope, name, type, ...] METADATA_TEMPLATE_VALUE= 26, // [distinct, scope, name, type, value, ...] METADATA_GLOBAL_VAR = 27, // [distinct, ...] - METADATA_LOCAL_VAR = 28 // [distinct, ...] + METADATA_LOCAL_VAR = 28, // [distinct, ...] + METADATA_EXPRESSION = 29 // [distinct, n x element] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 63eb96324fa..2fd9861c517 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -748,6 +748,7 @@ lltok::Kind LLLexer::LexIdentifier() { DWKEYWORD(ATE, DwarfAttEncoding); DWKEYWORD(VIRTUALITY, DwarfVirtuality); DWKEYWORD(LANG, DwarfLang); + DWKEYWORD(OP, DwarfOp); #undef DWKEYWORD // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 48dbaeeb76a..dc8367c5626 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -3599,9 +3599,44 @@ bool LLParser::ParseMDLocalVariable(MDNode *&Result, bool IsDistinct) { return false; } +/// ParseMDExpression: +/// ::= !MDExpression(0, 7, -1) bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) { - return TokError("unimplemented parser"); + assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); + Lex.Lex(); + + if (ParseToken(lltok::lparen, "expected '(' here")) + return true; + + SmallVector Elements; + if (Lex.getKind() != lltok::rparen) + do { + if (Lex.getKind() == lltok::DwarfOp) { + if (unsigned Op = dwarf::getOperationEncoding(Lex.getStrVal())) { + Lex.Lex(); + Elements.push_back(Op); + continue; + } + return TokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'"); + } + + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected unsigned integer"); + + auto &U = Lex.getAPSIntVal(); + if (U.ugt(UINT64_MAX)) + return TokError("element too large, limit is " + Twine(UINT64_MAX)); + Elements.push_back(U.getZExtValue()); + Lex.Lex(); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rparen, "expected ')' here")) + return true; + + Result = GET_OR_DISTINCT(MDExpression, (Context, Elements)); + return false; } + bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) { return TokError("unimplemented parser"); } diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index ff894df5db4..57218dafbb9 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -198,10 +198,11 @@ namespace lltok { LocalVar, // %foo %"foo" MetadataVar, // !foo StringConstant, // "foo" - DwarfTag, // DW_TAG_foo (includes "DW_TAG_") - DwarfAttEncoding, // DW_ATE_foo (includes "DW_ATE_") - DwarfVirtuality, // DW_VIRTUALITY_foo (includes "DW_VIRTUALITY_") - DwarfLang, // DW_LANG_foo (includes "DW_LANG_") + DwarfTag, // DW_TAG_foo + DwarfAttEncoding, // DW_ATE_foo + DwarfVirtuality, // DW_VIRTUALITY_foo + DwarfLang, // DW_LANG_foo + DwarfOp, // DW_OP_foo // Type valued tokens (TyVal). Type, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 5dee2f90677..98b4803e690 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1552,6 +1552,16 @@ std::error_code BitcodeReader::ParseMetadata() { NextMDValueNo++); break; } + case bitc::METADATA_EXPRESSION: { + if (Record.size() < 1) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDExpression, Record[0], + (Context, makeArrayRef(Record).slice(1))), + NextMDValueNo++); + break; + } case bitc::METADATA_STRING: { std::string String(Record.begin(), Record.end()); llvm::UpgradeMDStringConstant(String); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 9feb4ffda7f..6683e3e6962 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1092,11 +1092,20 @@ static void WriteMDLocalVariable(const MDLocalVariable *N, Record.clear(); } -static void WriteMDExpression(const MDExpression *, const ValueEnumerator &, - BitstreamWriter &, SmallVectorImpl &, - unsigned) { - llvm_unreachable("write not implemented"); +static void WriteMDExpression(const MDExpression *N, const ValueEnumerator &, + BitstreamWriter &Stream, + SmallVectorImpl &Record, + unsigned Abbrev) { + Record.reserve(N->getElements().size() + 1); + + Record.push_back(N->isDistinct()); + for (uint64_t I : N->getElements()) + Record.push_back(I); + + Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev); + Record.clear(); } + static void WriteMDObjCProperty(const MDObjCProperty *, const ValueEnumerator &, BitstreamWriter &, SmallVectorImpl &, unsigned) { diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index ae9a50c94da..5bfbe78496a 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1781,10 +1781,27 @@ static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N, Out << ")"; } -static void writeMDExpression(raw_ostream &, const MDExpression *, - TypePrinting *, SlotTracker *, const Module *) { - llvm_unreachable("write not implemented"); +static void writeMDExpression(raw_ostream &Out, const MDExpression *N, + TypePrinting *TypePrinter, SlotTracker *Machine, + const Module *Context) { + Out << "!MDExpression("; + FieldSeparator FS; + if (N->isValid()) { + for (auto I = N->expr_op_begin(), E = N->expr_op_end(); I != E; ++I) { + const char *OpStr = dwarf::OperationEncodingString(I->getOp()); + assert(OpStr && "Expected valid opcode"); + + Out << FS << OpStr; + for (unsigned A = 0, AE = I->getNumArgs(); A != AE; ++A) + Out << FS << I->getArg(A); + } + } else { + for (const auto &I : N->getElements()) + Out << FS << I; + } + Out << ")"; } + static void writeMDObjCProperty(raw_ostream &, const MDObjCProperty *, TypePrinting *, SlotTracker *, const Module *) { llvm_unreachable("write not implemented"); diff --git a/test/Assembler/invalid-mdexpression-large.ll b/test/Assembler/invalid-mdexpression-large.ll new file mode 100644 index 00000000000..43b8ce0c9ef --- /dev/null +++ b/test/Assembler/invalid-mdexpression-large.ll @@ -0,0 +1,7 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK-NOT: error +!0 = !MDExpression(18446744073709551615) + +; CHECK: :[[@LINE+1]]:20: error: element too large, limit is 18446744073709551615 +!1 = !MDExpression(18446744073709551616) diff --git a/test/Assembler/invalid-mdexpression-verify.ll b/test/Assembler/invalid-mdexpression-verify.ll new file mode 100644 index 00000000000..e573ef32155 --- /dev/null +++ b/test/Assembler/invalid-mdexpression-verify.ll @@ -0,0 +1,9 @@ +; RUN: not llvm-as -disable-output < %s 2>&1 | FileCheck -check-prefix VERIFY %s +; RUN: llvm-as -disable-verify < %s | llvm-dis | FileCheck -check-prefix NOVERIFY %s + +; NOVERIFY: !named = !{!0} +!named = !{!0} + +; NOVERIFY: !0 = !MDExpression(0, 1, 9, 7, 2) +; VERIFY: assembly parsed, but does not verify +!0 = !MDExpression(0, 1, 9, 7, 2) diff --git a/test/Assembler/mdexpression.ll b/test/Assembler/mdexpression.ll new file mode 100644 index 00000000000..42bbfe02d67 --- /dev/null +++ b/test/Assembler/mdexpression.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; RUN: verify-uselistorder %s + +; CHECK: !named = !{!0, !1, !2, !3, !4} +!named = !{!0, !1, !2, !3, !4} + +; CHECK: !0 = !MDExpression() +; CHECK-NEXT: !1 = !MDExpression(DW_OP_deref) +; CHECK-NEXT: !2 = !MDExpression(DW_OP_plus, 3) +; CHECK-NEXT: !3 = !MDExpression(DW_OP_bit_piece, 3, 7) +; CHECK-NEXT: !4 = !MDExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_bit_piece, 3, 7) +!0 = !MDExpression() +!1 = !MDExpression(DW_OP_deref) +!2 = !MDExpression(DW_OP_plus, 3) +!3 = !MDExpression(DW_OP_bit_piece, 3, 7) +!4 = !MDExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_bit_piece, 3, 7) diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim index e3e462f9a2f..6b4b8bbd12b 100644 --- a/utils/vim/llvm.vim +++ b/utils/vim/llvm.vim @@ -79,6 +79,7 @@ syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*[=!]/ syn match llvmType /!\zs\a\+\ze\s*(/ syn match llvmConstant /\/ syn match llvmConstant /\/ +syn match llvmConstant /\/ syn match llvmConstant /\/ syn match llvmConstant /\/