zcov: / tools/CIndex/CIndex.cpp


Files: 1 Branches Taken: 64.5% 468 / 726
Generated: 2010-02-10 01:31 Branches Executed: 92.6% 672 / 726
Line Coverage: 75.9% 710 / 935


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 main API hooks in the Clang-C Source Indexing
      11                 : // library.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #include "CIndexer.h"
      16                 : #include "CXCursor.h"
      17                 : #include "CXSourceLocation.h"
      18                 : #include "CIndexDiagnostic.h"
      19                 : 
      20                 : #include "clang/Basic/Version.h"
      21                 : 
      22                 : #include "clang/AST/DeclVisitor.h"
      23                 : #include "clang/AST/StmtVisitor.h"
      24                 : #include "clang/AST/TypeLocVisitor.h"
      25                 : #include "clang/Frontend/FrontendDiagnostic.h"
      26                 : #include "clang/Lex/Lexer.h"
      27                 : #include "clang/Lex/Preprocessor.h"
      28                 : #include "llvm/Support/MemoryBuffer.h"
      29                 : #include "llvm/System/Program.h"
      30                 : 
      31                 : // Needed to define L_TMPNAM on some systems.
      32                 : #include <cstdio>
      33                 : 
      34                 : using namespace clang;
      35                 : using namespace clang::cxcursor;
      36                 : using namespace idx;
      37                 : 
      38                 : //===----------------------------------------------------------------------===//
      39                 : // Crash Reporting.
      40                 : //===----------------------------------------------------------------------===//
      41                 : 
      42                 : #ifdef __APPLE__
      43                 : #ifndef NDEBUG
      44                 : #define USE_CRASHTRACER
      45                 : #include "clang/Analysis/Support/SaveAndRestore.h"
      46                 : // Integrate with crash reporter.
      47                 : extern "C" const char *__crashreporter_info__;
      48                 : #define NUM_CRASH_STRINGS 16
      49                 : static unsigned crashtracer_counter = 0;
      50                 : static unsigned crashtracer_counter_id[NUM_CRASH_STRINGS] = { 0 };
      51                 : static const char *crashtracer_strings[NUM_CRASH_STRINGS] = { 0 };
      52                 : static const char *agg_crashtracer_strings[NUM_CRASH_STRINGS] = { 0 };
      53                 : 
      54                 : static unsigned SetCrashTracerInfo(const char *str,
      55                 :                                    llvm::SmallString<1024> &AggStr) {
      56                 :   
      57                 :   unsigned slot = 0;
      58                 :   while (crashtracer_strings[slot]) {
      59                 :     if (++slot == NUM_CRASH_STRINGS)
      60                 :       slot = 0;
      61                 :   }
      62                 :   crashtracer_strings[slot] = str;
      63                 :   crashtracer_counter_id[slot] = ++crashtracer_counter;
      64                 : 
      65                 :   // We need to create an aggregate string because multiple threads
      66                 :   // may be in this method at one time.  The crash reporter string
      67                 :   // will attempt to overapproximate the set of in-flight invocations
      68                 :   // of this function.  Race conditions can still cause this goal
      69                 :   // to not be achieved.
      70                 :   {
      71                 :     llvm::raw_svector_ostream Out(AggStr);      
      72                 :     for (unsigned i = 0; i < NUM_CRASH_STRINGS; ++i)
      73                 :       if (crashtracer_strings[i]) Out << crashtracer_strings[i] << '\n';
      74                 :   }
      75                 :   __crashreporter_info__ = agg_crashtracer_strings[slot] =  AggStr.c_str();
      76                 :   return slot;
      77                 : }
      78                 : 
      79                 : static void ResetCrashTracerInfo(unsigned slot) {
      80                 :   unsigned max_slot = 0;
      81                 :   unsigned max_value = 0;
      82                 :   
      83                 :   crashtracer_strings[slot] = agg_crashtracer_strings[slot] = 0;
      84                 : 
      85                 :   for (unsigned i = 0 ; i < NUM_CRASH_STRINGS; ++i)
      86                 :     if (agg_crashtracer_strings[i] &&
      87                 :         crashtracer_counter_id[i] > max_value) {
      88                 :       max_slot = i;
      89                 :       max_value = crashtracer_counter_id[i];
      90                 :     }
      91                 : 
      92                 :   __crashreporter_info__ = agg_crashtracer_strings[max_slot];
      93                 : }
      94                 : 
      95                 : namespace {
      96                 : class ArgsCrashTracerInfo {
      97                 :   llvm::SmallString<1024> CrashString;
      98                 :   llvm::SmallString<1024> AggregateString;
      99                 :   unsigned crashtracerSlot;
     100                 : public:
     101                 :   ArgsCrashTracerInfo(llvm::SmallVectorImpl<const char*> &Args)
     102                 :     : crashtracerSlot(0)
     103                 :   {
     104                 :     {
     105                 :       llvm::raw_svector_ostream Out(CrashString);
     106                 :       Out << "ClangCIndex [createTranslationUnitFromSourceFile]: clang";
     107                 :       for (llvm::SmallVectorImpl<const char*>::iterator I=Args.begin(),
     108                 :            E=Args.end(); I!=E; ++I)
     109                 :         Out << ' ' << *I;
     110                 :     }
     111                 :     crashtracerSlot = SetCrashTracerInfo(CrashString.c_str(),
     112                 :                                          AggregateString);
     113                 :   }
     114                 :   
     115                 :   ~ArgsCrashTracerInfo() {
     116                 :     ResetCrashTracerInfo(crashtracerSlot);
     117                 :   }
     118                 : };
     119                 : }
     120                 : #endif
     121                 : #endif
     122                 : 
     123                 : /// \brief The result of comparing two source ranges.
     124                 : enum RangeComparisonResult {
     125                 :   /// \brief Either the ranges overlap or one of the ranges is invalid.
     126                 :   RangeOverlap,
     127                 :   
     128                 :   /// \brief The first range ends before the second range starts.
     129                 :   RangeBefore,
     130                 :   
     131                 :   /// \brief The first range starts after the second range ends.
     132                 :   RangeAfter
     133                 : };
     134                 : 
     135                 : /// \brief Compare two source ranges to determine their relative position in 
     136                 : /// the translation unit.
     137                 : static RangeComparisonResult RangeCompare(SourceManager &SM, 
     138                 :                                           SourceRange R1, 
     139           122878:                                           SourceRange R2) {
                   122878: branch 1 taken
                        0: branch 2 not taken
     140           122878:   assert(R1.isValid() && "First range is invalid?");
                   122878: branch 1 taken
                        0: branch 2 not taken
     141           122878:   assert(R2.isValid() && "Second range is invalid?");
                   118870: branch 3 taken
                     4008: branch 4 taken
     142           122878:   if (SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
     143           118870:     return RangeBefore;
                     2517: branch 3 taken
                     1491: branch 4 taken
     144             4008:   if (SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
     145             2517:     return RangeAfter;
     146             1491:   return RangeOverlap;
     147                 : }
     148                 : 
     149                 : 
     150                 : //===----------------------------------------------------------------------===//
     151                 : // Cursor visitor.
     152                 : //===----------------------------------------------------------------------===//
     153                 : 
     154                 : namespace {
     155                 :   
     156                 : // Cursor visitor.
     157                 : class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
     158                 :                       public TypeLocVisitor<CursorVisitor, bool>,
     159                 :                       public StmtVisitor<CursorVisitor, bool>
     160                 : {
     161                 :   /// \brief The translation unit we are traversing.
     162                 :   ASTUnit *TU;
     163                 :   
     164                 :   /// \brief The parent cursor whose children we are traversing.
     165                 :   CXCursor Parent;
     166                 :   
     167                 :   /// \brief The declaration that serves at the parent of any statement or
     168                 :   /// expression nodes.
     169                 :   Decl *StmtParent;
     170                 :   
     171                 :   /// \brief The visitor function.
     172                 :   CXCursorVisitor Visitor;
     173                 :   
     174                 :   /// \brief The opaque client data, to be passed along to the visitor.
     175                 :   CXClientData ClientData;
     176                 :   
     177                 :   // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
     178                 :   // to the visitor. Declarations with a PCH level greater than this value will
     179                 :   // be suppressed.
     180                 :   unsigned MaxPCHLevel;
     181                 : 
     182                 :   /// \brief When valid, a source range to which the cursor should restrict
     183                 :   /// its search.
     184                 :   SourceRange RegionOfInterest;
     185                 :     
     186                 :   using DeclVisitor<CursorVisitor, bool>::Visit;
     187                 :   using TypeLocVisitor<CursorVisitor, bool>::Visit;
     188                 :   using StmtVisitor<CursorVisitor, bool>::Visit;
     189                 :     
     190                 :   /// \brief Determine whether this particular source range comes before, comes 
     191                 :   /// after, or overlaps the region of interest. 
     192                 :   ///
     193                 :   /// \param R a source range retrieved from the abstract syntax tree.
     194                 :   RangeComparisonResult CompareRegionOfInterest(SourceRange R); 
     195                 :   
     196                 :   /// \brief Determine whether this particular source range comes before, comes 
     197                 :   /// after, or overlaps the region of interest. 
     198                 :   ///
     199                 :   /// \param CXR a source range retrieved from a cursor.
     200                 :   RangeComparisonResult CompareRegionOfInterest(CXSourceRange CXR); 
     201                 :   
     202                 : public:
     203                 :   CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, 
     204                 :                 unsigned MaxPCHLevel, 
     205            12836:                 SourceRange RegionOfInterest = SourceRange())
     206                 :     : TU(TU), Visitor(Visitor), ClientData(ClientData), 
     207            12836:       MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest)
     208                 :   {
     209            12836:     Parent.kind = CXCursor_NoDeclFound;
     210            12836:     Parent.data[0] = 0;
     211            12836:     Parent.data[1] = 0;
     212            12836:     Parent.data[2] = 0;
     213            12836:     StmtParent = 0;
     214            12836:   }
     215                 :   
     216                 :   bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
     217                 :   bool VisitChildren(CXCursor Parent);
     218                 :   
     219                 :   // Declaration visitors
     220                 :   bool VisitDeclContext(DeclContext *DC);
     221                 :   bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
     222                 :   bool VisitTypedefDecl(TypedefDecl *D);
     223                 :   bool VisitTagDecl(TagDecl *D);
     224                 :   bool VisitEnumConstantDecl(EnumConstantDecl *D);
     225                 :   bool VisitDeclaratorDecl(DeclaratorDecl *DD);
     226                 :   bool VisitFunctionDecl(FunctionDecl *ND);
     227                 :   bool VisitFieldDecl(FieldDecl *D);
     228                 :   bool VisitVarDecl(VarDecl *);
     229                 :   bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
     230                 :   bool VisitObjCContainerDecl(ObjCContainerDecl *D);
     231                 :   bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
     232                 :   bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
     233                 :   bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
     234                 :   bool VisitObjCImplDecl(ObjCImplDecl *D);
     235                 :   bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
     236                 :   bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
     237                 :   // FIXME: ObjCPropertyDecl requires TypeSourceInfo, getter/setter locations,
     238                 :   // etc.
     239                 :   // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
     240                 :   bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
     241                 :   bool VisitObjCClassDecl(ObjCClassDecl *D);
     242                 : 
     243                 :   // Type visitors
     244                 :   // FIXME: QualifiedTypeLoc doesn't provide any location information
     245                 :   bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
     246                 :   bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
     247                 :   bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
     248                 :   bool VisitTagTypeLoc(TagTypeLoc TL);
     249                 :   // FIXME: TemplateTypeParmTypeLoc doesn't provide any location information
     250                 :   bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
     251                 :   bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
     252                 :   bool VisitPointerTypeLoc(PointerTypeLoc TL);
     253                 :   bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
     254                 :   bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
     255                 :   bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
     256                 :   bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
     257                 :   bool VisitFunctionTypeLoc(FunctionTypeLoc TL);
     258                 :   bool VisitArrayTypeLoc(ArrayTypeLoc TL);
     259                 :   // FIXME: Implement for TemplateSpecializationTypeLoc
     260                 :   // FIXME: Implement visitors here when the unimplemented TypeLocs get
     261                 :   // implemented
     262                 :   bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
     263                 :   bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
     264                 :   
     265                 :   // Statement visitors
     266                 :   bool VisitStmt(Stmt *S);
     267                 :   bool VisitDeclStmt(DeclStmt *S);
     268                 :   // FIXME: LabelStmt label?
     269                 :   bool VisitIfStmt(IfStmt *S);
     270                 :   bool VisitSwitchStmt(SwitchStmt *S);
     271                 :   bool VisitWhileStmt(WhileStmt *S);
     272                 :   bool VisitForStmt(ForStmt *S);
     273                 :   
     274                 :   // Expression visitors
     275                 :   bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
     276                 :   bool VisitExplicitCastExpr(ExplicitCastExpr *E);
     277                 :   bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
     278                 : };
     279                 :   
     280                 : } // end anonymous namespace
     281                 : 
     282           122878: RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
                   122878: branch 1 taken
                        0: branch 2 not taken
     283           122878:   assert(RegionOfInterest.isValid() && "RangeCompare called with invalid range");
                        0: branch 1 not taken
                   122878: branch 2 taken
     284           122878:   if (R.isInvalid())
     285                0:     return RangeOverlap;
     286                 : 
     287                 :   // Move the end of the input range to the end of the last token in that
     288                 :   // range.
     289                 :   SourceLocation NewEnd
     290           122878:     = TU->getPreprocessor().getLocForEndOfToken(R.getEnd(), 1);
                   122878: branch 1 taken
                        0: branch 2 not taken
     291           122878:   if (NewEnd.isValid())
     292           122878:     R.setEnd(NewEnd);
     293           122878:   return RangeCompare(TU->getSourceManager(), R, RegionOfInterest);
     294                 : }
     295                 : 
     296             3191: RangeComparisonResult CursorVisitor::CompareRegionOfInterest(CXSourceRange CXR) {
     297             3191:   return CompareRegionOfInterest(cxloc::translateSourceRange(CXR));
     298                 : }
     299                 : 
     300                 : /// \brief Visit the given cursor and, if requested by the visitor,
     301                 : /// its children.
     302                 : ///
     303                 : /// \param Cursor the cursor to visit.
     304                 : ///
     305                 : /// \param CheckRegionOfInterest if true, then the caller already checked that
     306                 : /// this cursor is within the region of interest.
     307                 : ///
     308                 : /// \returns true if the visitation should be aborted, false if it
     309                 : /// should continue.
     310             4246: bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
                        0: branch 1 not taken
                     4246: branch 2 taken
     311             4246:   if (clang_isInvalid(Cursor.kind))
     312                0:     return false;
     313                 :   
                     1572: branch 1 taken
                     2674: branch 2 taken
     314             4246:   if (clang_isDeclaration(Cursor.kind)) {
     315             1572:     Decl *D = getCursorDecl(Cursor);
                        0: branch 0 not taken
                     1572: branch 1 taken
     316             1572:     assert(D && "Invalid declaration cursor");
                        3: branch 1 taken
                     1569: branch 2 taken
     317             1572:     if (D->getPCHLevel() > MaxPCHLevel)
     318                3:       return false;
     319                 : 
                        5: branch 1 taken
                     1564: branch 2 taken
     320             1569:     if (D->isImplicit())
     321                5:       return false;
     322                 :   }
     323                 : 
     324                 :   // If we have a range of interest, and this cursor doesn't intersect with it,
     325                 :   // we're done.
                     4001: branch 1 taken
                      237: branch 2 taken
                     3191: branch 3 taken
                      810: branch 4 taken
                     3191: branch 5 taken
                     1047: branch 6 taken
     326             4238:   if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
     327             3191:     CXSourceRange Range = clang_getCursorExtent(Cursor);
                     3191: branch 2 taken
                        0: branch 3 not taken
                     2510: branch 5 taken
                      681: branch 6 taken
                     2510: branch 7 taken
                      681: branch 8 taken
     328             3191:     if (cxloc::translateSourceRange(Range).isInvalid() || 
     329                 :         CompareRegionOfInterest(Range))
     330             2510:       return false;
     331                 :   }
     332                 :   
                        0: branch 1 not taken
                        0: branch 2 not taken
                     1728: branch 3 taken
                        0: branch 4 not taken
     333             1728:   switch (Visitor(Cursor, Parent, ClientData)) {
     334                 :   case CXChildVisit_Break:
     335                0:     return true;
     336                 : 
     337                 :   case CXChildVisit_Continue:
     338                0:     return false;
     339                 : 
     340                 :   case CXChildVisit_Recurse:
     341             1728:     return VisitChildren(Cursor);
     342                 :   }
     343                 : 
     344                0:   return false;
     345                 : }
     346                 : 
     347                 : /// \brief Visit the children of the given cursor.
     348                 : ///
     349                 : /// \returns true if the visitation should be aborted, false if it
     350                 : /// should continue.
     351            14564: bool CursorVisitor::VisitChildren(CXCursor Cursor) { 
                       88: branch 1 taken
                    14476: branch 2 taken
     352            14564:   if (clang_isReference(Cursor.kind)) {
     353                 :     // By definition, references have no children.
     354               88:     return false;
     355                 :   }
     356                 :   
     357                 :   // Set the Parent field to Cursor, then back to its old value once we're 
     358                 :   // done.
     359                 :   class SetParentRAII {
     360                 :     CXCursor &Parent;
     361                 :     Decl *&StmtParent;
     362                 :     CXCursor OldParent;
     363                 : 
     364                 :   public:
     365            14476:     SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
     366            14476:       : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 
     367                 :     {
     368            14476:       Parent = NewParent;
                     1037: branch 1 taken
                    13439: branch 2 taken
     369            14476:       if (clang_isDeclaration(Parent.kind))
     370             1037:         StmtParent = getCursorDecl(Parent);
     371            14476:     }
     372                 :     
     373            14476:     ~SetParentRAII() {
     374            14476:       Parent = OldParent;
                      498: branch 1 taken
                    13978: branch 2 taken
     375            14476:       if (clang_isDeclaration(Parent.kind))
     376              498:         StmtParent = getCursorDecl(Parent);
     377            14476:     }
     378            14476:   } SetParent(Parent, StmtParent, Cursor);
     379                 :   
                     1037: branch 1 taken
                    13439: branch 2 taken
     380            14476:   if (clang_isDeclaration(Cursor.kind)) {
     381             1037:     Decl *D = getCursorDecl(Cursor);
                        0: branch 0 not taken
                     1037: branch 1 taken
     382             1037:     assert(D && "Invalid declaration cursor");
     383             1037:     return Visit(D);
     384                 :   }
     385                 :   
                      330: branch 1 taken
                    13109: branch 2 taken
     386            13439:   if (clang_isStatement(Cursor.kind))
     387              330:     return Visit(getCursorStmt(Cursor));
                      273: branch 1 taken
                    12836: branch 2 taken
     388            13109:   if (clang_isExpression(Cursor.kind))
     389              273:     return Visit(getCursorExpr(Cursor));
     390                 :   
                    12836: branch 1 taken
                        0: branch 2 not taken
     391            12836:   if (clang_isTranslationUnit(Cursor.kind)) {
     392            12836:     ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
                        9: branch 1 taken
                    12827: branch 2 taken
                        1: branch 4 taken
                        8: branch 5 taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
                    12835: branch 10 taken
     393            12836:     if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
     394                 :         RegionOfInterest.isInvalid()) {
     395                1:       const std::vector<Decl*> &TLDs = CXXUnit->getTopLevelDecls();
                        2: branch 3 taken
                        1: branch 4 taken
     396                4:       for (std::vector<Decl*>::const_iterator it = TLDs.begin(),
     397                1:            ie = TLDs.end(); it != ie; ++it) {
                        0: branch 3 not taken
                        2: branch 4 taken
     398                2:         if (Visit(MakeCXCursor(*it, CXXUnit), true))
     399                0:           return true;
     400                 :       }
     401                 :     } else {
     402                 :       return VisitDeclContext(
                    12835: branch 2 taken
                        0: branch 3 not taken
     403            12835:                             CXXUnit->getASTContext().getTranslationUnitDecl());
     404                 :     }
     405                 :     
     406                1:     return false;
     407                 :   }
     408                 :   
     409                 :   // Nothing to visit at the moment.
     410                0:   return false;
     411                 : }
     412                 : 
     413            13197: bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
                   183881: branch 2 taken
                    11543: branch 3 taken
     414           195424:   for (DeclContext::decl_iterator
     415            13197:        I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
                   183792: branch 1 taken
                       89: branch 2 taken
     416           183881:     if (RegionOfInterest.isValid()) {
     417           183792:       SourceRange R = (*I)->getSourceRange();
                   119687: branch 1 taken
                    64105: branch 2 taken
     418           183792:       if (R.isInvalid())
     419            64105:         continue;
     420                 :       
                   117223: branch 1 taken
                     1654: branch 2 taken
                      810: branch 3 taken
     421           119687:       switch (CompareRegionOfInterest(R)) {
     422                 :       case RangeBefore:
     423                 :         // This declaration comes before the region of interest; skip it.
     424           117223:         continue;
     425                 :       
     426                 :       case RangeAfter:
     427                 :         // This declaration comes after the region of interest; we're done.
     428             1654:         return false;
     429                 :       
     430                 :       case RangeOverlap:
     431                 :         // This declaration overlaps the region of interest; visit it.
     432                 :         break;
     433                 :       }      
     434                 :     }
     435                 :     
                        0: branch 3 not taken
                      899: branch 4 taken
     436              899:     if (Visit(MakeCXCursor(*I, TU), true))
     437                0:       return true;
     438                 :   }
     439                 :   
     440            11543:   return false;
     441                 : }
     442                 : 
     443                0: bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
     444                0:   llvm_unreachable("Translation units are visited directly by Visit()");
     445                 :   return false;
     446                 : }
     447                 : 
     448               28: bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
                       28: branch 1 taken
                        0: branch 2 not taken
     449               28:   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
     450               28:     return Visit(TSInfo->getTypeLoc());
     451                 :   
     452                0:   return false;
     453                 : }
     454                 : 
     455               26: bool CursorVisitor::VisitTagDecl(TagDecl *D) {
                       26: branch 0 taken
                        0: branch 1 not taken
     456               26:   return VisitDeclContext(D);
     457                 : }
     458                 : 
     459                9: bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
                        0: branch 1 not taken
                        9: branch 2 taken
     460                9:   if (Expr *Init = D->getInitExpr())
     461                0:     return Visit(MakeCXCursor(Init, StmtParent, TU));
     462                9:   return false;
     463                 : }
     464                 : 
     465              493: bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
                      493: branch 1 taken
                        0: branch 2 not taken
     466              493:   if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
                        0: branch 2 not taken
                      493: branch 3 taken
     467              493:     if (Visit(TSInfo->getTypeLoc()))
     468                0:       return true;
     469                 : 
     470              493:   return false;
     471                 : }
     472                 : 
     473              323: bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
                        0: branch 1 not taken
                      323: branch 2 taken
     474              323:   if (VisitDeclaratorDecl(ND))
     475                0:     return true;
     476                 : 
                      318: branch 1 taken
                        5: branch 2 taken
                        0: branch 6 not taken
                      318: branch 7 taken
                        0: branch 8 not taken
                      323: branch 9 taken
     477              323:   if (ND->isThisDeclarationADefinition() &&
     478                 :       Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
     479                0:     return true;
     480                 :   
     481              323:   return false;
     482                 : }
     483                 : 
     484               24: bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
                        0: branch 1 not taken
                       24: branch 2 taken
     485               24:   if (VisitDeclaratorDecl(D))
     486                0:     return true;
     487                 :   
                        0: branch 1 not taken
                       24: branch 2 taken
     488               24:   if (Expr *BitWidth = D->getBitWidth())
     489                0:     return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
     490                 :   
     491               24:   return false;
     492                 : }
     493                 : 
     494              146: bool CursorVisitor::VisitVarDecl(VarDecl *D) {
                        0: branch 1 not taken
                      146: branch 2 taken
     495              146:   if (VisitDeclaratorDecl(D))
     496                0:     return true;
     497                 :   
                       54: branch 1 taken
                       92: branch 2 taken
     498              146:   if (Expr *Init = D->getInit())
     499               54:     return Visit(MakeCXCursor(Init, StmtParent, TU));
     500                 :   
     501               92:   return false;
     502                 : }
     503                 : 
     504              123: bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
     505                 :   // FIXME: We really need a TypeLoc covering Objective-C method declarations.
     506                 :   // At the moment, we don't have information about locations in the return 
     507                 :   // type.
                       41: branch 1 taken
                      123: branch 2 taken
     508              287:   for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 
     509              123:        PEnd = ND->param_end();
     510                 :        P != PEnd; ++P) {
                        0: branch 2 not taken
                       41: branch 3 taken
     511               41:     if (Visit(MakeCXCursor(*P, TU)))
     512                0:       return true;
     513                 :   }
     514                 :   
                        0: branch 1 not taken
                      123: branch 2 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                      123: branch 9 taken
     515              123:   if (ND->isThisDeclarationADefinition() &&
     516                 :       Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
     517                0:     return true;
     518                 :   
     519              123:   return false;
     520                 : }
     521                 : 
     522              336: bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
                      336: branch 0 taken
                        0: branch 1 not taken
     523              336:   return VisitDeclContext(D);
     524                 : }
     525                 : 
     526               93: bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
                        0: branch 4 not taken
                       93: branch 5 taken
     527               93:   if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
     528                 :                                    TU)))
     529                0:     return true;
     530                 :   
     531               93:   ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
                        0: branch 1 not taken
                       93: branch 2 taken
     532              186:   for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
     533               93:          E = ND->protocol_end(); I != E; ++I, ++PL)
                        0: branch 2 not taken
                        0: branch 3 not taken
     534                0:     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
     535                0:       return true;
     536                 :   
     537               93:   return VisitObjCContainerDecl(ND);
     538                 : }
     539                 : 
     540               72: bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
     541               72:   ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
                       40: branch 1 taken
                       72: branch 2 taken
     542              184:   for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
     543               72:        E = PID->protocol_end(); I != E; ++I, ++PL)
                        0: branch 2 not taken
                       40: branch 3 taken
     544               40:     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
     545                0:       return true;
     546                 :   
     547               72:   return VisitObjCContainerDecl(PID);
     548                 : }
     549                 : 
     550              171: bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
     551                 :   // Issue callbacks for super class.
                      109: branch 1 taken
                       62: branch 2 taken
                        0: branch 7 not taken
                      109: branch 8 taken
                        0: branch 9 not taken
                      171: branch 10 taken
     552              171:   if (D->getSuperClass() &&
     553                 :       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
     554                 :                                         D->getSuperClassLoc(), 
     555                 :                                         TU)))
     556                0:     return true;
     557                 :   
     558              171:   ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
                       77: branch 1 taken
                      171: branch 2 taken
     559              419:   for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
     560              171:          E = D->protocol_end(); I != E; ++I, ++PL)
                        0: branch 2 not taken
                       77: branch 3 taken
     561               77:     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
     562                0:       return true;
     563                 :   
     564              171:   return VisitObjCContainerDecl(D);
     565                 : }
     566                 : 
     567                0: bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
     568                0:   return VisitObjCContainerDecl(D);
     569                 : }
     570                 : 
     571                0: bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
                        0: branch 5 not taken
                        0: branch 6 not taken
     572                0:   if (Visit(MakeCursorObjCClassRef(D->getCategoryDecl()->getClassInterface(), 
     573                 :                                    D->getLocation(), TU)))
     574                0:     return true;
     575                 :   
     576                0:   return VisitObjCImplDecl(D);
     577                 : }
     578                 : 
     579                0: bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
     580                 : #if 0
     581                 :   // Issue callbacks for super class.
     582                 :   // FIXME: No source location information!
     583                 :   if (D->getSuperClass() &&
     584                 :       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
     585                 :                                         D->getSuperClassLoc(), 
     586                 :                                         TU)))
     587                 :     return true;
     588                 : #endif
     589                 :   
     590                0:   return VisitObjCImplDecl(D);
     591                 : }
     592                 : 
     593                0: bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
     594                0:   ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
                        0: branch 1 not taken
                        0: branch 2 not taken
     595                0:   for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
     596                0:                                                   E = D->protocol_end();
     597                 :        I != E; ++I, ++PL)
                        0: branch 2 not taken
                        0: branch 3 not taken
     598                0:     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
     599                0:       return true;
     600                 :   
     601                0:   return false; 
     602                 : }
     603                 : 
     604               22: bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
                       22: branch 2 taken
                       22: branch 3 taken
     605               44:   for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
                        0: branch 4 not taken
                       22: branch 5 taken
     606               22:     if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
     607                0:       return true;
     608                 :        
     609               22:   return false;
     610                 : }
     611                 : 
     612              441: bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
     613              441:   ASTContext &Context = TU->getASTContext();
     614                 : 
     615                 :   // Some builtin types (such as Objective-C's "id", "sel", and
     616                 :   // "Class") have associated declarations. Create cursors for those.
     617              441:   QualType VisitType;
                      400: branch 4 taken
                        0: branch 5 not taken
                       38: branch 6 taken
                        0: branch 7 not taken
                        3: branch 8 taken
                        0: branch 9 not taken
     618              441:   switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
     619                 :   case BuiltinType::Void:
     620                 :   case BuiltinType::Bool:
     621                 :   case BuiltinType::Char_U:
     622                 :   case BuiltinType::UChar:
     623                 :   case BuiltinType::Char16:
     624                 :   case BuiltinType::Char32:
     625                 :   case BuiltinType::UShort:
     626                 :   case BuiltinType::UInt:
     627                 :   case BuiltinType::ULong:
     628                 :   case BuiltinType::ULongLong:
     629                 :   case BuiltinType::UInt128:
     630                 :   case BuiltinType::Char_S:
     631                 :   case BuiltinType::SChar:
     632                 :   case BuiltinType::WChar:
     633                 :   case BuiltinType::Short:
     634                 :   case BuiltinType::Int:
     635                 :   case BuiltinType::Long:
     636                 :   case BuiltinType::LongLong:
     637                 :   case BuiltinType::Int128:
     638                 :   case BuiltinType::Float: 
     639                 :   case BuiltinType::Double: 
     640                 :   case BuiltinType::LongDouble:
     641                 :   case BuiltinType::NullPtr:
     642                 :   case BuiltinType::Overload:
     643                 :   case BuiltinType::Dependent:
     644              400:     break;
     645                 : 
     646                 :   case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor?
     647                0:     break;
     648                 : 
     649                 :   case BuiltinType::ObjCId:
     650               38:     VisitType = Context.getObjCIdType();
     651               38:     break;
     652                 : 
     653                 :   case BuiltinType::ObjCClass:
     654                0:     VisitType = Context.getObjCClassType();
     655                0:     break;
     656                 : 
     657                 :   case BuiltinType::ObjCSel:
     658                3:     VisitType = Context.getObjCSelType();
     659                 :     break;
     660                 :   }
     661                 : 
                       41: branch 1 taken
                      400: branch 2 taken
     662              441:   if (!VisitType.isNull()) {
                       41: branch 2 taken
                        0: branch 3 not taken
     663               41:     if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
     664                 :       return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 
     665               41:                                      TU));
     666                 :   }
     667                 : 
     668              400:   return false;
     669                 : }
     670                 : 
     671               32: bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
     672               32:   return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
     673                 : }
     674                 : 
     675                0: bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
     676                0:   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
     677                 : }
     678                 : 
     679                7: bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
     680                7:   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
     681                 : }
     682                 : 
     683               30: bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
                        0: branch 4 not taken
                       30: branch 5 taken
     684               30:   if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
     685                0:     return true;
     686                 : 
                        0: branch 1 not taken
                       30: branch 2 taken
     687               30:   for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
                        0: branch 4 not taken
                        0: branch 5 not taken
     688                0:     if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
     689                 :                                         TU)))
     690                0:       return true;
     691                 :   }
     692                 : 
     693               30:   return false;
     694                 : }
     695                 : 
     696               74: bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
                       68: branch 1 taken
                        6: branch 2 taken
                        0: branch 5 not taken
                       68: branch 6 taken
                        0: branch 7 not taken
                       74: branch 8 taken
     697               74:   if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseTypeLoc()))
     698                0:     return true;
     699                 : 
                       38: branch 1 taken
                       36: branch 2 taken
     700               74:   if (TL.hasProtocolsAsWritten()) {
                       38: branch 1 taken
                       38: branch 2 taken
     701               76:     for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
                        0: branch 4 not taken
                       38: branch 5 taken
     702               38:       if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), 
     703                 :                                           TL.getProtocolLoc(I),
     704                 :                                           TU)))
     705                0:         return true;
     706                 :     }
     707                 :   }
     708                 :   
     709               74:   return false;
     710                 : }
     711                 : 
     712               74: bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
     713               74:   return Visit(TL.getPointeeLoc());
     714                 : }
     715                 : 
     716                0: bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
     717                0:   return Visit(TL.getPointeeLoc());
     718                 : }
     719                 : 
     720                0: bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
     721                0:   return Visit(TL.getPointeeLoc());
     722                 : }
     723                 : 
     724                0: bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
     725                0:   return Visit(TL.getPointeeLoc());  
     726                 : }
     727                 : 
     728                0: bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
     729                0:   return Visit(TL.getPointeeLoc());  
     730                 : }
     731                 : 
     732              323: bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
                        0: branch 2 not taken
                      323: branch 3 taken
     733              323:   if (Visit(TL.getResultLoc()))
     734                0:     return true;
     735                 : 
                      549: branch 1 taken
                      323: branch 2 taken
     736              872:   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
                        0: branch 3 not taken
                      549: branch 4 taken
     737              549:     if (Visit(MakeCXCursor(TL.getArg(I), TU)))
     738                0:       return true;
     739                 : 
     740              323:   return false;
     741                 : }
     742                 : 
     743               15: bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
                        0: branch 2 not taken
                       15: branch 3 taken
     744               15:   if (Visit(TL.getElementLoc()))
     745                0:     return true;
     746                 : 
                        3: branch 1 taken
                       12: branch 2 taken
     747               15:   if (Expr *Size = TL.getSizeExpr())
     748                3:     return Visit(MakeCXCursor(Size, StmtParent, TU));
     749                 : 
     750               12:   return false;
     751                 : }
     752                 : 
     753                0: bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
     754                0:   return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
     755                 : }
     756                 : 
     757                0: bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
                        0: branch 1 not taken
                        0: branch 2 not taken
     758                0:   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
     759                0:     return Visit(TSInfo->getTypeLoc());
     760                 : 
     761                0:   return false;
     762                 : }
     763                 : 
     764              520: bool CursorVisitor::VisitStmt(Stmt *S) {
                     1803: branch 4 taken
                      520: branch 5 taken
     765             2323:   for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
     766                 :        Child != ChildEnd; ++Child) {
                     1800: branch 1 taken
                        3: branch 2 taken
                        0: branch 6 not taken
                     1800: branch 7 taken
                        0: branch 8 not taken
                     1803: branch 9 taken
     767             1803:     if (*Child && Visit(MakeCXCursor(*Child, StmtParent, TU)))
     768                0:       return true;
     769                 :   }
     770                 :   
     771              520:   return false;
     772                 : }
     773                 : 
     774               77: bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
                       77: branch 2 taken
                       77: branch 3 taken
     775              154:   for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
     776                 :        D != DEnd; ++D) {
                       77: branch 0 taken
                        0: branch 1 not taken
                        0: branch 4 not taken
                       77: branch 5 taken
                        0: branch 6 not taken
                       77: branch 7 taken
     777               77:     if (*D && Visit(MakeCXCursor(*D, TU)))
     778                0:       return true;
     779                 :   }
     780                 :   
     781               77:   return false;
     782                 : }
     783                 : 
     784                1: bool CursorVisitor::VisitIfStmt(IfStmt *S) {
                        1: branch 1 taken
                        0: branch 2 not taken
     785                1:   if (VarDecl *Var = S->getConditionVariable()) {
                        0: branch 2 not taken
                        1: branch 3 taken
     786                1:     if (Visit(MakeCXCursor(Var, TU)))
     787                0:       return true;
     788                 :   } 
     789                 :   
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     790                1:   if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
     791                0:     return true;
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     792                1:   if (S->getThen() && Visit(MakeCXCursor(S->getThen(), StmtParent, TU)))
     793                0:     return true;
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        1: branch 9 taken
     794                1:   if (S->getElse() && Visit(MakeCXCursor(S->getElse(), StmtParent, TU)))
     795                0:     return true;
     796                 : 
     797                1:   return false;
     798                 : }
     799                 : 
     800                1: bool CursorVisitor::VisitSwitchStmt(SwitchStmt *S) {
                        1: branch 1 taken
                        0: branch 2 not taken
     801                1:   if (VarDecl *Var = S->getConditionVariable()) {
                        0: branch 2 not taken
                        1: branch 3 taken
     802                1:     if (Visit(MakeCXCursor(Var, TU)))
     803                0:       return true;
     804                 :   } 
     805                 :   
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     806                1:   if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
     807                0:     return true;
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     808                1:   if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU)))
     809                0:     return true;
     810                 :   
     811                1:   return false;
     812                 : }
     813                 : 
     814                1: bool CursorVisitor::VisitWhileStmt(WhileStmt *S) {
                        1: branch 1 taken
                        0: branch 2 not taken
     815                1:   if (VarDecl *Var = S->getConditionVariable()) {
                        0: branch 2 not taken
                        1: branch 3 taken
     816                1:     if (Visit(MakeCXCursor(Var, TU)))
     817                0:       return true;
     818                 :   } 
     819                 :   
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     820                1:   if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
     821                0:     return true;
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     822                1:   if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU)))
     823                0:     return true;
     824                 : 
     825                1:   return false;
     826                 : }
     827                 : 
     828                1: bool CursorVisitor::VisitForStmt(ForStmt *S) {
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     829                1:   if (S->getInit() && Visit(MakeCXCursor(S->getInit(), StmtParent, TU)))
     830                0:     return true;
                        1: branch 1 taken
                        0: branch 2 not taken
     831                1:   if (VarDecl *Var = S->getConditionVariable()) {
                        0: branch 2 not taken
                        1: branch 3 taken
     832                1:     if (Visit(MakeCXCursor(Var, TU)))
     833                0:       return true;
     834                 :   } 
     835                 :   
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     836                1:   if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU)))
     837                0:     return true;
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     838                1:   if (S->getInc() && Visit(MakeCXCursor(S->getInc(), StmtParent, TU)))
     839                0:     return true;
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
     840                1:   if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU)))
     841                0:     return true;
     842                 :   
     843                1:   return false;
     844                 : }
     845                 : 
     846                2: bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
                        2: branch 1 taken
                        0: branch 2 not taken
     847                2:   if (E->isArgumentType()) {
                        2: branch 1 taken
                        0: branch 2 not taken
     848                2:     if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo())
     849                2:       return Visit(TSInfo->getTypeLoc());
     850                 :     
     851                0:     return false;
     852                 :   }
     853                 :   
     854                0:   return VisitExpr(E);
     855                 : }
     856                 : 
     857               23: bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
                       23: branch 1 taken
                        0: branch 2 not taken
     858               23:   if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten())
                        0: branch 2 not taken
                       23: branch 3 taken
     859               23:     if (Visit(TSInfo->getTypeLoc()))
     860                0:       return true;
     861                 :   
     862               23:   return VisitCastExpr(E);
     863                 : }
     864                 : 
     865                2: bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
                        2: branch 1 taken
                        0: branch 2 not taken
     866                2:   if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo())
                        0: branch 2 not taken
                        2: branch 3 taken
     867                2:     if (Visit(TSInfo->getTypeLoc()))
     868                0:       return true;
     869                 :   
     870                2:   return VisitExpr(E);
     871                 : }
     872                 : 
     873              378: CXString CIndexer::createCXString(const char *String, bool DupString){
     874                 :   CXString Str;
                       62: branch 0 taken
                      316: branch 1 taken
     875              378:   if (DupString) {
     876               62:     Str.Spelling = strdup(String);
     877               62:     Str.MustFreeString = 1;
     878                 :   } else {
     879              316:     Str.Spelling = String;
     880              316:     Str.MustFreeString = 0;
     881                 :   }
     882                 :   return Str;
     883                 : }
     884                 : 
     885               89: CXString CIndexer::createCXString(llvm::StringRef String, bool DupString) {
     886                 :   CXString Result;
                        2: branch 0 taken
                       87: branch 1 taken
                        2: branch 3 taken
                        0: branch 4 not taken
                        0: branch 7 not taken
                        2: branch 8 taken
                       87: branch 9 taken
                        2: branch 10 taken
     887               89:   if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
     888               87:     char *Spelling = (char *)malloc(String.size() + 1);
     889               87:     memmove(Spelling, String.data(), String.size());
     890               87:     Spelling[String.size()] = 0;
     891               87:     Result.Spelling = Spelling;
     892               87:     Result.MustFreeString = 1;
     893                 :   } else {
     894                2:     Result.Spelling = String.data();
     895                2:     Result.MustFreeString = 0;
     896                 :   }
     897                 :   return Result;
     898                 : }
     899                 : 
     900                 : extern "C" {
     901               69: CXIndex clang_createIndex(int excludeDeclarationsFromPCH) {
     902               69:   CIndexer *CIdxr = new CIndexer();
                        8: branch 0 taken
                       61: branch 1 taken
     903               69:   if (excludeDeclarationsFromPCH)
     904                8:     CIdxr->setOnlyLocalDecls();
     905               69:   return CIdxr;
     906                 : }
     907                 : 
     908               54: void clang_disposeIndex(CXIndex CIdx) {
                       54: branch 0 taken
                        0: branch 1 not taken
     909               54:   if (CIdx)
                       54: branch 0 taken
                        0: branch 1 not taken
     910               54:     delete static_cast<CIndexer *>(CIdx);
     911               54: }
     912                 : 
     913                1: void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) {
                        1: branch 0 taken
                        0: branch 1 not taken
     914                1:   if (CIdx) {
     915                1:     CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
     916                1:     CXXIdx->setUseExternalASTGeneration(value);
     917                 :   }
     918                1: }
     919                 : 
     920                 : CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
     921                 :                                               const char *ast_filename,
     922                 :                                              CXDiagnosticCallback diag_callback,
     923                8:                                               CXClientData diag_client_data) {
                        0: branch 0 not taken
                        8: branch 1 taken
     924                8:   if (!CIdx)
     925                0:     return 0;
     926                 :   
     927                8:   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
     928                 : 
     929                 :   // Configure the diagnostics.
     930                8:   DiagnosticOptions DiagOpts;
     931                8:   llvm::OwningPtr<Diagnostic> Diags;
     932                8:   Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0));
     933                8:   CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data);
     934                8:   Diags->setClient(&DiagClient);
     935                 :   
     936                 :   return ASTUnit::LoadFromPCHFile(ast_filename, *Diags,
     937                 :                                   CXXIdx->getOnlyLocalDecls(),
     938                8:                                   /* UseBumpAllocator = */ true);
     939                 : }
     940                 : 
     941                 : CXTranslationUnit
     942                 : clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
     943                 :                                           const char *source_filename,
     944                 :                                           int num_command_line_args,
     945                 :                                           const char **command_line_args,
     946                 :                                           unsigned num_unsaved_files,
     947                 :                                           struct CXUnsavedFile *unsaved_files,
     948                 :                                           CXDiagnosticCallback diag_callback,
     949               10:                                           CXClientData diag_client_data) {
                        0: branch 0 not taken
                       10: branch 1 taken
     950               10:   if (!CIdx)
     951                0:     return 0;
     952                 :   
     953               10:   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
     954                 : 
     955                 :   // Configure the diagnostics.
     956               10:   DiagnosticOptions DiagOpts;
     957               10:   llvm::OwningPtr<Diagnostic> Diags;
     958               10:   Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0));
     959               10:   CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data);
     960               10:   Diags->setClient(&DiagClient);
     961                 :                                
     962               10:   llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
                        4: branch 0 taken
                       10: branch 1 taken
     963               14:   for (unsigned I = 0; I != num_unsaved_files; ++I) {
     964                 :     const llvm::MemoryBuffer *Buffer 
     965                 :     = llvm::MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
     966                 :                                        unsaved_files[I].Contents + unsaved_files[I].Length,
     967                4:                                        unsaved_files[I].Filename);
     968                 :     RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
     969                4:                                            Buffer));
     970                 :   }
     971                 :     
                        9: branch 1 taken
                        1: branch 2 taken
     972               10:   if (!CXXIdx->getUseExternalASTGeneration()) {
     973                9:     llvm::SmallVector<const char *, 16> Args;
     974                 : 
     975                 :     // The 'source_filename' argument is optional.  If the caller does not
     976                 :     // specify it then it is assumed that the source file is specified
     977                 :     // in the actual argument list.
                        3: branch 0 taken
                        6: branch 1 taken
     978                9:     if (source_filename)
     979                3:       Args.push_back(source_filename);
     980                 :     Args.insert(Args.end(), command_line_args,
     981                9:                 command_line_args + num_command_line_args);
     982                 : 
     983                9:     unsigned NumErrors = Diags->getNumErrors();
     984                 :     
     985                 : #ifdef USE_CRASHTRACER
     986                 :     ArgsCrashTracerInfo ACTI(Args);
     987                 : #endif
     988                 :     
     989                 :     llvm::OwningPtr<ASTUnit> Unit(
     990                 :       ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
     991                 :                                    *Diags, 
     992                 :                                    CXXIdx->getClangResourcesPath(),
     993                 :                                    CXXIdx->getOnlyLocalDecls(),
     994                 :                                    /* UseBumpAllocator = */ true,
     995                 :                                    RemappedFiles.data(),
     996                9:                                    RemappedFiles.size()));
     997                 :     
     998                 :     // FIXME: Until we have broader testing, just drop the entire AST if we
     999                 :     // encountered an error.
                        1: branch 2 taken
                        8: branch 3 taken
    1000                9:     if (NumErrors != Diags->getNumErrors())
    1001                1:       return 0;
    1002                 : 
    1003                8:     return Unit.take();
    1004                 :   }
    1005                 : 
    1006                 :   // Build up the arguments for invoking 'clang'.
    1007                1:   std::vector<const char *> argv;
    1008                 : 
    1009                 :   // First add the complete path to the 'clang' executable.
    1010                1:   llvm::sys::Path ClangPath = static_cast<CIndexer *>(CIdx)->getClangPath();
    1011                1:   argv.push_back(ClangPath.c_str());
    1012                 : 
    1013                 :   // Add the '-emit-ast' option as our execution mode for 'clang'.
    1014                1:   argv.push_back("-emit-ast");
    1015                 : 
    1016                 :   // The 'source_filename' argument is optional.  If the caller does not
    1017                 :   // specify it then it is assumed that the source file is specified
    1018                 :   // in the actual argument list.
                        0: branch 0 not taken
                        1: branch 1 taken
    1019                1:   if (source_filename)
    1020                0:     argv.push_back(source_filename);
    1021                 : 
    1022                 :   // Generate a temporary name for the AST file.
    1023                1:   argv.push_back("-o");
    1024                 :   char astTmpFile[L_tmpnam];
    1025                1:   argv.push_back(tmpnam(astTmpFile));
    1026                 : 
    1027                 :   // Remap any unsaved files to temporary files.
    1028                1:   std::vector<llvm::sys::Path> TemporaryFiles;
    1029                1:   std::vector<std::string> RemapArgs;
                        0: branch 1 not taken
                        1: branch 2 taken
    1030                1:   if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
    1031                0:     return 0;
    1032                 :   
    1033                 :   // The pointers into the elements of RemapArgs are stable because we
    1034                 :   // won't be adding anything to RemapArgs after this point.
                        4: branch 1 taken
                        1: branch 2 taken
    1035                5:   for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
    1036                4:     argv.push_back(RemapArgs[i].c_str());
    1037                 :   
    1038                 :   // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
                        1: branch 0 taken
                        1: branch 1 taken
    1039                2:   for (int i = 0; i < num_command_line_args; ++i)
                        1: branch 0 taken
                        0: branch 1 not taken
    1040                1:     if (const char *arg = command_line_args[i]) {
                        0: branch 1 not taken
                        1: branch 2 taken
    1041                1:       if (strcmp(arg, "-o") == 0) {
    1042                0:         ++i; // Also skip the matching argument.
    1043                0:         continue;
    1044                 :       }
                        1: branch 1 taken
                        0: branch 2 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        0: branch 7 not taken
                        1: branch 8 taken
    1045                1:       if (strcmp(arg, "-emit-ast") == 0 ||
    1046                 :           strcmp(arg, "-c") == 0 ||
    1047                 :           strcmp(arg, "-fsyntax-only") == 0) {
    1048                0:         continue;
    1049                 :       }
    1050                 : 
    1051                 :       // Keep the argument.
    1052                1:       argv.push_back(arg);
    1053                 :     }
    1054                 : 
    1055                 :   // Generate a temporary name for the diagnostics file.
    1056                 :   char tmpFileResults[L_tmpnam];
    1057                1:   char *tmpResultsFileName = tmpnam(tmpFileResults);
    1058                1:   llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
    1059                1:   TemporaryFiles.push_back(DiagnosticsFile);
    1060                1:   argv.push_back("-fdiagnostics-binary");
    1061                 : 
    1062                 :   // Add the null terminator.
    1063                1:   argv.push_back(NULL);
    1064                 : 
    1065                 :   // Invoke 'clang'.
    1066                1:   llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
    1067                 :                            // on Unix or NUL (Windows).
    1068                1:   std::string ErrMsg;
    1069                 :   const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DiagnosticsFile,
    1070                1:                                          NULL };
    1071                 :   llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
    1072                 :       /* redirects */ &Redirects[0],
    1073                1:       /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg);
    1074                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
    1075                1:   if (!ErrMsg.empty()) {
    1076                0:     std::string AllArgs;
                        0: branch 4 not taken
                        0: branch 5 not taken
    1077                0:     for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
    1078                 :          I != E; ++I) {
    1079                0:       AllArgs += ' ';
                        0: branch 1 not taken
                        0: branch 2 not taken
    1080                0:       if (*I)
    1081                0:         AllArgs += *I;
    1082                 :     }
    1083                 :     
    1084                0:     Diags->Report(diag::err_fe_clang) << AllArgs << ErrMsg;
    1085                 :   }
    1086                 : 
    1087                 :   // FIXME: Parse the (redirected) standard error to emit diagnostics.
    1088                 : 
    1089                 :   ASTUnit *ATU = ASTUnit::LoadFromPCHFile(astTmpFile, *Diags,
    1090                 :                                           CXXIdx->getOnlyLocalDecls(),
    1091                 :                                           /* UseBumpAllocator = */ true,
    1092                 :                                           RemappedFiles.data(),
    1093                1:                                           RemappedFiles.size());
                        1: branch 0 taken
                        0: branch 1 not taken
    1094                1:   if (ATU)
    1095                1:     ATU->unlinkTemporaryFile();
    1096                 :   
    1097                 :   // FIXME: Currently we don't report diagnostics on invalid ASTs.
                        1: branch 0 taken
                        0: branch 1 not taken
    1098                1:   if (ATU)
    1099                 :     ReportSerializedDiagnostics(DiagnosticsFile, *Diags, 
    1100                 :                                 num_unsaved_files, unsaved_files,
    1101                1:                                 ATU->getASTContext().getLangOptions());
    1102                 : 
                        2: branch 1 taken
                        1: branch 2 taken
    1103                3:   for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i)
    1104                2:     TemporaryFiles[i].eraseFromDisk();
    1105                 :   
    1106                1:   return ATU;
    1107                 : }
    1108                 : 
    1109               14: void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
                       14: branch 0 taken
                        0: branch 1 not taken
    1110               14:   if (CTUnit)
                       14: branch 0 taken
                        0: branch 1 not taken
    1111               14:     delete static_cast<ASTUnit *>(CTUnit);
    1112               14: }
    1113                 : 
    1114                0: CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
                        0: branch 0 not taken
                        0: branch 1 not taken
    1115                0:   if (!CTUnit)
    1116                0:     return CIndexer::createCXString("");
    1117                 :   
    1118                0:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
    1119                 :   return CIndexer::createCXString(CXXUnit->getOriginalSourceFileName().c_str(),
    1120                0:                                   true);
    1121                 : }
    1122                 : 
    1123            12836: CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
    1124            12836:   CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
    1125                 :   return Result;
    1126                 : }
    1127                 : 
    1128                 : } // end: extern "C"
    1129                 : 
    1130                 : //===----------------------------------------------------------------------===//
    1131                 : // CXSourceLocation and CXSourceRange Operations.
    1132                 : //===----------------------------------------------------------------------===//
    1133                 : 
    1134                 : extern "C" {
    1135                3: CXSourceLocation clang_getNullLocation() {
    1136                3:   CXSourceLocation Result = { { 0, 0 }, 0 };
    1137                 :   return Result;
    1138                 : }
    1139                 : 
    1140                2: unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
    1141                 :   return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
    1142                 :           loc1.ptr_data[1] == loc2.ptr_data[1] &&
                        0: branch 0 not taken
                        2: branch 1 taken
                        2: branch 2 taken
                        2: branch 3 taken
                        2: branch 4 taken
                        2: branch 5 taken
    1143                2:           loc1.int_data == loc2.int_data);
    1144                 : }
    1145                 : 
    1146                 : CXSourceLocation clang_getLocation(CXTranslationUnit tu,
    1147                 :                                    CXFile file,
    1148                 :                                    unsigned line,
    1149            12827:                                    unsigned column) {
                        0: branch 0 not taken
                    12827: branch 1 taken
    1150            12827:   if (!tu)
    1151                0:     return clang_getNullLocation();
    1152                 :   
    1153            12827:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
    1154                 :   SourceLocation SLoc
    1155                 :     = CXXUnit->getSourceManager().getLocation(
    1156                 :                                         static_cast<const FileEntry *>(file), 
    1157            12827:                                               line, column);
    1158                 :   
    1159            12827:   return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc, false);
    1160                 : }
    1161                 : 
    1162                1: CXSourceRange clang_getNullRange() {
    1163                1:   CXSourceRange Result = { { 0, 0 }, 0, 0 };
    1164                 :   return Result;
    1165                 : }
    1166                 :   
    1167                1: CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
                        1: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        1: branch 3 taken
    1168                1:   if (begin.ptr_data[0] != end.ptr_data[0] ||
    1169                 :       begin.ptr_data[1] != end.ptr_data[1])
    1170                0:     return clang_getNullRange();
    1171                 :   
    1172                 :   CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, 
    1173                1:                            begin.int_data, end.int_data };
    1174                1:   return Result;
    1175                 : }
    1176                 : 
    1177                 : void clang_getInstantiationLocation(CXSourceLocation location,
    1178                 :                                     CXFile *file,
    1179                 :                                     unsigned *line,
    1180                 :                                     unsigned *column,
    1181             1430:                                     unsigned *offset) {
    1182                 :   cxloc::CXSourceLocationPtr Ptr
    1183             1430:     = cxloc::CXSourceLocationPtr::getFromOpaqueValue(location.ptr_data[0]);
    1184             1430:   SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
    1185                 : 
                     1430: branch 1 taken
                        0: branch 2 not taken
                       96: branch 4 taken
                     1334: branch 5 taken
                       96: branch 6 taken
                     1334: branch 7 taken
    1186             1430:   if (!Ptr.getPointer() || Loc.isInvalid()) {
                       54: branch 0 taken
                       42: branch 1 taken
    1187               96:     if (file)
    1188               54:       *file = 0;
                       78: branch 0 taken
                       18: branch 1 taken
    1189               96:     if (line)
    1190               78:       *line = 0;
                       78: branch 0 taken
                       18: branch 1 taken
    1191               96:     if (column)
    1192               78:       *column = 0;
                        0: branch 0 not taken
                       96: branch 1 taken
    1193               96:     if (offset)
    1194                0:       *offset = 0;
    1195               96:     return;
    1196                 :   }
    1197                 : 
    1198                 :   // FIXME: This is largely copy-paste from
    1199                 :   ///TextDiagnosticPrinter::HighlightRange.  When it is clear that this is
    1200                 :   // what we want the two routines should be refactored.  
    1201             1334:   const SourceManager &SM = *Ptr.getPointer();
    1202             1334:   SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
    1203                 :   
                      283: branch 1 taken
                     1051: branch 2 taken
    1204             1334:   if (Ptr.getInt()) {
    1205                 :     // We want the last character in this location, so we will adjust
    1206                 :     // the instantiation location accordingly.
    1207                 : 
    1208                 :     // If the location is from a macro instantiation, get the end of
    1209                 :     // the instantiation range.
                        0: branch 1 not taken
                      283: branch 2 taken
    1210              283:     if (Loc.isMacroID())
    1211                0:       InstLoc = SM.getInstantiationRange(Loc).second;
    1212                 : 
    1213                 :     // Measure the length token we're pointing at, so we can adjust
    1214                 :     // the physical location in the file to point at the last
    1215                 :     // character.
    1216                 :     // FIXME: This won't cope with trigraphs or escaped newlines
    1217                 :     // well. For that, we actually need a preprocessor, which isn't
    1218                 :     // currently available here. Eventually, we'll switch the pointer
    1219                 :     // data of CXSourceLocation/CXSourceRange to a translation unit
    1220                 :     // (CXXUnit), so that the preprocessor will be available here. At
    1221                 :     // that point, we can use Preprocessor::getLocForEndOfToken().
    1222                 :     unsigned Length = Lexer::MeasureTokenLength(InstLoc, SM, 
    1223              283:                              *static_cast<LangOptions *>(location.ptr_data[1]));
                      283: branch 0 taken
                        0: branch 1 not taken
    1224              283:     if (Length > 0)
    1225              283:       InstLoc = InstLoc.getFileLocWithOffset(Length - 1);
    1226                 :   }
    1227                 : 
                      742: branch 0 taken
                      592: branch 1 taken
    1228             1334:   if (file)
    1229              742:     *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
                     1115: branch 0 taken
                      219: branch 1 taken
    1230             1334:   if (line)
    1231             1115:     *line = SM.getInstantiationLineNumber(InstLoc);
                     1115: branch 0 taken
                      219: branch 1 taken
    1232             1334:   if (column)
    1233             1115:     *column = SM.getInstantiationColumnNumber(InstLoc);
                        0: branch 0 not taken
                     1334: branch 1 taken
    1234             1334:   if (offset)
    1235                0:     *offset = SM.getDecomposedLoc(InstLoc).second;
    1236                 : }
    1237                 : 
    1238              301: CXSourceLocation clang_getRangeStart(CXSourceRange range) {
    1239                 :   CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 
    1240              301:                               range.begin_int_data };
    1241                 :   return Result;
    1242                 : }
    1243                 : 
    1244              301: CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
    1245              301:   cxloc::CXSourceLocationPtr Ptr;
    1246              301:   Ptr.setPointer(static_cast<SourceManager *>(range.ptr_data[0]));
    1247              301:   Ptr.setInt(true);
    1248                 :   CXSourceLocation Result = { { Ptr.getOpaqueValue(), range.ptr_data[1] },
    1249              301:                               range.end_int_data };
    1250                 :   return Result;
    1251                 : }
    1252                 : 
    1253                 : } // end: extern "C"
    1254                 : 
    1255                 : //===----------------------------------------------------------------------===//
    1256                 : // CXFile Operations.
    1257                 : //===----------------------------------------------------------------------===//
    1258                 : 
    1259                 : extern "C" {
    1260              298: const char *clang_getFileName(CXFile SFile) {
                       53: branch 0 taken
                      245: branch 1 taken
    1261              298:   if (!SFile)
    1262               53:     return 0;
    1263                 :   
    1264              245:   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
    1265              245:   return FEnt->getName();
    1266                 : }
    1267                 : 
    1268                0: time_t clang_getFileTime(CXFile SFile) {
                        0: branch 0 not taken
                        0: branch 1 not taken
    1269                0:   if (!SFile)
    1270                0:     return 0;
    1271                 :   
    1272                0:   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
    1273                0:   return FEnt->getModificationTime();
    1274                 : }
    1275                 :   
    1276                8: CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
                        0: branch 0 not taken
                        8: branch 1 taken
    1277                8:   if (!tu)
    1278                0:     return 0;
    1279                 :   
    1280                8:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
    1281                 :   
    1282                8:   FileManager &FMgr = CXXUnit->getFileManager();
    1283                8:   const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name));
    1284                8:   return const_cast<FileEntry *>(File);
    1285                 : }
    1286                 :   
    1287                 : } // end: extern "C"
    1288                 : 
    1289                 : //===----------------------------------------------------------------------===//
    1290                 : // CXCursor Operations.
    1291                 : //===----------------------------------------------------------------------===//
    1292                 : 
    1293              233: static Decl *getDeclFromExpr(Stmt *E) {
                      111: branch 1 taken
                      122: branch 2 taken
    1294              233:   if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
    1295              111:     return RefExpr->getDecl();
                        0: branch 1 not taken
                      122: branch 2 taken
    1296              122:   if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
    1297                0:     return ME->getMemberDecl();
                        0: branch 1 not taken
                      122: branch 2 taken
    1298              122:   if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
    1299                0:     return RE->getDecl();
    1300                 :   
                        8: branch 1 taken
                      114: branch 2 taken
    1301              122:   if (CallExpr *CE = dyn_cast<CallExpr>(E))
    1302                8:     return getDeclFromExpr(CE->getCallee());
                       38: branch 1 taken
                       76: branch 2 taken
    1303              114:   if (CastExpr *CE = dyn_cast<CastExpr>(E))
    1304               38:     return getDeclFromExpr(CE->getSubExpr());
                       32: branch 1 taken
                       44: branch 2 taken
    1305               76:   if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
    1306               32:     return OME->getMethodDecl();
    1307                 :   
    1308               44:   return 0;
    1309                 : }
    1310                 : 
    1311              129: static SourceLocation getLocationFromExpr(Expr *E) {
                       10: branch 1 taken
                      119: branch 2 taken
    1312              129:   if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
    1313               10:     return /*FIXME:*/Msg->getLeftLoc();
                       55: branch 1 taken
                       64: branch 2 taken
    1314              119:   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
    1315               55:     return DRE->getLocation();
                        0: branch 1 not taken
                       64: branch 2 taken
    1316               64:   if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
    1317                0:     return Member->getMemberLoc();
                        0: branch 1 not taken
                       64: branch 2 taken
    1318               64:   if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
    1319                0:     return Ivar->getLocation();
    1320               64:   return E->getLocStart();
    1321                 : }
    1322                 : 
    1323                 : extern "C" {
    1324                 :   
    1325                 : unsigned clang_visitChildren(CXCursor parent, 
    1326                 :                              CXCursorVisitor visitor,
    1327               10:                              CXClientData client_data) {
    1328               10:   ASTUnit *CXXUnit = getCursorASTUnit(parent);
    1329                 : 
    1330               10:   unsigned PCHLevel = Decl::MaxPCHLevel;
    1331                 :   
    1332                 :   // Set the PCHLevel to filter out unwanted decls if requested.
                        4: branch 1 taken
                        6: branch 2 taken
    1333               10:   if (CXXUnit->getOnlyLocalDecls()) {
    1334                4:     PCHLevel = 0;
    1335                 :     
    1336                 :     // If the main input was an AST, bump the level.
                        3: branch 1 taken
                        1: branch 2 taken
    1337                4:     if (CXXUnit->isMainFileAST())
    1338                3:       ++PCHLevel;
    1339                 :   }
    1340                 :   
    1341               10:   CursorVisitor CursorVis(CXXUnit, visitor, client_data, PCHLevel);
    1342               10:   return CursorVis.VisitChildren(parent);
    1343                 : }
    1344                 : 
    1345              240: static CXString getDeclSpelling(Decl *D) {
    1346              240:   NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
                        4: branch 0 taken
                      236: branch 1 taken
    1347              240:   if (!ND)
    1348                4:     return CIndexer::createCXString("");
    1349                 :   
                       31: branch 1 taken
                      205: branch 2 taken
    1350              236:   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
    1351                 :     return CIndexer::createCXString(OMD->getSelector().getAsString().c_str(),
    1352               31:                                     true);
    1353                 :   
                        0: branch 1 not taken
                      205: branch 2 taken
    1354              205:   if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
    1355                 :     // No, this isn't the same as the code below. getIdentifier() is non-virtual
    1356                 :     // and returns different names. NamedDecl returns the class name and
    1357                 :     // ObjCCategoryImplDecl returns the category name.
    1358                0:     return CIndexer::createCXString(CIMP->getIdentifier()->getNameStart());
    1359                 :   
                      200: branch 1 taken
                        5: branch 2 taken
    1360              205:   if (ND->getIdentifier())
    1361              200:     return CIndexer::createCXString(ND->getIdentifier()->getNameStart());
    1362                 :   
    1363                5:   return CIndexer::createCXString("");
    1364                 : }
    1365                 :     
    1366              359: CXString clang_getCursorSpelling(CXCursor C) {
                        0: branch 1 not taken
                      359: branch 2 taken
    1367              359:   if (clang_isTranslationUnit(C.kind))
    1368                0:     return clang_getTranslationUnitSpelling(C.data[2]);
    1369                 : 
                       55: branch 1 taken
                      304: branch 2 taken
    1370              359:   if (clang_isReference(C.kind)) {
                        4: branch 0 taken
                       12: branch 1 taken
                        8: branch 2 taken
                       31: branch 3 taken
                        0: branch 4 not taken
    1371               55:     switch (C.kind) {
    1372                 :     case CXCursor_ObjCSuperClassRef: {
    1373                4:       ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
    1374                4:       return CIndexer::createCXString(Super->getIdentifier()->getNameStart());
    1375                 :     }
    1376                 :     case CXCursor_ObjCClassRef: {
    1377               12:       ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
    1378               12:       return CIndexer::createCXString(Class->getIdentifier()->getNameStart());
    1379                 :     }
    1380                 :     case CXCursor_ObjCProtocolRef: {
    1381                8:       ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
                        0: branch 0 not taken
                        8: branch 1 taken
    1382                8:       assert(OID && "getCursorSpelling(): Missing protocol decl");
    1383                8:       return CIndexer::createCXString(OID->getIdentifier()->getNameStart());
    1384                 :     }
    1385                 :     case CXCursor_TypeRef: {
    1386               31:       TypeDecl *Type = getCursorTypeRef(C).first;
                        0: branch 0 not taken
                       31: branch 1 taken
    1387               31:       assert(Type && "Missing type decl");
    1388                 : 
    1389                 :       return CIndexer::createCXString(
    1390                 :                getCursorContext(C).getTypeDeclType(Type).getAsString().c_str(),
    1391               31:                                       true);
    1392                 :     }
    1393                 : 
    1394                 :     default:
    1395                0:       return CIndexer::createCXString("<not implemented>");
    1396                 :     }
    1397                 :   }
    1398                 : 
                       92: branch 1 taken
                      212: branch 2 taken
    1399              304:   if (clang_isExpression(C.kind)) {
    1400               92:     Decl *D = getDeclFromExpr(getCursorExpr(C));
                       70: branch 0 taken
                       22: branch 1 taken
    1401               92:     if (D)
    1402               70:       return getDeclSpelling(D);
    1403               22:     return CIndexer::createCXString("");
    1404                 :   }
    1405                 : 
                      170: branch 1 taken
                       42: branch 2 taken
    1406              212:   if (clang_isDeclaration(C.kind))
    1407              170:     return getDeclSpelling(getCursorDecl(C));
    1408                 :   
    1409               42:   return CIndexer::createCXString("");
    1410                 : }
    1411                 : 
    1412             2106: const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) {
                       31: branch 0 taken
                       43: branch 1 taken
                        3: branch 2 taken
                        3: branch 3 taken
                        9: branch 4 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                       21: branch 7 taken
                       26: branch 8 taken
                       25: branch 9 taken
                       43: branch 10 taken
                       18: branch 11 taken
                       12: branch 12 taken
                       13: branch 13 taken
                        7: branch 14 taken
                       50: branch 15 taken
                        9: branch 16 taken
                        0: branch 17 not taken
                        0: branch 18 not taken
                        4: branch 19 taken
                        4: branch 20 taken
                        8: branch 21 taken
                       12: branch 22 taken
                       31: branch 23 taken
                       33: branch 24 taken
                       40: branch 25 taken
                        0: branch 26 not taken
                        4: branch 27 taken
                       15: branch 28 taken
                       42: branch 29 taken
                        0: branch 30 not taken
                       16: branch 31 taken
                     1584: branch 32 taken
                        0: branch 33 not taken
                        0: branch 34 not taken
    1413             2106:   switch (Kind) {
    1414               31:   case CXCursor_FunctionDecl: return "FunctionDecl";
    1415               43:   case CXCursor_TypedefDecl: return "TypedefDecl";
    1416                3:   case CXCursor_EnumDecl: return "EnumDecl";
    1417                3:   case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
    1418                9:   case CXCursor_StructDecl: return "StructDecl";
    1419                0:   case CXCursor_UnionDecl: return "UnionDecl";
    1420                0:   case CXCursor_ClassDecl: return "ClassDecl";
    1421               21:   case CXCursor_FieldDecl: return "FieldDecl";
    1422               26:   case CXCursor_VarDecl: return "VarDecl";
    1423               25:   case CXCursor_ParmDecl: return "ParmDecl";
    1424               43:   case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
    1425               18:   case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
    1426               12:   case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
    1427               13:   case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
    1428                7:   case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
    1429               50:   case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
    1430                9:   case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
    1431                0:   case CXCursor_ObjCImplementationDecl: return "ObjCImplementationDecl";
    1432                0:   case CXCursor_ObjCCategoryImplDecl: return "ObjCCategoryImplDecl";
    1433                4:   case CXCursor_UnexposedDecl: return "UnexposedDecl";
    1434                4:   case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
    1435                8:   case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
    1436               12:   case CXCursor_ObjCClassRef: return "ObjCClassRef";
    1437               31:   case CXCursor_TypeRef: return "TypeRef";
    1438               33:   case CXCursor_UnexposedExpr: return "UnexposedExpr";
    1439               40:   case CXCursor_DeclRefExpr: return "DeclRefExpr";
    1440                0:   case CXCursor_MemberRefExpr: return "MemberRefExpr";
    1441                4:   case CXCursor_CallExpr: return "CallExpr";
    1442               15:   case CXCursor_ObjCMessageExpr: return "ObjCMessageExpr";
    1443               42:   case CXCursor_UnexposedStmt: return "UnexposedStmt";
    1444                0:   case CXCursor_InvalidFile: return "InvalidFile";
    1445               16:   case CXCursor_NoDeclFound: return "NoDeclFound";
    1446             1584:   case CXCursor_NotImplemented: return "NotImplemented";
    1447                0:   case CXCursor_TranslationUnit: return "TranslationUnit";
    1448                 :   }
    1449                 :   
    1450                0:   llvm_unreachable("Unhandled CXCursorKind");
    1451                 :   return NULL;
    1452                 : }
    1453                 : 
    1454                 : enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, 
    1455                 :                                          CXCursor parent, 
    1456             1460:                                          CXClientData client_data) {
    1457             1460:   CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
    1458             1460:   *BestCursor = cursor;
    1459             1460:   return CXChildVisit_Recurse;
    1460                 : }
    1461                 :   
    1462            12825: CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
                        0: branch 0 not taken
                    12825: branch 1 taken
    1463            12825:   if (!TU)
    1464                0:     return clang_getNullCursor();
    1465                 :   
    1466            12825:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
    1467                 : 
    1468            12825:   SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
    1469            12825:   CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
                    12825: branch 1 taken
                        0: branch 2 not taken
    1470            12825:   if (SLoc.isValid()) {
    1471                 :     SourceRange RegionOfInterest(SLoc, 
    1472            12825:                        CXXUnit->getPreprocessor().getLocForEndOfToken(SLoc, 1));
    1473                 :     
    1474                 :     // FIXME: Would be great to have a "hint" cursor, then walk from that
    1475                 :     // hint cursor upward until we find a cursor whose source range encloses
    1476                 :     // the region of interest, rather than starting from the translation unit.
    1477            12825:     CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
    1478                 :     CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result, 
    1479            12825:                             Decl::MaxPCHLevel, RegionOfInterest);
    1480            12825:     CursorVis.VisitChildren(Parent);
    1481                 :   }
    1482            12825:   return Result;  
    1483                 : }
    1484                 : 
    1485              524: CXCursor clang_getNullCursor(void) {
    1486              524:   return MakeCXCursorInvalid(CXCursor_InvalidFile);
    1487                 : }
    1488                 : 
    1489            13180: unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
    1490            13180:   return X == Y;
    1491                 : }
    1492                 : 
    1493             5204: unsigned clang_isInvalid(enum CXCursorKind K) {
                     2514: branch 0 taken
                     2690: branch 1 taken
                       55: branch 2 taken
                     2459: branch 3 taken
    1494             5204:   return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
    1495                 : }
    1496                 : 
    1497            48808: unsigned clang_isDeclaration(enum CXCursorKind K) {
                    48808: branch 0 taken
                        0: branch 1 not taken
                     4829: branch 2 taken
                    43979: branch 3 taken
    1498            48808:   return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
    1499                 : }
    1500                 : 
    1501            19426: unsigned clang_isReference(enum CXCursorKind K) {
                    16771: branch 0 taken
                     2655: branch 1 taken
                      767: branch 2 taken
                    16004: branch 3 taken
    1502            19426:   return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
    1503                 : }
    1504                 : 
    1505            17442: unsigned clang_isExpression(enum CXCursorKind K) {
                    15769: branch 0 taken
                     1673: branch 1 taken
                     1722: branch 2 taken
                    14047: branch 3 taken
    1506            17442:   return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
    1507                 : }
    1508                 : 
    1509            15261: unsigned clang_isStatement(enum CXCursorKind K) {
                    14234: branch 0 taken
                     1027: branch 1 taken
                     1398: branch 2 taken
                    12836: branch 3 taken
    1510            15261:   return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
    1511                 : }
    1512                 : 
    1513            13195: unsigned clang_isTranslationUnit(enum CXCursorKind K) {
    1514            13195:   return K == CXCursor_TranslationUnit;
    1515                 : }
    1516                 : 
    1517               31: CXCursorKind clang_getCursorKind(CXCursor C) {
    1518               31:   return C.kind;
    1519                 : }
    1520                 : 
    1521              782: CXSourceLocation clang_getCursorLocation(CXCursor C) {
                       75: branch 1 taken
                      707: branch 2 taken
    1522              782:   if (clang_isReference(C.kind)) {
                        4: branch 0 taken
                        8: branch 1 taken
                       12: branch 2 taken
                       51: branch 3 taken
                        0: branch 4 not taken
    1523               75:     switch (C.kind) {
    1524                 :     case CXCursor_ObjCSuperClassRef: {       
    1525                 :       std::pair<ObjCInterfaceDecl *, SourceLocation> P
    1526                4:         = getCursorObjCSuperClassRef(C);
    1527                4:       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    1528                 :     }
    1529                 : 
    1530                 :     case CXCursor_ObjCProtocolRef: {       
    1531                 :       std::pair<ObjCProtocolDecl *, SourceLocation> P
    1532                8:         = getCursorObjCProtocolRef(C);
    1533                8:       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    1534                 :     }
    1535                 : 
    1536                 :     case CXCursor_ObjCClassRef: {       
    1537                 :       std::pair<ObjCInterfaceDecl *, SourceLocation> P
    1538               12:         = getCursorObjCClassRef(C);
    1539               12:       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    1540                 :     }
    1541                 : 
    1542                 :     case CXCursor_TypeRef: {       
    1543               51:       std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
    1544               51:       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    1545                 :     }
    1546                 :       
    1547                 :     default:
    1548                 :       // FIXME: Need a way to enumerate all non-reference cases.
    1549                0:       llvm_unreachable("Missed a reference kind");
    1550                 :     }
    1551                 :   }
    1552                 : 
                      129: branch 1 taken
                      578: branch 2 taken
    1553              707:   if (clang_isExpression(C.kind))
    1554                 :     return cxloc::translateSourceLocation(getCursorContext(C), 
    1555              129:                                    getLocationFromExpr(getCursorExpr(C)));
    1556                 : 
                        0: branch 1 not taken
                      578: branch 2 taken
    1557              578:   if (!getCursorDecl(C))
    1558                0:     return clang_getNullLocation();
    1559                 : 
    1560              578:   Decl *D = getCursorDecl(C);
    1561              578:   SourceLocation Loc = D->getLocation();
                       39: branch 1 taken
                      539: branch 2 taken
    1562              578:   if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
    1563               39:     Loc = Class->getClassLoc();
    1564              578:   return cxloc::translateSourceLocation(D->getASTContext(), Loc);
    1565                 : }
    1566                 : 
    1567             3428: CXSourceRange clang_getCursorExtent(CXCursor C) {
                      489: branch 1 taken
                     2939: branch 2 taken
    1568             3428:   if (clang_isReference(C.kind)) {
                      109: branch 0 taken
                      155: branch 1 taken
                      145: branch 2 taken
                       80: branch 3 taken
                        0: branch 4 not taken
    1569              489:     switch (C.kind) {
    1570                 :       case CXCursor_ObjCSuperClassRef: {       
    1571                 :         std::pair<ObjCInterfaceDecl *, SourceLocation> P
    1572              109:           = getCursorObjCSuperClassRef(C);
    1573              109:         return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
    1574                 :       }
    1575                 :         
    1576                 :       case CXCursor_ObjCProtocolRef: {       
    1577                 :         std::pair<ObjCProtocolDecl *, SourceLocation> P
    1578              155:           = getCursorObjCProtocolRef(C);
    1579              155:         return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
    1580                 :       }
    1581                 :         
    1582                 :       case CXCursor_ObjCClassRef: {       
    1583                 :         std::pair<ObjCInterfaceDecl *, SourceLocation> P
    1584              145:           = getCursorObjCClassRef(C);
    1585                 :         
    1586              145:         return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
    1587                 :       }
    1588                 : 
    1589                 :       case CXCursor_TypeRef: {       
    1590               80:         std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
    1591               80:         return cxloc::translateSourceRange(P.first->getASTContext(), P.second);
    1592                 :       }
    1593                 :         
    1594                 :       default:
    1595                 :         // FIXME: Need a way to enumerate all non-reference cases.
    1596                0:         llvm_unreachable("Missed a reference kind");
    1597                 :     }
    1598                 :   }
    1599                 : 
                     1117: branch 1 taken
                     1822: branch 2 taken
    1600             2939:   if (clang_isExpression(C.kind))
    1601                 :     return cxloc::translateSourceRange(getCursorContext(C), 
    1602             1117:                                 getCursorExpr(C)->getSourceRange());
    1603                 : 
                     1068: branch 1 taken
                      754: branch 2 taken
    1604             1822:   if (clang_isStatement(C.kind))
    1605                 :     return cxloc::translateSourceRange(getCursorContext(C), 
    1606             1068:                                 getCursorStmt(C)->getSourceRange());
    1607                 :   
                        0: branch 1 not taken
                      754: branch 2 taken
    1608              754:   if (!getCursorDecl(C))
    1609                0:     return clang_getNullRange();
    1610                 :   
    1611              754:   Decl *D = getCursorDecl(C);
    1612              754:   return cxloc::translateSourceRange(D->getASTContext(), D->getSourceRange());
    1613                 : }
    1614                 : 
    1615              362: CXCursor clang_getCursorReferenced(CXCursor C) {
                        0: branch 1 not taken
                      362: branch 2 taken
    1616              362:   if (clang_isInvalid(C.kind))
    1617                0:     return clang_getNullCursor();
    1618                 :   
    1619              362:   ASTUnit *CXXUnit = getCursorASTUnit(C);
                      170: branch 1 taken
                      192: branch 2 taken
    1620              362:   if (clang_isDeclaration(C.kind))
    1621              170:     return C;
    1622                 :   
                       95: branch 1 taken
                       97: branch 2 taken
    1623              192:   if (clang_isExpression(C.kind)) {
    1624               95:     Decl *D = getDeclFromExpr(getCursorExpr(C));
                       73: branch 0 taken
                       22: branch 1 taken
    1625               95:     if (D)
    1626               73:       return MakeCXCursor(D, CXXUnit);
    1627               22:     return clang_getNullCursor();
    1628                 :   }
    1629                 : 
                       42: branch 1 taken
                       55: branch 2 taken
    1630               97:   if (!clang_isReference(C.kind))
    1631               42:     return clang_getNullCursor();
    1632                 :   
                        4: branch 0 taken
                        8: branch 1 taken
                       12: branch 2 taken
                       31: branch 3 taken
                        0: branch 4 not taken
    1633               55:   switch (C.kind) {
    1634                 :     case CXCursor_ObjCSuperClassRef:
    1635                4:       return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit);
    1636                 :       
    1637                 :     case CXCursor_ObjCProtocolRef: {       
    1638                8:       return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit);
    1639                 :       
    1640                 :     case CXCursor_ObjCClassRef:      
    1641               12:       return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit);
    1642                 : 
    1643                 :     case CXCursor_TypeRef:      
    1644               31:       return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit);
    1645                 :       
    1646                 :     default:
    1647                 :       // We would prefer to enumerate all non-reference cursor kinds here.
    1648                0:       llvm_unreachable("Unhandled reference cursor kind");
    1649                 :       break;
    1650                 :     }
    1651                 :   }
    1652                 :   
    1653                 :   return clang_getNullCursor();
    1654                 : }
    1655                 : 
    1656              170: CXCursor clang_getCursorDefinition(CXCursor C) {
                        0: branch 1 not taken
                      170: branch 2 taken
    1657              170:   if (clang_isInvalid(C.kind))
    1658                0:     return clang_getNullCursor();
    1659                 :   
    1660              170:   ASTUnit *CXXUnit = getCursorASTUnit(C);
    1661                 :   
    1662              170:   bool WasReference = false;
                      170: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                      170: branch 5 taken
                        0: branch 6 not taken
                      170: branch 7 taken
    1663              170:   if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
    1664                0:     C = clang_getCursorReferenced(C);
    1665                0:     WasReference = true;
    1666                 :   }
    1667                 : 
                        0: branch 1 not taken
                      170: branch 2 taken
    1668              170:   if (!clang_isDeclaration(C.kind))
    1669                0:     return clang_getNullCursor();
    1670                 : 
    1671              170:   Decl *D = getCursorDecl(C);
                        0: branch 0 not taken
                      170: branch 1 taken
    1672              170:   if (!D)
    1673                0:     return clang_getNullCursor();
    1674                 :   
                       72: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        9: branch 6 taken
                       19: branch 7 taken
                       24: branch 8 taken
                        0: branch 9 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                       15: branch 13 taken
                        5: branch 14 taken
                        7: branch 15 taken
                       15: branch 16 taken
                        0: branch 17 not taken
                        0: branch 18 not taken
                        0: branch 19 not taken
                        4: branch 20 taken
                        0: branch 21 not taken
                        0: branch 22 not taken
                        0: branch 23 not taken
    1675              170:   switch (D->getKind()) {
    1676                 :   // Declaration kinds that don't really separate the notions of
    1677                 :   // declaration and definition.
    1678                 :   case Decl::Namespace:
    1679                 :   case Decl::Typedef:
    1680                 :   case Decl::TemplateTypeParm:
    1681                 :   case Decl::EnumConstant:
    1682                 :   case Decl::Field:
    1683                 :   case Decl::ObjCIvar:
    1684                 :   case Decl::ObjCAtDefsField:
    1685                 :   case Decl::ImplicitParam:
    1686                 :   case Decl::ParmVar:
    1687                 :   case Decl::NonTypeTemplateParm:
    1688                 :   case Decl::TemplateTemplateParm:
    1689                 :   case Decl::ObjCCategoryImpl:
    1690                 :   case Decl::ObjCImplementation:
    1691                 :   case Decl::LinkageSpec:
    1692                 :   case Decl::ObjCPropertyImpl:
    1693                 :   case Decl::FileScopeAsm:
    1694                 :   case Decl::StaticAssert:
    1695                 :   case Decl::Block:
    1696               72:     return C;
    1697                 : 
    1698                 :   // Declaration kinds that don't make any sense here, but are
    1699                 :   // nonetheless harmless.
    1700                 :   case Decl::TranslationUnit:
    1701                 :   case Decl::Template:
    1702                 :   case Decl::ObjCContainer:
    1703                0:     break;
    1704                 : 
    1705                 :   // Declaration kinds for which the definition is not resolvable.
    1706                 :   case Decl::UnresolvedUsingTypename:
    1707                 :   case Decl::UnresolvedUsingValue:
    1708                0:     break;
    1709                 : 
    1710                 :   case Decl::UsingDirective:
    1711                 :     return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
    1712                0:                         CXXUnit);
    1713                 : 
    1714                 :   case Decl::NamespaceAlias:
    1715                0:     return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit);
    1716                 : 
    1717                 :   case Decl::Enum:
    1718                 :   case Decl::Record:
    1719                 :   case Decl::CXXRecord:
    1720                 :   case Decl::ClassTemplateSpecialization:
    1721                 :   case Decl::ClassTemplatePartialSpecialization:
                        9: branch 3 taken
                        0: branch 4 not taken
    1722                9:     if (TagDecl *Def = cast<TagDecl>(D)->getDefinition(D->getASTContext()))
    1723                9:       return MakeCXCursor(Def, CXXUnit);
    1724                0:     return clang_getNullCursor();
    1725                 : 
    1726                 :   case Decl::Function:
    1727                 :   case Decl::CXXMethod:
    1728                 :   case Decl::CXXConstructor:
    1729                 :   case Decl::CXXDestructor:
    1730                 :   case Decl::CXXConversion: {
    1731               19:     const FunctionDecl *Def = 0;
                       14: branch 2 taken
                        5: branch 3 taken
    1732               19:     if (cast<FunctionDecl>(D)->getBody(Def))
    1733               14:       return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit);
    1734                5:     return clang_getNullCursor();
    1735                 :   }
    1736                 : 
    1737                 :   case Decl::Var: {
    1738                 :     // Ask the variable if it has a definition.
                       22: branch 2 taken
                        2: branch 3 taken
    1739               24:     if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
    1740               22:       return MakeCXCursor(Def, CXXUnit);
    1741                2:     return clang_getNullCursor();
    1742                 :   }
    1743                 :    
    1744                 :   case Decl::FunctionTemplate: {
    1745                0:     const FunctionDecl *Def = 0;
                        0: branch 3 not taken
                        0: branch 4 not taken
    1746                0:     if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
    1747                0:       return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit);
    1748                0:     return clang_getNullCursor();
    1749                 :   }
    1750                 :    
    1751                 :   case Decl::ClassTemplate: {
                        0: branch 0 not taken
                        0: branch 1 not taken
    1752                0:     if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
    1753                0:                                           ->getDefinition(D->getASTContext()))
    1754                 :       return MakeCXCursor(
    1755                 :                          cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), 
    1756                0:                           CXXUnit);
    1757                0:     return clang_getNullCursor();
    1758                 :   }
    1759                 : 
    1760                 :   case Decl::Using: {
    1761                0:     UsingDecl *Using = cast<UsingDecl>(D);
    1762                0:     CXCursor Def = clang_getNullCursor();
                        0: branch 3 not taken
                        0: branch 4 not taken
    1763                0:     for (UsingDecl::shadow_iterator S = Using->shadow_begin(), 
    1764                0:                                  SEnd = Using->shadow_end(); 
    1765                 :          S != SEnd; ++S) {
                        0: branch 2 not taken
                        0: branch 3 not taken
    1766                0:       if (Def != clang_getNullCursor()) {
    1767                 :         // FIXME: We have no way to return multiple results.
    1768                0:         return clang_getNullCursor();
    1769                 :       }
    1770                 : 
    1771                 :       Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl(), 
    1772                0:                                                    CXXUnit));
    1773                 :     }
    1774                 : 
    1775                0:     return Def;
    1776                 :   }
    1777                 : 
    1778                 :   case Decl::UsingShadow:
    1779                 :     return clang_getCursorDefinition(
    1780                 :                        MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), 
    1781                0:                                     CXXUnit));
    1782                 : 
    1783                 :   case Decl::ObjCMethod: {
    1784               15:     ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
                        0: branch 1 not taken
                       15: branch 2 taken
    1785               15:     if (Method->isThisDeclarationADefinition())
    1786                0:       return C;
    1787                 : 
    1788                 :     // Dig out the method definition in the associated
    1789                 :     // @implementation, if we have it.
    1790                 :     // FIXME: The ASTs should make finding the definition easier.
                        6: branch 0 taken
                        9: branch 1 taken
    1791               15:     if (ObjCInterfaceDecl *Class
    1792               15:                        = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
                        0: branch 1 not taken
                        6: branch 2 taken
    1793                6:       if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
                        0: branch 0 not taken
                        0: branch 1 not taken
    1794                0:         if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
    1795                0:                                                   Method->isInstanceMethod()))
                        0: branch 1 not taken
                        0: branch 2 not taken
    1796                0:           if (Def->isThisDeclarationADefinition())
    1797                0:             return MakeCXCursor(Def, CXXUnit);
    1798                 : 
    1799               15:     return clang_getNullCursor();
    1800                 :   }
    1801                 : 
    1802                 :   case Decl::ObjCCategory:
                        0: branch 0 not taken
                        5: branch 1 taken
    1803                5:     if (ObjCCategoryImplDecl *Impl
    1804                5:                                = cast<ObjCCategoryDecl>(D)->getImplementation())
    1805                0:       return MakeCXCursor(Impl, CXXUnit);
    1806                5:     return clang_getNullCursor();
    1807                 : 
    1808                 :   case Decl::ObjCProtocol:
                        7: branch 2 taken
                        0: branch 3 not taken
    1809                7:     if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
    1810                7:       return C;
    1811                0:     return clang_getNullCursor();
    1812                 : 
    1813                 :   case Decl::ObjCInterface:
    1814                 :     // There are two notions of a "definition" for an Objective-C
    1815                 :     // class: the interface and its implementation. When we resolved a
    1816                 :     // reference to an Objective-C class, produce the @interface as
    1817                 :     // the definition; when we were provided with the interface,
    1818                 :     // produce the @implementation as the definition.
                        0: branch 0 not taken
                       15: branch 1 taken
    1819               15:     if (WasReference) {
                        0: branch 2 not taken
                        0: branch 3 not taken
    1820                0:       if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
    1821                0:         return C;
                        0: branch 0 not taken
                       15: branch 1 taken
    1822               15:     } else if (ObjCImplementationDecl *Impl
    1823               15:                               = cast<ObjCInterfaceDecl>(D)->getImplementation())
    1824                0:       return MakeCXCursor(Impl, CXXUnit);
    1825               15:     return clang_getNullCursor();
    1826                 :   
    1827                 :   case Decl::ObjCProperty:
    1828                 :     // FIXME: We don't really know where to find the
    1829                 :     // ObjCPropertyImplDecls that implement this property.
    1830                0:     return clang_getNullCursor();
    1831                 : 
    1832                 :   case Decl::ObjCCompatibleAlias:
                        0: branch 0 not taken
                        0: branch 1 not taken
    1833                0:     if (ObjCInterfaceDecl *Class
    1834                0:           = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
                        0: branch 1 not taken
                        0: branch 2 not taken
    1835                0:       if (!Class->isForwardDecl())
    1836                0:         return MakeCXCursor(Class, CXXUnit);
    1837                 :     
    1838                0:     return clang_getNullCursor();
    1839                 : 
    1840                 :   case Decl::ObjCForwardProtocol: {
    1841                0:     ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1842                0:     if (Forward->protocol_size() == 1)
    1843                 :       return clang_getCursorDefinition(
    1844                 :                                      MakeCXCursor(*Forward->protocol_begin(), 
    1845                0:                                                   CXXUnit));
    1846                 : 
    1847                 :     // FIXME: Cannot return multiple definitions.
    1848                0:     return clang_getNullCursor();
    1849                 :   }
    1850                 : 
    1851                 :   case Decl::ObjCClass: {
    1852                4:     ObjCClassDecl *Class = cast<ObjCClassDecl>(D);
                        4: branch 1 taken
                        0: branch 2 not taken
    1853                4:     if (Class->size() == 1) {
    1854                4:       ObjCInterfaceDecl *IFace = Class->begin()->getInterface();
                        2: branch 1 taken
                        2: branch 2 taken
    1855                4:       if (!IFace->isForwardDecl())
    1856                2:         return MakeCXCursor(IFace, CXXUnit);
    1857                2:       return clang_getNullCursor();
    1858                 :     }
    1859                 : 
    1860                 :     // FIXME: Cannot return multiple definitions.
    1861                0:     return clang_getNullCursor();
    1862                 :   }
    1863                 : 
    1864                 :   case Decl::Friend:
                        0: branch 2 not taken
                        0: branch 3 not taken
    1865                0:     if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
    1866                0:       return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
    1867                0:     return clang_getNullCursor();
    1868                 : 
    1869                 :   case Decl::FriendTemplate:
                        0: branch 2 not taken
                        0: branch 3 not taken
    1870                0:     if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
    1871                0:       return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
    1872                0:     return clang_getNullCursor();
    1873                 :   }
    1874                 : 
    1875                0:   return clang_getNullCursor();
    1876                 : }
    1877                 : 
    1878              359: unsigned clang_isCursorDefinition(CXCursor C) {
                      189: branch 1 taken
                      170: branch 2 taken
    1879              359:   if (!clang_isDeclaration(C.kind))
    1880              189:     return 0;
    1881                 : 
    1882              170:   return clang_getCursorDefinition(C) == C;
    1883                 : }
    1884                 : 
    1885                 : void clang_getDefinitionSpellingAndExtent(CXCursor C,
    1886                 :                                           const char **startBuf,
    1887                 :                                           const char **endBuf,
    1888                 :                                           unsigned *startLine,
    1889                 :                                           unsigned *startColumn,
    1890                 :                                           unsigned *endLine,
    1891                0:                                           unsigned *endColumn) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1892                0:   assert(getCursorDecl(C) && "CXCursor has null decl");
    1893                0:   NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
    1894                0:   FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
    1895                0:   CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
    1896                 :   
    1897                0:   SourceManager &SM = FD->getASTContext().getSourceManager();
    1898                0:   *startBuf = SM.getCharacterData(Body->getLBracLoc());
    1899                0:   *endBuf = SM.getCharacterData(Body->getRBracLoc());
    1900                0:   *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
    1901                0:   *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
    1902                0:   *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
    1903                0:   *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
    1904                0: }
    1905                 :   
    1906                 : } // end: extern "C"
    1907                 : 
    1908                 : //===----------------------------------------------------------------------===//
    1909                 : // Token-based Operations.
    1910                 : //===----------------------------------------------------------------------===//
    1911                 : 
    1912                 : /* CXToken layout:
    1913                 :  *   int_data[0]: a CXTokenKind
    1914                 :  *   int_data[1]: starting token location
    1915                 :  *   int_data[2]: token length
    1916                 :  *   int_data[3]: reserved
    1917                 :  *   ptr_data: for identifiers and keywords, an IdentifierInfo*. 
    1918                 :  *   otherwise unused.
    1919                 :  */
    1920                 : extern "C" {
    1921                 : 
    1922              102: CXTokenKind clang_getTokenKind(CXToken CXTok) {
    1923              102:   return static_cast<CXTokenKind>(CXTok.int_data[0]);
    1924                 : }
    1925                 : 
    1926               51: CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
                       19: branch 1 taken
                        3: branch 2 taken
                       29: branch 3 taken
    1927               51:   switch (clang_getTokenKind(CXTok)) {
    1928                 :   case CXToken_Identifier:
    1929                 :   case CXToken_Keyword:
    1930                 :     // We know we have an IdentifierInfo*, so use that.
    1931                 :     return CIndexer::createCXString(
    1932               19:               static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
    1933                 : 
    1934                 :   case CXToken_Literal: {
    1935                 :     // We have stashed the starting pointer in the ptr_data field. Use it.
    1936                3:     const char *Text = static_cast<const char *>(CXTok.ptr_data);
    1937                 :     return CIndexer::createCXString(llvm::StringRef(Text, CXTok.int_data[2]), 
    1938                3:                                     true);
    1939                 :   }
    1940                 :       
    1941                 :   case CXToken_Punctuation:
    1942                 :   case CXToken_Comment:
    1943                 :     break;
    1944                 :   }
    1945                 :   
    1946                 :   // We have to find the starting buffer pointer the hard way, by 
    1947                 :   // deconstructing the source location.
    1948               29:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
                        0: branch 0 not taken
                       29: branch 1 taken
    1949               29:   if (!CXXUnit)
    1950                0:     return CIndexer::createCXString("");
    1951                 :   
    1952               29:   SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
    1953                 :   std::pair<FileID, unsigned> LocInfo
    1954               29:     = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
    1955                 :   std::pair<const char *,const char *> Buffer
    1956               29:     = CXXUnit->getSourceManager().getBufferData(LocInfo.first);
    1957                 : 
    1958                 :   return CIndexer::createCXString(llvm::StringRef(Buffer.first+LocInfo.second,
    1959                 :                                                   CXTok.int_data[2]), 
    1960               29:                                   true);
    1961                 : }
    1962                 :  
    1963                2: CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
    1964                2:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
                        0: branch 0 not taken
                        2: branch 1 taken
    1965                2:   if (!CXXUnit)
    1966                0:     return clang_getNullLocation();
    1967                 :   
    1968                 :   return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
    1969                2:                         SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
    1970                 : }
    1971                 : 
    1972               51: CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
    1973               51:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
                        0: branch 0 not taken
                       51: branch 1 taken
    1974               51:   if (!CXXUnit)
    1975                0:     return clang_getNullRange();
    1976                 :   
    1977                 :   return cxloc::translateSourceRange(CXXUnit->getASTContext(), 
    1978               51:                         SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
    1979                 : }
    1980                 :   
    1981                 : void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
    1982                1:                     CXToken **Tokens, unsigned *NumTokens) {
                        1: branch 0 taken
                        0: branch 1 not taken
    1983                1:   if (Tokens)
    1984                1:     *Tokens = 0;
                        1: branch 0 taken
                        0: branch 1 not taken
    1985                1:   if (NumTokens)
    1986                1:     *NumTokens = 0;
    1987                 :   
    1988                1:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
                        1: branch 0 taken
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        1: branch 5 taken
    1989                1:   if (!CXXUnit || !Tokens || !NumTokens)
    1990                0:     return;
    1991                 :   
    1992                1:   SourceRange R = cxloc::translateSourceRange(Range);
                        0: branch 1 not taken
                        1: branch 2 taken
    1993                1:   if (R.isInvalid())
    1994                0:     return;
    1995                 :   
    1996                1:   SourceManager &SourceMgr = CXXUnit->getSourceManager();
    1997                 :   std::pair<FileID, unsigned> BeginLocInfo
    1998                1:     = SourceMgr.getDecomposedLoc(R.getBegin());
    1999                 :   std::pair<FileID, unsigned> EndLocInfo
    2000                1:     = SourceMgr.getDecomposedLoc(R.getEnd());
    2001                 :   
    2002                 :   // Cannot tokenize across files.
                        0: branch 1 not taken
                        1: branch 2 taken
    2003                1:   if (BeginLocInfo.first != EndLocInfo.first)
    2004                0:     return;
    2005                 :   
    2006                 :   // Create a lexer 
    2007                 :   std::pair<const char *,const char *> Buffer
    2008                1:     = SourceMgr.getBufferData(BeginLocInfo.first);
    2009                 :   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
    2010                 :             CXXUnit->getASTContext().getLangOptions(),
    2011                1:             Buffer.first, Buffer.first + BeginLocInfo.second, Buffer.second);
    2012                1:   Lex.SetCommentRetentionState(true);
    2013                 :   
    2014                 :   // Lex tokens until we hit the end of the range.
    2015                1:   const char *EffectiveBufferEnd = Buffer.first + EndLocInfo.second;
    2016                1:   llvm::SmallVector<CXToken, 32> CXTokens;
    2017                1:   Token Tok;
                       50: branch 1 taken
                        1: branch 2 taken
    2018               51:   do {
    2019                 :     // Lex the next token
    2020               51:     Lex.LexFromRawLexer(Tok);
                        0: branch 1 not taken
                       51: branch 2 taken
    2021               51:     if (Tok.is(tok::eof))
    2022                0:       break;
    2023                 :     
    2024                 :     // Initialize the CXToken.
    2025                 :     CXToken CXTok;
    2026                 :     
    2027                 :     //   - Common fields
    2028               51:     CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
    2029               51:     CXTok.int_data[2] = Tok.getLength();
    2030               51:     CXTok.int_data[3] = 0;
    2031                 :     
    2032                 :     //   - Kind-specific fields
                        3: branch 1 taken
                       48: branch 2 taken
    2033               51:     if (Tok.isLiteral()) {
    2034                3:       CXTok.int_data[0] = CXToken_Literal;
    2035                3:       CXTok.ptr_data = (void *)Tok.getLiteralData();
                       19: branch 1 taken
                       29: branch 2 taken
    2036               48:     } else if (Tok.is(tok::identifier)) {
    2037                 :       // Lookup the identifier to determine whether we have a 
    2038                 :       std::pair<FileID, unsigned> LocInfo
    2039               19:         = SourceMgr.getDecomposedLoc(Tok.getLocation());
    2040                 :       const char *StartPos 
    2041                 :         = CXXUnit->getSourceManager().getBufferData(LocInfo.first).first + 
    2042               19:           LocInfo.second;
    2043                 :       IdentifierInfo *II
    2044               19:         = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos);
    2045                 :       CXTok.int_data[0] = II->getTokenID() == tok::identifier?
    2046                 :                                CXToken_Identifier
                       12: branch 1 taken
                        7: branch 2 taken
    2047               19:                              : CXToken_Keyword;
    2048               19:       CXTok.ptr_data = II;
                        1: branch 1 taken
                       28: branch 2 taken
    2049               29:     } else if (Tok.is(tok::comment)) {
    2050                1:       CXTok.int_data[0] = CXToken_Comment;
    2051                1:       CXTok.ptr_data = 0;
    2052                 :     } else {
    2053               28:       CXTok.int_data[0] = CXToken_Punctuation;
    2054               28:       CXTok.ptr_data = 0;
    2055                 :     }
    2056               51:     CXTokens.push_back(CXTok);
    2057                 :   } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
    2058                 :   
                        0: branch 1 not taken
                        1: branch 2 taken
    2059                1:   if (CXTokens.empty())
    2060                0:     return;
    2061                 :   
    2062                1:   *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
    2063                1:   memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 5 taken
                        0: branch 6 not taken
    2064                1:   *NumTokens = CXTokens.size();
    2065                 : }
    2066                 : 
    2067                 : typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
    2068                 : 
    2069                 : enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 
    2070                 :                                               CXCursor parent, 
    2071               31:                                               CXClientData client_data) {
    2072               31:   AnnotateTokensData *Data = static_cast<AnnotateTokensData *>(client_data);
    2073                 : 
    2074                 :   // We only annotate the locations of declarations, simple
    2075                 :   // references, and expressions which directly reference something.
    2076               31:   CXCursorKind Kind = clang_getCursorKind(cursor);
                       26: branch 1 taken
                        5: branch 2 taken
                        5: branch 4 taken
                       21: branch 5 taken
                       21: branch 6 taken
                       10: branch 7 taken
    2077               31:   if (clang_isDeclaration(Kind) || clang_isReference(Kind)) {
    2078                 :     // Okay: We can annotate the location of this declaration with the
    2079                 :     // declaration or reference
                       16: branch 1 taken
                        5: branch 2 taken
    2080               21:   } else if (clang_isExpression(cursor.kind)) {
                       13: branch 0 taken
                        3: branch 1 taken
                       13: branch 2 taken
                        0: branch 3 not taken
                       13: branch 4 taken
                        0: branch 5 not taken
    2081               16:     if (Kind != CXCursor_DeclRefExpr &&
    2082                 :         Kind != CXCursor_MemberRefExpr &&
    2083                 :         Kind != CXCursor_ObjCMessageExpr)
    2084               13:       return CXChildVisit_Recurse;
    2085                 : 
    2086                3:     CXCursor Referenced = clang_getCursorReferenced(cursor);
                        3: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        3: branch 6 taken
                        0: branch 7 not taken
                        3: branch 8 taken
    2087                3:     if (Referenced == cursor || Referenced == clang_getNullCursor())
    2088                0:       return CXChildVisit_Recurse;
    2089                 :     
    2090                 :     // Okay: we can annotate the location of this expression
    2091                 :   } else {
    2092                 :     // Nothing to annotate
    2093                5:     return CXChildVisit_Recurse;
    2094                 :   }
    2095                 :   
    2096               13:   CXSourceLocation Loc = clang_getCursorLocation(cursor);
    2097               13:   (*Data)[Loc.int_data] = cursor;
    2098               13:   return CXChildVisit_Recurse;
    2099                 : }
    2100                 : 
    2101                 : void clang_annotateTokens(CXTranslationUnit TU,
    2102                 :                           CXToken *Tokens, unsigned NumTokens,
    2103                1:                           CXCursor *Cursors) {
                        0: branch 0 not taken
                        1: branch 1 taken
    2104                1:   if (NumTokens == 0)
    2105                0:     return;
    2106                 : 
    2107                 :   // Any token we don't specifically annotate will have a NULL cursor.
                       51: branch 0 taken
                        1: branch 1 taken
    2108               52:   for (unsigned I = 0; I != NumTokens; ++I)
    2109               51:     Cursors[I] = clang_getNullCursor();
    2110                 : 
    2111                1:   ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
                        1: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        1: branch 3 taken
    2112                1:   if (!CXXUnit || !Tokens)
    2113                0:     return;
    2114                 : 
    2115                 :   // Annotate all of the source locations in the region of interest that map 
    2116                1:   SourceRange RegionOfInterest;
    2117                 :   RegionOfInterest.setBegin(
    2118                1:         cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
    2119                 :   SourceLocation End
    2120                 :     = cxloc::translateSourceLocation(clang_getTokenLocation(TU, 
    2121                1:                                                      Tokens[NumTokens - 1]));
    2122                 :   RegionOfInterest.setEnd(CXXUnit->getPreprocessor().getLocForEndOfToken(End, 
    2123                1:                                                                          1));
    2124                 :   // FIXME: Would be great to have a "hint" cursor, then walk from that
    2125                 :   // hint cursor upward until we find a cursor whose source range encloses
    2126                 :   // the region of interest, rather than starting from the translation unit.
    2127                1:   AnnotateTokensData Annotated;
    2128                1:   CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
    2129                 :   CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &Annotated, 
    2130                1:                             Decl::MaxPCHLevel, RegionOfInterest);
    2131                1:   AnnotateVis.VisitChildren(Parent);
    2132                 : 
                       51: branch 0 taken
                        1: branch 1 taken
    2133               52:   for (unsigned I = 0; I != NumTokens; ++I) {
    2134                 :     // Determine whether we saw a cursor at this token's location.
    2135               51:     AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
                       39: branch 3 taken
                       12: branch 4 taken
    2136               51:     if (Pos == Annotated.end())
    2137               39:       continue;
    2138                 : 
    2139               12:     Cursors[I] = Pos->second;
    2140                1:   }
    2141                 : }
    2142                 : 
    2143                 : void clang_disposeTokens(CXTranslationUnit TU, 
    2144                0:                          CXToken *Tokens, unsigned NumTokens) {
    2145                0:   free(Tokens);
    2146                0: }
    2147                 :   
    2148                 : } // end: extern "C"
    2149                 : 
    2150                 : //===----------------------------------------------------------------------===//
    2151                 : // CXString Operations.
    2152                 : //===----------------------------------------------------------------------===//
    2153                 : 
    2154                 : extern "C" {
    2155              522: const char *clang_getCString(CXString string) {
    2156              522:   return string.Spelling;
    2157                 : }
    2158                 : 
    2159              416: void clang_disposeString(CXString string) {
                      117: branch 0 taken
                      299: branch 1 taken
                      117: branch 2 taken
                        0: branch 3 not taken
    2160              416:   if (string.MustFreeString && string.Spelling)
    2161              117:     free((void*)string.Spelling);
    2162              416: }
    2163                 : 
    2164                 : } // end: extern "C"
    2165                 : 
    2166                 : //===----------------------------------------------------------------------===//
    2167                 : // Misc. utility functions.
    2168                 : //===----------------------------------------------------------------------===//
    2169                 :   
    2170                 : extern "C" {
    2171                 : 
    2172                0: const char *clang_getClangVersion() {
    2173                0:   return getClangFullVersion();
    2174                 : }
    2175                 : 
    2176                 : } // end: extern "C"
    2177                 : 

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