Improve crash recovery cleanup to recovery CompilerInstances during crash recovery. This was a huge resource "root" during crashes.

This change requires making a bunch of fundamental Clang structures (optionally) reference counted to allow correct
ownership semantics of these objects (e.g., ASTContext) to play out between an active ASTUnit and CompilerInstance
object.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128011 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2011-03-21 18:40:17 +00:00
Родитель cd1eecfe4f
Коммит 4f32786ac4
13 изменённых файлов: 141 добавлений и 163 удалений

Просмотреть файл

@ -28,6 +28,7 @@
#include "clang/AST/UsuallyTinyPtrVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
@ -78,7 +79,7 @@ namespace clang {
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
class ASTContext : public llvm::RefCountedBase<ASTContext> {
ASTContext &this_() { return *this; }
mutable std::vector<Type*> Types;

Просмотреть файл

@ -15,6 +15,7 @@
#define LLVM_CLANG_FILEMANAGER_H
#include "clang/Basic/FileSystemOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@ -105,7 +106,7 @@ public:
/// properties, such as uniquing files based on "inode", so that a file with two
/// names (e.g. symlinked) will be treated as a single file.
///
class FileManager {
class FileManager : public llvm::RefCountedBase<FileManager> {
FileSystemOptions FileSystemOpts;
class UniqueDirContainer;

Просмотреть файл

@ -19,6 +19,7 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/DenseMap.h"
#include <vector>
#include <cassert>
@ -378,7 +379,7 @@ public:
/// user's view. In the case of a macro expansion, for example, the spelling
/// location indicates where the expanded token came from and the instantiation
/// location specifies where it was expanded.
class SourceManager {
class SourceManager : public llvm::RefCountedBase<SourceManager> {
/// \brief Diagnostic object.
Diagnostic &Diag;

Просмотреть файл

@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
#define LLVM_CLANG_BASIC_TARGETINFO_H
// FIXME: Daniel isn't smart enough to use a prototype for this.
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
@ -57,7 +57,7 @@ enum TargetCXXABI {
/// TargetInfo - This class exposes information about the current target.
///
class TargetInfo {
class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
llvm::Triple Triple;
protected:
// Target values set by the ctor of the actual target implementation. Default

Просмотреть файл

@ -71,12 +71,12 @@ public:
private:
llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
llvm::OwningPtr<FileManager> FileMgr;
llvm::OwningPtr<SourceManager> SourceMgr;
llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr;
llvm::OwningPtr<HeaderSearch> HeaderInfo;
llvm::OwningPtr<TargetInfo> Target;
llvm::OwningPtr<Preprocessor> PP;
llvm::OwningPtr<ASTContext> Ctx;
llvm::IntrusiveRefCntPtr<TargetInfo> Target;
llvm::IntrusiveRefCntPtr<Preprocessor> PP;
llvm::IntrusiveRefCntPtr<ASTContext> Ctx;
FileSystemOptions FileSystemOpts;
@ -90,7 +90,7 @@ private:
/// Optional owned invocation, just used to make the invocation used in
/// LoadFromCommandLine available.
llvm::OwningPtr<CompilerInvocation> Invocation;
llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
/// \brief The set of target features.
///
@ -396,11 +396,11 @@ public:
const SourceManager &getSourceManager() const { return *SourceMgr; }
SourceManager &getSourceManager() { return *SourceMgr; }
const Preprocessor &getPreprocessor() const { return *PP.get(); }
Preprocessor &getPreprocessor() { return *PP.get(); }
const Preprocessor &getPreprocessor() const { return *PP; }
Preprocessor &getPreprocessor() { return *PP; }
const ASTContext &getASTContext() const { return *Ctx.get(); }
ASTContext &getASTContext() { return *Ctx.get(); }
const ASTContext &getASTContext() const { return *Ctx; }
ASTContext &getASTContext() { return *Ctx; }
bool hasSema() const { return TheSema; }
Sema &getSema() const {

Просмотреть файл

@ -59,25 +59,25 @@ class TargetInfo;
/// and a long form that takes explicit instances of any required objects.
class CompilerInstance {
/// The options used in this compiler instance.
llvm::OwningPtr<CompilerInvocation> Invocation;
llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
/// The diagnostics engine instance.
llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
/// The target being compiled for.
llvm::OwningPtr<TargetInfo> Target;
llvm::IntrusiveRefCntPtr<TargetInfo> Target;
/// The file manager.
llvm::OwningPtr<FileManager> FileMgr;
llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
/// The source manager.
llvm::OwningPtr<SourceManager> SourceMgr;
llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr;
/// The preprocessor.
llvm::OwningPtr<Preprocessor> PP;
llvm::IntrusiveRefCntPtr<Preprocessor> PP;
/// The AST context.
llvm::OwningPtr<ASTContext> Context;
llvm::IntrusiveRefCntPtr<ASTContext> Context;
/// The AST consumer.
llvm::OwningPtr<ASTConsumer> Consumer;
@ -161,10 +161,7 @@ public:
return *Invocation;
}
CompilerInvocation *takeInvocation() { return Invocation.take(); }
/// setInvocation - Replace the current invocation; the compiler instance
/// takes ownership of \arg Value.
/// setInvocation - Replace the current invocation.
void setInvocation(CompilerInvocation *Value);
/// }
@ -251,13 +248,13 @@ public:
bool hasDiagnostics() const { return Diagnostics != 0; }
/// Get the current diagnostics engine.
Diagnostic &getDiagnostics() const {
assert(Diagnostics && "Compiler instance has no diagnostics!");
return *Diagnostics;
}
/// setDiagnostics - Replace the current diagnostics engine; the compiler
/// instance takes ownership of \arg Value.
/// setDiagnostics - Replace the current diagnostics engine.
void setDiagnostics(Diagnostic *Value);
DiagnosticClient &getDiagnosticClient() const {
@ -277,12 +274,7 @@ public:
return *Target;
}
/// takeTarget - Remove the current diagnostics engine and give ownership
/// to the caller.
TargetInfo *takeTarget() { return Target.take(); }
/// setTarget - Replace the current diagnostics engine; the compiler
/// instance takes ownership of \arg Value.
/// Replace the current diagnostics engine.
void setTarget(TargetInfo *Value);
/// }
@ -291,17 +283,17 @@ public:
bool hasFileManager() const { return FileMgr != 0; }
/// Return the current file manager to the caller.
FileManager &getFileManager() const {
assert(FileMgr && "Compiler instance has no file manager!");
return *FileMgr;
}
void resetAndLeakFileManager() {
FileMgr.resetWithoutRelease();
}
/// takeFileManager - Remove the current file manager and give ownership to
/// the caller.
FileManager *takeFileManager() { return FileMgr.take(); }
/// setFileManager - Replace the current file manager; the compiler instance
/// takes ownership of \arg Value.
/// setFileManager - Replace the current file manager.
void setFileManager(FileManager *Value);
/// }
@ -310,17 +302,17 @@ public:
bool hasSourceManager() const { return SourceMgr != 0; }
/// Return the current source manager.
SourceManager &getSourceManager() const {
assert(SourceMgr && "Compiler instance has no source manager!");
return *SourceMgr;
}
void resetAndLeakSourceManager() {
SourceMgr.resetWithoutRelease();
}
/// takeSourceManager - Remove the current source manager and give ownership
/// to the caller.
SourceManager *takeSourceManager() { return SourceMgr.take(); }
/// setSourceManager - Replace the current source manager; the compiler
/// instance takes ownership of \arg Value.
/// setSourceManager - Replace the current source manager.
void setSourceManager(SourceManager *Value);
/// }
@ -329,17 +321,17 @@ public:
bool hasPreprocessor() const { return PP != 0; }
/// Return the current preprocessor.
Preprocessor &getPreprocessor() const {
assert(PP && "Compiler instance has no preprocessor!");
return *PP;
}
/// takePreprocessor - Remove the current preprocessor and give ownership to
/// the caller.
Preprocessor *takePreprocessor() { return PP.take(); }
void resetAndLeakPreprocessor() {
PP.resetWithoutRelease();
}
/// setPreprocessor - Replace the current preprocessor; the compiler instance
/// takes ownership of \arg Value.
/// Replace the current preprocessor.
void setPreprocessor(Preprocessor *Value);
/// }
@ -352,13 +344,12 @@ public:
assert(Context && "Compiler instance has no AST context!");
return *Context;
}
void resetAndLeakASTContext() {
Context.resetWithoutRelease();
}
/// takeASTContext - Remove the current AST context and give ownership to the
/// caller.
ASTContext *takeASTContext() { return Context.take(); }
/// setASTContext - Replace the current AST context; the compiler instance
/// takes ownership of \arg Value.
/// setASTContext - Replace the current AST context.
void setASTContext(ASTContext *Value);
/// \brief Replace the current Sema; the compiler instance takes ownership

Просмотреть файл

@ -22,6 +22,7 @@
#include "clang/Frontend/LangStandard.h"
#include "clang/Frontend/PreprocessorOptions.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
#include <string>
@ -41,7 +42,7 @@ class Diagnostic;
/// This class is designed to represent an abstract "invocation" of the
/// compiler, including data such as the include paths, the code generation
/// options, the warning flags, and so on.
class CompilerInvocation {
class CompilerInvocation : public llvm::RefCountedBase<CompilerInvocation> {
/// Options controlling the static analyzer.
AnalyzerOptions AnalyzerOpts;

Просмотреть файл

@ -25,6 +25,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
@ -53,7 +54,7 @@ class PreprocessingRecord;
/// single source file, and don't know anything about preprocessor-level issues
/// like the #include stack, token expansion, etc.
///
class Preprocessor {
class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
Diagnostic *Diags;
LangOptions Features;
const TargetInfo &Target;

Просмотреть файл

@ -121,7 +121,7 @@ ASTUnit::~ASTUnit() {
// perform this operation here because we explicitly request that the
// compiler instance *not* free these buffers for each invocation of the
// parser.
if (Invocation.get() && OwnsRemappedFileBuffers) {
if (Invocation.getPtr() && OwnsRemappedFileBuffers) {
PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
for (PreprocessorOptions::remapped_file_buffer_iterator
FB = PPOpts.remapped_file_buffer_begin(),
@ -512,9 +512,9 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->Diagnostics = Diags;
AST->FileMgr.reset(new FileManager(FileSystemOpts));
AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics(),
AST->getFileManager()));
AST->FileMgr = new FileManager(FileSystemOpts);
AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
AST->getFileManager());
AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
for (unsigned I = 0; I != NumRemappedFiles; ++I) {
@ -602,12 +602,11 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
TargetOpts.CPU = "";
TargetOpts.Features.clear();
TargetOpts.Triple = TargetTriple;
AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
TargetOpts));
AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo,
*AST->Target.get(),
AST->getSourceManager(), HeaderInfo));
Preprocessor &PP = *AST->PP.get();
AST->Target = TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
TargetOpts);
AST->PP = new Preprocessor(AST->getDiagnostics(), LangInfo, *AST->Target,
AST->getSourceManager(), HeaderInfo);
Preprocessor &PP = *AST->PP;
PP.setPredefines(Reader->getSuggestedPredefines());
PP.setCounterValue(Counter);
@ -615,14 +614,14 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
// Create and initialize the ASTContext.
AST->Ctx.reset(new ASTContext(LangInfo,
AST->getSourceManager(),
*AST->Target.get(),
PP.getIdentifierTable(),
PP.getSelectorTable(),
PP.getBuiltinInfo(),
/* size_reserve = */0));
ASTContext &Context = *AST->Ctx.get();
AST->Ctx = new ASTContext(LangInfo,
AST->getSourceManager(),
*AST->Target,
PP.getIdentifierTable(),
PP.getSelectorTable(),
PP.getBuiltinInfo(),
/* size_reserve = */0);
ASTContext &Context = *AST->Ctx;
Reader->InitializeContext(Context);
@ -842,7 +841,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
delete SavedMainFileBuffer;
SavedMainFileBuffer = 0;
if (!Invocation.get()) {
if (!Invocation) {
delete OverrideMainBuffer;
return true;
}
@ -855,7 +854,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
CICleanup(llvm::CrashRecoveryContextCleanup::
create<CompilerInstance>(Clang.get()));
Clang->setInvocation(Invocation.take());
Clang->setInvocation(&*Invocation);
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
// Set up diagnostics, capturing any diagnostics that would
@ -865,7 +864,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
// Create the target instance.
Clang->getTargetOpts().Features = TargetFeatures;
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
Clang->getTargetOpts()));
Clang->getTargetOpts()));
if (!Clang->hasTarget()) {
delete OverrideMainBuffer;
return true;
@ -887,11 +886,11 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
// Configure the various subsystems.
// FIXME: Should we retain the previous file manager?
FileSystemOpts = Clang->getFileSystemOpts();
FileMgr.reset(new FileManager(FileSystemOpts));
SourceMgr.reset(new SourceManager(getDiagnostics(), *FileMgr));
FileMgr = new FileManager(FileSystemOpts);
SourceMgr = new SourceManager(getDiagnostics(), *FileMgr);
TheSema.reset();
Ctx.reset();
PP.reset();
Ctx = 0;
PP = 0;
// Clear out old caches and data.
TopLevelDecls.clear();
@ -954,15 +953,14 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
Act->Execute();
// Steal the created target, context, and preprocessor, and take back the
// source and file managers.
// Steal the created target, context, and preprocessor.
TheSema.reset(Clang->takeSema());
Consumer.reset(Clang->takeASTConsumer());
Ctx.reset(Clang->takeASTContext());
PP.reset(Clang->takePreprocessor());
Clang->takeSourceManager();
Clang->takeFileManager();
Target.reset(Clang->takeTarget());
Ctx = &Clang->getASTContext();
PP = &Clang->getPreprocessor();
Clang->setSourceManager(0);
Clang->setFileManager(0);
Target = &Clang->getTarget();
Act->EndSourceFile();
@ -973,9 +971,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude;
}
Invocation.reset(Clang->takeInvocation());
return false;
error:
// Remove the overridden buffer we used for the preamble.
if (OverrideMainBuffer) {
@ -987,9 +984,6 @@ error:
}
StoredDiagnostics.clear();
Clang->takeSourceManager();
Clang->takeFileManager();
Invocation.reset(Clang->takeInvocation());
return true;
}
@ -1392,13 +1386,12 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
// Create the source manager.
Clang->setSourceManager(new SourceManager(getDiagnostics(),
Clang->getFileManager()));
Clang->getFileManager()));
llvm::OwningPtr<PrecompilePreambleAction> Act;
Act.reset(new PrecompilePreambleAction(*this));
if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second,
Clang->getFrontendOpts().Inputs[0].first)) {
Clang->takeInvocation();
llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
Preamble.clear();
PreambleRebuildCounter = DefaultPreambleRebuildInterval;
@ -1409,8 +1402,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
Act->Execute();
Act->EndSourceFile();
Clang->takeInvocation();
if (Diagnostics->hasErrorOccurred()) {
// There were errors parsing the preamble, so no precompiled header was
// generated. Forget that we even tried.
@ -1548,10 +1540,10 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI,
AST.reset(new ASTUnit(false));
ConfigureDiags(Diags, 0, 0, *AST, /*CaptureDiagnostics=*/false);
AST->Diagnostics = Diags;
AST->Invocation.reset(CI);
AST->Invocation = CI;
AST->FileSystemOpts = CI->getFileSystemOpts();
AST->FileMgr.reset(new FileManager(AST->FileSystemOpts));
AST->SourceMgr.reset(new SourceManager(*Diags, *AST->FileMgr));
AST->FileMgr = new FileManager(AST->FileSystemOpts);
AST->SourceMgr = new SourceManager(*Diags, *AST->FileMgr);
return AST.take();
}
@ -1597,7 +1589,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->CompleteTranslationUnit = CompleteTranslationUnit;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
AST->Invocation.reset(CI);
AST->Invocation = CI;
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar
@ -1639,7 +1631,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
llvm::OwningPtr<CompilerInvocation> CI;
llvm::IntrusiveRefCntPtr<CompilerInvocation> CI;
{
CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
@ -1679,7 +1671,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
}
const driver::ArgStringList &CCArgs = Cmd->getArguments();
CI.reset(new CompilerInvocation);
CI = new CompilerInvocation();
CompilerInvocation::CreateFromArgs(*CI,
const_cast<const char **>(CCArgs.data()),
const_cast<const char **>(CCArgs.data()) +
@ -1721,7 +1713,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
AST->Diagnostics = Diags;
AST->FileSystemOpts = CI->getFileSystemOpts();
AST->FileMgr.reset(new FileManager(AST->FileSystemOpts));
AST->FileMgr = new FileManager(AST->FileSystemOpts);
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->CompleteTranslationUnit = CompleteTranslationUnit;
@ -1729,7 +1721,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
AST->NumStoredDiagnosticsInPreamble = StoredDiagnostics.size();
AST->StoredDiagnostics.swap(StoredDiagnostics);
AST->Invocation.reset(CI.take());
AST->Invocation = CI;
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar
@ -1740,7 +1732,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
}
bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
if (!Invocation.get())
if (!Invocation)
return true;
SimpleTimer ParsingTimer(WantTiming);
@ -2036,16 +2028,18 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
SourceManager &SourceMgr, FileManager &FileMgr,
llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
if (!Invocation.get())
if (!Invocation)
return;
SimpleTimer CompletionTimer(WantTiming);
CompletionTimer.setOutput("Code completion @ " + File + ":" +
llvm::Twine(Line) + ":" + llvm::Twine(Column));
CompilerInvocation CCInvocation(*Invocation);
FrontendOptions &FrontendOpts = CCInvocation.getFrontendOpts();
PreprocessorOptions &PreprocessorOpts = CCInvocation.getPreprocessorOpts();
llvm::IntrusiveRefCntPtr<CompilerInvocation>
CCInvocation(new CompilerInvocation(*Invocation));
FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
FrontendOpts.ShowMacrosInCodeCompletion
= IncludeMacros && CachedCompletionResults.empty();
@ -2057,7 +2051,7 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
FrontendOpts.CodeCompletionAt.Column = Column;
// Set the language options appropriately.
LangOpts = CCInvocation.getLangOpts();
LangOpts = CCInvocation->getLangOpts();
llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
@ -2066,12 +2060,12 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
CICleanup(llvm::CrashRecoveryContextCleanup::
create<CompilerInstance>(Clang.get()));
Clang->setInvocation(&CCInvocation);
Clang->setInvocation(&*CCInvocation);
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
// Set up diagnostics, capturing any diagnostics produced.
Clang->setDiagnostics(&Diag);
ProcessWarningOptions(Diag, CCInvocation.getDiagnosticOpts());
ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts());
CaptureDroppedDiagnostics Capture(true,
Clang->getDiagnostics(),
StoredDiagnostics);
@ -2081,7 +2075,7 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
Clang->getTargetOpts()));
if (!Clang->hasTarget()) {
Clang->takeInvocation();
Clang->setInvocation(0);
return;
}
@ -2140,7 +2134,7 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
if (const FileStatus *MainStatus = MainPath.getFileStatus())
if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID())
OverrideMainBuffer
= getMainBufferWithPrecompiledPreamble(CCInvocation, false,
= getMainBufferWithPrecompiledPreamble(*CCInvocation, false,
Line - 1);
}
@ -2182,11 +2176,6 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
Act->Execute();
Act->EndSourceFile();
}
// Steal back our resources.
Clang->takeFileManager();
Clang->takeSourceManager();
Clang->takeInvocation();
}
bool ASTUnit::Save(llvm::StringRef File) {

Просмотреть файл

@ -47,7 +47,7 @@ CompilerInstance::~CompilerInstance() {
}
void CompilerInstance::setInvocation(CompilerInvocation *Value) {
Invocation.reset(Value);
Invocation = Value;
}
void CompilerInstance::setDiagnostics(Diagnostic *Value) {
@ -55,24 +55,20 @@ void CompilerInstance::setDiagnostics(Diagnostic *Value) {
}
void CompilerInstance::setTarget(TargetInfo *Value) {
Target.reset(Value);
Target = Value;
}
void CompilerInstance::setFileManager(FileManager *Value) {
FileMgr.reset(Value);
FileMgr = Value;
}
void CompilerInstance::setSourceManager(SourceManager *Value) {
SourceMgr.reset(Value);
void CompilerInstance::setSourceManager(SourceManager *Value) {
SourceMgr = Value;
}
void CompilerInstance::setPreprocessor(Preprocessor *Value) {
PP.reset(Value);
}
void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
void CompilerInstance::setASTContext(ASTContext *Value) {
Context.reset(Value);
}
void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
void CompilerInstance::setSema(Sema *S) {
TheSema.reset(S);
@ -145,23 +141,23 @@ CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
// File Manager
void CompilerInstance::createFileManager() {
FileMgr.reset(new FileManager(getFileSystemOpts()));
FileMgr = new FileManager(getFileSystemOpts());
}
// Source Manager
void CompilerInstance::createSourceManager(FileManager &FileMgr) {
SourceMgr.reset(new SourceManager(getDiagnostics(), FileMgr));
SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
}
// Preprocessor
void CompilerInstance::createPreprocessor() {
PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(),
getPreprocessorOpts(), getHeaderSearchOpts(),
getDependencyOutputOpts(), getTarget(),
getFrontendOpts(), getSourceManager(),
getFileManager()));
PP = createPreprocessor(getDiagnostics(), getLangOpts(),
getPreprocessorOpts(), getHeaderSearchOpts(),
getDependencyOutputOpts(), getTarget(),
getFrontendOpts(), getSourceManager(),
getFileManager());
}
Preprocessor *
@ -219,10 +215,10 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags,
void CompilerInstance::createASTContext() {
Preprocessor &PP = getPreprocessor();
Context.reset(new ASTContext(getLangOpts(), PP.getSourceManager(),
getTarget(), PP.getIdentifierTable(),
PP.getSelectorTable(), PP.getBuiltinInfo(),
/*size_reserve=*/ 0));
Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
getTarget(), PP.getIdentifierTable(),
PP.getSelectorTable(), PP.getBuiltinInfo(),
/*size_reserve=*/ 0);
}
// ExternalASTSource

Просмотреть файл

@ -258,10 +258,10 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
// matching EndSourceFile().
failure:
if (isCurrentFileAST()) {
CI.takeASTContext();
CI.takePreprocessor();
CI.takeSourceManager();
CI.takeFileManager();
CI.setASTContext(0);
CI.setPreprocessor(0);
CI.setSourceManager(0);
CI.setFileManager(0);
}
CI.getDiagnosticClient().EndSourceFile();
@ -313,7 +313,7 @@ void FrontendAction::EndSourceFile() {
CI.takeASTConsumer();
if (!isCurrentFileAST()) {
CI.takeSema();
CI.takeASTContext();
CI.resetAndLeakASTContext();
}
} else {
if (!isCurrentFileAST()) {
@ -342,10 +342,10 @@ void FrontendAction::EndSourceFile() {
if (isCurrentFileAST()) {
CI.takeSema();
CI.takeASTContext();
CI.takePreprocessor();
CI.takeSourceManager();
CI.takeFileManager();
CI.resetAndLeakASTContext();
CI.resetAndLeakPreprocessor();
CI.resetAndLeakSourceManager();
CI.resetAndLeakFileManager();
}
setCompilerInstance(0);

Просмотреть файл

@ -149,11 +149,8 @@ bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
if (!Clang->getDiagnostics().hasErrorOccurred()) {
// Create and execute the frontend action.
llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang));
if (Act) {
if (Act)
Success = Clang->ExecuteAction(*Act);
if (Clang->getFrontendOpts().DisableFree)
Act.take();
}
}
return Success;

Просмотреть файл

@ -216,10 +216,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
FileSystemOptions FileSystemOpts;
/// \brief File manager, used for diagnostics.
FileManager FileMgr;
llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
/// \brief Source manager, used for diagnostics.
SourceManager SourceMgr;
llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr;
/// \brief Temporary files that should be removed once we have finished
/// with the code-completion results.
@ -249,8 +249,8 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
Diag(new Diagnostic(
llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs))),
FileSystemOpts(FileSystemOpts),
FileMgr(FileSystemOpts),
SourceMgr(*Diag, FileMgr) {
FileMgr(new FileManager(FileSystemOpts)),
SourceMgr(new SourceManager(*Diag, *FileMgr)) {
if (getenv("LIBCLANG_OBJTRACKING")) {
llvm::sys::AtomicIncrement(&CodeCompletionResultObjects);
fprintf(stderr, "+++ %d completion results\n", CodeCompletionResultObjects);
@ -396,8 +396,8 @@ void clang_codeCompleteAt_Impl(void *UserData) {
(options & CXCodeComplete_IncludeMacros),
(options & CXCodeComplete_IncludeCodePatterns),
Capture,
*Results->Diag, Results->LangOpts, Results->SourceMgr,
Results->FileMgr, Results->Diagnostics,
*Results->Diag, Results->LangOpts, *Results->SourceMgr,
*Results->FileMgr, Results->Diagnostics,
Results->TemporaryBuffers);
// Keep a reference to the allocator used for cached global completions, so