zcov: / lib/Driver/Compilation.cpp


Files: 1 Branches Taken: 67.5% 54 / 80
Generated: 2010-02-10 01:31 Branches Executed: 75.0% 60 / 80
Line Coverage: 88.0% 73 / 83


Programs: 2 Runs 3018


       1                 : //===--- Compilation.cpp - Compilation Task Implementation --------------*-===//
       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                 : #include "clang/Driver/Compilation.h"
      11                 : 
      12                 : #include "clang/Driver/Action.h"
      13                 : #include "clang/Driver/ArgList.h"
      14                 : #include "clang/Driver/Driver.h"
      15                 : #include "clang/Driver/DriverDiagnostic.h"
      16                 : #include "clang/Driver/Options.h"
      17                 : #include "clang/Driver/ToolChain.h"
      18                 : 
      19                 : #include "llvm/Support/raw_ostream.h"
      20                 : #include "llvm/System/Program.h"
      21                 : #include <sys/stat.h>
      22                 : #include <errno.h>
      23                 : using namespace clang::driver;
      24                 : 
      25                 : Compilation::Compilation(const Driver &D,
      26                 :                          const ToolChain &_DefaultToolChain,
      27              248:                          InputArgList *_Args)
      28              248:   : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
      29              248: }
      30                 : 
      31              248: Compilation::~Compilation() {
                      248: branch 0 taken
                        0: branch 1 not taken
                      248: branch 3 taken
                      248: branch 4 taken
      32              248:   delete Args;
      33                 : 
      34                 :   // Free any derived arg lists.
                      207: branch 3 taken
                      248: branch 4 taken
                        0: branch 8 not taken
                        0: branch 9 not taken
      35              455:   for (llvm::DenseMap<std::pair<const ToolChain*, const char*>,
      36              248:                       DerivedArgList*>::iterator it = TCArgs.begin(),
      37              248:          ie = TCArgs.end(); it != ie; ++it)
                      207: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      38              207:     delete it->second;
      39                 : 
      40                 :   // Free the actions, if built.
                      235: branch 2 taken
                      248: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
      41              483:   for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
      42                 :        it != ie; ++it)
                      235: branch 0 taken
                        0: branch 1 not taken
                      235: branch 3 taken
                      235: branch 4 taken
      43              235:     delete *it;
      44              248: }
      45                 : 
      46                 : const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC,
      47              235:                                                        const char *BoundArch) {
                        0: branch 0 not taken
                      235: branch 1 taken
      48              235:   if (!TC)
      49                0:     TC = &DefaultToolChain;
      50                 : 
      51              235:   DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)];
                      207: branch 0 taken
                       28: branch 1 taken
      52              235:   if (!Entry)
      53              207:     Entry = TC->TranslateArgs(*Args, BoundArch);
      54                 : 
      55              235:   return *Entry;
      56                 : }
      57                 : 
      58                 : void Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J,
      59              138:                            const char *Terminator, bool Quote) const {
                       84: branch 1 taken
                       54: branch 2 taken
      60              138:   if (const Command *C = dyn_cast<Command>(&J)) {
      61               84:     OS << " \"" << C->getExecutable() << '"';
                     1614: branch 2 taken
                       84: branch 3 taken
      62             1782:     for (ArgStringList::const_iterator it = C->getArguments().begin(),
      63               84:            ie = C->getArguments().end(); it != ie; ++it) {
                     1580: branch 0 taken
                       34: branch 1 taken
      64             1614:       if (Quote)
      65             1580:         OS << " \"" << *it << '"';
      66                 :       else
      67               34:         OS << ' ' << *it;
      68                 :     }
      69               84:     OS << Terminator;
                        2: branch 1 taken
                       52: branch 2 taken
      70               54:   } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
                        2: branch 0 taken
                        2: branch 1 taken
      71                4:     for (PipedJob::const_iterator
      72                2:            it = PJ->begin(), ie = PJ->end(); it != ie; ++it)
                        0: branch 1 not taken
                        2: branch 2 taken
      73                2:       PrintJob(OS, **it, (it + 1 != PJ->end()) ? " |\n" : "\n", Quote);
      74                 :   } else {
      75               52:     const JobList *Jobs = cast<JobList>(&J);
                       81: branch 0 taken
                       52: branch 1 taken
      76              133:     for (JobList::const_iterator
      77               52:            it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
      78               81:       PrintJob(OS, **it, Terminator, Quote);
      79                 :   }
      80              138: }
      81                 : 
      82                 : bool Compilation::CleanupFileList(const ArgStringList &Files,
      83              188:                                   bool IssueErrors) const {
      84              188:   bool Success = true;
      85                 : 
                        2: branch 1 taken
                       11: branch 2 taken
                        2: branch 4 taken
                       11: branch 5 taken
                       13: branch 6 taken
                      188: branch 7 taken
      86              214:   for (ArgStringList::const_iterator
      87              188:          it = Files.begin(), ie = Files.end(); it != ie; ++it) {
      88                 : 
      89               13:     llvm::sys::Path P(*it);
      90               13:     std::string Error;
      91                 : 
                       11: branch 1 taken
                        2: branch 2 taken
      92               13:     if (!P.isRegularFile()) {
      93                 :       // If we have a special file in our list, i.e. /dev/null
      94                 :       //  then don't call eraseFromDisk() and just continue.
      95               11:       continue;
      96                 :     }
      97                 : 
                        0: branch 1 not taken
                        2: branch 2 taken
      98                2:     if (P.eraseFromDisk(false, &Error)) {
      99                 :       // Failure is only failure if the file doesn't exist. There is a
     100                 :       // race condition here due to the limited interface of
     101                 :       // llvm::sys::Path, we want to know if the removal gave E_NOENT.
     102                 : 
     103                 :       // FIXME: Grumble, P.exists() is broken. PR3837.
     104                 :       struct stat buf;
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
     105                0:       if (::stat(P.c_str(), &buf) == 0
     106                 :           || errno != ENOENT) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     107                0:         if (IssueErrors)
     108                 :           getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
     109                0:             << Error;
     110                0:         Success = false;
     111                 :       }
     112                 :     }
     113                 :   }
     114                 : 
     115              188:   return Success;
     116                 : }
     117                 : 
     118                 : int Compilation::ExecuteCommand(const Command &C,
     119              144:                                 const Command *&FailingCommand) const {
     120              144:   llvm::sys::Path Prog(C.getExecutable());
     121              144:   const char **Argv = new const char*[C.getArguments().size() + 2];
     122              144:   Argv[0] = C.getExecutable();
     123              144:   std::copy(C.getArguments().begin(), C.getArguments().end(), Argv+1);
     124              144:   Argv[C.getArguments().size() + 1] = 0;
     125                 : 
                      141: branch 1 taken
                        3: branch 2 taken
                        0: branch 6 not taken
                      141: branch 7 taken
                        3: branch 8 taken
                      141: branch 9 taken
     126              144:   if (getDriver().CCCEcho || getArgs().hasArg(options::OPT_v))
     127                3:     PrintJob(llvm::errs(), C, "\n", false);
     128                 : 
     129              144:   std::string Error;
     130                 :   int Res =
     131                 :     llvm::sys::Program::ExecuteAndWait(Prog, Argv,
     132                 :                                        /*env*/0, /*redirects*/0,
     133                 :                                        /*secondsToWait*/0, /*memoryLimit*/0,
     134              144:                                        &Error);
                        0: branch 1 not taken
                      144: branch 2 taken
     135              144:   if (!Error.empty()) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     136                0:     assert(Res && "Error string set with 0 result code!");
     137                0:     getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
     138                 :   }
     139                 : 
                        5: branch 0 taken
                      139: branch 1 taken
     140              144:   if (Res)
     141                5:     FailingCommand = &C;
     142                 : 
                      144: branch 0 taken
                        0: branch 1 not taken
     143              144:   delete[] Argv;
     144              144:   return Res;
     145                 : }
     146                 : 
     147                 : int Compilation::ExecuteJob(const Job &J,
     148              327:                             const Command *&FailingCommand) const {
                      134: branch 1 taken
                      193: branch 2 taken
     149              327:   if (const Command *C = dyn_cast<Command>(&J)) {
     150              134:     return ExecuteCommand(*C, FailingCommand);
                       10: branch 1 taken
                      183: branch 2 taken
     151              193:   } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
     152                 :     // Piped commands with a single job are easy.
                       10: branch 1 taken
                        0: branch 2 not taken
     153               10:     if (PJ->size() == 1)
     154               10:       return ExecuteCommand(**PJ->begin(), FailingCommand);
     155                 : 
     156                0:     FailingCommand = *PJ->begin();
     157                0:     getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe";
     158                0:     return 1;
     159                 :   } else {
     160              183:     const JobList *Jobs = cast<JobList>(&J);
                      144: branch 0 taken
                      178: branch 1 taken
     161              322:     for (JobList::const_iterator
     162              183:            it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
                        5: branch 1 taken
                      139: branch 2 taken
     163              144:       if (int Res = ExecuteJob(**it, FailingCommand))
     164                5:         return Res;
     165              178:     return 0;
     166                 :   }
     167                 : }

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