[PATCH] Emit Clang version information into .comment section (Clang's part of implementation) [PART 1]

Katya Romanova Katya_Romanova at playstation.sony.com
Tue Sep 24 17:27:46 PDT 2013


kromanova added you to the CC list for the revision "Emit Clang version information into .comment section (Clang's part of implementation) [PART 1]".

GCC compiler (as well as many other compilers) record their own version information into the object file. However, Clang compiler is not currently doing this.

Emitting compiler version information in an object file could be used for variety of reasons. For example: a developer is saying that he is using the compiler with the latest fix, but
he is claiming that the bug is still not fixed. After many hours of investigation you discover that the developer used an older version of the compiler for building some of the files in the project because he forgot to change the value of an environment variable in one of his scripts. Both you and the developer lost several hours of work. With all the version information recorded in the final executable file, it would have been very easy to check which compilers were used to to build it. You might find many other examples where compilation information emitted in the produced object file could be very handy.

Some time ago there was discussion in the mailing list about embedding a compilation database into an object file.
http://clang-developers.42468.n3.nabble.com/RFC-Embedding-compilation-database-info-in-object-files-tt4033300.html
It's an excellent idea, but it requires a user to use a special tool to extract this information.

The implementation provided here is a "lightweight" version for embedding compilation information into the object file. This information is very easy to extract by using any standard object file dumper tool (readelf, objdump, etc).

In the current implementation only compiler version information was embedded in object (and assembly) file. This could be easily expanded. Adding any other compilation
information into the object file (i.e. compilation command line) could be fitted into the provided framework.

See "Emit Clang version information into .comment section (LLVM's part of implementation) [PART 2]" patch for more information.




Our goal is to get the get the Clang version into into the .comment section. The assembler can already handle putting things into the .comment section via the .ident directive. This is how GCC outputs its version string into the .comment section: .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

We should the same general approach. (Thus compiling with clang -S would produce an appropriate .ident entry in the assembly listing.)

There are 2 parts of this solution:

(1) Emit Clang's version as metadata. 
(2) Teach the backend to output this metadata in an .ident directive and .comment section.

This patch covers only Clang changes. LLVM changes are provided in separate patch  "Emit Clang version information into .comment section (LLVM's part of implementation) [PART 2]".

Clang changes:
- Added an additional function "EmitVersionIdentMetadata()" to clang/lib/CodeGen/CodeGenModule.cpp. This emits named metadata for the version string. The format of the metadata is:

    !llvm.ident = !{!N}
    !N = metadata !{metadata !"clang version string"}

Tests changes:

The following new test was added:
- clang/test/Driver/ident-md.c  - Verifies that an llvm.ident metadata entry with the clang version string is generated by default.

The following test was changed:
 - clang/test/CodeGenObjC/ivar-base-invariant-load.m - Adding the Clang Ident (version) metadata caused the numbering of all other named metadata to be incremented by one.


http://llvm-reviews.chandlerc.com/D1720

Files:
  test/Driver/ident_md.c
  test/CodeGenObjC/ivar-base-as-invariant-load.m
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/CodeGenModule.cpp

Index: test/Driver/ident_md.c
===================================================================
--- test/Driver/ident_md.c
+++ test/Driver/ident_md.c
@@ -0,0 +1,6 @@
+// RUN: %clang %s -emit-llvm -S -o - | FileCheck %s
+// Verify that clang version appears in the llvm.ident metadata.
+
+// CHECK: !llvm.ident = !{!0}
+// CHECK: !0 = metadata !{metadata !"clang version
+
Index: test/CodeGenObjC/ivar-base-as-invariant-load.m
===================================================================
--- test/CodeGenObjC/ivar-base-as-invariant-load.m
+++ test/CodeGenObjC/ivar-base-as-invariant-load.m
@@ -23,7 +23,7 @@
 
 @end
 
-// CHECK: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !4
-// CHECK: [[T2:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !4
-// CHECK: [[T3:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !4
+// CHECK: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
+// CHECK: [[T2:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
+// CHECK: [[T3:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
 
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1093,6 +1093,9 @@
 
   void EmitDeclMetadata();
 
+  /// \brief Emit the Clang version as llvm.ident metadata.
+  void EmitVersionIdentMetadata();
+
   /// EmitCoverageFile - Emit the llvm.gcov metadata used to tell LLVM where
   /// to emit the .gcno and .gcda files in a way that persists in .bc files.
   void EmitCoverageFile();
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -35,6 +35,7 @@
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Version.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/Triple.h"
@@ -204,6 +205,8 @@
 
   if (DebugInfo)
     DebugInfo->finalize();
+
+  EmitVersionIdentMetadata();
 }
 
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
@@ -3034,6 +3037,18 @@
   }
 }
 
+void CodeGenModule::EmitVersionIdentMetadata() {
+  llvm::NamedMDNode *IdentMetadata =
+    TheModule.getOrInsertNamedMetadata("llvm.ident");
+  std::string Version = getClangFullVersion();
+  llvm::LLVMContext &Ctx = TheModule.getContext();
+
+  llvm::Value *IdentNode[] = {
+    llvm::MDString::get(Ctx, Version)
+  };
+  IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode));
+}
+
 void CodeGenModule::EmitCoverageFile() {
   if (!getCodeGenOpts().CoverageFile.empty()) {
     if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1720.1.patch
Type: text/x-patch
Size: 2805 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130924/511b4b7c/attachment.bin>


More information about the cfe-commits mailing list