aboutsummaryrefslogtreecommitdiff
path: root/tools/libclang/CIndexHigh.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang/CIndexHigh.cpp')
-rw-r--r--tools/libclang/CIndexHigh.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index 7e12386841..6af55e8eb7 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -337,6 +337,72 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
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 cursor, CXFile file,
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(CXCursor cursor,
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"