zcov: / tools/CIndex/CIndexer.cpp


Files: 1 Branches Taken: 53.6% 15 / 28
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 28 / 28
Line Coverage: 88.1% 52 / 59


Programs: 1 Runs 121


       1                 : //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This file implements the Clang-C Source Indexing library.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CIndexer.h"
      15                 : 
      16                 : #include "clang/AST/Decl.h"
      17                 : #include "clang/AST/DeclVisitor.h"
      18                 : #include "clang/AST/StmtVisitor.h"
      19                 : #include "clang/Basic/FileManager.h"
      20                 : #include "clang/Basic/SourceManager.h"
      21                 : #include "clang/Basic/Version.h"
      22                 : #include "clang/Sema/CodeCompleteConsumer.h"
      23                 : #include "llvm/ADT/StringExtras.h"
      24                 : #include "llvm/Config/config.h"
      25                 : #include "llvm/Support/Compiler.h"
      26                 : #include "llvm/Support/MemoryBuffer.h"
      27                 : #include "llvm/Support/raw_ostream.h"
      28                 : #include "llvm/System/Program.h"
      29                 : 
      30                 : #include <cstdio>
      31                 : #include <vector>
      32                 : #include <sstream>
      33                 : 
      34                 : #ifdef LLVM_ON_WIN32
      35                 : #include <windows.h>
      36                 : #else
      37                 : #include <dlfcn.h>
      38                 : #endif
      39                 : 
      40                 : using namespace clang;
      41                 : using namespace idx;
      42                 : 
      43               61: const llvm::sys::Path& CIndexer::getClangPath() {
      44                 :   // Did we already compute the path?
                        0: branch 1 not taken
                       61: branch 2 taken
      45               61:   if (!ClangPath.empty())
      46                0:     return ClangPath;
      47                 : 
      48                 :   // Find the location where this library lives (libCIndex.dylib).
      49                 : #ifdef LLVM_ON_WIN32
      50                 :   MEMORY_BASIC_INFORMATION mbi;
      51                 :   char path[MAX_PATH];
      52                 :   VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi,
      53                 :                sizeof(mbi));
      54                 :   GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH);
      55                 : 
      56                 :   llvm::sys::Path CIndexPath(path);
      57                 : 
      58                 :   CIndexPath.eraseComponent();
      59                 :   CIndexPath.appendComponent("clang");
      60                 :   CIndexPath.appendSuffix("exe");
      61                 :   CIndexPath.makeAbsolute();
      62                 : #else
      63                 :   // This silly cast below avoids a C++ warning.
      64                 :   Dl_info info;
                        0: branch 1 not taken
                       61: branch 2 taken
      65               61:   if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
      66                0:     assert(0 && "Call to dladdr() failed");
      67                 : 
      68               61:   llvm::sys::Path CIndexPath(info.dli_fname);
      69                 : 
      70                 :   // We now have the CIndex directory, locate clang relative to it.
      71               61:   CIndexPath.eraseComponent();
      72               61:   CIndexPath.appendComponent("..");
      73               61:   CIndexPath.appendComponent("bin");
      74               61:   CIndexPath.appendComponent("clang");
      75                 : #endif
      76                 : 
      77                 :   // Cache our result.
      78               61:   ClangPath = CIndexPath;
      79               61:   return ClangPath;
      80                 : }
      81                 : 
      82                9: std::string CIndexer::getClangResourcesPath() {
      83                9:   llvm::sys::Path P = getClangPath();
      84                 : 
                        9: branch 1 taken
                        0: branch 2 not taken
      85                9:   if (!P.empty()) {
      86                9:     P.eraseComponent();  // Remove /clang from foo/bin/clang
      87                9:     P.eraseComponent();  // Remove /bin   from foo/bin
      88                 : 
      89                 :     // Get foo/lib/clang/<version>/include
      90                9:     P.appendComponent("lib");
      91                9:     P.appendComponent("clang");
      92                9:     P.appendComponent(CLANG_VERSION_STRING);
      93                 :   }
      94                 : 
      95                9:   return P.str();
      96                 : }
      97                 : 
      98                2: static llvm::sys::Path GetTemporaryPath() {
      99                 :   // FIXME: This is lame; sys::Path should provide this function (in particular,
     100                 :   // it should know how to find the temporary files dir).
     101                2:   std::string Error;
     102                2:   const char *TmpDir = ::getenv("TMPDIR");
                        2: branch 0 taken
                        0: branch 1 not taken
     103                2:   if (!TmpDir)
     104                2:     TmpDir = ::getenv("TEMP");
                        2: branch 0 taken
                        0: branch 1 not taken
     105                2:   if (!TmpDir)
     106                2:     TmpDir = ::getenv("TMP");
                        2: branch 0 taken
                        0: branch 1 not taken
     107                2:   if (!TmpDir)
     108                2:     TmpDir = "/tmp";
     109                2:   llvm::sys::Path P(TmpDir);
     110                2:   P.appendComponent("remap");
                        0: branch 1 not taken
                        2: branch 2 taken
     111                2:   if (P.makeUnique(false, &Error))
     112                0:     return llvm::sys::Path("");
     113                 : 
     114                 :   // FIXME: Grumble, makeUnique sometimes leaves the file around!?  PR3837.
     115                2:   P.eraseFromDisk(false, 0);
     116                 : 
     117                2:   return P;
     118                 : }
     119                 : 
     120                 : bool clang::RemapFiles(unsigned num_unsaved_files,
     121                 :                        struct CXUnsavedFile *unsaved_files,
     122                 :                        std::vector<std::string> &RemapArgs,
     123               52:                        std::vector<llvm::sys::Path> &TemporaryFiles) {
                        2: branch 2 taken
                        0: branch 3 not taken
                        2: branch 5 taken
                        0: branch 6 not taken
                        2: branch 8 taken
                        0: branch 9 not taken
                        2: branch 10 taken
                       52: branch 11 taken
     124              108:   for (unsigned i = 0; i != num_unsaved_files; ++i) {
     125                 :     // Write the contents of this unsaved file into the temporary file.
     126                2:     llvm::sys::Path SavedFile(GetTemporaryPath());
                        0: branch 1 not taken
                        2: branch 2 taken
     127                2:     if (SavedFile.empty())
     128                0:       return true;
     129                 : 
     130                2:     std::string ErrorInfo;
     131                2:     llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo);
                        0: branch 1 not taken
                        2: branch 2 taken
     132                2:     if (!ErrorInfo.empty())
     133                0:       return true;
     134                 :     
     135                2:     OS.write(unsaved_files[i].Contents, unsaved_files[i].Length);
     136                2:     OS.close();
                        0: branch 1 not taken
                        2: branch 2 taken
     137                2:     if (OS.has_error()) {
     138                0:       SavedFile.eraseFromDisk();
     139                0:       return true;
     140                 :     }
     141                 :     
     142                 :     // Remap the file.
     143                2:     std::string RemapArg = unsaved_files[i].Filename;
     144                2:     RemapArg += ';';
     145                2:     RemapArg += SavedFile.str();
     146                2:     RemapArgs.push_back("-Xclang");
     147                2:     RemapArgs.push_back("-remap-file");
     148                2:     RemapArgs.push_back("-Xclang");
     149                2:     RemapArgs.push_back(RemapArg);
     150                2:     TemporaryFiles.push_back(SavedFile);
     151                 :   }
     152                 :   
     153               52:   return false;
     154                 : }
     155                 : 

Generated: 2010-02-10 01:31 by zcov