Patch LGTM, thanks for it! ~Aaron
On Sun, Mar 10, 2013 at 8:55 AM, Benyei, Guy <[email protected]> wrote: > 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: [email protected] > [mailto:[email protected]] On Behalf Of Argyrios Kyrtzidis > Sent: Friday, March 08, 2013 04:33 > To: [email protected] > 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 > [email protected] > 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. > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
