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")) 
{
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")) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to