Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -834,6 +834,11 @@ nodes ` (but not metadata strings) are the only valid operands for a named metadata. +#. Named metadata are represented as a string of characters with the + metadata prefix. The rules for metadata names are the same as for + identifiers, but quoted names are not allowed. ``"\xx"`` type escapes + are still valid, which allows any character to be part of a name. + Syntax:: ; Some unnamed metadata nodes, which are referenced by the named metadata. Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -2215,15 +2215,13 @@ } } -void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { - Out << '!'; - StringRef Name = NMD->getName(); +static void printMetadataIdentifier(StringRef Name, + formatted_raw_ostream &Out) { if (Name.empty()) { Out << " "; } else { - if (isalpha(static_cast(Name[0])) || - Name[0] == '-' || Name[0] == '$' || - Name[0] == '.' || Name[0] == '_') + if (isalpha(static_cast(Name[0])) || Name[0] == '-' || + Name[0] == '$' || Name[0] == '.' || Name[0] == '_') Out << Name[0]; else Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F); @@ -2236,9 +2234,15 @@ Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); } } +} + +void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { + Out << '!'; + printMetadataIdentifier(NMD->getName(), Out); Out << " = !{"; for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - if (i) Out << ", "; + if (i) + Out << ", "; int Slot = Machine.getMetadataSlot(NMD->getOperand(i)); if (Slot == -1) Out << ""; @@ -2248,7 +2252,6 @@ Out << "}\n"; } - static void PrintLinkage(GlobalValue::LinkageTypes LT, formatted_raw_ostream &Out) { switch (LT) { @@ -2268,7 +2271,6 @@ } } - static void PrintVisibility(GlobalValue::VisibilityTypes Vis, formatted_raw_ostream &Out) { switch (Vis) { @@ -3008,9 +3010,10 @@ for (const auto &I : MDs) { unsigned Kind = I.first; Out << Separator; - if (Kind < MDNames.size()) - Out << "!" << MDNames[Kind]; - else + if (Kind < MDNames.size()) { + Out << "!"; + printMetadataIdentifier(MDNames[Kind], Out); + } else Out << "!"; Out << ' '; WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule); Index: lib/IR/LLVMContext.cpp =================================================================== --- lib/IR/LLVMContext.cpp +++ lib/IR/LLVMContext.cpp @@ -240,15 +240,12 @@ // Metadata Kind Uniquing //===----------------------------------------------------------------------===// -/// getMDKindID - Return a unique non-zero ID for the specified metadata kind. +/// Return a unique non-zero ID for the specified metadata kind. unsigned LLVMContext::getMDKindID(StringRef Name) const { - assert(!std::isdigit(Name.front()) && - "Named metadata may not start with a digit"); - // If this is new, assign it its ID. - return pImpl->CustomMDKindNames.insert(std::make_pair( - Name, - pImpl->CustomMDKindNames.size())) + return pImpl->CustomMDKindNames.insert( + std::make_pair( + Name, pImpl->CustomMDKindNames.size())) .first->second; } Index: test/Assembler/metadata.ll =================================================================== --- test/Assembler/metadata.ll +++ test/Assembler/metadata.ll @@ -1,7 +1,7 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: @test +; CHECK-LABEL: @test ; CHECK: ret void, !bar !1, !foo !0 define void @test() { add i32 2, 1, !bar !0 @@ -11,17 +11,24 @@ ret void, !foo !0, !bar !1 } -; CHECK: define void @test2() !foo !2 !baz !3 +; CHECK-LABEL: define void @test2() !foo !2 !baz !3 define void @test2() !foo !2 !baz !3 { unreachable } -; CHECK: define void @test3() !bar !3 +; CHECK-LABEL: define void @test3() !bar !3 ; CHECK: unreachable, !bar !4 define void @test3() !bar !3 { unreachable, !bar !4 } +; CHECK-LABEL: define void @test_attachment_name() { +; CHECK: unreachable, !\342abc !4 +define void @test_attachment_name() { + ;; Escape the first character when printing text IR, since it's a digit + unreachable, !\34\32abc !4 +} + !0 = !DILocation(line: 662302, column: 26, scope: !1) !1 = !DISubprogram(name: "foo") !2 = distinct !{}