diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/CIndex/CIndex.cpp | 35 | ||||
-rw-r--r-- | tools/CIndex/CIndex.exports | 5 | ||||
-rw-r--r-- | tools/CIndex/CIndexCodeCompletion.cpp | 56 | ||||
-rw-r--r-- | tools/CIndex/CIndexDiagnostic.cpp | 158 | ||||
-rw-r--r-- | tools/CIndex/CIndexDiagnostic.h | 48 | ||||
-rw-r--r-- | tools/c-index-test/c-index-test.c | 44 |
6 files changed, 168 insertions, 178 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 0b08874709..cb81988d95 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -933,9 +933,7 @@ void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) { } CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, - const char *ast_filename, - CXDiagnosticCallback diag_callback, - CXClientData diag_client_data) { + const char *ast_filename) { if (!CIdx) return 0; @@ -945,11 +943,9 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, DiagnosticOptions DiagOpts; llvm::OwningPtr<Diagnostic> Diags; Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0)); - CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data); - Diags->setClient(&DiagClient); - return ASTUnit::LoadFromPCHFile(ast_filename, *Diags, - CXXIdx->getOnlyLocalDecls()); + CXXIdx->getOnlyLocalDecls(), + 0, 0, true); } CXTranslationUnit @@ -958,9 +954,7 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, int num_command_line_args, const char **command_line_args, unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - CXDiagnosticCallback diag_callback, - CXClientData diag_client_data) { + struct CXUnsavedFile *unsaved_files) { if (!CIdx) return 0; @@ -970,8 +964,6 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, DiagnosticOptions DiagOpts; llvm::OwningPtr<Diagnostic> Diags; Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0)); - CIndexDiagnosticClient DiagClient(diag_callback, diag_client_data); - Diags->setClient(&DiagClient); llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; for (unsigned I = 0; I != num_unsaved_files; ++I) { @@ -1006,7 +998,8 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(), RemappedFiles.data(), - RemappedFiles.size())); + RemappedFiles.size(), + /*CaptureDiagnostics=*/true)); // FIXME: Until we have broader testing, just drop the entire AST if we // encountered an error. @@ -1097,20 +1090,22 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx, 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(), RemappedFiles.data(), - RemappedFiles.size()); + RemappedFiles.size(), + /*CaptureDiagnostics=*/true); if (ATU) ATU->unlinkTemporaryFile(); // FIXME: Currently we don't report diagnostics on invalid ASTs. - if (ATU) - ReportSerializedDiagnostics(DiagnosticsFile, *Diags, - num_unsaved_files, unsaved_files, - ATU->getASTContext().getLangOptions()); + if (ATU) { + LoadSerializedDiagnostics(DiagnosticsFile, + num_unsaved_files, unsaved_files, + ATU->getFileManager(), + ATU->getSourceManager(), + ATU->getDiagnostics()); + } for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) TemporaryFiles[i].eraseFromDisk(); diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index 2c738190b4..1c445b74aa 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -1,9 +1,12 @@ _clang_annotateTokens _clang_codeComplete +_clang_codeCompleteGetDiagnostic +_clang_codeCompleteGetNumDiagnostics _clang_createIndex _clang_createTranslationUnit _clang_createTranslationUnitFromSourceFile _clang_disposeCodeCompleteResults +_clang_disposeDiagnostic _clang_disposeIndex _clang_disposeString _clang_disposeTokens @@ -25,6 +28,7 @@ _clang_getCursorReferenced _clang_getCursorSpelling _clang_getCursorUSR _clang_getDefinitionSpellingAndExtent +_clang_getDiagnostic _clang_getDiagnosticFixItInsertion _clang_getDiagnosticFixItKind _clang_getDiagnosticFixItRemoval @@ -45,6 +49,7 @@ _clang_getNullCursor _clang_getNullLocation _clang_getNullRange _clang_getNumCompletionChunks +_clang_getNumDiagnostics _clang_getRange _clang_getRangeEnd _clang_getRangeStart diff --git a/tools/CIndex/CIndexCodeCompletion.cpp b/tools/CIndex/CIndexCodeCompletion.cpp index 4912fef2e2..9e8946381a 100644 --- a/tools/CIndex/CIndexCodeCompletion.cpp +++ b/tools/CIndex/CIndexCodeCompletion.cpp @@ -181,7 +181,17 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { /// retain this buffer because the completion strings point into it. llvm::MemoryBuffer *Buffer; + /// \brief Diagnostics produced while performing code completion. + llvm::SmallVector<StoredDiagnostic, 8> Diagnostics; + + /// \brief Language options used to adjust source locations. LangOptions LangOpts; + + /// \brief Source manager, used for diagnostics. + SourceManager SourceMgr; + + /// \brief File manager, used for diagnostics. + FileManager FileMgr; }; CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, @@ -192,9 +202,7 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, struct CXUnsavedFile *unsaved_files, const char *complete_filename, unsigned complete_line, - unsigned complete_column, - CXDiagnosticCallback diag_callback, - CXClientData diag_client_data) { + unsigned complete_column) { // The indexer, which is mainly used to determine where diagnostics go. CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); @@ -202,8 +210,6 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, DiagnosticOptions DiagOpts; llvm::OwningPtr<Diagnostic> 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<llvm::sys::Path> TemporaryFiles; @@ -310,7 +316,11 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, // Parse the resulting source file to find code-completion results. using llvm::MemoryBuffer; using llvm::StringRef; - AllocatedCXCodeCompleteResults *Results = 0; + AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults; + Results->Results = 0; + Results->NumResults = 0; + Results->Buffer = 0; + // FIXME: Set Results->LangOpts! if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) { llvm::SmallVector<CXCompletionResult, 4> CompletionResults; StringRef Buffer = F->getBuffer(); @@ -335,7 +345,6 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, }; // Allocate the results. - Results = new AllocatedCXCodeCompleteResults; Results->Results = new CXCompletionResult [CompletionResults.size()]; Results->NumResults = CompletionResults.size(); memcpy(Results->Results, CompletionResults.data(), @@ -343,13 +352,10 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, Results->Buffer = F; } - // FIXME: The LangOptions we are passing here are not at all correct. However, - // in the current design we must pass something in so the SourceLocations have - // a LangOptions object to refer to. - ReportSerializedDiagnostics(DiagnosticsFile, *Diags, - num_unsaved_files, unsaved_files, - Results->LangOpts); - + LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files, + Results->FileMgr, Results->SourceMgr, + Results->Diagnostics); + for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) TemporaryFiles[i].eraseFromDisk(); @@ -374,4 +380,26 @@ void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) { delete Results; } +unsigned +clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) { + AllocatedCXCodeCompleteResults *Results + = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); + if (!Results) + return 0; + + return Results->Diagnostics.size(); +} + +CXDiagnostic +clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn, + unsigned Index) { + AllocatedCXCodeCompleteResults *Results + = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); + if (!Results || Index >= Results->Diagnostics.size()) + return 0; + + return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts); +} + + } // end extern "C" diff --git a/tools/CIndex/CIndexDiagnostic.cpp b/tools/CIndex/CIndexDiagnostic.cpp index 5c18c9534f..70676f0e14 100644 --- a/tools/CIndex/CIndexDiagnostic.cpp +++ b/tools/CIndex/CIndexDiagnostic.cpp @@ -1,4 +1,4 @@ -/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface -----------*- C -*-===*\ +/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| @@ -15,67 +15,44 @@ #include "CXSourceLocation.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/MemoryBuffer.h" using namespace clang; using namespace clang::cxloc; using namespace clang::cxstring; +using namespace llvm; //----------------------------------------------------------------------------- -// Opaque data structures -//----------------------------------------------------------------------------- -namespace { - /// \brief The storage behind a CXDiagnostic - struct CXStoredDiagnostic { - /// \brief The translation unit this diagnostic came from. - const LangOptions *LangOptsPtr; - - /// \brief The severity level of this diagnostic. - Diagnostic::Level Level; - - /// \brief A reference to the diagnostic information. - const DiagnosticInfo &Info; - }; -} - -//----------------------------------------------------------------------------- -// CIndex Diagnostic Client +// C Interface Routines //----------------------------------------------------------------------------- -CIndexDiagnosticClient::~CIndexDiagnosticClient() { } - -void CIndexDiagnosticClient::BeginSourceFile(const LangOptions &LangOpts, - const Preprocessor *PP) { - assert(!LangOptsPtr && "Invalid state!"); - LangOptsPtr = &LangOpts; -} +extern "C" { -void CIndexDiagnosticClient::EndSourceFile() { - assert(LangOptsPtr && "Invalid state!"); - LangOptsPtr = 0; +unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) { + ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit); + return CXXUnit? CXXUnit->diag_size() : 0; } -void CIndexDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info) { - if (!Callback) - return; +CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) { + ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit); + if (!CXXUnit || Index >= CXXUnit->diag_size()) + return 0; - assert((LangOptsPtr || Info.getLocation().isInvalid()) && - "Missing language options with located diagnostic!"); - CXStoredDiagnostic Stored = { this->LangOptsPtr, DiagLevel, Info }; - Callback(&Stored, ClientData); + return new CXStoredDiagnostic(CXXUnit->diag_begin()[Index], + CXXUnit->getASTContext().getLangOptions()); } -//----------------------------------------------------------------------------- -// C Interface Routines -//----------------------------------------------------------------------------- -extern "C" { +void clang_disposeDiagnostic(CXDiagnostic Diagnostic) { + CXStoredDiagnostic *Stored = static_cast<CXStoredDiagnostic *>(Diagnostic); + delete Stored; +} enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) { CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); if (!StoredDiag) return CXDiagnostic_Ignored; - switch (StoredDiag->Level) { + switch (StoredDiag->Diag.getLevel()) { case Diagnostic::Ignored: return CXDiagnostic_Ignored; case Diagnostic::Note: return CXDiagnostic_Note; case Diagnostic::Warning: return CXDiagnostic_Warning; @@ -89,12 +66,12 @@ enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) { CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) { CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || StoredDiag->Info.getLocation().isInvalid()) + if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) return clang_getNullLocation(); - return translateSourceLocation(StoredDiag->Info.getLocation().getManager(), - *StoredDiag->LangOptsPtr, - StoredDiag->Info.getLocation()); + return translateSourceLocation(StoredDiag->Diag.getLocation().getManager(), + StoredDiag->LangOpts, + StoredDiag->Diag.getLocation()); } CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) { @@ -102,28 +79,26 @@ CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) { if (!StoredDiag) return createCXString(""); - llvm::SmallString<64> Spelling; - StoredDiag->Info.FormatDiagnostic(Spelling); - return createCXString(Spelling.str(), true); + return createCXString(StoredDiag->Diag.getMessage(), false); } unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) { CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || StoredDiag->Info.getLocation().isInvalid()) + if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) return 0; - return StoredDiag->Info.getNumRanges(); + return StoredDiag->Diag.range_size(); } CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) { CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || Range >= StoredDiag->Info.getNumRanges() || - StoredDiag->Info.getLocation().isInvalid()) + if (!StoredDiag || Range >= StoredDiag->Diag.range_size() || + StoredDiag->Diag.getLocation().isInvalid()) return clang_getNullRange(); - return translateSourceRange(StoredDiag->Info.getLocation().getManager(), - *StoredDiag->LangOptsPtr, - StoredDiag->Info.getRange(Range)); + return translateSourceRange(StoredDiag->Diag.getLocation().getManager(), + StoredDiag->LangOpts, + StoredDiag->Diag.range_begin()[Range]); } unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { @@ -131,17 +106,16 @@ unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { if (!StoredDiag) return 0; - return StoredDiag->Info.getNumCodeModificationHints(); + return StoredDiag->Diag.fixit_size(); } enum CXFixItKind clang_getDiagnosticFixItKind(CXDiagnostic Diag, unsigned FixIt) { CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints()) + if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size()) return CXFixIt_Insertion; - const CodeModificationHint &Hint - = StoredDiag->Info.getCodeModificationHint(FixIt); + const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; if (Hint.RemoveRange.isInvalid()) return CXFixIt_Insertion; if (Hint.InsertionLoc.isInvalid()) @@ -157,16 +131,15 @@ CXString clang_getDiagnosticFixItInsertion(CXDiagnostic Diag, *Location = clang_getNullLocation(); CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints()) + if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size()) return createCXString(""); - const CodeModificationHint &Hint - = StoredDiag->Info.getCodeModificationHint(FixIt); + const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - if (Location && StoredDiag->Info.getLocation().isValid()) + if (Location && StoredDiag->Diag.getLocation().isValid()) *Location = translateSourceLocation( - StoredDiag->Info.getLocation().getManager(), - *StoredDiag->LangOptsPtr, + StoredDiag->Diag.getLocation().getManager(), + StoredDiag->LangOpts, Hint.InsertionLoc); return createCXString(Hint.CodeToInsert); } @@ -174,14 +147,13 @@ CXString clang_getDiagnosticFixItInsertion(CXDiagnostic Diag, CXSourceRange clang_getDiagnosticFixItRemoval(CXDiagnostic Diag, unsigned FixIt) { CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() || - StoredDiag->Info.getLocation().isInvalid()) + if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || + StoredDiag->Diag.getLocation().isInvalid()) return clang_getNullRange(); - const CodeModificationHint &Hint - = StoredDiag->Info.getCodeModificationHint(FixIt); - return translateSourceRange(StoredDiag->Info.getLocation().getManager(), - *StoredDiag->LangOptsPtr, + const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; + return translateSourceRange(StoredDiag->Diag.getLocation().getManager(), + StoredDiag->LangOpts, Hint.RemoveRange); } @@ -192,30 +164,30 @@ CXString clang_getDiagnosticFixItReplacement(CXDiagnostic Diag, *Range = clang_getNullRange(); CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() || - StoredDiag->Info.getLocation().isInvalid()) { + if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || + StoredDiag->Diag.getLocation().isInvalid()) { if (Range) *Range = clang_getNullRange(); return createCXString(""); } - const CodeModificationHint &Hint - = StoredDiag->Info.getCodeModificationHint(FixIt); + const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; if (Range) - *Range = translateSourceRange(StoredDiag->Info.getLocation().getManager(), - *StoredDiag->LangOptsPtr, + *Range = translateSourceRange(StoredDiag->Diag.getLocation().getManager(), + StoredDiag->LangOpts, Hint.RemoveRange); return createCXString(Hint.CodeToInsert); } } // end extern "C" -void clang::ReportSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, - Diagnostic &Diags, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - const LangOptions &LangOpts) { +void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, + unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + FileManager &FileMgr, + SourceManager &SourceMgr, + SmallVectorImpl<StoredDiagnostic> &Diags) { using llvm::MemoryBuffer; using llvm::StringRef; MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str()); @@ -223,15 +195,15 @@ void clang::ReportSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, return; // Enter the unsaved files into the file manager. - SourceManager SourceMgr; - FileManager FileMgr; for (unsigned I = 0; I != num_unsaved_files; ++I) { const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename, unsaved_files[I].Length, 0); if (!File) { - Diags.Report(diag::err_fe_remap_missing_from_file) - << unsaved_files[I].Filename; + // FIXME: Hard to localize when we have no diagnostics engine! + Diags.push_back(StoredDiagnostic(Diagnostic::Fatal, + (Twine("could not remap from missing file ") + + unsaved_files[I].Filename).str())); return; } @@ -244,18 +216,16 @@ void clang::ReportSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, SourceMgr.overrideFileContents(File, Buffer); } - Diags.getClient()->BeginSourceFile(LangOpts, 0); - // Parse the diagnostics, emitting them one by one until we've // exhausted the data. StringRef Buffer = F->getBuffer(); const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size(); while (Memory != MemoryEnd) { - DiagnosticBuilder DB = Diags.Deserialize(FileMgr, SourceMgr, - Memory, MemoryEnd); - if (!DB.isActive()) + StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr, + Memory, MemoryEnd); + if (!Stored) return; - } - Diags.getClient()->EndSourceFile(); + Diags.push_back(Stored); + } } diff --git a/tools/CIndex/CIndexDiagnostic.h b/tools/CIndex/CIndexDiagnostic.h index 9f7ae51a10..79a5df0381 100644 --- a/tools/CIndex/CIndexDiagnostic.h +++ b/tools/CIndex/CIndexDiagnostic.h @@ -16,6 +16,7 @@ #include "clang-c/Index.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { namespace sys { class Path; @@ -26,40 +27,25 @@ namespace clang { class Diagnostic; class LangOptions; class Preprocessor; - -/** - * \brief Diagnostic client that translates Clang diagnostics into diagnostics - * for the C interface to Clang. - */ -class CIndexDiagnosticClient : public DiagnosticClient { - CXDiagnosticCallback Callback; - CXClientData ClientData; - const LangOptions *LangOptsPtr; - -public: - CIndexDiagnosticClient(CXDiagnosticCallback Callback, - CXClientData ClientData) - : Callback(Callback), ClientData(ClientData), LangOptsPtr(0) { } - - virtual ~CIndexDiagnosticClient(); - - virtual void BeginSourceFile(const LangOptions &LangOpts, - const Preprocessor *PP); - - virtual void EndSourceFile(); - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); +/// \brief The storage behind a CXDiagnostic +struct CXStoredDiagnostic { + const StoredDiagnostic &Diag; + const LangOptions &LangOpts; + + CXStoredDiagnostic(const StoredDiagnostic &Diag, + const LangOptions &LangOpts) + : Diag(Diag), LangOpts(LangOpts) { } }; - + /// \brief Given the path to a file that contains binary, serialized -/// diagnostics produced by Clang, emit those diagnostics via the -/// given diagnostic engine. -void ReportSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, - Diagnostic &Diags, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - const LangOptions &LangOpts); +/// diagnostics produced by Clang, load those diagnostics. +void LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, + unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + FileManager &FileMgr, + SourceManager &SourceMgr, + llvm::SmallVectorImpl<StoredDiagnostic> &Diags); } // end namespace clang diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 640375aaea..b983d3a4de 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -28,10 +28,6 @@ char *basename(const char* path) extern char *basename(const char *); #endif -static void PrintDiagnosticCallback(CXDiagnostic Diagnostic, - CXClientData ClientData); - - static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column, unsigned end_line, unsigned end_column) { fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column, @@ -41,7 +37,7 @@ static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column, static unsigned CreateTranslationUnit(CXIndex Idx, const char *file, CXTranslationUnit *TU) { - *TU = clang_createTranslationUnit(Idx, file, PrintDiagnosticCallback, stderr); + *TU = clang_createTranslationUnit(Idx, file); if (!TU) { fprintf(stderr, "Unable to load translation unit from '%s'!\n", file); return 0; @@ -199,9 +195,8 @@ static const char* GetCursorSource(CXCursor Cursor) { typedef void (*PostVisitTU)(CXTranslationUnit); -static void PrintDiagnosticCallback(CXDiagnostic Diagnostic, - CXClientData ClientData) { - FILE *out = (FILE *)ClientData; +void PrintDiagnostic(CXDiagnostic Diagnostic) { + FILE *out = stderr; CXFile file; unsigned line, column; CXString text; @@ -321,6 +316,15 @@ static void PrintDiagnosticCallback(CXDiagnostic Diagnostic, } } +void PrintDiagnostics(CXTranslationUnit TU) { + int i, n = clang_getNumDiagnostics(TU); + for (i = 0; i != n; ++i) { + CXDiagnostic Diag = clang_getDiagnostic(TU, i); + PrintDiagnostic(Diag); + clang_disposeDiagnostic(Diag); + } +} + /******************************************************************************/ /* Logic for testing traversal. */ /******************************************************************************/ @@ -518,6 +522,7 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, if (PV) PV(TU); + PrintDiagnostics(TU); clang_disposeTranslationUnit(TU); return 0; } @@ -567,9 +572,7 @@ int perform_test_load_source(int argc, const char **argv, argc - num_unsaved_files, argv + num_unsaved_files, num_unsaved_files, - unsaved_files, - PrintDiagnosticCallback, - stderr); + unsaved_files); if (!TU) { fprintf(stderr, "Unable to load translation unit!\n"); clang_disposeIndex(Idx); @@ -815,13 +818,18 @@ int perform_code_completion(int argc, const char **argv) { argv[argc - 1], argc - num_unsaved_files - 3, argv + num_unsaved_files + 2, num_unsaved_files, unsaved_files, - filename, line, column, - PrintDiagnosticCallback, stderr); + filename, line, column); if (results) { unsigned i, n = results->NumResults; for (i = 0; i != n; ++i) print_completion_result(results->Results + i, stdout); + n = clang_codeCompleteGetNumDiagnostics(results); + for (i = 0; i != n; ++i) { + CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i); + PrintDiagnostic(diag); + clang_disposeDiagnostic(diag); + } clang_disposeCodeCompleteResults(results); } @@ -874,9 +882,7 @@ int inspect_cursor_at(int argc, const char **argv) { argc - num_unsaved_files - 2 - NumLocations, argv + num_unsaved_files + 1 + NumLocations, num_unsaved_files, - unsaved_files, - PrintDiagnosticCallback, - stderr); + unsaved_files); if (!TU) { fprintf(stderr, "unable to parse input\n"); return -1; @@ -895,6 +901,7 @@ int inspect_cursor_at(int argc, const char **argv) { free(Locations[Loc].filename); } + PrintDiagnostics(TU); clang_disposeTranslationUnit(TU); clang_disposeIndex(CIdx); free(Locations); @@ -933,9 +940,7 @@ int perform_token_annotation(int argc, const char **argv) { argc - num_unsaved_files - 3, argv + num_unsaved_files + 2, num_unsaved_files, - unsaved_files, - PrintDiagnosticCallback, - stderr); + unsaved_files); if (!TU) { fprintf(stderr, "unable to parse input\n"); clang_disposeIndex(CIdx); @@ -1000,6 +1005,7 @@ int perform_token_annotation(int argc, const char **argv) { free(cursors); teardown: + PrintDiagnostics(TU); clang_disposeTranslationUnit(TU); clang_disposeIndex(CIdx); free(filename); |