зеркало из https://github.com/microsoft/clang.git
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:
Родитель
cd1eecfe4f
Коммит
4f32786ac4
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче