Switch clang_createTranslationUnitFromSourceFile to use ASTUnit::LoadFromCommandLine.

- This is much faster, as it avoids the overhead of dumping an AST file to disk and reloading it.
 - For debugging purposes, there is a clang_setUseExternalASTGeneration hook which can be used to disable this.

On the Sketch Cocoa app, the speedup is pretty nice, especially when using a PCH file while scanning the source:

Wall time to c-index-test all files (no PCH):
Old: 23.4221
New: 12.3884

Wall time to c-index-test all files (with a PCH, and "local" mode):
Old: 10.9233
New:  1.9038

llvm-svn: 90385
This commit is contained in:
Daniel Dunbar 2009-12-03 01:54:28 +00:00
parent aba7d48764
commit 1108966959
4 changed files with 87 additions and 20 deletions

View File

@ -202,8 +202,22 @@ CINDEX_LINKAGE void clang_disposeString(CXString string);
*/
CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
int displayDiagnostics);
CINDEX_LINKAGE void clang_disposeIndex(CXIndex);
CINDEX_LINKAGE CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
CINDEX_LINKAGE void clang_disposeIndex(CXIndex index);
CINDEX_LINKAGE CXString
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
/*
* \brief Request that AST's be generated external for API calls which parse
* source code on the fly, e.g. \see createTranslationUnitFromSourceFile.
*
* Note: This is for debugging purposes only, and may be removed at a later
* date.
*
* \param index - The index to update.
* \param value - The new flag value.
*/
CINDEX_LINKAGE void clang_setUseExternalASTGeneration(CXIndex index,
int value);
/*
* \brief Create a translation unit from an AST file (-emit-ast).
@ -211,6 +225,7 @@ CINDEX_LINKAGE CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUni
CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
CXIndex, const char *ast_filename
);
/**
* \brief Destroy the specified CXTranslationUnit object.
*/
@ -220,20 +235,25 @@ CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
* \brief Return the CXTranslationUnit for a given source file and the provided
* command line arguments one would pass to the compiler.
*
* Note: The 'source_filename' argument is optional. If the caller provides a NULL pointer,
* the name of the source file is expected to reside in the specified command line arguments.
* Note: The 'source_filename' argument is optional. If the caller provides a
* NULL pointer, the name of the source file is expected to reside in the
* specified command line arguments.
*
* Note: When encountered in 'clang_command_line_args', the following options are ignored:
* Note: When encountered in 'clang_command_line_args', the following options
* are ignored:
*
* '-c'
* '-emit-ast'
* '-fsyntax-only'
* '-o <output file>' (both '-o' and '<output file>' are ignored)
*
*
* \param source_filename - The name of the source file to load, or NULL if the
* source file is included in clang_command_line_args.
*/
CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
CXIndex CIdx,
const char *source_filename /* specify NULL if the source file is in clang_command_line_args */,
CXIndex CIdx,
const char *source_filename,
int num_clang_command_line_args,
const char **clang_command_line_args
);
@ -253,13 +273,14 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
}
static void usage {
clang_loadTranslationUnit(CXTranslationUnit, printObjCInterfaceNames);
}
}
*/
typedef void *CXClientData;
typedef void (*CXTranslationUnitIterator)(CXTranslationUnit, CXCursor,
CXClientData);
CINDEX_LINKAGE void clang_loadTranslationUnit(CXTranslationUnit, CXTranslationUnitIterator,
CXClientData);
CINDEX_LINKAGE void clang_loadTranslationUnit(CXTranslationUnit,
CXTranslationUnitIterator,
CXClientData);
/*
Usage: clang_loadDeclaration(). Will load the declaration, issuing a
@ -320,8 +341,9 @@ CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl);
Usage: clang_getCursor() will translate a source/line/column position
into an AST cursor (to derive semantic information from the source code).
*/
CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
unsigned line, unsigned column);
CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit,
const char *source_name,
unsigned line, unsigned column);
CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
@ -634,11 +656,11 @@ clang_getNumCompletionChunks(CXCompletionString completion_string);
* \param CIdx the \c CXIndex instance that will be used to perform code
* completion.
*
* \param source_filename the name of the source file that should be parsed
* to perform code-completion. This source file must be the same as or
* include the filename described by \p complete_filename, or no code-completion
* results will be produced. NOTE: One can also specify NULL for this argument if
* the source file is included in command_line_args.
* \param source_filename the name of the source file that should be parsed to
* perform code-completion. This source file must be the same as or include the
* filename described by \p complete_filename, or no code-completion results
* will be produced. NOTE: One can also specify NULL for this argument if the
* source file is included in command_line_args.
*
* \param num_command_line_args the number of command-line arguments stored in
* \p command_line_args.

View File

@ -324,6 +324,11 @@ public:
DisplayDiagnostics = Display;
}
bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; }
void setUseExternalASTGeneration(bool Value) {
UseExternalASTGeneration = Value;
}
Diagnostic &getDiags() {
return DisplayDiagnostics ? *TextDiags : IgnoreDiags;
}
@ -466,6 +471,12 @@ void clang_disposeIndex(CXIndex CIdx) {
delete static_cast<CIndexer *>(CIdx);
}
void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) {
assert(CIdx && "Passed null CXIndex");
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
CXXIdx->setUseExternalASTGeneration(value);
}
// FIXME: need to pass back error info.
CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
const char *ast_filename) {
@ -485,6 +496,24 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
assert(CIdx && "Passed null CXIndex");
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
if (!CXXIdx->getUseExternalASTGeneration()) {
llvm::SmallVector<const char *, 16> Args;
// The 'source_filename' argument is optional. If the caller does not
// specify it then it is assumed that the source file is specified
// in the actual argument list.
if (source_filename)
Args.push_back(source_filename);
Args.insert(Args.end(), command_line_args,
command_line_args + num_command_line_args);
void *MainAddr = (void *)(uintptr_t)clang_createTranslationUnit;
return ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
CXXIdx->getDiags(), "<clang>", MainAddr,
CXXIdx->getOnlyLocalDecls(),
/* UseBumpAllocator = */ true);
}
// Build up the arguments for invoking 'clang'.
std::vector<const char *> argv;
@ -572,8 +601,18 @@ void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
ASTContext &Ctx = CXXUnit->getASTContext();
TUVisitor DVisit(CTUnit, callback, CData,
CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel);
unsigned PCHLevel = Decl::MaxPCHLevel;
// Set the PCHLevel to filter out unwanted decls if requested.
if (CXXUnit->getOnlyLocalDecls()) {
PCHLevel = 0;
// If the main input was an AST, bump the level.
if (CXXUnit->isMainFileAST())
++PCHLevel;
}
TUVisitor DVisit(CTUnit, callback, CData, PCHLevel);
DVisit.Visit(Ctx.getTranslationUnitDecl());
}

View File

@ -6,6 +6,7 @@ _clang_disposeIndex
_clang_disposeString
_clang_disposeTranslationUnit
_clang_equalCursors
_clang_getCString
_clang_getCompletionChunkCompletionString
_clang_getCompletionChunkKind
_clang_getCompletionChunkText
@ -19,7 +20,6 @@ _clang_getCursorLine
_clang_getCursorSource
_clang_getCursorSourceFile
_clang_getCursorSpelling
_clang_getCString
_clang_getDeclColumn
_clang_getDeclLine
_clang_getDeclSource
@ -41,3 +41,4 @@ _clang_isInvalid
_clang_isReference
_clang_loadDeclaration
_clang_loadTranslationUnit
_clang_setUseExternalASTGeneration

View File

@ -179,12 +179,17 @@ int perform_test_load_tu(const char *file, const char *filter) {
}
int perform_test_load_source(int argc, const char **argv, const char *filter) {
const char *UseExternalASTs =
getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");
CXIndex Idx;
CXTranslationUnit TU;
Idx = clang_createIndex(/* excludeDeclsFromPCH */
!strcmp(filter, "local") ? 1 : 0,
/* displayDiagnostics */ 1);
if (UseExternalASTs && strlen(UseExternalASTs))
clang_setUseExternalASTGeneration(Idx, 1);
TU = clang_createTranslationUnitFromSourceFile(Idx, 0, argc, argv);
if (!TU) {
fprintf(stderr, "Unable to load translation unit!\n");