[llvm] r225830 - AsmParser/Bitcode: Add support for MDLocation

Duncan P. N. Exon Smith dexonsmith at apple.com
Tue Jan 13 13:10:45 PST 2015


Author: dexonsmith
Date: Tue Jan 13 15:10:44 2015
New Revision: 225830

URL: http://llvm.org/viewvc/llvm-project?rev=225830&view=rev
Log:
AsmParser/Bitcode: Add support for MDLocation

This adds assembly and bitcode support for `MDLocation`.  The assembly
side is rather big, since this is the first `MDNode` subclass (that
isn't `MDTuple`).  Part of PR21433.

(If you're wondering where the mountains of testcase updates are, we
don't need them until I update `DILocation` and `DebugLoc` to actually
use this class.)

Added:
    llvm/trunk/test/Assembler/invalid-mdlocation-field-bad.ll
    llvm/trunk/test/Assembler/invalid-mdlocation-field-twice.ll
    llvm/trunk/test/Assembler/invalid-mdlocation-overflow-column.ll
    llvm/trunk/test/Assembler/invalid-mdlocation-overflow-line.ll
    llvm/trunk/test/Assembler/invalid-specialized-mdnode.ll
    llvm/trunk/test/Assembler/mdlocation.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
    llvm/trunk/utils/vim/llvm.vim

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Jan 13 15:10:44 2015
@@ -2883,6 +2883,23 @@ attached to the ``add`` instruction usin
 More information about specific metadata nodes recognized by the
 optimizers and code generator is found below.
 
+Specialized Metadata Nodes
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Specialized metadata nodes are custom data structures in metadata (as opposed
+to generic tuples).  Their fields are labelled, and can be specified in any
+order.
+
+MDLocation
+""""""""""
+
+``MDLocation`` nodes represent source debug locations.  The ``scope:`` field is
+mandatory.
+
+.. code-block:: llvm
+
+    !0 = !MDLocation(line: 2900, column: 42, scope: !1, inlinedAt: !2)
+
 '``tbaa``' Metadata
 ^^^^^^^^^^^^^^^^^^^
 

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Jan 13 15:10:44 2015
@@ -142,7 +142,7 @@ namespace bitc {
     METADATA_NAME          = 4,   // STRING:        [values]
     METADATA_DISTINCT_NODE = 5,   // DISTINCT_NODE: [n x md num]
     METADATA_KIND          = 6,   // [n x [id, name]]
-    // 7 is unused.
+    METADATA_LOCATION      = 7,   // [distinct, line, col, scope, inlined-at?]
     METADATA_OLD_NODE      = 8,   // OLD_NODE:      [n x (type num, value num)]
     METADATA_OLD_FN_NODE   = 9,   // OLD_FN_NODE:   [n x (type num, value num)]
     METADATA_NAMED_NODE    = 10,  // NAMED_NODE:    [n x mdnodes]

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Jan 13 15:10:44 2015
@@ -587,8 +587,11 @@ bool LLParser::ParseStandaloneMetadata()
     return TokError("unexpected type in metadata definition");
 
   bool IsDistinct = EatIfPresent(lltok::kw_distinct);
-  if (ParseToken(lltok::exclaim, "Expected '!' here") ||
-      ParseMDTuple(Init, IsDistinct))
+  if (Lex.getKind() == lltok::MetadataVar) {
+    if (ParseSpecializedMDNode(Init, IsDistinct))
+      return true;
+  } else if (ParseToken(lltok::exclaim, "Expected '!' here") ||
+             ParseMDTuple(Init, IsDistinct))
     return true;
 
   // See if this was forward referenced, if so, handle it.
@@ -2902,7 +2905,11 @@ bool LLParser::ParseMDTuple(MDNode *&MD,
 /// MDNode:
 ///  ::= !{ ... }
 ///  ::= !7
+///  ::= !MDLocation(...)
 bool LLParser::ParseMDNode(MDNode *&N) {
+  if (Lex.getKind() == lltok::MetadataVar)
+    return ParseSpecializedMDNode(N);
+
   return ParseToken(lltok::exclaim, "expected '!' here") ||
          ParseMDNodeTail(N);
 }
@@ -2916,6 +2923,106 @@ bool LLParser::ParseMDNodeTail(MDNode *&
   return ParseMDNodeID(N);
 }
 
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
+                            MDUnsignedField<uint32_t> &Result) {
+  if (Result.Seen)
+    return Error(Loc,
+                 "field '" + Name + "' cannot be specified more than once");
+
+  if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
+    return TokError("expected unsigned integer");
+  uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(Result.Max + 1ull);
+
+  if (Val64 > Result.Max)
+    return TokError("value for '" + Name + "' too large, limit is " +
+                    Twine(Result.Max));
+  Result.assign(Val64);
+  Lex.Lex();
+  return false;
+}
+
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
+  if (Result.Seen)
+    return Error(Loc,
+                 "field '" + Name + "' cannot be specified more than once");
+
+  Metadata *MD;
+  if (ParseMetadata(MD, nullptr))
+    return true;
+
+  Result.assign(MD);
+  return false;
+}
+
+template <class ParserTy>
+bool LLParser::ParseMDFieldsImpl(ParserTy parseField) {
+  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+  Lex.Lex();
+
+  if (ParseToken(lltok::lparen, "expected '(' here"))
+    return true;
+  if (EatIfPresent(lltok::rparen))
+    return false;
+
+  do {
+    if (Lex.getKind() != lltok::LabelStr)
+      return TokError("expected field label here");
+
+    if (parseField())
+      return true;
+  } while (EatIfPresent(lltok::comma));
+
+  return ParseToken(lltok::rparen, "expected ')' here");
+}
+
+bool LLParser::ParseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
+  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+#define DISPATCH_TO_PARSER(CLASS)                                              \
+  if (Lex.getStrVal() == #CLASS)                                               \
+    return Parse##CLASS(N, IsDistinct);
+
+  DISPATCH_TO_PARSER(MDLocation);
+#undef DISPATCH_TO_PARSER
+
+  return TokError("expected metadata type");
+}
+
+#define PARSE_MD_FIELD(NAME)                                                   \
+  do {                                                                         \
+    if (Lex.getStrVal() == #NAME) {                                            \
+      LocTy Loc = Lex.getLoc();                                                \
+      Lex.Lex();                                                               \
+      if (ParseMDField(Loc, #NAME, NAME))                                      \
+        return true;                                                           \
+      return false;                                                            \
+    }                                                                          \
+  } while (0)
+
+/// ParseMDLocationFields:
+///   ::= !MDLocation(line: 43, column: 8, scope: !5, inlinedAt: !6)
+bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) {
+  MDUnsignedField<uint32_t> line(0, ~0u >> 8);
+  MDUnsignedField<uint32_t> column(0, ~0u >> 24);
+  MDField scope;
+  MDField inlinedAt;
+  if (ParseMDFieldsImpl([&]() -> bool {
+        PARSE_MD_FIELD(line);
+        PARSE_MD_FIELD(column);
+        PARSE_MD_FIELD(scope);
+        PARSE_MD_FIELD(inlinedAt);
+        return TokError(Twine("invalid field '") + Lex.getStrVal() + "'");
+      }))
+    return true;
+
+  if (!scope.Seen)
+    return TokError("missing required field 'scope'");
+
+  auto get = (IsDistinct ? MDLocation::getDistinct : MDLocation::get);
+  Result = get(Context, line.Val, column.Val, scope.Val, inlinedAt.Val);
+  return false;
+}
+#undef PARSE_MD_FIELD
+
 /// ParseMetadataAsValue
 ///  ::= metadata i32 %local
 ///  ::= metadata i32 @global
@@ -2960,7 +3067,16 @@ bool LLParser::ParseValueAsMetadata(Meta
 ///  ::= !42
 ///  ::= !{...}
 ///  ::= !"string"
+///  ::= !MDLocation(...)
 bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
+  if (Lex.getKind() == lltok::MetadataVar) {
+    MDNode *N;
+    if (ParseSpecializedMDNode(N))
+      return true;
+    MD = N;
+    return false;
+  }
+
   // ValueAsMetadata:
   // <type> <value>
   if (Lex.getKind() != lltok::exclaim)

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue Jan 13 15:10:44 2015
@@ -80,6 +80,31 @@ namespace llvm {
     }
   };
 
+  /// Structure to represent an optional metadata field.
+  template <class FieldTy> struct MDFieldImpl {
+    typedef MDFieldImpl ImplTy;
+    FieldTy Val;
+    bool Seen;
+
+    void assign(FieldTy Val) {
+      Seen = true;
+      this->Val = Val;
+    }
+
+    explicit MDFieldImpl(FieldTy Default) : Val(Default), Seen(false) {}
+  };
+  template <class NumTy> struct MDUnsignedField : public MDFieldImpl<NumTy> {
+    typedef typename MDUnsignedField::ImplTy ImplTy;
+    NumTy Max;
+
+    MDUnsignedField(NumTy Default = 0,
+                    NumTy Max = std::numeric_limits<NumTy>::max())
+        : ImplTy(Default), Max(Max) {}
+  };
+  struct MDField : public MDFieldImpl<Metadata *> {
+    MDField() : ImplTy(nullptr) {}
+  };
+
   class LLParser {
   public:
     typedef LLLexer::LocTy LocTy;
@@ -393,6 +418,13 @@ namespace llvm {
     bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs);
     bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);
 
+    bool ParseMDField(LocTy Loc, StringRef Name,
+                      MDUnsignedField<uint32_t> &Result);
+    bool ParseMDField(LocTy Loc, StringRef Name, MDField &Result);
+    template <class ParserTy> bool ParseMDFieldsImpl(ParserTy parseField);
+    bool ParseSpecializedMDNode(MDNode *&N, bool IsDistinct = false);
+    bool ParseMDLocation(MDNode *&Result, bool IsDistinct);
+
     // Function Parsing.
     struct ArgInfo {
       LocTy Loc;

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Jan 13 15:10:44 2015
@@ -1267,6 +1267,20 @@ std::error_code BitcodeReader::ParseMeta
                               NextMDValueNo++);
       break;
     }
+    case bitc::METADATA_LOCATION: {
+      if (Record.size() != 5)
+        return Error("Invalid record");
+
+      auto get = Record[0] ? MDLocation::getDistinct : MDLocation::get;
+      unsigned Line = Record[1];
+      unsigned Column = Record[2];
+      MDNode *Scope = cast<MDNode>(MDValueList.getValueFwdRef(Record[3]));
+      Metadata *InlinedAt =
+          Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr;
+      MDValueList.AssignValue(get(Context, Line, Column, Scope, InlinedAt),
+                              NextMDValueNo++);
+      break;
+    }
     case bitc::METADATA_STRING: {
       std::string String(Record.begin(), Record.end());
       llvm::UpgradeMDStringConstant(String);

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Jan 13 15:10:44 2015
@@ -779,6 +779,25 @@ static void WriteMDNode(const MDNode *N,
   Record.clear();
 }
 
+static void WriteMDLocation(const MDLocation *N, const ValueEnumerator &VE,
+                            BitstreamWriter &Stream,
+                            SmallVectorImpl<uint64_t> &Record,
+                            unsigned Abbrev) {
+  Record.push_back(N->isDistinct());
+  Record.push_back(N->getLine());
+  Record.push_back(N->getColumn());
+  Record.push_back(VE.getMetadataID(N->getScope()));
+
+  // Always emit the inlined-at location, even though it's optional.
+  if (Metadata *InlinedAt = N->getInlinedAt())
+    Record.push_back(VE.getMetadataID(InlinedAt) + 1);
+  else
+    Record.push_back(0);
+
+  Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+  Record.clear();
+}
+
 static void WriteModuleMetadata(const Module *M,
                                 const ValueEnumerator &VE,
                                 BitstreamWriter &Stream) {
@@ -798,6 +817,22 @@ static void WriteModuleMetadata(const Mo
     MDSAbbrev = Stream.EmitAbbrev(Abbv);
   }
 
+  unsigned LocAbbrev = 0;
+  if (VE.hasMDLocation()) {
+    // Abbrev for METADATA_LOCATION.
+    //
+    // Assume the column is usually under 128, and always output the inlined-at
+    // location (it's never more expensive than building an array size 1).
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    LocAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
   unsigned NameAbbrev = 0;
   if (!M->named_metadata_empty()) {
     // Abbrev for METADATA_NAME.
@@ -810,6 +845,10 @@ static void WriteModuleMetadata(const Mo
 
   SmallVector<uint64_t, 64> Record;
   for (const Metadata *MD : MDs) {
+    if (const MDLocation *Loc = dyn_cast<MDLocation>(MD)) {
+      WriteMDLocation(Loc, VE, Stream, Record, LocAbbrev);
+      continue;
+    }
     if (const MDNode *N = dyn_cast<MDNode>(MD)) {
       WriteMDNode(N, VE, Stream, Record);
       continue;

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Tue Jan 13 15:10:44 2015
@@ -282,7 +282,8 @@ static bool isIntOrIntVectorValue(const
   return V.first->getType()->isIntOrIntVectorTy();
 }
 
-ValueEnumerator::ValueEnumerator(const Module &M) : HasMDString(false) {
+ValueEnumerator::ValueEnumerator(const Module &M)
+    : HasMDString(false), HasMDLocation(false) {
   if (shouldPreserveBitcodeUseListOrder())
     UseListOrders = predictUseListOrder(M);
 
@@ -547,6 +548,7 @@ void ValueEnumerator::EnumerateMetadata(
     EnumerateValue(C->getValue());
 
   HasMDString |= isa<MDString>(MD);
+  HasMDLocation |= isa<MDLocation>(MD);
 
   // Replace the dummy ID inserted above with the correct one.  MDValueMap may
   // have changed by inserting operands, so we need a fresh lookup here.

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Tue Jan 13 15:10:44 2015
@@ -65,6 +65,7 @@ private:
   typedef DenseMap<const Metadata *, unsigned> MetadataMapType;
   MetadataMapType MDValueMap;
   bool HasMDString;
+  bool HasMDLocation;
 
   typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
   AttributeGroupMapType AttributeGroupMap;
@@ -111,6 +112,7 @@ public:
   unsigned getMetadataID(const Metadata *V) const;
 
   bool hasMDString() const { return HasMDString; }
+  bool hasMDLocation() const { return HasMDLocation; }
 
   unsigned getTypeID(Type *T) const {
     TypeMapType::const_iterator I = TypeMap.find(T);

Added: llvm/trunk/test/Assembler/invalid-mdlocation-field-bad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-mdlocation-field-bad.ll?rev=225830&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-mdlocation-field-bad.ll (added)
+++ llvm/trunk/test/Assembler/invalid-mdlocation-field-bad.ll Tue Jan 13 15:10:44 2015
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:18: error: invalid field 'bad'
+!0 = !MDLocation(bad: 0)

Added: llvm/trunk/test/Assembler/invalid-mdlocation-field-twice.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-mdlocation-field-twice.ll?rev=225830&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-mdlocation-field-twice.ll (added)
+++ llvm/trunk/test/Assembler/invalid-mdlocation-field-twice.ll Tue Jan 13 15:10:44 2015
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+!0 = !{}
+
+; CHECK: <stdin>:[[@LINE+1]]:38: error: field 'line' cannot be specified more than once
+!1 = !MDLocation(line: 3, scope: !0, line: 3)

Added: llvm/trunk/test/Assembler/invalid-mdlocation-overflow-column.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-mdlocation-overflow-column.ll?rev=225830&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-mdlocation-overflow-column.ll (added)
+++ llvm/trunk/test/Assembler/invalid-mdlocation-overflow-column.ll Tue Jan 13 15:10:44 2015
@@ -0,0 +1,9 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+!0 = !{}
+
+; CHECK-NOT: error
+!1 = !MDLocation(column: 255, scope: !0)
+
+; CHECK: <stdin>:[[@LINE+1]]:26: error: value for 'column' too large, limit is 255
+!2 = !MDLocation(column: 256, scope: !0)

Added: llvm/trunk/test/Assembler/invalid-mdlocation-overflow-line.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-mdlocation-overflow-line.ll?rev=225830&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-mdlocation-overflow-line.ll (added)
+++ llvm/trunk/test/Assembler/invalid-mdlocation-overflow-line.ll Tue Jan 13 15:10:44 2015
@@ -0,0 +1,9 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+!0 = !{}
+
+; CHECK-NOT: error
+!1 = !MDLocation(line: 16777215, scope: !0)
+
+; CHECK: <stdin>:[[@LINE+1]]:24: error: value for 'line' too large, limit is 16777215
+!2 = !MDLocation(line: 16777216, scope: !0)

Added: llvm/trunk/test/Assembler/invalid-specialized-mdnode.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invalid-specialized-mdnode.ll?rev=225830&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invalid-specialized-mdnode.ll (added)
+++ llvm/trunk/test/Assembler/invalid-specialized-mdnode.ll Tue Jan 13 15:10:44 2015
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:6: error: expected metadata type
+!0 = !Invalid(field: 0)

Added: llvm/trunk/test/Assembler/mdlocation.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/mdlocation.ll?rev=225830&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/mdlocation.ll (added)
+++ llvm/trunk/test/Assembler/mdlocation.ll Tue Jan 13 15:10:44 2015
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+
+; CHECK: !named = !{!0, !1, !1, !2, !2, !3, !3}
+!named = !{!0, !1, !2, !3, !4, !5, !6}
+
+; CHECK: !0 = !{}
+!0 = !{}
+
+; CHECK-NEXT: !1 = !MDLocation(line: 3, column: 7, scope: !0)
+!1 = !MDLocation(line: 3, column: 7, scope: !0)
+!2 = !MDLocation(scope: !0, column: 7, line: 3)
+
+; CHECK-NEXT: !2 = !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !1)
+!3 = !MDLocation(scope: !0, inlinedAt: !1, column: 7, line: 3)
+!4 = !MDLocation(column: 7, line: 3, scope: !0, inlinedAt: !1)
+
+; CHECK-NEXT: !3 = !MDLocation(scope: !0)
+!5 = !MDLocation(scope: !0)
+!6 = !MDLocation(scope: !0, column: 0, line: 0)

Modified: llvm/trunk/utils/vim/llvm.vim
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/vim/llvm.vim?rev=225830&r1=225829&r2=225830&view=diff
==============================================================================
--- llvm/trunk/utils/vim/llvm.vim (original)
+++ llvm/trunk/utils/vim/llvm.vim Tue Jan 13 15:10:44 2015
@@ -62,7 +62,7 @@ syn keyword llvmKeyword uselistorder_bb
 syn keyword llvmError  getresult begin end
 
 " Misc syntax.
-syn match   llvmNoName /[%@]\d\+\>/
+syn match   llvmNoName /[%@!]\d\+\>/
 syn match   llvmNumber /-\?\<\d\+\>/
 syn match   llvmFloat  /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/
 syn match   llvmFloat  /\<0x\x\+\>/
@@ -73,6 +73,11 @@ syn region  llvmString start=/"/ skip=/\
 syn match   llvmLabel /[-a-zA-Z$._][-a-zA-Z$._0-9]*:/
 syn match   llvmIdentifier /[%@][-a-zA-Z$._][-a-zA-Z$._0-9]*/
 
+" Named metadata and specialized metadata keywords.
+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*(/
+
 " Syntax-highlight dejagnu test commands.
 syn match  llvmSpecialComment /;\s*RUN:.*$/
 syn match  llvmSpecialComment /;\s*PR\d*\s*$/





More information about the llvm-commits mailing list