[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