[cfe-commits] r68022 - in /cfe/trunk: lib/Driver/Tools.cpp lib/Driver/Tools.h test/Frontend/dependency-gen.c tools/clang-cc/DependencyFile.cpp tools/clang-cc/clang.cpp tools/clang-cc/clang.h

Daniel Dunbar daniel at zuster.org
Sun Mar 29 17:34:07 PDT 2009


Author: ddunbar
Date: Sun Mar 29 19:34:04 2009
New Revision: 68022

URL: http://llvm.org/viewvc/llvm-project?rev=68022&view=rev
Log:
Improve dependency file support.
 - Rip out various bits of logic from clang-cc's dependency file gen,
   force driver to provide instead.

 - -MD output now goes to proper location
<rdar://problem/6723948> clang -MD puts dep file in /tmp with wrong name

 - -M and -MM still don't work correctly.

Modified:
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Driver/Tools.h
    cfe/trunk/test/Frontend/dependency-gen.c
    cfe/trunk/tools/clang-cc/DependencyFile.cpp
    cfe/trunk/tools/clang-cc/clang.cpp
    cfe/trunk/tools/clang-cc/clang.h

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=68022&r1=68021&r2=68022&view=diff

==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Sun Mar 29 19:34:04 2009
@@ -210,14 +210,58 @@
     // FIXME: Add --stack-protector-buffer-size=<xxx> on
     // -fstack-protect.
 
-    Args.AddLastArg(CmdArgs, options::OPT_MD);
-    Args.AddLastArg(CmdArgs, options::OPT_MMD);
-    Args.AddAllArgs(CmdArgs, options::OPT_MF);
+    // Handle dependency file generation.
+    Arg *A;
+    if ((A = Args.getLastArg(options::OPT_M)) ||
+        (A = Args.getLastArg(options::OPT_MM)) ||
+        (A = Args.getLastArg(options::OPT_MD)) ||
+        (A = Args.getLastArg(options::OPT_MMD))) {
+      // Determine the output location.
+      const char *DepFile;
+      if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
+        DepFile = MF->getValue(Args);
+      } else if (A->getOption().getId() == options::OPT_M ||
+                 A->getOption().getId() == options::OPT_MM) {
+        DepFile = "-";
+      } else {
+        DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
+      }
+      CmdArgs.push_back("-dependency-file");
+      CmdArgs.push_back(DepFile);
+
+      // Add an -MT option if the user didn't specify their own.
+      // FIXME: This should use -MQ, when we support it.
+      if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
+        const char *DepTarget;
+
+        // If user provided -o, that is the dependency target.
+        if (Arg *A = Args.getLastArg(options::OPT_o)) {
+          DepTarget = A->getValue(Args); 
+        } else {
+          // Otherwise derive from the base input.
+          //
+          // FIXME: This should use the computed output file location.
+          llvm::sys::Path P(Inputs[0].getBaseInput());
+          
+          P.eraseSuffix();
+          P.appendSuffix("o");
+          DepTarget = Args.MakeArgString(P.getLast().c_str());
+        }
+
+        CmdArgs.push_back("-MT");
+        CmdArgs.push_back(DepTarget);
+      }
+
+      if (A->getOption().getId() == options::OPT_M ||
+          A->getOption().getId() == options::OPT_MD)
+        CmdArgs.push_back("-sys-header-deps");
+    }
+
     Args.AddLastArg(CmdArgs, options::OPT_MP);
     Args.AddAllArgs(CmdArgs, options::OPT_MT);
 
     Arg *Unsupported = Args.getLastArg(options::OPT_M);
-    if (!Unsupported) 
+     if (!Unsupported) 
       Unsupported = Args.getLastArg(options::OPT_MM);
     if (!Unsupported) 
       Unsupported = Args.getLastArg(options::OPT_MG);
@@ -327,7 +371,10 @@
   CmdArgs.push_back("-arch");
   CmdArgs.push_back(getToolChain().getArchName().c_str());
 
-  if (Output.isPipe()) {
+  // FIXME: We should have a separate type for this.
+  if (Args.hasArg(options::OPT_M) || Args.hasArg(options::OPT_MM)) {
+    CmdArgs.push_back("-M");
+  } else if (Output.isPipe()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back("-");
   } else if (Output.isFilename()) {
@@ -478,13 +525,13 @@
 }
 
 const char *darwin::CC1::getBaseInputName(const ArgList &Args, 
-                                          const InputInfoList &Inputs) const {
+                                          const InputInfoList &Inputs) {
   llvm::sys::Path P(Inputs[0].getBaseInput());
   return Args.MakeArgString(P.getLast().c_str());
 }
 
 const char *darwin::CC1::getBaseInputStem(const ArgList &Args, 
-                                          const InputInfoList &Inputs) const {
+                                          const InputInfoList &Inputs) {
   const char *Str = getBaseInputName(Args, Inputs);
 
   if (const char *End = strchr(Str, '.'))
@@ -495,7 +542,7 @@
 
 const char *
 darwin::CC1::getDependencyFileName(const ArgList &Args, 
-                                   const InputInfoList &Inputs) const {
+                                   const InputInfoList &Inputs) {
   // FIXME: Think about this more.
   std::string Res;
 
@@ -504,7 +551,7 @@
     
     Res = Str.substr(0, Str.rfind('.'));
   } else
-    Res = getBaseInputStem(Args, Inputs);
+    Res = darwin::CC1::getBaseInputStem(Args, Inputs);
 
   return Args.MakeArgString((Res + ".d").c_str());
 }
@@ -558,7 +605,7 @@
     CmdArgs.push_back("-quiet");
 
   CmdArgs.push_back("-dumpbase");
-  CmdArgs.push_back(getBaseInputName(Args, Inputs));
+  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
 
   Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
 
@@ -575,7 +622,7 @@
     CmdArgs.push_back(OutputOpt->getValue(Args));
   } else {
     CmdArgs.push_back("-auxbase");
-    CmdArgs.push_back(getBaseInputStem(Args, Inputs));
+    CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
@@ -686,12 +733,12 @@
 
   if (Args.hasArg(options::OPT_MD)) {
     CmdArgs.push_back("-MD");
-    CmdArgs.push_back(getDependencyFileName(Args, Inputs));
+    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
   }
 
   if (Args.hasArg(options::OPT_MMD)) {
     CmdArgs.push_back("-MMD");
-    CmdArgs.push_back(getDependencyFileName(Args, Inputs));
+    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
   }
 
   Args.AddLastArg(CmdArgs, options::OPT_M);

Modified: cfe/trunk/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=68022&r1=68021&r2=68022&view=diff

==============================================================================
--- cfe/trunk/lib/Driver/Tools.h (original)
+++ cfe/trunk/lib/Driver/Tools.h Sun Mar 29 19:34:04 2009
@@ -117,14 +117,16 @@
 
 namespace darwin {
   class VISIBILITY_HIDDEN CC1 : public Tool  {
+  public:
+    static const char *getBaseInputName(const ArgList &Args, 
+                                 const InputInfoList &Input);
+    static const char *getBaseInputStem(const ArgList &Args, 
+                                 const InputInfoList &Input);
+    static const char *getDependencyFileName(const ArgList &Args, 
+                                             const InputInfoList &Inputs);
+
   protected:
     const char *getCC1Name(types::ID Type) const;
-    const char *getBaseInputName(const ArgList &Args, 
-                                 const InputInfoList &Input) const;
-    const char *getBaseInputStem(const ArgList &Args, 
-                                 const InputInfoList &Input) const;
-    const char *getDependencyFileName(const ArgList &Args, 
-                                      const InputInfoList &Inputs) const;
 
     void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
     void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,

Modified: cfe/trunk/test/Frontend/dependency-gen.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/dependency-gen.c?rev=68022&r1=68021&r2=68022&view=diff

==============================================================================
--- cfe/trunk/test/Frontend/dependency-gen.c (original)
+++ cfe/trunk/test/Frontend/dependency-gen.c Sun Mar 29 19:34:04 2009
@@ -1,5 +1,5 @@
-
 // rdar://6533411
-// RUN: clang-cc -MD -MF %t.d -x c /dev/null
-
+// RUN: clang -MD -MF %t.d -c -x c -o %t.o /dev/null && 
 
+// RUN: grep '.*dependency-gen.c.out.tmp.o:' %t.d
+// RUN: grep '/dev/null' %t.d

Modified: cfe/trunk/tools/clang-cc/DependencyFile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/DependencyFile.cpp?rev=68022&r1=68021&r2=68022&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/DependencyFile.cpp (original)
+++ cfe/trunk/tools/clang-cc/DependencyFile.cpp Sun Mar 29 19:34:04 2009
@@ -23,7 +23,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
-#include <fstream>
 #include <string>
 
 using namespace clang;
@@ -33,9 +32,8 @@
   std::vector<std::string> Files;
   llvm::StringSet<> FilesSet;
   const Preprocessor *PP;
-  std::ofstream OS;
-  const std::string &InputFile;
   std::vector<std::string> Targets;
+  llvm::raw_ostream *OS;
 
 private:
   bool FileMatchesDepCriteria(const char *Filename,
@@ -43,36 +41,33 @@
   void OutputDependencyFile();
 
 public:
-  DependencyFileCallback(const Preprocessor *PP, 
-                         const std::string &InputFile,
-                         const std::string &DepFile,
-                         const std::vector<std::string> &Targets,
-                         const char  *&ErrStr);
-  ~DependencyFileCallback();
+  DependencyFileCallback(const Preprocessor *_PP, 
+                         llvm::raw_ostream *_OS, 
+                         const std::vector<std::string> &_Targets)
+    : PP(_PP), Targets(_Targets), OS(_OS) {
+  }
+
+  ~DependencyFileCallback() {
+    OutputDependencyFile();
+    OS->flush();
+    delete OS;
+  }
+
   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                            SrcMgr::CharacteristicKind FileType);
 };
 }
 
-static const char *DependencyFileExt = "d";
-static const char *ObjectFileExt = "o";
-
 //===----------------------------------------------------------------------===//
 // Dependency file options
 //===----------------------------------------------------------------------===//
-static llvm::cl::opt<bool>
-GenerateDependencyFile("MD",
-             llvm::cl::desc("Generate dependency for main source file "
-                            "(system headers included)"));
+static llvm::cl::opt<std::string>
+DependencyFile("dependency-file",
+               llvm::cl::desc("Filename (or -) to write dependency output to"));
 
 static llvm::cl::opt<bool>
-GenerateDependencyFileNoSysHeaders("MMD",
-             llvm::cl::desc("Generate dependency for main source file "
-                            "(no system headers)"));
-
-static llvm::cl::opt<std::string>
-DependencyOutputFile("MF",
-           llvm::cl::desc("Specify dependency output file"));
+DependenciesIncludeSystemHeaders("sys-header-deps",
+                 llvm::cl::desc("Include system headers in dependency output"));
 
 static llvm::cl::list<std::string>
 DependencyTargets("MT",
@@ -85,82 +80,41 @@
                            "(other than main file)"));
 
 bool clang::CreateDependencyFileGen(Preprocessor *PP,
-                                    std::string &OutputFile,
-                                    const std::string &InputFile,
-                                    const char  *&ErrStr) {
-  assert(!InputFile.empty() && "No file given");
-  
-  ErrStr = NULL;
+                                    std::string &ErrStr) {
+  ErrStr = "";
+  if (DependencyFile.empty())
+    return false;
 
-  if (!GenerateDependencyFile && !GenerateDependencyFileNoSysHeaders) {
-    if (!DependencyOutputFile.empty() || !DependencyTargets.empty() ||
-        PhonyDependencyTarget)
-      ErrStr = "Error: to generate dependencies you must specify -MD or -MMD\n";
+  if (DependencyTargets.empty()) {
+    ErrStr = "-dependency-file requires at least one -MT option\n";
     return false;
   }
-  
-  // Handle conflicting options
-  if (GenerateDependencyFileNoSysHeaders)
-    GenerateDependencyFile = false;
-
-  // Determine name of dependency output filename
-  llvm::sys::Path DepFile;
-  if (!DependencyOutputFile.empty())
-    DepFile = DependencyOutputFile;
-  else if (!OutputFile.empty()) {
-    DepFile = OutputFile;
-    DepFile.eraseSuffix();
-    DepFile.appendSuffix(DependencyFileExt);
-  }
-  else {
-    DepFile = InputFile;
-    DepFile.eraseSuffix();
-    DepFile.appendSuffix(DependencyFileExt);
-  }
-
-  std::vector<std::string> Targets(DependencyTargets);
-
-  // Infer target name if unspecified
-  if (Targets.empty()) {
-    if (!OutputFile.empty()) {
-      llvm::sys::Path TargetPath(OutputFile);
-      TargetPath.eraseSuffix();
-      TargetPath.appendSuffix(ObjectFileExt);
-      Targets.push_back(TargetPath.toString());
-    } else {
-      llvm::sys::Path TargetPath(InputFile);
-      TargetPath.eraseSuffix();
-      TargetPath.appendSuffix(ObjectFileExt);
-      Targets.push_back(TargetPath.toString());
-    }
-  }
 
-  DependencyFileCallback *PPDep = 
-    new DependencyFileCallback(PP, InputFile, DepFile.toString(),
-                               Targets, ErrStr);
-  if (ErrStr){
-    delete PPDep;
+  std::string ErrMsg;
+  llvm::raw_ostream *OS =
+    new llvm::raw_fd_ostream(DependencyFile.c_str(), false, ErrStr);
+  if (!ErrMsg.empty()) {
+    ErrStr = "unable to open dependency file: " + ErrMsg;
     return false;
   }
-  else {
-    PP->setPPCallbacks(PPDep);
-    return true;
-  }
+
+  DependencyFileCallback *PPDep = 
+    new DependencyFileCallback(PP, OS, DependencyTargets);
+  PP->setPPCallbacks(PPDep);
+  return true;
 }
 
 /// FileMatchesDepCriteria - Determine whether the given Filename should be
 /// considered as a dependency.
 bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename,
                                           SrcMgr::CharacteristicKind FileType) {
-  if (strcmp(InputFile.c_str(), Filename) != 0 &&
-      strcmp("<built-in>", Filename) != 0) {
-      if (GenerateDependencyFileNoSysHeaders)
-        return FileType == SrcMgr::C_User;
-      else
-        return true;
-  }
+  if (strcmp("<built-in>", Filename) == 0)
+    return false;
+
+  if (DependenciesIncludeSystemHeaders)
+    return true;
 
-  return false;
+  return FileType == SrcMgr::C_User;
 }
 
 void DependencyFileCallback::FileChanged(SourceLocation Loc,
@@ -169,9 +123,9 @@
   if (Reason != PPCallbacks::EnterFile)
     return;
   
-  // Depedency generation really does want to go all the way to the file entry
-  // for a source location to find out what is depended on.  We do not want
-  // #line markers to affect dependency generation!
+  // Dependency generation really does want to go all the way to the
+  // file entry for a source location to find out what is depended on.
+  // We do not want #line markers to affect dependency generation!
   SourceManager &SM = PP->getSourceManager();
   
   const FileEntry *FE =
@@ -203,17 +157,17 @@
     unsigned N = I->length();
     if (Columns == 0) {
       Columns += N;
-      OS << *I;
+      *OS << *I;
     } else if (Columns + N + 2 > MaxColumns) {
       Columns = N + 2;
-      OS << " \\\n  " << *I;
+      *OS << " \\\n  " << *I;
     } else {
       Columns += N + 1;
-      OS << " " << *I;
+      *OS << ' ' << *I;
     }
   }
 
-  OS << ":";
+  *OS << ':';
   Columns += 1;
   
   // Now add each dependency in the order it was seen, but avoiding
@@ -225,48 +179,22 @@
     // break the line on the next iteration.
     unsigned N = I->length();
     if (Columns + (N + 1) + 2 > MaxColumns) {
-      OS << " \\\n ";
+      *OS << " \\\n ";
       Columns = 2;
     }
-    OS << " " << *I;
+    *OS << ' ' << *I;
     Columns += N + 1;
   }
-  OS << "\n";
+  *OS << '\n';
 
   // Create phony targets if requested.
   if (PhonyDependencyTarget) {
     // Skip the first entry, this is always the input file itself.
     for (std::vector<std::string>::iterator I = Files.begin() + 1,
            E = Files.end(); I != E; ++I) {
-      OS << "\n";
-      OS << *I << ":\n";
+      *OS << '\n';
+      *OS << *I << ":\n";
     }
   }
 }
 
-DependencyFileCallback::DependencyFileCallback(const Preprocessor *PP,
-                                               const std::string &InputFile,
-                                               const std::string &DepFile,
-                                               const std::vector<std::string>
-                                               &Targets,
-                                               const char  *&ErrStr)
-  : PP(PP), InputFile(InputFile), Targets(Targets) {
-
-  OS.open(DepFile.c_str());
-  if (OS.fail())
-    ErrStr = "Could not open dependency output file\n";
-  else
-    ErrStr = NULL;
-
-  Files.push_back(InputFile);
-}
-
-DependencyFileCallback::~DependencyFileCallback() {
-  if ((!GenerateDependencyFile && !GenerateDependencyFileNoSysHeaders) || 
-      OS.fail())
-    return;
-  
-  OutputDependencyFile();
-  OS.close();
-}
-

Modified: cfe/trunk/tools/clang-cc/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/clang.cpp?rev=68022&r1=68021&r2=68022&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/clang.cpp (original)
+++ cfe/trunk/tools/clang-cc/clang.cpp Sun Mar 29 19:34:04 2009
@@ -1197,11 +1197,11 @@
     }
     
     /// FIXME: PP can only handle one callback
-    if (ProgAction != PrintPreprocessedInput) {    
-      const char* ErrStr;
-      bool DFG = CreateDependencyFileGen(PP.get(), OutputFile, InFile, ErrStr);
-       if (!DFG && ErrStr) {
-        fprintf(stderr, "%s", ErrStr);
+    if (ProgAction != PrintPreprocessedInput) {
+      std::string ErrStr;
+      bool DFG = CreateDependencyFileGen(PP.get(), ErrStr);
+      if (!DFG && !ErrStr.empty()) {
+        fprintf(stderr, "%s", ErrStr.c_str());
         return NULL;
       }
     }

Modified: cfe/trunk/tools/clang-cc/clang.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/clang.h?rev=68022&r1=68021&r2=68022&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/clang.h (original)
+++ cfe/trunk/tools/clang-cc/clang.h Sun Mar 29 19:34:04 2009
@@ -50,10 +50,7 @@
 
 /// CreateDependencyFileGen - Create dependency file generator.
 /// This is only done if either -MD or -MMD has been specified.
-bool CreateDependencyFileGen(Preprocessor *PP,
-                             std::string &OutputFile,
-                             const std::string &InputFile,
-                             const char  *&ErrStr);
+bool CreateDependencyFileGen(Preprocessor *PP, std::string &ErrStr);
 
 /// CacheTokens - Cache tokens for use with PCH.
 void CacheTokens(Preprocessor& PP, const std::string& OutFile);





More information about the cfe-commits mailing list