zcov: / tools/CIndex/CIndexDiagnostic.cpp


Files: 1 Branches Taken: 54.5% 61 / 112
Generated: 2010-02-10 01:31 Branches Executed: 92.9% 104 / 112
Line Coverage: 84.8% 95 / 112


Programs: 1 Runs 121


       1                 : /*===-- CIndexDiagnostics.cpp - Diagnostics C Interface -----------*- C -*-===*\
       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                 : |* Implements the diagnostic functions of the Clang C interface.              *|
      11                 : |*                                                                            *|
      12                 : \*===----------------------------------------------------------------------===*/
      13                 : #include "CIndexDiagnostic.h"
      14                 : #include "CIndexer.h"
      15                 : #include "CXSourceLocation.h"
      16                 : 
      17                 : #include "clang/Frontend/FrontendDiagnostic.h"
      18                 : #include "llvm/Support/MemoryBuffer.h"
      19                 : 
      20                 : using namespace clang;
      21                 : using namespace clang::cxloc;
      22                 : 
      23                 : //-----------------------------------------------------------------------------
      24                 : // Opaque data structures                        
      25                 : //-----------------------------------------------------------------------------
      26                 : namespace {
      27                 :   /// \brief The storage behind a CXDiagnostic
      28                 :   struct CXStoredDiagnostic {
      29                 :     /// \brief The translation unit this diagnostic came from.
      30                 :     const LangOptions *LangOptsPtr;
      31                 :     
      32                 :     /// \brief The severity level of this diagnostic.
      33                 :     Diagnostic::Level Level;
      34                 :     
      35                 :     /// \brief A reference to the diagnostic information.
      36                 :     const DiagnosticInfo &Info;
      37                 :   };
      38                 : }
      39                 : 
      40                 : //-----------------------------------------------------------------------------
      41                 : // CIndex Diagnostic Client                        
      42                 : //-----------------------------------------------------------------------------
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                       69: branch 6 taken
                        0: branch 9 not taken
                        0: branch 10 not taken
      43               69: CIndexDiagnosticClient::~CIndexDiagnosticClient() { }
      44                 : 
      45                 : void CIndexDiagnosticClient::BeginSourceFile(const LangOptions &LangOpts,
      46               61:                                              const Preprocessor *PP) {
                        0: branch 0 not taken
                       61: branch 1 taken
      47               61:   assert(!LangOptsPtr && "Invalid state!");
      48               61:   LangOptsPtr = &LangOpts;
      49               61: }
      50                 : 
      51               42: void CIndexDiagnosticClient::EndSourceFile() {
                        0: branch 0 not taken
                       42: branch 1 taken
      52               42:   assert(LangOptsPtr && "Invalid state!");
      53               42:   LangOptsPtr = 0;
      54               42: }
      55                 : 
      56                 : void CIndexDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
      57               55:                                               const DiagnosticInfo &Info) {
                       55: branch 0 taken
                        0: branch 1 not taken
      58               55:   if (!Callback)
      59                0:     return;
      60                 : 
      61                 :   assert((LangOptsPtr || Info.getLocation().isInvalid()) &&
                        0: branch 0 not taken
                       55: branch 1 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
      62               55:          "Missing language options with located diagnostic!");
      63               55:   CXStoredDiagnostic Stored = { this->LangOptsPtr, DiagLevel, Info };
      64               55:   Callback(&Stored, ClientData);
      65                 : }
      66                 : 
      67                 : //-----------------------------------------------------------------------------
      68                 : // C Interface Routines                        
      69                 : //-----------------------------------------------------------------------------
      70                 : extern "C" {
      71                 :   
      72               55: enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
      73               55:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        0: branch 0 not taken
                       55: branch 1 taken
      74               55:   if (!StoredDiag)
      75                0:     return CXDiagnostic_Ignored;
      76                 :   
                        0: branch 0 not taken
                        3: branch 1 taken
                       44: branch 2 taken
                        6: branch 3 taken
                        2: branch 4 taken
                        0: branch 5 not taken
      77               55:   switch (StoredDiag->Level) {
      78                0:   case Diagnostic::Ignored: return CXDiagnostic_Ignored;
      79                3:   case Diagnostic::Note:    return CXDiagnostic_Note;
      80               44:   case Diagnostic::Warning: return CXDiagnostic_Warning;
      81                6:   case Diagnostic::Error:   return CXDiagnostic_Error;
      82                2:   case Diagnostic::Fatal:   return CXDiagnostic_Fatal;
      83                 :   }
      84                 :  
      85                0:   llvm_unreachable("Invalid diagnostic level");
      86                 :   return CXDiagnostic_Ignored;
      87                 : }
      88                 :   
      89               55: CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
      90               55:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                       55: branch 0 taken
                        0: branch 1 not taken
                        0: branch 4 not taken
                       55: branch 5 taken
                        0: branch 6 not taken
                       55: branch 7 taken
      91               55:   if (!StoredDiag || StoredDiag->Info.getLocation().isInvalid())
      92                0:     return clang_getNullLocation();
      93                 :   
      94                 :   return translateSourceLocation(StoredDiag->Info.getLocation().getManager(),
      95                 :                                  *StoredDiag->LangOptsPtr,
      96               55:                                  StoredDiag->Info.getLocation());
      97                 : }
      98                 : 
      99               55: CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
     100               55:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        0: branch 0 not taken
                       55: branch 1 taken
     101               55:   if (!StoredDiag)
     102                0:     return CIndexer::createCXString("");
     103                 :   
     104               55:   llvm::SmallString<64> Spelling;
     105               55:   StoredDiag->Info.FormatDiagnostic(Spelling);
     106               55:   return CIndexer::createCXString(Spelling.str(), true);
     107                 : }
     108                 : 
     109               55: unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
     110               55:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                       55: branch 0 taken
                        0: branch 1 not taken
                        0: branch 4 not taken
                       55: branch 5 taken
                        0: branch 6 not taken
                       55: branch 7 taken
     111               55:   if (!StoredDiag || StoredDiag->Info.getLocation().isInvalid())
     112                0:     return 0;
     113                 :   
     114               55:   return StoredDiag->Info.getNumRanges();
     115                 : }
     116                 :   
     117               11: CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
     118               11:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                       11: branch 0 taken
                        0: branch 1 not taken
                       11: branch 3 taken
                        0: branch 4 not taken
                        0: branch 7 not taken
                       11: branch 8 taken
                        0: branch 9 not taken
                       11: branch 10 taken
     119               11:   if (!StoredDiag || Range >= StoredDiag->Info.getNumRanges() || 
     120                 :       StoredDiag->Info.getLocation().isInvalid())
     121                0:     return clang_getNullRange();
     122                 :   
     123                 :   return translateSourceRange(StoredDiag->Info.getLocation().getManager(),
     124                 :                               *StoredDiag->LangOptsPtr,
     125               11:                               StoredDiag->Info.getRange(Range));
     126                 : }
     127                 : 
     128               55: unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
     129               55:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        0: branch 0 not taken
                       55: branch 1 taken
     130               55:   if (!StoredDiag)
     131                0:     return 0;
     132                 :   
     133               55:   return StoredDiag->Info.getNumCodeModificationHints();
     134                 : }
     135                 : 
     136                 : enum CXFixItKind clang_getDiagnosticFixItKind(CXDiagnostic Diag, 
     137                3:                                               unsigned FixIt) {
     138                3:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        3: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        3: branch 4 taken
                        0: branch 5 not taken
                        3: branch 6 taken
     139                3:   if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints())
     140                0:     return CXFixIt_Insertion;
     141                 :   
     142                 :   const CodeModificationHint &Hint
     143                3:     = StoredDiag->Info.getCodeModificationHint(FixIt);
                        1: branch 1 taken
                        2: branch 2 taken
     144                3:   if (Hint.RemoveRange.isInvalid())
     145                1:     return CXFixIt_Insertion;
                        1: branch 1 taken
                        1: branch 2 taken
     146                2:   if (Hint.InsertionLoc.isInvalid())
     147                1:     return CXFixIt_Removal;
     148                 :   
     149                1:   return CXFixIt_Replacement;  
     150                 : }
     151                 : 
     152                 : CXString clang_getDiagnosticFixItInsertion(CXDiagnostic Diag, 
     153                 :                                            unsigned FixIt,
     154                1:                                            CXSourceLocation *Location) {
                        1: branch 0 taken
                        0: branch 1 not taken
     155                1:   if (Location)
     156                1:     *Location = clang_getNullLocation();
     157                 : 
     158                1:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        1: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
     159                1:   if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints())
     160                0:     return CIndexer::createCXString("");
     161                 :   
     162                 :   const CodeModificationHint &Hint
     163                1:     = StoredDiag->Info.getCodeModificationHint(FixIt);
     164                 : 
                        1: branch 0 taken
                        0: branch 1 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
     165                1:   if (Location && StoredDiag->Info.getLocation().isValid())
     166                 :     *Location = translateSourceLocation(
     167                 :                                     StoredDiag->Info.getLocation().getManager(),
     168                 :                                         *StoredDiag->LangOptsPtr,
     169                1:                                         Hint.InsertionLoc);
     170                1:   return CIndexer::createCXString(Hint.CodeToInsert);
     171                 : }
     172                 : 
     173                 : CXSourceRange clang_getDiagnosticFixItRemoval(CXDiagnostic Diag, 
     174                1:                                               unsigned FixIt) {
     175                1:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        1: branch 0 taken
                        0: branch 1 not taken
                        1: branch 3 taken
                        0: branch 4 not taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
                        1: branch 10 taken
     176                1:   if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() ||
     177                 :       StoredDiag->Info.getLocation().isInvalid())
     178                0:     return clang_getNullRange();
     179                 :   
     180                 :   const CodeModificationHint &Hint
     181                1:     = StoredDiag->Info.getCodeModificationHint(FixIt);
     182                 :   return translateSourceRange(StoredDiag->Info.getLocation().getManager(),
     183                 :                               *StoredDiag->LangOptsPtr,
     184                1:                               Hint.RemoveRange);
     185                 : }
     186                 : 
     187                 : CXString clang_getDiagnosticFixItReplacement(CXDiagnostic Diag, 
     188                 :                                              unsigned FixIt,
     189                1:                                              CXSourceRange *Range) {
                        1: branch 0 taken
                        0: branch 1 not taken
     190                1:   if (Range)
     191                1:     *Range = clang_getNullRange();
     192                 : 
     193                1:   CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
                        1: branch 0 taken
                        0: branch 1 not taken
                        1: branch 3 taken
                        0: branch 4 not taken
                        0: branch 7 not taken
                        1: branch 8 taken
                        0: branch 9 not taken
                        1: branch 10 taken
     194                1:   if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() ||
     195                 :       StoredDiag->Info.getLocation().isInvalid()) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     196                0:     if (Range)
     197                0:       *Range = clang_getNullRange();
     198                 :     
     199                0:     return CIndexer::createCXString("");
     200                 :   }
     201                 :   
     202                 :   const CodeModificationHint &Hint
     203                1:     = StoredDiag->Info.getCodeModificationHint(FixIt);
                        1: branch 0 taken
                        0: branch 1 not taken
     204                1:   if (Range)
     205                 :     *Range = translateSourceRange(StoredDiag->Info.getLocation().getManager(),
     206                 :                                   *StoredDiag->LangOptsPtr,
     207                1:                                   Hint.RemoveRange);
     208                1:   return CIndexer::createCXString(Hint.CodeToInsert);  
     209                 : }
     210                 :   
     211                 : } // end extern "C"
     212                 : 
     213                 : void clang::ReportSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath,
     214                 :                                         Diagnostic &Diags,
     215                 :                                         unsigned num_unsaved_files,
     216                 :                                         struct CXUnsavedFile *unsaved_files,
     217               52:                                         const LangOptions &LangOpts) {
     218                 :   using llvm::MemoryBuffer;
     219                 :   using llvm::StringRef;
     220               52:   MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str());
                        0: branch 0 not taken
                       52: branch 1 taken
     221               52:   if (!F)
     222                0:     return;
     223                 : 
     224                 :   // Enter the unsaved files into the file manager.
     225               52:   SourceManager SourceMgr;
     226               52:   FileManager FileMgr;
                        2: branch 0 taken
                       52: branch 1 taken
     227               54:   for (unsigned I = 0; I != num_unsaved_files; ++I) {
     228                 :     const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename,
     229                 :                                                    unsaved_files[I].Length,
     230                2:                                                    0);
                        0: branch 0 not taken
                        2: branch 1 taken
     231                2:     if (!File) {
     232                 :       Diags.Report(diag::err_fe_remap_missing_from_file)
     233                0:         << unsaved_files[I].Filename;
     234               19:       return;
     235                 :     }
     236                 : 
     237                 :     MemoryBuffer *Buffer
     238                 :       = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
     239                2:                            unsaved_files[I].Contents + unsaved_files[I].Length);
                        0: branch 0 not taken
                        2: branch 1 taken
     240                2:     if (!Buffer)
     241                 :       return;
     242                 : 
     243                2:     SourceMgr.overrideFileContents(File, Buffer);
     244                 :   }
     245                 : 
     246               52:   Diags.getClient()->BeginSourceFile(LangOpts, 0);
     247                 : 
     248                 :   // Parse the diagnostics, emitting them one by one until we've
     249                 :   // exhausted the data.
     250               52:   StringRef Buffer = F->getBuffer();
     251               52:   const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size();
                       54: branch 1 taken
                       19: branch 2 taken
                       73: branch 3 taken
                       33: branch 4 taken
     252              125:   while (Memory != MemoryEnd) {
     253                 :     DiagnosticBuilder DB = Diags.Deserialize(FileMgr, SourceMgr, 
     254               73:                                              Memory, MemoryEnd);
                       19: branch 1 taken
                       54: branch 2 taken
     255               73:     if (!DB.isActive())
     256                 :       return;
     257                 :   }
     258                 : 
                       33: branch 3 taken
                       19: branch 4 taken
                       33: branch 6 taken
                       19: branch 7 taken
     259               33:   Diags.getClient()->EndSourceFile();
     260                 : }

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