r176682 - [libclang] Introduce clang_findIncludesInFile, that can be used to retrieve all #import/#include directives in a specific file.

Benyei, Guy guy.benyei at intel.com
Sun Mar 10 05:55:56 PDT 2013


Hi Argyrios,
The file-includes test you've added fails in Windows, since it doesn't expect backslash characters in the paths. Also, the freeing of a 'const char **' in c-index-test.c triggers a warning in windows.
Attached a fix for both issues - please review.

Thanks
    Guy


-----Original Message-----
From: cfe-commits-bounces at cs.uiuc.edu [mailto:cfe-commits-bounces at cs.uiuc.edu] On Behalf Of Argyrios Kyrtzidis
Sent: Friday, March 08, 2013 04:33
To: cfe-commits at cs.uiuc.edu
Subject: r176682 - [libclang] Introduce clang_findIncludesInFile, that can be used to retrieve all #import/#include directives in a specific file.

Author: akirtzidis
Date: Thu Mar  7 20:32:34 2013
New Revision: 176682

URL: http://llvm.org/viewvc/llvm-project?rev=176682&view=rev
Log:
[libclang] Introduce clang_findIncludesInFile, that can be used to retrieve all #import/#include directives in a specific file.

It passes to the visitor, that the caller provides, CXCursor_InclusionDirective cursors for all the include directives in a particular file.

Added:
    cfe/trunk/test/Index/file-includes.c
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndexHigh.cpp
    cfe/trunk/tools/libclang/libclang.exports

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=176682&r1=176681&r2=176682&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Thu Mar  7 20:32:34 2013
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 12
+#define CINDEX_VERSION_MINOR 13
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
       ((major) * 10000)                       \
@@ -5021,6 +5021,19 @@ typedef struct {
 CINDEX_LINKAGE void clang_findReferencesInFile(CXCursor cursor, CXFile file,
                                                CXCursorAndRangeVisitor visitor);
 
+/**
+ * \brief Find #import/#include directives in a specific file.
+ *
+ * \param TU translation unit containing the file to query.
+ *
+ * \param file to search for #import/#include directives.
+ *
+ * \param visitor callback that will receive pairs of 
+CXCursor/CXSourceRange for
+ * each directive found.
+ */
+CINDEX_LINKAGE void clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
+                                             CXCursorAndRangeVisitor 
+visitor);
+
 #ifdef __has_feature
 #  if __has_feature(blocks)
 
@@ -5031,6 +5044,10 @@ CINDEX_LINKAGE
 void clang_findReferencesInFileWithBlock(CXCursor, CXFile,
                                          CXCursorAndRangeVisitorBlock);
 
+CINDEX_LINKAGE
+void clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile,
+                                       CXCursorAndRangeVisitorBlock);
+
 #  endif
 #endif
 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=176682&r1=176681&r2=176682&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Mar  7 20:32:34 2013
@@ -4000,7 +4000,7 @@ ASTReader::findBeginPreprocessedEntity(S
 
   GlobalSLocOffsetMapType::const_iterator
     SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
-                                        BLoc.getOffset());
+                                        BLoc.getOffset() - 1);
   assert(SLocMapI != GlobalSLocOffsetMap.end() &&
          "Corrupted global sloc offset map");
 
@@ -4048,7 +4048,7 @@ ASTReader::findEndPreprocessedEntity(Sou
 
   GlobalSLocOffsetMapType::const_iterator
     SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
-                                        ELoc.getOffset());
+                                        ELoc.getOffset() - 1);
   assert(SLocMapI != GlobalSLocOffsetMap.end() &&
          "Corrupted global sloc offset map");
 

Added: cfe/trunk/test/Index/file-includes.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/file-includes.c?rev=176682&view=auto
==============================================================================
--- cfe/trunk/test/Index/file-includes.c (added)
+++ cfe/trunk/test/Index/file-includes.c Thu Mar  7 20:32:34 2013
@@ -0,0 +1,24 @@
+
+#include "targeted-top.h"
+#include "targeted-preamble.h"
+
+extern int LocalVar;
+int LocalVar;
+
+// RUN: c-index-test -write-pch %t.h.pch %S/targeted-top.h -Xclang 
+-detailed-preprocessing-record
+
+// RUN: c-index-test -file-includes-in=%s %s | FileCheck %s 
+-check-prefix=LOCAL // RUN: env CINDEXTEST_EDITING=1 c-index-test 
+-file-includes-in=%s %s | FileCheck %s -check-prefix=LOCAL // RUN: 
+c-index-test -file-includes-in=%s %s -include %t.h | FileCheck %s 
+-check-prefix=LOCAL // RUN: env CINDEXTEST_EDITING=1 c-index-test 
+-file-includes-in=%s %s -include %t.h | FileCheck %s 
+-check-prefix=LOCAL
+
+// LOCAL: inclusion directive=targeted-top.h 
+({{.*}}/test/Index/targeted-top.h) {{.*}}=[2:1 - 2:2] // LOCAL: 
+inclusion directive=targeted-preamble.h 
+({{.*}}/test/Index/targeted-preamble.h) =[3:1 - 3:2]
+
+// RUN: c-index-test -file-includes-in=%S/targeted-top.h %s | FileCheck 
+%s -check-prefix=TOP // RUN: env CINDEXTEST_EDITING=1 c-index-test 
+-file-includes-in=%S/targeted-top.h %s | FileCheck %s -check-prefix=TOP 
+// RUN: c-index-test -file-includes-in=%S/targeted-top.h %s -include 
+%t.h | FileCheck %s -check-prefix=TOP // RUN: env CINDEXTEST_EDITING=1 
+c-index-test -file-includes-in=%S/targeted-top.h %s -include %t.h | 
+FileCheck %s -check-prefix=TOP
+
+// TOP: inclusion directive=targeted-nested1.h 
+({{.*}}/test/Index/targeted-nested1.h) =[5:1 - 5:2] // TOP: inclusion 
+directive=targeted-fields.h ({{.*}}/test/Index/targeted-fields.h) 
+=[16:1 - 16:2]

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=176682&r1=176681&r2=176682&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Mar  7 20:32:34 2013
@@ -2135,6 +2135,99 @@ static int find_file_refs_at(int argc, c
   return 0;
 }
 
+static enum CXVisitorResult findFileIncludesVisit(void *context,
+                                         CXCursor cursor, CXSourceRange 
+range) {
+  PrintCursor(cursor, NULL);
+  PrintRange(range, "");
+  printf("\n");
+  return CXVisit_Continue;
+}
+
+static int find_file_includes_in(int argc, const char **argv) {
+  CXIndex CIdx;
+  struct CXUnsavedFile *unsaved_files = 0;
+  int num_unsaved_files = 0;
+  CXTranslationUnit TU;
+  const char **Filenames = 0;
+  unsigned NumFilenames = 0;
+  unsigned Repeats = 1;
+  unsigned I, FI;
+
+  /* Count the number of locations. */
+  while (strstr(argv[NumFilenames+1], "-file-includes-in=") == argv[NumFilenames+1])
+    ++NumFilenames;
+
+  /* Parse the locations. */
+  assert(NumFilenames > 0 && "Unable to count filenames?");  Filenames 
+ = (const char **)malloc(NumFilenames * sizeof(const char *));  for (I 
+ = 0; I < NumFilenames; ++I) {
+    const char *input = argv[I + 1] + strlen("-file-includes-in=");
+    /* Copy the file name. */
+    Filenames[I] = input;
+  }
+
+  if (parse_remapped_files(argc, argv, NumFilenames + 1, &unsaved_files,
+                           &num_unsaved_files))
+    return -1;
+
+  if (getenv("CINDEXTEST_EDITING"))
+    Repeats = 2;
+
+  /* Parse the translation unit. When we're testing clang_getCursor() after
+     reparsing, don't remap unsaved files until the second parse. */  
+ CIdx = clang_createIndex(1, 1);  TU = clang_parseTranslationUnit(CIdx, 
+ argv[argc - 1],
+                                  argv + num_unsaved_files + 1 + NumFilenames,
+                                  argc - num_unsaved_files - 2 - NumFilenames,
+                                  unsaved_files,
+                                  Repeats > 1? 0 : num_unsaved_files,
+                                  getDefaultParsingOptions());
+
+  if (!TU) {
+    fprintf(stderr, "unable to parse input\n");
+    return -1;
+  }
+
+  if (checkForErrors(TU) != 0)
+    return -1;
+
+  for (I = 0; I != Repeats; ++I) {
+    if (Repeats > 1 &&
+        clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+                                     clang_defaultReparseOptions(TU))) {
+      clang_disposeTranslationUnit(TU);
+      return 1;
+    }
+
+    if (checkForErrors(TU) != 0)
+      return -1;
+
+    for (FI = 0; FI < NumFilenames; ++FI) {
+      CXFile file = clang_getFile(TU, Filenames[FI]);
+      if (!file)
+        continue;
+
+      if (checkForErrors(TU) != 0)
+        return -1;
+
+      if (I + 1 == Repeats) {
+        CXCursorAndRangeVisitor visitor = { 0, findFileIncludesVisit };
+        clang_findIncludesInFile(TU, file, visitor);
+
+        if (checkForErrors(TU) != 0)
+          return -1;
+      }
+    }
+  }
+
+  PrintDiagnostics(TU);
+  clang_disposeTranslationUnit(TU);
+  clang_disposeIndex(CIdx);
+  free(Filenames);
+  free_remapped_files(unsaved_files, num_unsaved_files);
+  return 0;
+}
+
 #define MAX_IMPORTED_ASTFILES 200
 
 typedef struct {
@@ -3520,7 +3613,8 @@ static void print_usage(void) {
     "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
     "       c-index-test -code-completion-timing=<site> <compiler arguments>\n"
     "       c-index-test -cursor-at=<site> <compiler arguments>\n"
-    "       c-index-test -file-refs-at=<site> <compiler arguments>\n");
+    "       c-index-test -file-refs-at=<site> <compiler arguments>\n"
+    "       c-index-test -file-includes-in=<filename> <compiler arguments>\n");
   fprintf(stderr,
     "       c-index-test -index-file [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
     "       c-index-test -index-file-full [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
@@ -3582,6 +3676,8 @@ int cindextest_main(int argc, const char
     return inspect_cursor_at(argc, argv);
   if (argc > 2 && strstr(argv[1], "-file-refs-at=") == argv[1])
     return find_file_refs_at(argc, argv);
+  if (argc > 2 && strstr(argv[1], "-file-includes-in=") == argv[1])
+    return find_file_includes_in(argc, argv);
   if (argc > 2 && strcmp(argv[1], "-index-file") == 0)
     return index_file(argc - 2, argv + 2, /*full=*/0);
   if (argc > 2 && strcmp(argv[1], "-index-file-full") == 0)

Modified: cfe/trunk/tools/libclang/CIndexHigh.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexHigh.cpp?rev=176682&r1=176681&r2=176682&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexHigh.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexHigh.cpp Thu Mar  7 20:32:34 2013
@@ -337,6 +337,72 @@ static void findMacroRefsInFile(CXTransl
   FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion();
 }
 
+namespace {
+
+struct FindFileIncludesVisitor {
+  ASTUnit &Unit;
+  const FileEntry *File;
+  CXCursorAndRangeVisitor visitor;
+
+  FindFileIncludesVisitor(ASTUnit &Unit, const FileEntry *File,
+                          CXCursorAndRangeVisitor visitor)
+    : Unit(Unit), File(File), visitor(visitor) { }
+
+  ASTContext &getASTContext() const {
+    return Unit.getASTContext();
+  }
+
+  enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
+    if (cursor.kind != CXCursor_InclusionDirective)
+      return CXChildVisit_Continue;
+
+    SourceLocation
+      Loc = 
+ cxloc::translateSourceLocation(clang_getCursorLocation(cursor));
+
+    ASTContext &Ctx = getASTContext();
+    SourceManager &SM = Ctx.getSourceManager();
+
+    // We are looking for includes in a specific file.
+    std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+    if (SM.getFileEntryForID(LocInfo.first) != File)
+      return CXChildVisit_Continue;
+
+    if (visitor.visit(visitor.context, cursor,
+                      cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+      return CXChildVisit_Break;
+    return CXChildVisit_Continue;
+  }
+
+  static enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent,
+                                       CXClientData client_data) {
+    return static_cast<FindFileIncludesVisitor*>(client_data)->
+                                                          visit(cursor, 
+parent);
+  }
+};
+
+} // anonymous namespace
+
+static void findIncludesInFile(CXTranslationUnit TU, const FileEntry *File,
+                               CXCursorAndRangeVisitor Visitor) {
+  assert(TU && File && Visitor.visit);
+
+  ASTUnit *Unit = cxtu::getASTUnit(TU);  SourceManager &SM = 
+ Unit->getSourceManager();
+
+  FileID FID = SM.translateFile(File);
+
+  FindFileIncludesVisitor IncludesVisitor(*Unit, File, Visitor);
+
+  SourceRange Range(SM.getLocForStartOfFile(FID), 
+SM.getLocForEndOfFile(FID));
+  CursorVisitor InclusionCursorsVisitor(TU,
+                                        FindFileIncludesVisitor::visit,
+                                        &IncludesVisitor,
+                                        /*VisitPreprocessorLast=*/false,
+                                        /*VisitIncludedEntities=*/false,
+                                        Range);
+  InclusionCursorsVisitor.visitPreprocessedEntitiesInRegion();
+}
+
 
 //===----------------------------------------------------------------------===//
 // libclang public APIs.
@@ -410,6 +476,38 @@ void clang_findReferencesInFile(CXCursor
                    visitor);
 }
 
+void clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
+                              CXCursorAndRangeVisitor visitor) {
+  LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
+
+  if (!TU) {
+    if (Log)
+      *Log << "Null CXTranslationUnit";
+    return;
+  }
+  if (!file) {
+    if (Log)
+      *Log << "Null file";
+    return;
+  }
+  if (!visitor.visit) {
+    if (Log)
+      *Log << "Null visitor";
+    return;
+  }
+
+  if (Log)
+    *Log << TU << " @" << static_cast<const FileEntry *>(file);
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);  if (!CXXUnit)
+    return;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  findIncludesInFile(TU, static_cast<const FileEntry *>(file), 
+visitor); }
+
 static enum CXVisitorResult _visitCursorAndRange(void *context,
                                                  CXCursor cursor,
                                                  CXSourceRange range) { @@ -425,5 +523,13 @@ void clang_findReferencesInFileWithBlock
   return clang_findReferencesInFile(cursor, file, visitor);  }
 
+void clang_findIncludesInFileWithBlock(CXTranslationUnit TU,
+                                       CXFile file,
+                                       CXCursorAndRangeVisitorBlock 
+block) {
+  CXCursorAndRangeVisitor visitor = { block,
+                                      block ? _visitCursorAndRange : 0 
+};
+  return clang_findIncludesInFile(TU, file, visitor); }
+
 } // end: extern "C"
 

Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=176682&r1=176681&r2=176682&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Thu Mar  7 20:32:34 2013
@@ -98,6 +98,8 @@ clang_equalLocations
 clang_equalRanges
 clang_equalTypes
 clang_executeOnThread
+clang_findIncludesInFile
+clang_findIncludesInFileWithBlock
 clang_findReferencesInFile
 clang_findReferencesInFileWithBlock
 clang_formatDiagnostic


_______________________________________________
cfe-commits mailing list
cfe-commits at cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cindex_win.patch
Type: application/octet-stream
Size: 2233 bytes
Desc: cindex_win.patch
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130310/cf712b39/attachment.obj>


More information about the cfe-commits mailing list