From: Douglas Gregor Date: Thu, 28 Jan 2010 00:56:43 +0000 (+0000) Subject: Switch the remaining diagnostic printing in CIndex over to the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=936ea3b590117d2cd73b1b92621d06c4a7edbe60;p=clang Switch the remaining diagnostic printing in CIndex over to the diagnostic callback mechanism, so all diagnostics now go through that callback. Also, eliminate the displayDiagnostics flag to clang_createIndex(), since it is no longer necessary: the client determines whether to display diagnostics or not. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94714 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index e26dff1eb1..d9b4b0906b 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -143,13 +143,10 @@ CINDEX_LINKAGE void clang_disposeString(CXString string); * 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. - * * Here is an example: * - * // excludeDeclsFromPCH = 1, displayDiagnostics = 1 - * Idx = clang_createIndex(1, 1); + * // excludeDeclsFromPCH = 1 + * Idx = clang_createIndex(1); * * // IndexTest.pch was produced with the following command: * // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch" @@ -173,8 +170,7 @@ CINDEX_LINKAGE void clang_disposeString(CXString string); * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks * (which gives the indexer the same performance benefit as the compiler). */ -CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH, - int displayDiagnostics); +CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH); CINDEX_LINKAGE void clang_disposeIndex(CXIndex index); /** @@ -1593,6 +1589,13 @@ typedef struct { * Note that the column should point just after the syntactic construct that * initiated code completion, and not in the middle of a lexical token. * + * \param diag_callback callback function that will receive any diagnostics + * emitted while processing this source file. If NULL, diagnostics will be + * suppressed. + * + * \param diag_client_data client data that will be passed to the diagnostic + * callback function. + * * \returns if successful, a new CXCodeCompleteResults structure * containing code-completion results, which should eventually be * freed with \c clang_disposeCodeCompleteResults(). If code @@ -1607,7 +1610,9 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, struct CXUnsavedFile *unsaved_files, const char *complete_filename, unsigned complete_line, - unsigned complete_column); + unsigned complete_column, + CXDiagnosticCallback diag_callback, + CXClientData diag_client_data); /** * \brief Free the given set of code-completion results. diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 66a841a8af..59287b3def 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -80,6 +80,8 @@ def note_fixit_main_file_unchanged : Note< def warn_fixit_no_changes : Note< "FIX-IT detected errors it could not fix; no output will be generated">; +def err_fe_clang : Error<"error invoking%s: %s">, DefaultFatal; + // PCH reader def err_relocatable_without_without_isysroot : Error< "must specify system root with -isysroot when building a relocatable " diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 336a638b3a..57b463cba0 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -18,9 +18,11 @@ #include "CIndexDiagnostic.h" #include "clang/Basic/Version.h" + #include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeLocVisitor.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" #include "llvm/Support/MemoryBuffer.h" @@ -893,13 +895,10 @@ CXString CIndexer::createCXString(llvm::StringRef String, bool DupString) { } extern "C" { -CXIndex clang_createIndex(int excludeDeclarationsFromPCH, - int displayDiagnostics) { +CXIndex clang_createIndex(int excludeDeclarationsFromPCH) { CIndexer *CIdxr = new CIndexer(); if (excludeDeclarationsFromPCH) CIdxr->setOnlyLocalDecls(); - if (displayDiagnostics) - CIdxr->setDisplayDiagnostics(); return CIdxr; } @@ -1054,20 +1053,23 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, std::string ErrMsg; const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DevNull, NULL }; llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL, - /* redirects */ !CXXIdx->getDisplayDiagnostics() ? &Redirects[0] : NULL, + /* redirects */ &Redirects[0], /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg); - if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty()) { - llvm::errs() << "clang_createTranslationUnitFromSourceFile: " << ErrMsg - << '\n' << "Arguments: \n"; + if (!ErrMsg.empty()) { + std::string AllArgs; for (std::vector::iterator I = argv.begin(), E = argv.end(); - I!=E; ++I) { + I != E; ++I) { + AllArgs += ' '; if (*I) - llvm::errs() << ' ' << *I << '\n'; + AllArgs += *I; } - llvm::errs() << '\n'; + + Diags->Report(diag::err_fe_clang) << AllArgs << ErrMsg; } + // FIXME: Parse the (redirected) standard error to emit diagnostics. + ASTUnit *ATU = ASTUnit::LoadFromPCHFile(astTmpFile, *Diags, CXXIdx->getOnlyLocalDecls(), /* UseBumpAllocator = */ true, diff --git a/tools/CIndex/CIndexCodeCompletion.cpp b/tools/CIndex/CIndexCodeCompletion.cpp index f3b60dc8b0..25b1417c97 100644 --- a/tools/CIndex/CIndexCodeCompletion.cpp +++ b/tools/CIndex/CIndexCodeCompletion.cpp @@ -13,6 +13,8 @@ //===----------------------------------------------------------------------===// #include "CIndexer.h" +#include "CIndexDiagnostic.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/MemoryBuffer.h" @@ -186,10 +188,19 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, struct CXUnsavedFile *unsaved_files, const char *complete_filename, unsigned complete_line, - unsigned complete_column) { + unsigned complete_column, + CXDiagnosticCallback diag_callback, + CXClientData diag_client_data) { // The indexer, which is mainly used to determine where diagnostics go. CIndexer *CXXIdx = static_cast(CIdx); + // Configure the diagnostics. + DiagnosticOptions DiagOpts; + llvm::OwningPtr Diags; + Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0)); + CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data); + Diags->setClient(&DiagClient); + // The set of temporary files that we've built. std::vector TemporaryFiles; @@ -272,15 +283,16 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg); - if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty()) { - llvm::errs() << "clang_codeComplete: " << ErrMsg - << '\n' << "Arguments: \n"; + if (!ErrMsg.empty()) { + std::string AllArgs; for (std::vector::iterator I = argv.begin(), E = argv.end(); - I!=E; ++I) { + I != E; ++I) { + AllArgs += ' '; if (*I) - llvm::errs() << ' ' << *I << '\n'; + AllArgs += *I; } - llvm::errs() << '\n'; + + Diags->Report(diag::err_fe_clang) << AllArgs << ErrMsg; } // Parse the resulting source file to find code-completion results. @@ -319,6 +331,8 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, Results->Buffer = F; } + // FIXME: Parse the (redirected) standard error to emit diagnostics. + for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) TemporaryFiles[i].eraseFromDisk(); diff --git a/tools/CIndex/CIndexer.h b/tools/CIndex/CIndexer.h index 44eaaec8b5..b83e2b7f32 100644 --- a/tools/CIndex/CIndexer.h +++ b/tools/CIndex/CIndexer.h @@ -27,14 +27,11 @@ using namespace clang; class CIndexer { bool UseExternalASTGeneration; bool OnlyLocalDecls; - bool DisplayDiagnostics; llvm::sys::Path ClangPath; public: - CIndexer() - : UseExternalASTGeneration(false), OnlyLocalDecls(false), - DisplayDiagnostics(false) { } + CIndexer() : UseExternalASTGeneration(false), OnlyLocalDecls(false) { } /// \brief Whether we only want to see "local" declarations (that did not /// come from a previous precompiled header). If false, we want to see all @@ -42,11 +39,6 @@ public: bool getOnlyLocalDecls() const { return OnlyLocalDecls; } void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; } - bool getDisplayDiagnostics() const { return DisplayDiagnostics; } - void setDisplayDiagnostics(bool Display = true) { - DisplayDiagnostics = Display; - } - bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; } void setUseExternalASTGeneration(bool Value) { UseExternalASTGeneration = Value; diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 39c3446f04..d4bc008369 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -411,8 +411,7 @@ int perform_test_load_tu(const char *file, const char *filter, CXIndex Idx; CXTranslationUnit TU; Idx = clang_createIndex(/* excludeDeclsFromPCH */ - !strcmp(filter, "local") ? 1 : 0, - /* displayDiagnostics */ 1); + !strcmp(filter, "local") ? 1 : 0); if (!CreateTranslationUnit(Idx, file, &TU)) return 1; @@ -432,8 +431,7 @@ int perform_test_load_source(int argc, const char **argv, int result; Idx = clang_createIndex(/* excludeDeclsFromPCH */ - !strcmp(filter, "local") ? 1 : 0, - /* displayDiagnostics */ 1); + !strcmp(filter, "local") ? 1 : 0); if (UseExternalASTs && strlen(UseExternalASTs)) clang_setUseExternalASTGeneration(Idx, 1); @@ -487,8 +485,7 @@ static int perform_file_scan(const char *ast_file, const char *source_file, unsigned start_line, start_col, last_line, last_col; size_t i; - if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1, - /* displayDiagnostics */ 1))) { + if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1))) { fprintf(stderr, "Could not create Index\n"); return 1; } @@ -700,12 +697,14 @@ int perform_code_completion(int argc, const char **argv) { if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) return -1; - CIdx = clang_createIndex(0, 0); + CIdx = clang_createIndex(0); results = clang_codeComplete(CIdx, argv[argc - 1], argc - num_unsaved_files - 3, argv + num_unsaved_files + 2, num_unsaved_files, unsaved_files, - filename, line, column); + filename, line, column, + PrintDiagnosticCallback, stderr); + if (results) { unsigned i, n = results->NumResults; for (i = 0; i != n; ++i) @@ -757,7 +756,7 @@ int inspect_cursor_at(int argc, const char **argv) { &num_unsaved_files)) return -1; - CIdx = clang_createIndex(0, 1); + CIdx = clang_createIndex(0); TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1], argc - num_unsaved_files - 2 - NumLocations, argv + num_unsaved_files + 1 + NumLocations, @@ -816,7 +815,7 @@ int perform_token_annotation(int argc, const char **argv) { if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) return -1; - CIdx = clang_createIndex(0, 0); + CIdx = clang_createIndex(0); TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1], argc - num_unsaved_files - 3, argv + num_unsaved_files + 2,