[cfe-commits] r143605 - in /cfe/trunk: include/clang/AST/ExternalASTSource.h include/clang/Frontend/ASTUnit.h include/clang/Serialization/ASTReader.h lib/Frontend/ASTUnit.cpp lib/Serialization/ASTReader.cpp test/Index/targeted-cursor.c test/Index/targeted-fields.h test/Index/targeted-nested1.h test/Index/targeted-preamble.h test/Index/targeted-top.h tools/libclang/CIndex.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Nov 2 19:20:32 PDT 2011


Author: akirtzidis
Date: Wed Nov  2 21:20:32 2011
New Revision: 143605

URL: http://llvm.org/viewvc/llvm-project?rev=143605&view=rev
Log:
[libclang] Add infrastructure to be able to only deserialize decls in a file region and
use it for clang_getCursor.

Added:
    cfe/trunk/test/Index/targeted-cursor.c
    cfe/trunk/test/Index/targeted-fields.h
    cfe/trunk/test/Index/targeted-nested1.h
    cfe/trunk/test/Index/targeted-preamble.h
    cfe/trunk/test/Index/targeted-top.h
Modified:
    cfe/trunk/include/clang/AST/ExternalASTSource.h
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=143605&r1=143604&r2=143605&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExternalASTSource.h (original)
+++ cfe/trunk/include/clang/AST/ExternalASTSource.h Wed Nov  2 21:20:32 2011
@@ -153,6 +153,12 @@
     return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
   }
 
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of
+  /// a range. 
+  virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
+                                   SmallVectorImpl<Decl *> &Decls) {}
+
   /// \brief Gives the external AST source an opportunity to complete
   /// an incomplete type.
   virtual void CompleteType(TagDecl *Tag) {}

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=143605&r1=143604&r2=143605&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Wed Nov  2 21:20:32 2011
@@ -519,6 +519,12 @@
   /// \brief Add a new local file-level declaration.
   void addFileLevelDecl(Decl *D);
 
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of
+  /// a range. 
+  void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
+                           SmallVectorImpl<Decl *> &Decls);
+
   /// \brief Add a new top-level declaration, identified by its ID in
   /// the precompiled preamble.
   void addTopLevelDeclFromPreamble(serialization::DeclID D) {

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=143605&r1=143604&r2=143605&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Wed Nov  2 21:20:32 2011
@@ -921,6 +921,9 @@
   /// \brief Returns true if global DeclID \arg ID originated from module
   /// \arg M.
   bool isDeclIDFromModule(serialization::GlobalDeclID ID, Module &M) const;
+
+  /// \brief Returns the source location for the decl \arg ID.
+  SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
   
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
@@ -1006,6 +1009,12 @@
                                         bool (*isKindWeWant)(Decl::Kind),
                                         SmallVectorImpl<Decl*> &Decls);
 
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of
+  /// a range. 
+  virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
+                                   SmallVectorImpl<Decl *> &Decls);
+
   /// \brief Notify ASTReader that we started deserialization of
   /// a decl or type so until FinishedDeserializing is called there may be
   /// decls that are initializing. Must be paired with FinishedDeserializing.

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=143605&r1=143604&r2=143605&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Wed Nov  2 21:20:32 2011
@@ -2518,6 +2518,42 @@
   Decls->insert(I, LocDecl);
 }
 
+void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
+                                  SmallVectorImpl<Decl *> &Decls) {
+  if (File.isInvalid())
+    return;
+
+  if (SourceMgr->isLoadedFileID(File)) {
+    assert(Ctx->getExternalSource() && "No external source!");
+    return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
+                                                         Decls);
+  }
+
+  FileDeclsTy::iterator I = FileDecls.find(File);
+  if (I == FileDecls.end())
+    return;
+
+  LocDeclsTy &LocDecls = *I->second;
+  if (LocDecls.empty())
+    return;
+
+  LocDeclsTy::iterator
+    BeginIt = std::lower_bound(LocDecls.begin(), LocDecls.end(),
+                               std::make_pair(Offset, (Decl*)0), compLocDecl);
+  if (BeginIt != LocDecls.begin())
+    --BeginIt;
+
+  LocDeclsTy::iterator
+    EndIt = std::upper_bound(LocDecls.begin(), LocDecls.end(),
+                             std::make_pair(Offset+Length, (Decl*)0),
+                             compLocDecl);
+  if (EndIt != LocDecls.end())
+    ++EndIt;
+  
+  for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
+    Decls.push_back(DIt->second);
+}
+
 SourceLocation ASTUnit::getLocation(const FileEntry *File,
                                     unsigned Line, unsigned Col) const {
   const SourceManager &SM = getSourceManager();

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=143605&r1=143604&r2=143605&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Nov  2 21:20:32 2011
@@ -4020,6 +4020,25 @@
   return &M == I->second;
 }
 
+SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
+  if (ID < NUM_PREDEF_DECL_IDS)
+    return SourceLocation();
+  
+  unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+
+  if (Index > DeclsLoaded.size()) {
+    Error("declaration ID out-of-range for AST file");
+    return SourceLocation();
+  }
+  
+  if (Decl *D = DeclsLoaded[Index])
+    return D->getLocation();
+
+  unsigned RawLocation = 0;
+  RecordLocation Rec = DeclCursorForID(ID, RawLocation);
+  return ReadSourceLocation(*Rec.F, RawLocation);
+}
+
 Decl *ASTReader::GetDecl(DeclID ID) {
   if (ID < NUM_PREDEF_DECL_IDS) {    
     switch ((PredefinedDeclIDs)ID) {
@@ -4163,6 +4182,74 @@
 }
 
 namespace {
+
+class DeclIDComp {
+  ASTReader &Reader;
+  Module &Mod;
+
+public:
+  DeclIDComp(ASTReader &Reader, Module &M) : Reader(Reader), Mod(M) {}
+
+  bool operator()(LocalDeclID L, LocalDeclID R) const {
+    SourceLocation LHS = getLocation(L);
+    SourceLocation RHS = getLocation(R);
+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
+  }
+
+  bool operator()(SourceLocation LHS, LocalDeclID R) const {
+    SourceLocation RHS = getLocation(R);
+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
+  }
+
+  bool operator()(LocalDeclID L, SourceLocation RHS) const {
+    SourceLocation LHS = getLocation(L);
+    return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
+  }
+
+  SourceLocation getLocation(LocalDeclID ID) const {
+    return Reader.getSourceManager().getFileLoc(
+            Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID)));
+  }
+};
+
+}
+
+void ASTReader::FindFileRegionDecls(FileID File,
+                                    unsigned Offset, unsigned Length,
+                                    SmallVectorImpl<Decl *> &Decls) {
+  SourceManager &SM = getSourceManager();
+
+  llvm::DenseMap<FileID, FileDeclsInfo>::iterator I = FileDeclIDs.find(File);
+  if (I == FileDeclIDs.end())
+    return;
+
+  FileDeclsInfo &DInfo = I->second;
+  if (DInfo.Decls.empty())
+    return;
+
+  SourceLocation
+    BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset);
+  SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length);
+
+  DeclIDComp DIDComp(*this, *DInfo.Mod);
+  ArrayRef<serialization::LocalDeclID>::iterator
+    BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
+                               BeginLoc, DIDComp);
+  if (BeginIt != DInfo.Decls.begin())
+    --BeginIt;
+
+  ArrayRef<serialization::LocalDeclID>::iterator
+    EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
+                             EndLoc, DIDComp);
+  if (EndIt != DInfo.Decls.end())
+    ++EndIt;
+  
+  for (ArrayRef<serialization::LocalDeclID>::iterator
+         DIt = BeginIt; DIt != EndIt; ++DIt)
+    Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
+}
+
+namespace {
   /// \brief Module visitor used to perform name lookup into a
   /// declaration context.
   class DeclContextNameLookupVisitor {

Added: cfe/trunk/test/Index/targeted-cursor.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/targeted-cursor.c?rev=143605&view=auto
==============================================================================
--- cfe/trunk/test/Index/targeted-cursor.c (added)
+++ cfe/trunk/test/Index/targeted-cursor.c Wed Nov  2 21:20:32 2011
@@ -0,0 +1,52 @@
+
+#include "targeted-top.h"
+#include "targeted-preamble.h"
+
+int LocalVar1;
+int LocalVar2;
+
+// RUN: c-index-test -write-pch %t.h.pch %S/targeted-top.h
+// RUN: env CINDEXTEST_FAILONERROR=1 c-index-test -cursor-at=%s:5:10 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=NestedVar1  \
+// RUN:    -Xclang -error-on-deserialized-decl=TopVar  \
+// RUN:  | FileCheck %s -check-prefix=LOCAL-CURSOR1
+
+// RUN: env CINDEXTEST_FAILONERROR=1 c-index-test -cursor-at=%S/targeted-top.h:11:15 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=NestedVar1  \
+// RUN:    -Xclang -error-on-deserialized-decl=vector_get_x  \
+// RUN:  | FileCheck %s -check-prefix=TOP-CURSOR1
+
+// RUN: env CINDEXTEST_FAILONERROR=1 c-index-test -cursor-at=%S/targeted-nested1.h:2:16 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=TopVar  \
+// RUN:  | FileCheck %s -check-prefix=NESTED-CURSOR1
+
+// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \
+// RUN:   c-index-test -cursor-at=%s:5:10 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=PreambleVar  \
+// RUN:    -Xclang -error-on-deserialized-decl=NestedVar1  \
+// RUN:    -Xclang -error-on-deserialized-decl=TopVar  \
+// RUN:  | FileCheck %s -check-prefix=LOCAL-CURSOR1
+
+// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \
+// RUN:   c-index-test -cursor-at=%S/targeted-top.h:11:15 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=PreambleVar  \
+// RUN:    -Xclang -error-on-deserialized-decl=NestedVar1  \
+// RUN:    -Xclang -error-on-deserialized-decl=vector_get_x  \
+// RUN:  | FileCheck %s -check-prefix=TOP-CURSOR1
+
+// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \
+// RUN:   c-index-test -cursor-at=%S/targeted-nested1.h:2:16 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=PreambleVar  \
+// RUN:    -Xclang -error-on-deserialized-decl=TopVar  \
+// RUN:  | FileCheck %s -check-prefix=NESTED-CURSOR1
+
+// RUN: env CINDEXTEST_FAILONERROR=1 CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_NO_CACHING=1 \
+// RUN:   c-index-test -cursor-at=%S/targeted-preamble.h:2:15 %s -include %t.h \
+// RUN:    -Xclang -error-on-deserialized-decl=NestedVar1  \
+// RUN:    -Xclang -error-on-deserialized-decl=TopVar  \
+// RUN:  | FileCheck %s -check-prefix=PREAMBLE-CURSOR1
+
+// LOCAL-CURSOR1: VarDecl=LocalVar1:5:5
+// TOP-CURSOR1: VarDecl=TopVar:11:12
+// NESTED-CURSOR1: VarDecl=NestedVar1:2:12
+// PREAMBLE-CURSOR1: VarDecl=PreambleVar:2:12

Added: cfe/trunk/test/Index/targeted-fields.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/targeted-fields.h?rev=143605&view=auto
==============================================================================
--- cfe/trunk/test/Index/targeted-fields.h (added)
+++ cfe/trunk/test/Index/targeted-fields.h Wed Nov  2 21:20:32 2011
@@ -0,0 +1,3 @@
+
+  int z;
+  int w;

Added: cfe/trunk/test/Index/targeted-nested1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/targeted-nested1.h?rev=143605&view=auto
==============================================================================
--- cfe/trunk/test/Index/targeted-nested1.h (added)
+++ cfe/trunk/test/Index/targeted-nested1.h Wed Nov  2 21:20:32 2011
@@ -0,0 +1,2 @@
+
+extern int NestedVar1;

Added: cfe/trunk/test/Index/targeted-preamble.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/targeted-preamble.h?rev=143605&view=auto
==============================================================================
--- cfe/trunk/test/Index/targeted-preamble.h (added)
+++ cfe/trunk/test/Index/targeted-preamble.h Wed Nov  2 21:20:32 2011
@@ -0,0 +1,2 @@
+
+extern int PreambleVar;

Added: cfe/trunk/test/Index/targeted-top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/targeted-top.h?rev=143605&view=auto
==============================================================================
--- cfe/trunk/test/Index/targeted-top.h (added)
+++ cfe/trunk/test/Index/targeted-top.h Wed Nov  2 21:20:32 2011
@@ -0,0 +1,24 @@
+
+#ifndef TARGETED_TOP_H
+#define TARGETED_TOP_H
+
+#include "targeted-nested1.h"
+
+enum {
+  VALUE = 3
+};
+
+extern int TopVar;
+
+typedef struct {
+  int x;
+  int y;
+#include "targeted-fields.h"
+} Vector;
+
+static inline int vector_get_x(Vector v) {
+  int x = v.x;
+  return x;
+}
+
+#endif

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=143605&r1=143604&r2=143605&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Nov  2 21:20:32 2011
@@ -219,6 +219,12 @@
   /// \param R a half-open source range retrieved from the abstract syntax tree.
   RangeComparisonResult CompareRegionOfInterest(SourceRange R);
 
+  CXChildVisitResult invokeVisitor(CXCursor cursor, CXCursor parent) {
+    return Visitor(cursor, parent, ClientData);
+  }
+
+  void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
+
   class SetParentRAII {
     CXCursor &Parent;
     Decl *&StmtParent;
@@ -271,6 +277,10 @@
   CXTranslationUnit getTU() const { return TU; }
 
   bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
+
+  /// \brief Visit declarations and preprocessed entities for the file region
+  /// designated by \see RegionOfInterest.
+  void visitFileRegion();
   
   bool visitPreprocessedEntitiesInRegion();
 
@@ -431,6 +441,139 @@
                                            PPRec, FID);
 }
 
+void CursorVisitor::visitFileRegion() {
+  if (RegionOfInterest.isInvalid())
+    return;
+
+  ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+  SourceManager &SM = Unit->getSourceManager();
+  
+  std::pair<FileID, unsigned>
+    Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())), 
+    End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd())); 
+
+  if (End.first != Begin.first) {
+    // If the end does not reside in the same file, try to recover by
+    // picking the end of the file of begin location.
+    End.first = Begin.first;
+    End.second = SM.getFileIDSize(Begin.first);
+  }
+
+  assert(Begin.first == End.first);
+  if (Begin.second > End.second)
+    return;
+  
+  FileID File = Begin.first;
+  unsigned Offset = Begin.second;
+  unsigned Length = End.second - Begin.second;
+
+  if (!VisitPreprocessorLast &&
+      Unit->getPreprocessor().getPreprocessingRecord())
+    visitPreprocessedEntitiesInRegion();
+
+  visitDeclsFromFileRegion(File, Offset, Length);
+
+  if (VisitPreprocessorLast &&
+      Unit->getPreprocessor().getPreprocessingRecord())
+    visitPreprocessedEntitiesInRegion();
+}
+
+void CursorVisitor::visitDeclsFromFileRegion(FileID File,
+                                             unsigned Offset, unsigned Length) {
+  ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+  SourceManager &SM = Unit->getSourceManager();
+
+  SourceRange Range = RegionOfInterest;
+  CXCursor Parent = clang_getTranslationUnitCursor(TU);
+
+  SmallVector<Decl *, 16> Decls;
+  Unit->findFileRegionDecls(File, Offset, Length, Decls);
+
+  // If we didn't find any file level decls for the file, try looking at the
+  // file that it was included from.
+  while (Decls.empty()) {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
+    if (Invalid)
+      return;
+
+    SourceLocation Outer;
+    if (SLEntry.isFile())
+      Outer = SLEntry.getFile().getIncludeLoc();
+    else
+      Outer = SLEntry.getExpansion().getExpansionLocStart();
+    if (Outer.isInvalid())
+      return;
+
+    llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
+    Length = 0;
+    Unit->findFileRegionDecls(File, Offset, Length, Decls);
+  }
+
+  assert(!Decls.empty());
+
+  bool VisitedAtLeastOnce = false;
+  SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
+  for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
+    Decl *D = *DIt;
+
+    // We handle forward decls via ObjCClassDecl.
+    if (ObjCInterfaceDecl *InterD = dyn_cast<ObjCInterfaceDecl>(D)) {
+      if (InterD->isForwardDecl())
+        continue;
+      // An interface that started as a forward decl may have changed location
+      // because its @interface was parsed.
+      if (InterD->isInitiallyForwardDecl() &&
+          !SM.isInFileID(SM.getFileLoc(InterD->getLocation()), File))
+        continue;
+    }
+
+    RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
+    if (CompRes == RangeBefore)
+      continue;
+    if (CompRes == RangeAfter)
+      break;
+
+    assert(CompRes == RangeOverlap);
+    VisitedAtLeastOnce = true;
+    CXCursor C = MakeCXCursor(D, TU, Range);
+    CXChildVisitResult
+      Res = invokeVisitor(C, Parent);
+    if (Res == CXChildVisit_Break)
+      break;
+    if (Res == CXChildVisit_Recurse)
+      if (VisitChildren(C))
+        break;
+  }
+
+  if (VisitedAtLeastOnce)
+    return;
+
+  // No Decls overlapped with the range. Move up the lexical context until there
+  // is a context that contains the range or we reach the translation unit
+  // level.
+  DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
+                                         : (*(DIt-1))->getLexicalDeclContext();
+
+  while (DC && !DC->isTranslationUnit()) {
+    Decl *D = cast<Decl>(DC);
+    SourceRange CurDeclRange = D->getSourceRange();
+    if (CurDeclRange.isInvalid())
+      break;
+
+    if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
+      CXCursor C = MakeCXCursor(D, TU, Range);
+      CXChildVisitResult
+        Res = invokeVisitor(C, Parent);
+      if (Res == CXChildVisit_Recurse)
+        VisitChildren(C);
+      break;
+    }
+
+    DC = D->getLexicalDeclContext();
+  }
+}
+
 bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
   PreprocessingRecord &PPRec
     = *AU->getPreprocessor().getPreprocessingRecord();
@@ -3741,16 +3884,12 @@
   
   CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
   if (SLoc.isValid()) {
-    // FIXME: Would be great to have a "hint" cursor, then walk from that
-    // hint cursor upward until we find a cursor whose source range encloses
-    // the region of interest, rather than starting from the translation unit.
     GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
-    CXCursor Parent = clang_getTranslationUnitCursor(TU);
     CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
                             /*VisitPreprocessorLast=*/true, 
                             /*VisitIncludedEntities=*/false,
                             SourceLocation(SLoc));
-    CursorVis.VisitChildren(Parent);
+    CursorVis.visitFileRegion();
   }
 
   return Result;





More information about the cfe-commits mailing list