зеркало из https://github.com/microsoft/clang.git
Implement 'clang_getInclusions()' in CIndex. This API allows clients to walk the set of files included in a translation unit via the C API.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94575 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
46766dc31c
Коммит
16b55a7169
|
@ -1402,6 +1402,38 @@ void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);
|
|||
*/
|
||||
CINDEX_LINKAGE const char *clang_getClangVersion();
|
||||
|
||||
/**
|
||||
* \brief Return a version string, suitable for showing to a user, but not
|
||||
* intended to be parsed (the format is not guaranteed to be stable).
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Visitor invoked for each file in a translation unit
|
||||
* (used with clang_getInclusions()).
|
||||
*
|
||||
* This visitor function will be invoked by clang_getInclusions() for each
|
||||
* file included (either at the top-level or by #include directives) within
|
||||
* a translation unit. The first argument is the file being included, and
|
||||
* the second and third arguments provide the inclusion stack. The
|
||||
* array is sorted in order of immediate inclusion. For example,
|
||||
* the first element refers to the location that included 'included_file'.
|
||||
*/
|
||||
typedef void (*CXInclusionVisitor)(CXFile included_file,
|
||||
CXSourceLocation* inclusion_stack,
|
||||
unsigned include_len,
|
||||
CXClientData client_data);
|
||||
|
||||
/**
|
||||
* \brief Visit the set of preprocessor inclusions in a translation unit.
|
||||
* The visitor function is called with the provided data for every included
|
||||
* file. This does not include headers included by the PCH file (unless one
|
||||
* is inspecting the inclusions in the PCH file itself).
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
|
||||
CXInclusionVisitor visitor,
|
||||
CXClientData client_data);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -675,6 +675,11 @@ public:
|
|||
void PrintStats() const;
|
||||
|
||||
unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
|
||||
|
||||
// FIXME: Exposing this is a little gross; what we want is a good way
|
||||
// to iterate the entries that were not defined in a PCH file (or
|
||||
// any other external source).
|
||||
unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
|
||||
|
||||
const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
|
||||
assert(ID < SLocEntryTable.size() && "Invalid id");
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// RUN: c-index-test -test-inclusion-stack-source %s 2>&1 | FileCheck %s
|
||||
|
||||
#include "include_test.h"
|
||||
|
||||
// CHECK: cindex-test-inclusions.c
|
||||
// CHECK: included by:
|
||||
// CHECK: include_test.h
|
||||
// CHECK: included by:
|
||||
// CHECK: cindex-test-inclusions.c:3:10
|
||||
// CHECK: include_test_2.h
|
||||
// CHECK: included by:
|
||||
// CHECK: include_test.h:1:10
|
||||
// CHECK: cindex-test-inclusions.c:3:10
|
|
@ -0,0 +1 @@
|
|||
#include "include_test_2.h"
|
|
@ -28,6 +28,7 @@ _clang_getDefinitionSpellingAndExtent
|
|||
_clang_getFile
|
||||
_clang_getFileName
|
||||
_clang_getFileTime
|
||||
_clang_getInclusions
|
||||
_clang_getInstantiationLocation
|
||||
_clang_getLocation
|
||||
_clang_getNullCursor
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a callback mechanism for clients to get the inclusion
|
||||
// stack from a translation unit.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CIndexer.h"
|
||||
#include "CXSourceLocation.h"
|
||||
#include "clang/AST/DeclVisitor.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
extern "C" {
|
||||
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
|
||||
CXClientData clientData) {
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
SourceManager &SM = CXXUnit->getSourceManager();
|
||||
ASTContext &Ctx = CXXUnit->getASTContext();
|
||||
|
||||
llvm::SmallVector<CXSourceLocation, 10> InclusionStack;
|
||||
unsigned i = SM.sloc_loaded_entry_size();
|
||||
unsigned n = SM.sloc_entry_size();
|
||||
|
||||
// In the case where all the SLocEntries are in an external source, traverse
|
||||
// those SLocEntries as well. This is the case where we are looking
|
||||
// at the inclusion stack of an AST/PCH file.
|
||||
if (i >= n)
|
||||
i = 0;
|
||||
|
||||
for ( ; i < n ; ++i) {
|
||||
|
||||
const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i);
|
||||
|
||||
if (!SL.isFile())
|
||||
continue;
|
||||
|
||||
const SrcMgr::FileInfo &FI = SL.getFile();
|
||||
if (!FI.getContentCache()->Entry)
|
||||
continue;
|
||||
|
||||
// Build the inclusion stack.
|
||||
SourceLocation L = FI.getIncludeLoc();
|
||||
InclusionStack.clear();
|
||||
while (L.isValid()) {
|
||||
PresumedLoc PLoc = SM.getPresumedLoc(L);
|
||||
InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));
|
||||
L = PLoc.getIncludeLoc();
|
||||
}
|
||||
|
||||
// Callback to the client.
|
||||
// FIXME: We should have a function to construct CXFiles.
|
||||
CB((CXFile) FI.getContentCache()->Entry,
|
||||
InclusionStack.data(), InclusionStack.size(), clientData);
|
||||
}
|
||||
}
|
||||
} // end extern C
|
|
@ -21,6 +21,7 @@ set( LLVM_LINK_COMPONENTS
|
|||
add_clang_library(CIndex
|
||||
CIndex.cpp
|
||||
CIndexCodeCompletion.cpp
|
||||
CIndexInclusionStack.cpp
|
||||
CIndexUSRs.cpp
|
||||
CIndexer.cpp
|
||||
CXCursor.cpp
|
||||
|
|
|
@ -302,6 +302,29 @@ enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent,
|
|||
return CXChildVisit_Continue;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Inclusion stack testing. */
|
||||
/******************************************************************************/
|
||||
|
||||
void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack,
|
||||
unsigned includeStackLen, CXClientData data) {
|
||||
|
||||
unsigned i;
|
||||
printf("file: %s\nincluded by:\n", clang_getFileName(includedFile));
|
||||
for (i = 0; i < includeStackLen; ++i) {
|
||||
CXFile includingFile;
|
||||
unsigned line, column;
|
||||
clang_getInstantiationLocation(includeStack[i], &includingFile, &line,
|
||||
&column, 0);
|
||||
printf(" %s:%d:%d\n", clang_getFileName(includingFile), line, column);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void PrintInclusionStack(CXTranslationUnit TU) {
|
||||
clang_getInclusions(TU, InclusionVisitor, NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Loading ASTs/source. */
|
||||
/******************************************************************************/
|
||||
|
@ -853,7 +876,9 @@ static void print_usage(void) {
|
|||
" c-index-test -test-load-source <symbol filter> {<args>}*\n"
|
||||
" c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n");
|
||||
fprintf(stderr,
|
||||
" c-index-test -test-annotate-tokens=<range> {<args>}* \n\n"
|
||||
" c-index-test -test-annotate-tokens=<range> {<args>}*\n"
|
||||
" c-index-test -test-inclusion-stack-source {<args>}*\n"
|
||||
" c-index-test -test-inclusion-stack-tu <AST file>\n\n"
|
||||
" <symbol filter> values:\n%s",
|
||||
" all - load all symbols, including those from PCH\n"
|
||||
" local - load all symbols except those in PCH\n"
|
||||
|
@ -886,6 +911,13 @@ int main(int argc, const char **argv) {
|
|||
argc >= 5 ? argv[4] : 0);
|
||||
else if (argc > 2 && strstr(argv[1], "-test-annotate-tokens=") == argv[1])
|
||||
return perform_token_annotation(argc, argv);
|
||||
else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-source") == 0)
|
||||
return perform_test_load_source(argc - 2, argv + 2, "all", NULL,
|
||||
PrintInclusionStack);
|
||||
else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0)
|
||||
return perform_test_load_tu(argv[2], "all", NULL, NULL,
|
||||
PrintInclusionStack);
|
||||
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче