]> granicus.if.org Git - clang/commitdiff
Record where the GCOV data files should be placed.
authorNick Lewycky <nicholas@mxc.ca>
Wed, 4 May 2011 20:46:58 +0000 (20:46 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Wed, 4 May 2011 20:46:58 +0000 (20:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130866 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp

index b4c0c7f7c0d4d16db1d6291dcb168a17a2b01b33..9f4ada4b3cbc4866bbca482c68561ecab870a205 100644 (file)
@@ -140,6 +140,9 @@ def femit_coverage_notes : Flag<"-femit-coverage-notes">,
   HelpText<"Emit a gcov coverage notes file when compiling.">;
 def femit_coverage_data: Flag<"-femit-coverage-data">,
   HelpText<"Instrument the program to emit gcov coverage data when run.">;
+def coverage_dir : Separate<"-coverage-dir">,
+  HelpText<"Emit coverage data to this directory.">;
+def coverage_dir_EQ : Joined<"-coverage-dir=">, Alias<coverage_dir>;
 def relaxed_aliasing : Flag<"-relaxed-aliasing">,
   HelpText<"Turn off Type Based Alias Analysis">;
 def masm_verbose : Flag<"-masm-verbose">,
index 8bef6a3e0d43ab95ba93694de0837a2b1a51148e..7221f0d554819519604852b7078302b96b3a4f31 100644 (file)
@@ -95,6 +95,9 @@ public:
   /// The code model to use (-mcmodel).
   std::string CodeModel;
 
+  /// The directory in which to place coverage data files.
+  std::string CoverageDir;
+
   /// Enable additional debugging information.
   std::string DebugPass;
 
index 83e927fcadbc2190e049b1fec2cba1b98bafc771..22df86aca2d798ad768b192ce2cfdbd62c6f2226 100644 (file)
@@ -132,6 +132,9 @@ void CodeGenModule::Release() {
 
   if (getCodeGenOpts().EmitDeclMetadata)
     EmitDeclMetadata();
+
+  if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes)
+    EmitCoverageDir();
 }
 
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
@@ -2216,6 +2219,23 @@ void CodeGenFunction::EmitDeclMetadata() {
   }
 }
 
+void CodeGenModule::EmitCoverageDir() {
+  if (!getCodeGenOpts().CoverageDir.empty()) {
+    if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) {
+      llvm::NamedMDNode *GCov = TheModule.getOrInsertNamedMetadata("llvm.gcov");
+      llvm::LLVMContext &Ctx = TheModule.getContext();
+      llvm::MDString *CoverageDir =
+          llvm::MDString::get(Ctx, getCodeGenOpts().CoverageDir);
+      for (int i = 0, e = CUNode->getNumOperands(); i != e; ++i) {
+        llvm::MDNode *CU = CUNode->getOperand(i);
+        llvm::Value *node[] = { CoverageDir, CU };
+        llvm::MDNode *N = llvm::MDNode::get(Ctx, node);
+        GCov->addOperand(N);
+      }
+    }
+  }
+}
+
 ///@name Custom Runtime Function Interfaces
 ///@{
 //
index 99c973cce62822ef279096ff09faddeb89225d0a..65ee922279da427181e474c1c5726ea1804250f1 100644 (file)
@@ -735,6 +735,10 @@ private:
 
   void EmitDeclMetadata();
 
+  /// EmitCoverageDir - 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 EmitCoverageDir();
+
   /// MayDeferGeneration - Determine if the given decl can be emitted
   /// lazily; this is only relevant for definitions. The given decl
   /// must be either a function or var decl.
index 3592fc5ead6595e6738e233237cd190e93105e5d..f4e0f2e35903e0ac808b31e13bf795246dd38cee 100644 (file)
@@ -1303,6 +1303,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       Args.hasArg(options::OPT_coverage))
     CmdArgs.push_back("-femit-coverage-data");
 
+  if (C.getArgs().hasArg(options::OPT_c) ||
+      C.getArgs().hasArg(options::OPT_S)) {
+    if (Output.isFilename()) {
+      llvm::StringRef CoverageDir =
+          llvm::sys::path::parent_path(Output.getFilename());
+      if (!CoverageDir.empty()) {
+        CmdArgs.push_back("-coverage-dir");
+        CmdArgs.push_back(Args.MakeArgString(CoverageDir));
+      }
+    }
+  }
+
   Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
   Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
   Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
index eadf1b39dcc24bfaadf85f44453edaa01e579e98..7a7692f3771e728c9fbbce01ed5e46d7fa8468e1 100644 (file)
@@ -977,6 +977,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
   Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
   Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
+  Opts.CoverageDir = Args.getLastArgValue(OPT_coverage_dir);
 
   if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
     llvm::StringRef Name = A->getValue(Args);