[llvm-branch-commits] [cfe-branch] r119252 - in /cfe/branches/Apple/whitney: include/clang/Frontend/ASTUnit.h include/clang/Frontend/CompilerInstance.h lib/Frontend/ASTUnit.cpp lib/Frontend/CompilerInstance.cpp test/Index/complete-driver-errors.c tools/libclang/CIndex.cpp

Daniel Dunbar daniel at zuster.org
Mon Nov 15 13:46:16 PST 2010


Author: ddunbar
Date: Mon Nov 15 15:46:16 2010
New Revision: 119252

URL: http://llvm.org/viewvc/llvm-project?rev=119252&view=rev
Log:
Merge r118751:
--
Author: Douglas Gregor <dgregor at apple.com>
Date:   Thu Nov 11 00:39:14 2010 +0000

    Improve ASTUnit's capture of diagnostics so that the
    diagnostic-capturing client lives as long as the ASTUnit itself
    does. Otherwise, we can end up with crashes when we get a diagnostic
    outside of parsing/code completion. The circumstances under which this
    happen are really hard to reproduce, because a file needs to change
    from under us.

Modified:
    cfe/branches/Apple/whitney/include/clang/Frontend/ASTUnit.h
    cfe/branches/Apple/whitney/include/clang/Frontend/CompilerInstance.h
    cfe/branches/Apple/whitney/lib/Frontend/ASTUnit.cpp
    cfe/branches/Apple/whitney/lib/Frontend/CompilerInstance.cpp
    cfe/branches/Apple/whitney/test/Index/complete-driver-errors.c
    cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp

Modified: cfe/branches/Apple/whitney/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/Frontend/ASTUnit.h?rev=119252&r1=119251&r2=119252&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/branches/Apple/whitney/include/clang/Frontend/ASTUnit.h Mon Nov 15 15:46:16 2010
@@ -91,7 +91,7 @@
 
   /// \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 @@
   /// \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 @@
                                     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,

Modified: cfe/branches/Apple/whitney/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/Frontend/CompilerInstance.h?rev=119252&r1=119251&r2=119252&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/branches/Apple/whitney/include/clang/Frontend/CompilerInstance.h Mon Nov 15 15:46:16 2010
@@ -477,8 +477,14 @@
   /// 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 @@
   /// 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();

Modified: cfe/branches/Apple/whitney/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Frontend/ASTUnit.cpp?rev=119252&r1=119251&r2=119252&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Frontend/ASTUnit.cpp Mon Nov 15 15:46:16 2010
@@ -416,7 +416,7 @@
 
 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) {
@@ -457,6 +457,22 @@
                                    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,
@@ -465,16 +481,10 @@
                                   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);
@@ -484,10 +494,6 @@
   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
@@ -718,9 +724,6 @@
   // 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(),
@@ -1211,9 +1214,6 @@
   
   // 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(),
@@ -1379,20 +1379,14 @@
                                              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);
@@ -1405,22 +1399,19 @@
                                     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;
@@ -1434,9 +1425,9 @@
   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.
@@ -1469,12 +1460,12 @@
     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,
@@ -1496,9 +1487,10 @@
   // 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();
@@ -1831,7 +1823,7 @@
   Clang.setDiagnostics(&Diag);
   ProcessWarningOptions(Diag, CCInvocation.getDiagnosticOpts());
   CaptureDroppedDiagnostics Capture(true, 
-                                    Clang.getDiagnostics(),
+                                    Clang.getDiagnostics(), 
                                     StoredDiagnostics);
   
   // Create the target instance.

Modified: cfe/branches/Apple/whitney/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Frontend/CompilerInstance.cpp?rev=119252&r1=119251&r2=119252&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Frontend/CompilerInstance.cpp Mon Nov 15 15:46:16 2010
@@ -113,19 +113,23 @@
   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)

Modified: cfe/branches/Apple/whitney/test/Index/complete-driver-errors.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/test/Index/complete-driver-errors.c?rev=119252&r1=119251&r2=119252&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/test/Index/complete-driver-errors.c (original)
+++ cfe/branches/Apple/whitney/test/Index/complete-driver-errors.c Mon Nov 15 15:46:16 2010
@@ -2,20 +2,21 @@
 
 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

Modified: cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp?rev=119252&r1=119251&r2=119252&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp (original)
+++ cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp Mon Nov 15 15:46:16 2010
@@ -2186,9 +2186,9 @@
                                  Diags,
                                  CXXIdx->getClangResourcesPath(),
                                  CXXIdx->getOnlyLocalDecls(),
+                                 /*CaptureDiagnostics=*/true,
                                  RemappedFiles.data(),
                                  RemappedFiles.size(),
-                                 /*CaptureDiagnostics=*/true,
                                  PrecompilePreamble,
                                  CompleteTranslationUnit,
                                  CacheCodeCompetionResults,





More information about the llvm-branch-commits mailing list