zcov: / lib/Frontend/FrontendAction.cpp


Files: 1 Branches Taken: 72.1% 49 / 68
Generated: 2010-02-10 01:31 Branches Executed: 94.1% 64 / 68
Line Coverage: 89.4% 93 / 104


Programs: 2 Runs 3018


       1                 : //===--- FrontendAction.cpp -----------------------------------------------===//
       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/Frontend/FrontendAction.h"
      11                 : #include "clang/AST/ASTContext.h"
      12                 : #include "clang/Lex/HeaderSearch.h"
      13                 : #include "clang/Lex/Preprocessor.h"
      14                 : #include "clang/Frontend/ASTUnit.h"
      15                 : #include "clang/Frontend/CompilerInstance.h"
      16                 : #include "clang/Frontend/FrontendDiagnostic.h"
      17                 : #include "clang/Sema/ParseAST.h"
      18                 : #include "llvm/Support/MemoryBuffer.h"
      19                 : #include "llvm/Support/Timer.h"
      20                 : #include "llvm/Support/ErrorHandling.h"
      21                 : #include "llvm/Support/raw_ostream.h"
      22                 : using namespace clang;
      23                 : 
      24             2523: FrontendAction::FrontendAction() : Instance(0) {}
      25                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 12 not taken
                     2523: branch 13 taken
      26             2523: FrontendAction::~FrontendAction() {}
      27                 : 
      28             5047: void FrontendAction::setCurrentFile(llvm::StringRef Value, ASTUnit *AST) {
      29             5047:   CurrentFile = Value;
      30             5047:   CurrentASTUnit.reset(AST);
      31             5047: }
      32                 : 
      33                 : bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
      34                 :                                      llvm::StringRef Filename,
      35             2522:                                      bool IsAST) {
                        0: branch 0 not taken
                     2522: branch 1 taken
      36             2522:   assert(!Instance && "Already processing a source file!");
                     2522: branch 1 taken
                        0: branch 2 not taken
      37             2522:   assert(!Filename.empty() && "Unexpected empty filename!");
      38             2522:   setCurrentFile(Filename);
      39             2522:   setCompilerInstance(&CI);
      40                 : 
      41                 :   // AST files follow a very different path, since they share objects via the
      42                 :   // AST unit.
                        2: branch 0 taken
                     2520: branch 1 taken
      43             2522:   if (IsAST) {
      44                 :     assert(!usesPreprocessorOnly() &&
                        2: branch 1 taken
                        0: branch 2 not taken
      45                2:            "Attempt to pass AST file to preprocessor only action!");
                        2: branch 1 taken
                        0: branch 2 not taken
      46                2:     assert(hasASTSupport() && "This action does not have AST support!");
      47                 : 
      48                2:     std::string Error;
      49                2:     ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, CI.getDiagnostics());
                        0: branch 0 not taken
                        2: branch 1 taken
      50                2:     if (!AST)
      51                0:       goto failure;
      52                 : 
      53                2:     setCurrentFile(Filename, AST);
      54                 : 
      55                 :     // Set the shared objects, these are reset when we finish processing the
      56                 :     // file, otherwise the CompilerInstance will happily destroy them.
      57                2:     CI.setFileManager(&AST->getFileManager());
      58                2:     CI.setSourceManager(&AST->getSourceManager());
      59                2:     CI.setPreprocessor(&AST->getPreprocessor());
      60                2:     CI.setASTContext(&AST->getASTContext());
      61                 : 
      62                 :     // Initialize the action.
                        0: branch 1 not taken
                        2: branch 2 taken
      63                2:     if (!BeginSourceFileAction(CI, Filename))
      64                 :       goto failure;
      65                 : 
      66                 :     /// Create the AST consumer.
      67                2:     CI.setASTConsumer(CreateASTConsumer(CI, Filename));
                        0: branch 1 not taken
                        2: branch 2 taken
      68                2:     if (!CI.hasASTConsumer())
      69                 :       goto failure;
      70                 : 
                        0: branch 1 not taken
                        2: branch 2 taken
      71                4:     return true;
      72                 :   }
      73                 : 
      74                 :   // Inform the diagnostic client we are processing a source file.
      75                 :   CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
      76             2520:                                            &CI.getPreprocessor());
      77                 : 
      78                 :   // Initialize the action.
                     2520: branch 1 taken
                        0: branch 2 not taken
      79             2520:   if (!BeginSourceFileAction(CI, Filename))
      80                0:     goto failure;
      81                 : 
      82                 :   /// Create the AST context and consumer unless this is a preprocessor only
      83                 :   /// action.
                     2237: branch 1 taken
                      283: branch 2 taken
      84             2520:   if (!usesPreprocessorOnly()) {
      85             2237:     CI.createASTContext();
      86             2237:     CI.setASTConsumer(CreateASTConsumer(CI, Filename));
                        1: branch 1 taken
                     2236: branch 2 taken
      87             2237:     if (!CI.hasASTConsumer())
      88                1:       goto failure;
      89                 : 
      90                 :     /// Use PCH?
                       35: branch 2 taken
                     2201: branch 3 taken
      91             2236:     if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
                       35: branch 1 taken
                        0: branch 2 not taken
      92               35:       assert(hasPCHSupport() && "This action does not have PCH support!");
      93                 :       CI.createPCHExternalASTSource(
      94               35:         CI.getPreprocessorOpts().ImplicitPCHInclude);
                        2: branch 2 taken
                       33: branch 3 taken
      95               35:       if (!CI.getASTContext().getExternalSource())
      96                2:         goto failure;
      97                 :     }
      98                 :   }
      99                 : 
     100                 :   // Initialize builtin info as long as we aren't using an external AST
     101                 :   // source.
                     2234: branch 1 taken
                      283: branch 2 taken
                     2201: branch 5 taken
                       33: branch 6 taken
                     2484: branch 7 taken
                       33: branch 8 taken
     102             2517:   if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
     103             2484:     Preprocessor &PP = CI.getPreprocessor();
     104                 :     PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
     105             2484:                                            PP.getLangOptions().NoBuiltin);
     106                 :   }
     107                 : 
     108             2517:   return true;
     109                 : 
     110                 :   // If we failed, reset state since the client will not end up calling the
     111                 :   // matching EndSourceFile().
     112                3:   failure:
                        0: branch 1 not taken
                        3: branch 2 taken
     113                3:   if (isCurrentFileAST()) {
     114                0:     CI.takeASTContext();
     115                0:     CI.takePreprocessor();
     116                0:     CI.takeSourceManager();
     117                0:     CI.takeFileManager();
     118                 :   }
     119                 : 
     120                3:   CI.getDiagnosticClient().EndSourceFile();
     121                3:   setCurrentFile("");
     122                3:   setCompilerInstance(0);
     123                3:   return false;
     124                 : }
     125                 : 
     126             2519: void FrontendAction::Execute() {
     127             2519:   CompilerInstance &CI = getCompilerInstance();
     128                 : 
     129                 :   // Initialize the main file entry. This needs to be delayed until after PCH
     130                 :   // has loaded.
                        2: branch 1 taken
                     2517: branch 2 taken
     131             2519:   if (isCurrentFileAST()) {
     132                 :     // Set the main file ID to an empty file.
     133                 :     //
     134                 :     // FIXME: We probably shouldn't need this, but for now this is the
     135                 :     // simplest way to reuse the logic in ParseAST.
     136                2:     const char *EmptyStr = "";
     137                 :     llvm::MemoryBuffer *SB =
     138                2:       llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<dummy input>");
     139                2:     CI.getSourceManager().createMainFileIDForMemBuffer(SB);
     140                 :   } else {
                        0: branch 3 not taken
                     2517: branch 4 taken
     141             2517:     if (!CI.InitializeSourceManager(getCurrentFile()))
     142                0:       return;
     143                 :   }
     144                 : 
                        0: branch 1 not taken
                     2519: branch 2 taken
     145             2519:   if (CI.hasFrontendTimer()) {
     146                0:     llvm::TimeRegion Timer(CI.getFrontendTimer());
     147                0:     ExecuteAction();
     148                 :   }
     149             2519:   else ExecuteAction();
     150                 : }
     151                 : 
     152             2519: void FrontendAction::EndSourceFile() {
     153             2519:   CompilerInstance &CI = getCompilerInstance();
     154                 : 
     155                 :   // Finalize the action.
     156             2519:   EndSourceFileAction();
     157                 : 
     158                 :   // Release the consumer and the AST, in that order since the consumer may
     159                 :   // perform actions in its destructor which require the context.
     160                 :   //
     161                 :   // FIXME: There is more per-file stuff we could just drop here?
                      152: branch 1 taken
                     2367: branch 2 taken
     162             2519:   if (CI.getFrontendOpts().DisableFree) {
     163              152:     CI.takeASTConsumer();
                      150: branch 1 taken
                        2: branch 2 taken
     164              152:     if (!isCurrentFileAST())
     165              150:       CI.takeASTContext();
     166                 :   } else {
     167             2367:     CI.setASTConsumer(0);
                     2367: branch 1 taken
                        0: branch 2 not taken
     168             2367:     if (!isCurrentFileAST())
     169             2367:       CI.setASTContext(0);
     170                 :   }
     171                 : 
                        2: branch 1 taken
                     2517: branch 2 taken
     172             2519:   if (CI.getFrontendOpts().ShowStats) {
     173                2:     llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
     174                2:     CI.getPreprocessor().PrintStats();
     175                2:     CI.getPreprocessor().getIdentifierTable().PrintStats();
     176                2:     CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
     177                2:     CI.getSourceManager().PrintStats();
     178                2:     llvm::errs() << "\n";
     179                 :   }
     180                 : 
     181                 :   // Cleanup the output streams, and erase the output files if we encountered
     182                 :   // an error.
     183             2519:   CI.ClearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().getNumErrors());
     184                 : 
     185                 :   // Inform the diagnostic client we are done with this source file.
     186             2519:   CI.getDiagnosticClient().EndSourceFile();
     187                 : 
                        2: branch 1 taken
                     2517: branch 2 taken
     188             2519:   if (isCurrentFileAST()) {
     189                2:     CI.takeASTContext();
     190                2:     CI.takePreprocessor();
     191                2:     CI.takeSourceManager();
     192                2:     CI.takeFileManager();
     193                 :   }
     194                 : 
     195             2519:   setCompilerInstance(0);
     196             2519:   setCurrentFile("");
     197             2519: }
     198                 : 
     199                 : //===----------------------------------------------------------------------===//
     200                 : // Utility Actions
     201                 : //===----------------------------------------------------------------------===//
     202                 : 
     203             2236: void ASTFrontendAction::ExecuteAction() {
     204             2236:   CompilerInstance &CI = getCompilerInstance();
     205                 : 
     206                 :   // FIXME: Move the truncation aspect of this into Sema, we delayed this till
     207                 :   // here so the source manager would be initialized.
                     1278: branch 1 taken
                      958: branch 2 taken
                       87: branch 5 taken
                     1191: branch 6 taken
                       87: branch 7 taken
                     2149: branch 8 taken
     208             2236:   if (hasCodeCompletionSupport() &&
     209                 :       !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
     210               87:     CI.createCodeCompletionConsumer();
     211                 : 
     212                 :   // Use a code completion consumer?
     213             2236:   CodeCompleteConsumer *CompletionConsumer = 0;
                       87: branch 1 taken
                     2149: branch 2 taken
     214             2236:   if (CI.hasCodeCompletionConsumer())
     215               87:     CompletionConsumer = &CI.getCodeCompletionConsumer();
     216                 : 
     217                 :   ParseAST(CI.getPreprocessor(), &CI.getASTConsumer(), CI.getASTContext(),
     218                 :            CI.getFrontendOpts().ShowStats,
     219             2236:            usesCompleteTranslationUnit(), CompletionConsumer);
     220             2236: }
     221                 : 
     222                 : ASTConsumer *
     223                 : PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
     224                0:                                               llvm::StringRef InFile) {
     225                0:   llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
     226                 : }

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