Make Diagnostic reference-counted, which is simpler than juggling

maybe-ownership vs. ownership.

llvm-svn: 100498
This commit is contained in:
Douglas Gregor 2010-04-05 23:52:57 +00:00
parent 1a9b3f3484
commit 7f95d26e53
9 changed files with 41 additions and 63 deletions

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_DIAGNOSTIC_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/type_traits.h"
#include <string>
@ -150,7 +151,7 @@ public:
/// problems and issues. It massages the diagnostics (e.g. handling things like
/// "report warnings as errors" and passes them off to the DiagnosticClient for
/// reporting to the user.
class Diagnostic {
class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
public:
/// Level - The level of the diagnostic, after it has been through mapping.
enum Level {

View File

@ -16,6 +16,7 @@
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "clang/Basic/FileManager.h"
#include "clang/Index/ASTLocation.h"
@ -52,7 +53,7 @@ public:
typedef std::map<FileID, std::vector<PreprocessedEntity *> >
PreprocessedEntitiesByFileMap;
private:
llvm::MaybeOwningPtr<Diagnostic> Diagnostics;
llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
llvm::OwningPtr<FileManager> FileMgr;
llvm::OwningPtr<SourceManager> SourceMgr;
llvm::OwningPtr<HeaderSearch> HeaderInfo;
@ -214,7 +215,7 @@ public:
///
/// \returns - The initialized ASTUnit or null if the PCH failed to load.
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
llvm::MaybeOwningPtr<Diagnostic> Diags,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
bool OnlyLocalDecls = false,
RemappedFile *RemappedFiles = 0,
unsigned NumRemappedFiles = 0,
@ -232,7 +233,7 @@ public:
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
// shouldn't need to specify them at construction time.
static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
llvm::MaybeOwningPtr<Diagnostic> Diags,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
bool OnlyLocalDecls = false,
bool CaptureDiagnostics = false);
@ -252,7 +253,7 @@ public:
// shouldn't need to specify them at construction time.
static ASTUnit *LoadFromCommandLine(const char **ArgBegin,
const char **ArgEnd,
llvm::MaybeOwningPtr<Diagnostic> Diags,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls = false,
RemappedFile *RemappedFiles = 0,
@ -260,24 +261,6 @@ public:
bool CaptureDiagnostics = false);
};
/// \brief Return an potentially-owning pointer for the given diagnostic engine
/// that owns the pointer.
inline llvm::MaybeOwningPtr<Diagnostic> OwnedDiag(Diagnostic &Diags) {
return llvm::MaybeOwningPtr<Diagnostic>(&Diags, true);
}
/// \brief Return a potentially-owning pointer for the given diagnostic engine
/// that does not own the pointer.
inline llvm::MaybeOwningPtr<Diagnostic> UnownedDiag(Diagnostic &Diags) {
return llvm::MaybeOwningPtr<Diagnostic>(&Diags, false);
}
/// \brief Return an potentially-owning pointer that indicates that the
/// default diagnostic engine should be used.
inline llvm::MaybeOwningPtr<Diagnostic> DefaultDiag() {
return llvm::MaybeOwningPtr<Diagnostic>();
}
} // namespace clang
#endif

View File

@ -11,6 +11,7 @@
#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
#include "clang/Frontend/CompilerInvocation.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
#include <cassert>
@ -63,7 +64,7 @@ class CompilerInstance {
llvm::OwningPtr<CompilerInvocation> Invocation;
/// The diagnostics engine instance.
llvm::OwningPtr<Diagnostic> Diagnostics;
llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
/// The diagnostics client instance.
llvm::OwningPtr<DiagnosticClient> DiagClient;
@ -255,10 +256,6 @@ public:
return *Diagnostics;
}
/// takeDiagnostics - Remove the current diagnostics engine and give ownership
/// to the caller.
Diagnostic *takeDiagnostics() { return Diagnostics.take(); }
/// setDiagnostics - Replace the current diagnostics engine; the compiler
/// instance takes ownership of \arg Value.
void setDiagnostics(Diagnostic *Value);
@ -469,8 +466,8 @@ public:
/// must extend past that of the diagnostic engine.
///
/// \return The new object on success, or null on failure.
static Diagnostic *createDiagnostics(const DiagnosticOptions &Opts,
int Argc, char **Argv);
static llvm::IntrusiveRefCntPtr<Diagnostic>
createDiagnostics(const DiagnosticOptions &Opts, int Argc, char **Argv);
/// Create the file manager and replace any existing one with it.
void createFileManager();

View File

@ -12,6 +12,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTImporter.h"
#include "clang/Basic/Diagnostic.h"
using namespace clang;
@ -36,10 +37,9 @@ void ASTMergeAction::ExecuteAction() {
CI.getASTContext().getLangOptions());
CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
&CI.getASTContext());
llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I],
UnownedDiag(CI.getDiagnostics()),
false);
ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], Diags, false);
if (!Unit)
continue;

View File

@ -141,24 +141,22 @@ const std::string &ASTUnit::getPCHFileName() {
}
ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
llvm::MaybeOwningPtr<Diagnostic> Diags,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
bool OnlyLocalDecls,
RemappedFile *RemappedFiles,
unsigned NumRemappedFiles,
bool CaptureDiagnostics) {
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
if (Diags.get())
AST->Diagnostics = Diags;
else {
if (!Diags.getPtr()) {
// No diagnostics engine was provided, so create our own diagnostics object
// with the default options.
DiagnosticOptions DiagOpts;
AST->Diagnostics.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0),
true);
Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
}
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->Diagnostics = Diags;
AST->FileMgr.reset(new FileManager);
AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
@ -290,7 +288,7 @@ public:
}
ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
llvm::MaybeOwningPtr<Diagnostic> Diags,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
bool OnlyLocalDecls,
bool CaptureDiagnostics) {
// Create the compiler instance to use for building the AST.
@ -298,16 +296,16 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
llvm::OwningPtr<ASTUnit> AST;
llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
if (!Diags.get()) {
if (!Diags.getPtr()) {
// No diagnostics engine was provided, so create our own diagnostics object
// with the default options.
DiagnosticOptions DiagOpts;
Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0), true);
Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
}
Clang.setInvocation(CI);
Clang.setDiagnostics(Diags.get());
Clang.setDiagnostics(Diags.getPtr());
Clang.setDiagnosticClient(Diags->getClient());
// Create the target instance.
@ -315,7 +313,6 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
Clang.getTargetOpts()));
if (!Clang.hasTarget()) {
Clang.takeDiagnosticClient();
Clang.takeDiagnostics();
return 0;
}
@ -370,7 +367,6 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
Act->EndSourceFile();
Clang.takeDiagnosticClient();
Clang.takeDiagnostics();
Clang.takeInvocation();
AST->Invocation.reset(Clang.takeInvocation());
@ -380,23 +376,22 @@ error:
Clang.takeSourceManager();
Clang.takeFileManager();
Clang.takeDiagnosticClient();
Clang.takeDiagnostics();
return 0;
}
ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
const char **ArgEnd,
llvm::MaybeOwningPtr<Diagnostic> Diags,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls,
RemappedFile *RemappedFiles,
unsigned NumRemappedFiles,
bool CaptureDiagnostics) {
if (!Diags.get()) {
if (!Diags.getPtr()) {
// No diagnostics engine was provided, so create our own diagnostics object
// with the default options.
DiagnosticOptions DiagOpts;
Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0), true);
Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
}
llvm::SmallVector<const char *, 16> Args;

View File

@ -52,7 +52,7 @@ void CompilerInstance::setInvocation(CompilerInvocation *Value) {
}
void CompilerInstance::setDiagnostics(Diagnostic *Value) {
Diagnostics.reset(Value);
Diagnostics = Value;
}
void CompilerInstance::setDiagnosticClient(DiagnosticClient *Value) {
@ -130,15 +130,16 @@ static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
}
void CompilerInstance::createDiagnostics(int Argc, char **Argv) {
Diagnostics.reset(createDiagnostics(getDiagnosticOpts(), Argc, Argv));
Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv);
if (Diagnostics)
DiagClient.reset(Diagnostics->getClient());
}
Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
int Argc, char **Argv) {
llvm::OwningPtr<Diagnostic> Diags(new Diagnostic());
llvm::IntrusiveRefCntPtr<Diagnostic>
CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
int Argc, char **Argv) {
llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic());
// Create the diagnostic client for reporting errors or for
// implementing -verify.
@ -152,7 +153,7 @@ Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
Diags->setClient(DiagClient.take());
Diags->Report(diag::err_fe_stderr_binary);
return Diags.take();
return Diags;
} else {
DiagClient.reset(new BinaryDiagnosticSerializer(llvm::errs()));
}
@ -171,7 +172,7 @@ Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
// Configure our handling of diagnostics.
ProcessWarningOptions(*Diags, Opts);
return Diags.take();
return Diags;
}
// File Manager

View File

@ -45,9 +45,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
"Attempt to pass AST file to preprocessor only action!");
assert(hasASTSupport() && "This action does not have AST support!");
llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
std::string Error;
ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename,
UnownedDiag(CI.getDiagnostics()));
ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags);
if (!AST)
goto failure;

View File

@ -996,7 +996,8 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
return ASTUnit::LoadFromPCHFile(ast_filename, DefaultDiag(),
llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
return ASTUnit::LoadFromPCHFile(ast_filename, Diags,
CXXIdx->getOnlyLocalDecls(),
0, 0, true);
}
@ -1015,8 +1016,8 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
// Configure the diagnostics.
DiagnosticOptions DiagOpts;
llvm::MaybeOwningPtr<Diagnostic> Diags;
Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0), true);
llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
for (unsigned I = 0; I != num_unsaved_files; ++I) {

View File

@ -231,8 +231,8 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
// Configure the diagnostics.
DiagnosticOptions DiagOpts;
llvm::OwningPtr<Diagnostic> Diags;
Diags.reset(CompilerInstance::createDiagnostics(DiagOpts, 0, 0));
llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
// The set of temporary files that we've built.
std::vector<llvm::sys::Path> TemporaryFiles;