zcov: / tools/driver/cc1_main.cpp


Files: 1 Branches Taken: 51.9% 40 / 77
Generated: 2010-02-10 01:31 Branches Executed: 74.0% 57 / 77
Line Coverage: 44.0% 55 / 125


Programs: 1 Runs 2897


       1                 : //===-- cc1_main.cpp - Clang CC1 Driver -----------------------------------===//
       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 is the entry point to the clang -cc1 functionality, which implements the
      11                 : // core compiler functionality along with a number of additional tools for
      12                 : // demonstration and testing purposes.
      13                 : //
      14                 : //===----------------------------------------------------------------------===//
      15                 : 
      16                 : #include "clang/Basic/Diagnostic.h"
      17                 : #include "clang/Driver/Arg.h"
      18                 : #include "clang/Driver/ArgList.h"
      19                 : #include "clang/Driver/CC1Options.h"
      20                 : #include "clang/Driver/DriverDiagnostic.h"
      21                 : #include "clang/Driver/OptTable.h"
      22                 : #include "clang/Frontend/CompilerInstance.h"
      23                 : #include "clang/Frontend/CompilerInvocation.h"
      24                 : #include "clang/Frontend/FrontendActions.h"
      25                 : #include "clang/Frontend/FrontendDiagnostic.h"
      26                 : #include "clang/Frontend/FrontendPluginRegistry.h"
      27                 : #include "clang/Frontend/TextDiagnosticBuffer.h"
      28                 : #include "clang/Frontend/TextDiagnosticPrinter.h"
      29                 : #include "llvm/LLVMContext.h"
      30                 : #include "llvm/ADT/OwningPtr.h"
      31                 : #include "llvm/Support/ErrorHandling.h"
      32                 : #include "llvm/Support/ManagedStatic.h"
      33                 : #include "llvm/Support/PrettyStackTrace.h"
      34                 : #include "llvm/Support/raw_ostream.h"
      35                 : #include "llvm/System/DynamicLibrary.h"
      36                 : #include "llvm/System/Signals.h"
      37                 : #include "llvm/Target/TargetSelect.h"
      38                 : #include <cstdio>
      39                 : using namespace clang;
      40                 : 
      41                 : //===----------------------------------------------------------------------===//
      42                 : // Main driver
      43                 : //===----------------------------------------------------------------------===//
      44                 : 
      45                0: void LLVMErrorHandler(void *UserData, const std::string &Message) {
      46                0:   Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
      47                 : 
      48                0:   Diags.Report(diag::err_fe_error_backend) << Message;
      49                 : 
      50                 :   // We cannot recover from llvm errors.
      51                0:   exit(1);
      52                 : }
      53                 : 
      54             2513: static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
      55                 :   using namespace clang::frontend;
      56                 : 
                        0: branch 1 not taken
                        5: branch 2 taken
                       17: branch 3 taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        3: branch 8 taken
                       57: branch 9 taken
                       18: branch 10 taken
                        3: branch 11 taken
                      516: branch 12 taken
                       35: branch 13 taken
                        0: branch 14 not taken
                       12: branch 15 taken
                       44: branch 16 taken
                        1: branch 17 taken
                        0: branch 18 not taken
                       13: branch 19 taken
                        2: branch 20 taken
                     1280: branch 21 taken
                        0: branch 22 not taken
                        2: branch 23 taken
                      245: branch 24 taken
                        1: branch 25 taken
                       51: branch 26 taken
                        0: branch 27 not taken
                      188: branch 28 taken
                       18: branch 29 taken
      57             2513:   switch (CI.getFrontendOpts().ProgramAction) {
      58                 :   default:
      59                0:     llvm_unreachable("Invalid program action!");
      60                 : 
      61                5:   case ASTDump:                return new ASTDumpAction();
      62               17:   case ASTPrint:               return new ASTPrintAction();
      63                1:   case ASTPrintXML:            return new ASTPrintXMLAction();
      64                0:   case ASTView:                return new ASTViewAction();
      65                0:   case DumpRawTokens:          return new DumpRawTokensAction();
      66                1:   case DumpRecordLayouts:      return new DumpRecordAction();
      67                3:   case DumpTokens:             return new DumpTokensAction();
      68               57:   case EmitAssembly:           return new EmitAssemblyAction();
      69               18:   case EmitBC:                 return new EmitBCAction();
      70                3:   case EmitHTML:               return new HTMLPrintAction();
      71              516:   case EmitLLVM:               return new EmitLLVMAction();
      72               35:   case EmitLLVMOnly:           return new EmitLLVMOnlyAction();
      73                0:   case EmitObj:                return new EmitObjAction();
      74               12:   case FixIt:                  return new FixItAction();
      75               44:   case GeneratePCH:            return new GeneratePCHAction();
      76                1:   case GeneratePTH:            return new GeneratePTHAction();
      77                0:   case InheritanceView:        return new InheritanceViewAction();
      78               13:   case ParseNoop:              return new ParseOnlyAction();
      79                2:   case ParsePrintCallbacks:    return new PrintParseAction();
      80             1280:   case ParseSyntaxOnly:        return new SyntaxOnlyAction();
      81                 : 
      82                 :   case PluginAction: {
                        0: branch 2 not taken
                        0: branch 3 not taken
      83                0:     if (CI.getFrontendOpts().ActionName == "help") {
      84                0:       llvm::errs() << "clang -cc1 plugins:\n";
                        0: branch 2 not taken
                        0: branch 3 not taken
      85                0:       for (FrontendPluginRegistry::iterator it =
      86                0:              FrontendPluginRegistry::begin(),
      87                0:              ie = FrontendPluginRegistry::end();
      88                 :            it != ie; ++it)
      89                0:         llvm::errs() << "  " << it->getName() << " - " << it->getDesc() << "\n";
      90                0:       return 0;
      91                 :     }
      92                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
      93                0:     for (FrontendPluginRegistry::iterator it =
      94                0:            FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
      95                 :          it != ie; ++it) {
                        0: branch 4 not taken
                        0: branch 5 not taken
      96                0:       if (it->getName() == CI.getFrontendOpts().ActionName)
      97                0:         return it->instantiate();
      98                 :     }
      99                 : 
     100                 :     CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
     101                0:       << CI.getFrontendOpts().ActionName;
     102                0:     return 0;
     103                 :   }
     104                 : 
     105                2:   case PrintDeclContext:       return new DeclContextPrintAction();
     106              245:   case PrintPreprocessedInput: return new PrintPreprocessedAction();
     107                1:   case RewriteMacros:          return new RewriteMacrosAction();
     108               51:   case RewriteObjC:            return new RewriteObjCAction();
     109                0:   case RewriteTest:            return new RewriteTestAction();
     110              188:   case RunAnalysis:            return new AnalysisAction();
     111               18:   case RunPreprocessorOnly:    return new PreprocessOnlyAction();
     112                 :   }
     113                 : }
     114                 : 
     115             2513: static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
     116                 :   // Create the underlying action.
     117             2513:   FrontendAction *Act = CreateFrontendBaseAction(CI);
                        0: branch 0 not taken
                     2513: branch 1 taken
     118             2513:   if (!Act)
     119                0:     return 0;
     120                 : 
     121                 :   // If there are any AST files to merge, create a frontend action
     122                 :   // adaptor to perform the merge.
                        1: branch 2 taken
                     2512: branch 3 taken
     123             2513:   if (!CI.getFrontendOpts().ASTMergeFiles.empty())
     124                 :     Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0],
     125                1:                              CI.getFrontendOpts().ASTMergeFiles.size());
     126                 : 
     127             2513:   return Act;
     128                 : }
     129                 : 
     130                 : // FIXME: Define the need for this testing away.
     131                 : static int cc1_test(Diagnostic &Diags,
     132                0:                     const char **ArgBegin, const char **ArgEnd) {
     133                 :   using namespace clang::driver;
     134                 : 
     135                0:   llvm::errs() << "cc1 argv:";
                        0: branch 0 not taken
                        0: branch 1 not taken
     136                0:   for (const char **i = ArgBegin; i != ArgEnd; ++i)
     137                0:     llvm::errs() << " \"" << *i << '"';
     138                0:   llvm::errs() << "\n";
     139                 : 
     140                 :   // Parse the arguments.
     141                0:   OptTable *Opts = createCC1OptTable();
     142                 :   unsigned MissingArgIndex, MissingArgCount;
     143                 :   InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd,
     144                0:                                        MissingArgIndex, MissingArgCount);
     145                 : 
     146                 :   // Check for missing argument error.
                        0: branch 0 not taken
                        0: branch 1 not taken
     147                0:   if (MissingArgCount)
     148                 :     Diags.Report(clang::diag::err_drv_missing_argument)
     149                0:       << Args->getArgString(MissingArgIndex) << MissingArgCount;
     150                 : 
     151                 :   // Dump the parsed arguments.
     152                0:   llvm::errs() << "cc1 parsed options:\n";
                        0: branch 2 not taken
                        0: branch 3 not taken
     153                0:   for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
     154                 :        it != ie; ++it)
     155                0:     (*it)->dump();
     156                 : 
     157                 :   // Create a compiler invocation.
     158                0:   llvm::errs() << "cc1 creating invocation.\n";
     159                0:   CompilerInvocation Invocation;
     160                0:   CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags);
     161                 : 
     162                 :   // Convert the invocation back to argument strings.
     163                0:   std::vector<std::string> InvocationArgs;
     164                0:   Invocation.toArgs(InvocationArgs);
     165                 : 
     166                 :   // Dump the converted arguments.
     167                0:   llvm::SmallVector<const char*, 32> Invocation2Args;
     168                0:   llvm::errs() << "invocation argv :";
                        0: branch 1 not taken
                        0: branch 2 not taken
     169                0:   for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) {
     170                0:     Invocation2Args.push_back(InvocationArgs[i].c_str());
     171                0:     llvm::errs() << " \"" << InvocationArgs[i] << '"';
     172                 :   }
     173                0:   llvm::errs() << "\n";
     174                 : 
     175                 :   // Convert those arguments to another invocation, and check that we got the
     176                 :   // same thing.
     177                0:   CompilerInvocation Invocation2;
     178                 :   CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(),
     179                0:                                      Invocation2Args.end(), Diags);
     180                 : 
     181                 :   // FIXME: Implement CompilerInvocation comparison.
     182                0:   if (true) {
     183                 :     //llvm::errs() << "warning: Invocations differ!\n";
     184                 : 
     185                0:     std::vector<std::string> Invocation2Args;
     186                0:     Invocation2.toArgs(Invocation2Args);
     187                0:     llvm::errs() << "invocation2 argv:";
                        0: branch 1 not taken
                        0: branch 2 not taken
     188                0:     for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i)
     189                0:       llvm::errs() << " \"" << Invocation2Args[i] << '"';
     190                0:     llvm::errs() << "\n";
     191                 :   }
     192                 : 
     193                0:   return 0;
     194                 : }
     195                 : 
     196                 : int cc1_main(const char **ArgBegin, const char **ArgEnd,
     197             2514:              const char *Argv0, void *MainAddr) {
     198             2514:   CompilerInstance Clang(&llvm::getGlobalContext(), false);
     199                 : 
     200                 :   // Run clang -cc1 test.
                     2514: branch 0 taken
                        0: branch 1 not taken
                        0: branch 5 not taken
                     2514: branch 6 taken
                        0: branch 7 not taken
                     2514: branch 8 taken
     201             2514:   if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") {
     202                0:     TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
     203                0:     Diagnostic Diags(&DiagClient);
     204                0:     return cc1_test(Diags, ArgBegin + 1, ArgEnd);
     205                 :   }
     206                 : 
     207                 :   // Initialize targets first, so that --version shows registered targets.
     208             2514:   llvm::InitializeAllTargets();
     209             2514:   llvm::InitializeAllAsmPrinters();
     210                 : 
     211                 :   // Buffer diagnostics from argument parsing so that we can output them using a
     212                 :   // well formed diagnostic object.
     213             2514:   TextDiagnosticBuffer DiagsBuffer;
     214             2514:   Diagnostic Diags(&DiagsBuffer);
     215                 :   CompilerInvocation::CreateFromArgs(Clang.getInvocation(), ArgBegin, ArgEnd,
     216             2514:                                      Diags);
     217                 : 
     218                 :   // Infer the builtin include path if unspecified.
                     2514: branch 1 taken
                        0: branch 2 not taken
                     2372: branch 5 taken
                      142: branch 6 taken
                     2372: branch 7 taken
                      142: branch 8 taken
     219             2514:   if (Clang.getHeaderSearchOpts().UseBuiltinIncludes &&
     220                 :       Clang.getHeaderSearchOpts().ResourceDir.empty())
     221                 :     Clang.getHeaderSearchOpts().ResourceDir =
     222             2372:       CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
     223                 : 
     224                 :   // Honor -help.
                        0: branch 1 not taken
                     2514: branch 2 taken
     225             2514:   if (Clang.getFrontendOpts().ShowHelp) {
     226                0:     llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable());
     227                 :     Opts->PrintHelp(llvm::outs(), "clang -cc1",
     228                0:                     "LLVM 'Clang' Compiler: http://clang.llvm.org");
     229                0:     return 0;
     230                 :   }
     231                 : 
     232                 :   // Honor -version.
     233                 :   //
     234                 :   // FIXME: Use a better -version message?
                        0: branch 1 not taken
                     2514: branch 2 taken
     235             2514:   if (Clang.getFrontendOpts().ShowVersion) {
     236                0:     llvm::cl::PrintVersionMessage();
     237                0:     return 0;
     238                 :   }
     239                 : 
     240                 :   // Create the actual diagnostics engine.
     241             2514:   Clang.createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin));
                        0: branch 1 not taken
                     2514: branch 2 taken
     242             2514:   if (!Clang.hasDiagnostics())
     243                0:     return 1;
     244                 : 
     245                 :   // Set an error handler, so that any LLVM backend diagnostics go through our
     246                 :   // error handler.
     247                 :   llvm::llvm_install_error_handler(LLVMErrorHandler,
     248             2514:                                    static_cast<void*>(&Clang.getDiagnostics()));
     249                 : 
     250             2514:   DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics());
     251                 : 
     252                 :   // Load any requested plugins.
                        0: branch 1 not taken
                     2514: branch 2 taken
     253             5028:   for (unsigned i = 0,
     254             2514:          e = Clang.getFrontendOpts().Plugins.size(); i != e; ++i) {
     255                0:     const std::string &Path = Clang.getFrontendOpts().Plugins[i];
     256                0:     std::string Error;
                        0: branch 2 not taken
                        0: branch 3 not taken
     257                0:     if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
     258                0:       Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error;
     259                 :   }
     260                 : 
     261                 :   // If there were errors in processing arguments, don't do anything else.
     262             2514:   bool Success = false;
                     2513: branch 2 taken
                        1: branch 3 taken
     263             2514:   if (!Clang.getDiagnostics().getNumErrors()) {
     264                 :     // Create and execute the frontend action.
     265             2513:     llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
                     2513: branch 1 taken
                        0: branch 2 not taken
     266             2513:     if (Act)
     267             2513:       Success = Clang.ExecuteAction(*Act);
     268                 :   }
     269                 : 
     270                 :   // Managed static deconstruction. Useful for making things like
     271                 :   // -time-passes usable.
     272             2514:   llvm::llvm_shutdown();
     273                 : 
     274             2514:   return !Success;
     275                 : }

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