diff options
-rw-r--r-- | include/clang/Frontend/ASTUnit.h | 7 | ||||
-rw-r--r-- | include/clang/Frontend/CompilerInstance.h | 24 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 70 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 14 | ||||
-rw-r--r-- | test/Index/complete-driver-errors.c | 11 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 2 |
6 files changed, 70 insertions, 58 deletions
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 980cd54cb3..559c8c5e07 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -91,7 +91,7 @@ private: /// \brief Whether to capture any diagnostics produced. bool CaptureDiagnostics; - + /// \brief Track whether the main file was loaded from an AST or not. bool MainFileIsAST; @@ -218,6 +218,9 @@ private: /// \brief Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults; + static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, + ASTUnit &AST, bool CaptureDiagnostics); + public: /// \brief A cached code-completion result, which may be introduced in one of /// many different contexts. @@ -540,9 +543,9 @@ public: llvm::IntrusiveRefCntPtr<Diagnostic> Diags, llvm::StringRef ResourceFilesPath, bool OnlyLocalDecls = false, + bool CaptureDiagnostics = false, RemappedFile *RemappedFiles = 0, unsigned NumRemappedFiles = 0, - bool CaptureDiagnostics = false, bool PrecompilePreamble = false, bool CompleteTranslationUnit = true, bool CacheCodeCompletionResults = false, diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 3db6077029..f5d6221efc 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -477,8 +477,14 @@ public: /// Create the diagnostics engine using the invocation's diagnostic options /// and replace any existing one with it. /// - /// Note that this routine also replaces the diagnostic client. - void createDiagnostics(int Argc, const char* const *Argv); + /// Note that this routine also replaces the diagnostic client, + /// allocating one if one is not provided. + /// + /// \param Client If non-NULL, a diagnostic client that will be + /// attached to (and, then, owned by) the Diagnostic inside this AST + /// unit. + void createDiagnostics(int Argc, const char* const *Argv, + DiagnosticClient *Client = 0); /// Create a Diagnostic object with a the TextDiagnosticPrinter. /// @@ -486,18 +492,24 @@ public: /// when the diagnostic options indicate that the compiler should output /// logging information. /// - /// Note that this creates an unowned DiagnosticClient, if using directly the - /// caller is responsible for releasing the returned Diagnostic's client - /// eventually. + /// If no diagnostic client is provided, this creates a + /// DiagnosticClient that is owned by the returned diagnostic + /// object, if using directly the caller is responsible for + /// releasing the returned Diagnostic's client eventually. /// /// \param Opts - The diagnostic options; note that the created text /// diagnostic object contains a reference to these options and its lifetime /// must extend past that of the diagnostic engine. /// + /// \param Client If non-NULL, a diagnostic client that will be + /// attached to (and, then, owned by) the returned Diagnostic + /// object. + /// /// \return The new object on success, or null on failure. static llvm::IntrusiveRefCntPtr<Diagnostic> createDiagnostics(const DiagnosticOptions &Opts, int Argc, - const char* const *Argv); + const char* const *Argv, + DiagnosticClient *Client = 0); /// Create the file manager and replace any existing one with it. void createFileManager(); diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index e130e4b79b..ff05f45b14 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -406,7 +406,7 @@ class CaptureDroppedDiagnostics { public: CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, - llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) + llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) : Diags(Diags), Client(StoredDiags), PreviousClient(0) { if (RequestCapture || Diags.getClient() == 0) { @@ -447,6 +447,22 @@ llvm::MemoryBuffer *ASTUnit::getBufferForFile(llvm::StringRef Filename, ErrorStr, FileSize, FileInfo); } +/// \brief Configure the diagnostics object for use with ASTUnit. +void ASTUnit::ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, + ASTUnit &AST, bool CaptureDiagnostics) { + if (!Diags.getPtr()) { + // No diagnostics engine was provided, so create our own diagnostics object + // with the default options. + DiagnosticOptions DiagOpts; + DiagnosticClient *Client = 0; + if (CaptureDiagnostics) + Client = new StoredDiagnosticClient(AST.StoredDiagnostics); + Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0, Client); + } else if (CaptureDiagnostics) { + Diags->setClient(new StoredDiagnosticClient(AST.StoredDiagnostics)); + } +} + ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, llvm::IntrusiveRefCntPtr<Diagnostic> Diags, const FileSystemOptions &FileSystemOpts, @@ -455,16 +471,10 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, unsigned NumRemappedFiles, bool CaptureDiagnostics) { llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); - - if (!Diags.getPtr()) { - // No diagnostics engine was provided, so create our own diagnostics object - // with the default options. - DiagnosticOptions DiagOpts; - Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - } + ConfigureDiags(Diags, *AST, CaptureDiagnostics); - AST->CaptureDiagnostics = CaptureDiagnostics; AST->OnlyLocalDecls = OnlyLocalDecls; + AST->CaptureDiagnostics = CaptureDiagnostics; AST->Diagnostics = Diags; AST->FileSystemOpts = FileSystemOpts; AST->FileMgr.reset(new FileManager); @@ -474,10 +484,6 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager(), AST->getFileSystemOpts())); - // If requested, capture diagnostics in the ASTUnit. - CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(), - AST->StoredDiagnostics); - for (unsigned I = 0; I != NumRemappedFiles; ++I) { // Create the file entry for the file that we're mapping from. const FileEntry *FromFile @@ -708,9 +714,6 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // Set up diagnostics, capturing any diagnostics that would // otherwise be dropped. Clang.setDiagnostics(&getDiagnostics()); - CaptureDroppedDiagnostics Capture(CaptureDiagnostics, - getDiagnostics(), - StoredDiagnostics); // Create the target instance. Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), @@ -1200,9 +1203,6 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // Set up diagnostics, capturing all of the diagnostics produced. Clang.setDiagnostics(&getDiagnostics()); - CaptureDroppedDiagnostics Capture(CaptureDiagnostics, - getDiagnostics(), - StoredDiagnostics); // Create the target instance. Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), @@ -1367,20 +1367,14 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, bool CaptureDiagnostics, bool PrecompilePreamble, bool CompleteTranslationUnit, - bool CacheCodeCompletionResults) { - if (!Diags.getPtr()) { - // No diagnostics engine was provided, so create our own diagnostics object - // with the default options. - DiagnosticOptions DiagOpts; - Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - } - + bool CacheCodeCompletionResults) { // Create the AST unit. llvm::OwningPtr<ASTUnit> AST; AST.reset(new ASTUnit(false)); + ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; - AST->CaptureDiagnostics = CaptureDiagnostics; AST->OnlyLocalDecls = OnlyLocalDecls; + AST->CaptureDiagnostics = CaptureDiagnostics; AST->CompleteTranslationUnit = CompleteTranslationUnit; AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; AST->Invocation.reset(CI); @@ -1393,22 +1387,19 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, llvm::IntrusiveRefCntPtr<Diagnostic> Diags, llvm::StringRef ResourceFilesPath, bool OnlyLocalDecls, + bool CaptureDiagnostics, RemappedFile *RemappedFiles, unsigned NumRemappedFiles, - bool CaptureDiagnostics, bool PrecompilePreamble, bool CompleteTranslationUnit, bool CacheCodeCompletionResults, bool CXXPrecompilePreamble, bool CXXChainedPCH) { - bool CreatedDiagnosticsObject = false; - if (!Diags.getPtr()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. DiagnosticOptions DiagOpts; Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - CreatedDiagnosticsObject = true; } llvm::SmallVector<const char *, 16> Args; @@ -1422,9 +1413,9 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics; llvm::OwningPtr<CompilerInvocation> CI; + { - CaptureDroppedDiagnostics Capture(CaptureDiagnostics, - *Diags, + CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, StoredDiagnostics); // FIXME: We shouldn't have to pass in the path info. @@ -1457,12 +1448,12 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, const driver::ArgStringList &CCArgs = Cmd->getArguments(); CI.reset(new CompilerInvocation); CompilerInvocation::CreateFromArgs(*CI, - const_cast<const char **>(CCArgs.data()), - const_cast<const char **>(CCArgs.data()) + + const_cast<const char **>(CCArgs.data()), + const_cast<const char **>(CCArgs.data()) + CCArgs.size(), *Diags); } - + // Override any files that need remapping for (unsigned I = 0; I != NumRemappedFiles; ++I) CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, @@ -1484,9 +1475,10 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, // Create the AST unit. llvm::OwningPtr<ASTUnit> AST; AST.reset(new ASTUnit(false)); + ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; - AST->CaptureDiagnostics = CaptureDiagnostics; AST->OnlyLocalDecls = OnlyLocalDecls; + AST->CaptureDiagnostics = CaptureDiagnostics; AST->CompleteTranslationUnit = CompleteTranslationUnit; AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); @@ -1813,7 +1805,7 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, Clang.setDiagnostics(&Diag); ProcessWarningOptions(Diag, CCInvocation.getDiagnosticOpts()); CaptureDroppedDiagnostics Capture(true, - Clang.getDiagnostics(), + Clang.getDiagnostics(), StoredDiagnostics); // Create the target instance. diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index c5e5d7f90a..7cfcd1c419 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -113,19 +113,23 @@ static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts, Diags.setClient(new ChainedDiagnosticClient(Diags.takeClient(), Logger)); } -void CompilerInstance::createDiagnostics(int Argc, const char* const *Argv) { - Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv); +void CompilerInstance::createDiagnostics(int Argc, const char* const *Argv, + DiagnosticClient *Client) { + Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv, Client); } llvm::IntrusiveRefCntPtr<Diagnostic> CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts, - int Argc, const char* const *Argv) { + int Argc, const char* const *Argv, + DiagnosticClient *Client) { llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic()); // Create the diagnostic client for reporting errors or for // implementing -verify. - llvm::OwningPtr<DiagnosticClient> DiagClient; - Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); + if (Client) + Diags->setClient(Client); + else + Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); // Chain in -verify checker, if requested. if (Opts.VerifyDiagnostics) diff --git a/test/Index/complete-driver-errors.c b/test/Index/complete-driver-errors.c index 1918511a18..566090c260 100644 --- a/test/Index/complete-driver-errors.c +++ b/test/Index/complete-driver-errors.c @@ -2,20 +2,21 @@ int *blah = 1; int -// Test driver errors with code completion -// RUN: c-index-test -code-completion-at=%s:4:1 -std= %s 2> %t | FileCheck -check-prefix=CHECK-RESULTS %s -// RUN: FileCheck -check-prefix=CHECK-DIAGS %s < %t // CHECK-RESULTS: NotImplemented:{TypedText const} (40) // CHECK-RESULTS: NotImplemented:{TypedText restrict} (40) // CHECK-RESULTS: NotImplemented:{TypedText volatile} (40) +// CHECK-DIAGS: error: invalid value '' in '-std=' +// CHECK-DIAGS: complete-driver-errors.c:1:6:{1:13-1:14}: warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' + +// Test driver errors with code completion +// RUN: c-index-test -code-completion-at=%s:4:1 -std= %s 2> %t | FileCheck -check-prefix=CHECK-RESULTS %s +// RUN: FileCheck -check-prefix=CHECK-DIAGS %s < %t // Test driver errors with parsing // RUN: c-index-test -test-load-source all -std= %s 2> %t | FileCheck -check-prefix=CHECK-LOAD %s // RUN: FileCheck -check-prefix=CHECK-DIAGS %s < %t // CHECK-LOAD: complete-driver-errors.c:1:6: VarDecl=blah:1:6 -// CHECK-DIAGS: error: invalid value '' in '-std=' -// CHECK-DIAGS: complete-driver-errors.c:1:6:{1:13-1:14}: warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' // Test driver errors with code completion and precompiled preamble // RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:4:1 -std= %s 2> %t | FileCheck -check-prefix=CHECK-RESULTS %s // RUN: FileCheck -check-prefix=CHECK-DIAGS %s < %t diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 30e903449f..8de774cb88 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2186,9 +2186,9 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { Diags, CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(), + /*CaptureDiagnostics=*/true, RemappedFiles.data(), RemappedFiles.size(), - /*CaptureDiagnostics=*/true, PrecompilePreamble, CompleteTranslationUnit, CacheCodeCompetionResults, |