From: Steve Naroff Date: Tue, 20 Oct 2009 14:46:24 +0000 (+0000) Subject: - Extend clang_createIndex() to support PCH and diagnostic 'filtering'. This seems... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e56b4baeba5097852e04bc41ca2e0396cf729955;p=clang - Extend clang_createIndex() to support PCH and diagnostic 'filtering'. This seems cleaner to me without sacrificing much flexibility. - Remove clang_wantOnlyLocalDeclarations(). - Remove 'displayDiagnostics' arguments to clang_createTranslationUnitFromSourceFile() and clang_createTranslationUnit(). - Have clang_createTranslationUnitFromSourceFile() strip the '-o ' command line arguments if they exist. Document this semantic in the header. Also verify we have a valid ASTUnit before telling it to 'unlinkTemporaryFile()'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84634 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index b9a982ec0c..4f0751da08 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -99,46 +99,52 @@ typedef struct { } CXCursor; /* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ -typedef void *CXEntity; +typedef void *CXEntity; -CXIndex clang_createIndex(); +/** + * \brief clang_createIndex() provides a shared context for creating + * translation units. It provides two options: + * + * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local" + * declarations (when loading any new translation units). A "local" declaration + * is one that belongs in the translation unit itself and not in a precompiled + * header that was used by the translation unit. If zero, all declarations + * will be enumerated. + * + * - displayDiagnostics: when non-zero, diagnostics will be output. If zero, + * diagnostics will be ignored. + */ +CXIndex clang_createIndex(int excludeDeclarationsFromPCH, + int displayDiagnostics); void clang_disposeIndex(CXIndex); const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); +/* + * \brief Create a translation unit from an AST file (-emit-ast). + */ CXTranslationUnit clang_createTranslationUnit( - CXIndex, const char *ast_filename, - int displayDiagnostics + CXIndex, const char *ast_filename ); - /** * \brief Destroy the specified CXTranslationUnit object. */ 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. + * \brief Return the CXTranslationUnit for a given source file and the provided + * command line arguments one would pass to the compiler. + * + * Note: If provided, this routine will strip the '-o ' command + * line arguments. */ CXTranslationUnit clang_createTranslationUnitFromSourceFile( CXIndex CIdx, const char *source_filename, int num_clang_command_line_args, - const char **clang_command_line_args, - int displayDiagnostics + const char **clang_command_line_args ); -/** - * \brief Indicate to Clang that it should only enumerate "local" declarations - * when loading any new translation units. - * - * A "local" declaration is one that belongs in the translation unit itself and - * not in a precompiled header that was used by the translation unit. - * - * FIXME: Remove this hook. - */ -void clang_wantOnlyLocalDeclarations(CXIndex); - /* Usage: clang_loadTranslationUnit(). Will load the toplevel declarations within a translation unit, issuing a 'callback' for each one. diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index db7b9f3934..eff602ff8e 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -282,7 +282,9 @@ public: class CIndexer : public Indexer { public: - explicit CIndexer(Program *prog) : Indexer(*prog), OnlyLocalDecls(false) {} + explicit CIndexer(Program *prog) : Indexer(*prog), + OnlyLocalDecls(false), + DisplayDiagnostics(false) {} virtual ~CIndexer() { delete &getProgram(); } @@ -292,10 +294,17 @@ public: bool getOnlyLocalDecls() const { return OnlyLocalDecls; } void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; } + void setDisplayDiagnostics(bool Display = true) { + DisplayDiagnostics = Display; + } + bool getDisplayDiagnostics() const { return DisplayDiagnostics; } + /// \brief Get the path of the clang binary. const llvm::sys::Path& getClangPath(); private: bool OnlyLocalDecls; + bool DisplayDiagnostics; + llvm::sys::Path ClangPath; }; @@ -337,9 +346,15 @@ const llvm::sys::Path& CIndexer::getClangPath() { extern "C" { -CXIndex clang_createIndex() +CXIndex clang_createIndex(int excludeDeclarationsFromPCH, + int displayDiagnostics) { - return new CIndexer(new Program()); + CIndexer *CIdxr = new CIndexer(new Program()); + if (excludeDeclarationsFromPCH) + CIdxr->setOnlyLocalDecls(); + if (displayDiagnostics) + CIdxr->setDisplayDiagnostics(); + return CIdxr; } void clang_disposeIndex(CXIndex CIdx) @@ -350,16 +365,16 @@ void clang_disposeIndex(CXIndex CIdx) // FIXME: need to pass back error info. CXTranslationUnit clang_createTranslationUnit( - CXIndex CIdx, const char *ast_filename, int displayDiagnostics) + CXIndex CIdx, const char *ast_filename) { assert(CIdx && "Passed null CXIndex"); CIndexer *CXXIdx = static_cast(CIdx); std::string astName(ast_filename); std::string ErrMsg; - DiagnosticClient *diagClient = displayDiagnostics - ? NULL : new IgnoreDiagnosticsClient(); - return ASTUnit::LoadFromPCHFile(astName, &ErrMsg, diagClient, + return ASTUnit::LoadFromPCHFile(astName, &ErrMsg, + CXXIdx->getDisplayDiagnostics() ? + NULL : new IgnoreDiagnosticsClient(), CXXIdx->getOnlyLocalDecls(), /* UseBumpAllocator = */ true); } @@ -367,8 +382,10 @@ CXTranslationUnit clang_createTranslationUnit( CXTranslationUnit clang_createTranslationUnitFromSourceFile( CXIndex CIdx, const char *source_filename, - int num_command_line_args, const char **command_line_args, - int displayDiagnostics) { + int num_command_line_args, const char **command_line_args) { + assert(CIdx && "Passed null CXIndex"); + CIndexer *CXXIdx = static_cast(CIdx); + // Build up the arguments for involing clang. llvm::sys::Path ClangPath = static_cast(CIdx)->getClangPath(); std::vector argv; @@ -379,16 +396,22 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile( // Generate a temporary name for the AST file. char astTmpFile[L_tmpnam]; argv.push_back(tmpnam(astTmpFile)); - for (int i = 0; i < num_command_line_args; i++) - argv.push_back(command_line_args[i]); + for (int i = 0; i < num_command_line_args; i++) { + if (command_line_args[i] && strcmp(command_line_args[i], "-o") != 0) + argv.push_back(command_line_args[i]); + else { + if (++i < num_command_line_args) // Skip "-o"... + i++; // ...and the following argument as well. + } + } argv.push_back(NULL); - // Generate the AST file in a separate process. #ifndef LLVM_ON_WIN32 llvm::sys::Path DevNull("/dev/null"); const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DevNull, NULL }; llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], NULL, - !displayDiagnostics ? &Redirects[0] :NULL); + !CXXIdx->getDisplayDiagnostics() ? + &Redirects[0] : NULL); #else // FIXME: I don't know what is the equivalent '/dev/null' redirect for // Windows for this API. @@ -397,9 +420,9 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile( // Finally, we create the translation unit from the ast file. ASTUnit *ATU = static_cast( - clang_createTranslationUnit(CIdx, astTmpFile, - displayDiagnostics)); - ATU->unlinkTemporaryFile(); + clang_createTranslationUnit(CIdx, astTmpFile)); + if (ATU) + ATU->unlinkTemporaryFile(); return ATU; } @@ -409,10 +432,6 @@ void clang_disposeTranslationUnit( assert(CTUnit && "Passed null CXTranslationUnit"); delete static_cast(CTUnit); } - -void clang_wantOnlyLocalDeclarations(CXIndex CIdx) { - static_cast(CIdx)->setOnlyLocalDecls(true); -} const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index cbffbed1a2..ea647b46a6 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -28,4 +28,3 @@ _clang_getCursorSpelling _clang_getCursorKindSpelling _clang_getDefinitionSpellingAndExtent _clang_getTranslationUnitSpelling -_clang_wantOnlyLocalDeclarations diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 29cd1370e5..83d3d3f313 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -91,12 +91,10 @@ int main(int argc, char **argv) { CXTranslationUnit TU; enum CXCursorKind K = CXCursor_NotImplemented; - Idx = clang_createIndex(); + Idx = clang_createIndex(/* excludeDeclsFromPCH */ !strcmp(argv[2], "local") ? 1 : 0, + /* displayDiagnostics */ 1); - if (!strcmp(argv[2], "local")) - clang_wantOnlyLocalDeclarations(Idx); - - TU = clang_createTranslationUnit(Idx, argv[1], /* displayDiagnostics= */ 1); + TU = clang_createTranslationUnit(Idx, argv[1]); if (!TU) { fprintf(stderr, "Unable to load translation unit!\n");