Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -487,6 +487,8 @@ const MachineBasicBlock *MBB, unsigned uid) const; void EmitLLVMUsedList(const ConstantArray *InitList); + /// Emit llvm.ident metadata in an '.ident' directive. + void EmitModuleIdents(Module &M); void EmitXXStructorList(const Constant *List, bool isCtor); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); }; Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -953,6 +953,9 @@ if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I)) MP->finishAssembly(*this); + // Emit llvm.ident metadata in an '.ident' directive. + EmitModuleIdents(M); + // If we don't have any trampolines, then we don't require stack memory // to be executable. Some targets have a directive to declare this. Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); @@ -1332,6 +1335,21 @@ } } +void AsmPrinter::EmitModuleIdents(Module &M) { + if (!MAI->hasIdentDirective()) + return; + + if (const NamedMDNode *NMD = M.getNamedMetadata("llvm.ident")) { + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + const MDNode *N = NMD->getOperand(i); + assert(N->getNumOperands() == 1 && + "llvm.ident metadata entry can have only one operand"); + if (const MDString *S = cast(N->getOperand(0))) + OutStreamer.EmitIdent(S->getString()); + } + } +} + //===--------------------------------------------------------------------===// // Emission and print routines // Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -216,6 +216,7 @@ visitNamedMDNode(*I); visitModuleFlags(M); + visitModuleIdents(M); // Verify Debug Info. verifyDebugInfo(M); @@ -260,6 +261,7 @@ void visitGlobalAlias(GlobalAlias &GA); void visitNamedMDNode(NamedMDNode &NMD); void visitMDNode(MDNode &MD, Function *F); + void visitModuleIdents(Module &M); void visitModuleFlags(Module &M); void visitModuleFlag(MDNode *Op, DenseMap &SeenIDs, SmallVectorImpl &Requirements); @@ -614,6 +616,23 @@ } } +void Verifier::visitModuleIdents(Module &M) { + const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident"); + if (!Idents) return; + + // llvm.ident takes a list of metadata entry. Each entry has only one string. + // Scan each llvm.ident entry and make sure that this requirement is met. + for (unsigned i = 0, e = Idents->getNumOperands(); i != e; ++i) { + const MDNode *N = Idents->getOperand(i); + Assert1(N->getNumOperands() == 1, + "incorrect number of operands in llvm.ident metadata", N); + Assert1(isa(N->getOperand(0)), + ("invalid value for llvm.ident metadata entry operand" + "(the operand should be a string)"), + N->getOperand(0)); + } +} + void Verifier::visitModuleFlags(Module &M) { const NamedMDNode *Flags = M.getModuleFlagsMetadata(); if (!Flags) return; Index: test/CodeGen/X86/ident-metadata.ll =================================================================== --- test/CodeGen/X86/ident-metadata.ll +++ test/CodeGen/X86/ident-metadata.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=x86 < %s | FileCheck %s +; RUN: llc -march=x86 -filetype=obj -o %t < %s +; RUN: llvm-readobj -s -sd %t | FileCheck %s -check-prefix=OBJ +; Verify that llvm.ident metadata is emitted as .ident +; directives in assembly files, and in the .comment section in ELF object files. + +; CHECK: .ident "clang version x.x" +; CHECK-NEXT: .ident "something else" + +; OBJ: Name: .comment (7) +; OBJ: SectionData ( +; OBJ-NEXT: 0000: 00636C61 6E672076 65727369 6F6E2078 +; OBJ-NEXT: 0010: 2E780073 6F6D6574 68696E67 20656C73 +; OBJ-NEXT: 0020: 6500 +!llvm.ident = !{!0, !1} +!0 = metadata !{metadata !"clang version x.x"} +!1 = metadata !{metadata !"something else"} Index: test/Verifier/ident-meta1.ll =================================================================== --- test/Verifier/ident-meta1.ll +++ test/Verifier/ident-meta1.ll @@ -0,0 +1,12 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; Verify that llvm.ident is properly structured. +; llvm.ident takes a list of metadata entries. +; Each metadata entry can have only one string. + +!llvm.ident = !{!0, !1} +!0 = metadata !{metadata !"version string"} +!1 = metadata !{metadata !"string1", metadata !"string2"} +; CHECK: assembly parsed, but does not verify as correct! +; CHECK-NEXT: incorrect number of operands in llvm.ident metadata +; CHECK-NEXT: metadata !1 + Index: test/Verifier/ident-meta2.ll =================================================================== --- test/Verifier/ident-meta2.ll +++ test/Verifier/ident-meta2.ll @@ -0,0 +1,13 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; Verify that llvm.ident is properly structured. +; llvm.ident takes a list of metadata entries. +; Each metadata entry can contain one string only. + +!llvm.ident = !{!0, !1, !2, !3} +!0 = metadata !{metadata !"str1"} +!1 = metadata !{metadata !"str2"} +!2 = metadata !{metadata !"str3"} +!3 = metadata !{i32 1} +; CHECK: assembly parsed, but does not verify as correct! +; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string) +; CHECK-NEXT: i32 1 Index: test/Verifier/ident-meta3.ll =================================================================== --- test/Verifier/ident-meta3.ll +++ test/Verifier/ident-meta3.ll @@ -0,0 +1,10 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s +; Verify that llvm.ident is properly structured. +; llvm.ident takes a list of metadata entries. +; Each metadata entry can contain one string only. + +!llvm.ident = !{!0} +!0 = metadata !{metadata !{metadata !"nested metadata"}} +; CHECK: assembly parsed, but does not verify as correct! +; CHECK-NEXT: invalid value for llvm.ident metadata entry operand(the operand should be a string) +; CHECK-NEXT: metadata !1