зеркало из https://github.com/microsoft/clang.git
When compiling a module on-demand, re-use the diagnostics client
already provided. This required a little bit of clean-up in the way that VerifyDiagnosticsClient managed ownership of its underlying "primary" client, because now it will no longer always take ownership. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139570 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
21cae2059a
Коммит
78243658c5
|
@ -315,6 +315,9 @@ public:
|
|||
DiagnosticClient *getClient() { return Client; }
|
||||
const DiagnosticClient *getClient() const { return Client; }
|
||||
|
||||
/// \brief Determine whether this \c Diagnostic object own its client.
|
||||
bool ownsClient() const { return OwnsDiagClient; }
|
||||
|
||||
/// \brief Return the current diagnostic client along with ownership of that
|
||||
/// client.
|
||||
DiagnosticClient *takeClient() {
|
||||
|
|
|
@ -457,8 +457,12 @@ public:
|
|||
/// \param Client If non-NULL, a diagnostic client that will be
|
||||
/// attached to (and, then, owned by) the Diagnostic inside this AST
|
||||
/// unit.
|
||||
///
|
||||
/// \param ShouldOwnClient If Client is non-NULL, specifies whether
|
||||
/// the diagnostic object should take ownership of the client.
|
||||
void createDiagnostics(int Argc, const char* const *Argv,
|
||||
DiagnosticClient *Client = 0);
|
||||
DiagnosticClient *Client = 0,
|
||||
bool ShouldOwnClient = true);
|
||||
|
||||
/// Create a Diagnostic object with a the TextDiagnosticPrinter.
|
||||
///
|
||||
|
@ -487,6 +491,7 @@ public:
|
|||
createDiagnostics(const DiagnosticOptions &Opts, int Argc,
|
||||
const char* const *Argv,
|
||||
DiagnosticClient *Client = 0,
|
||||
bool ShouldOwnClient = true,
|
||||
const CodeGenOptions *CodeGenOpts = 0);
|
||||
|
||||
/// Create the file manager and replace any existing one with it.
|
||||
|
|
|
@ -65,7 +65,8 @@ class TextDiagnosticBuffer;
|
|||
class VerifyDiagnosticsClient : public DiagnosticClient {
|
||||
public:
|
||||
Diagnostic &Diags;
|
||||
llvm::OwningPtr<DiagnosticClient> PrimaryClient;
|
||||
DiagnosticClient *PrimaryClient;
|
||||
bool OwnsPrimaryClient;
|
||||
llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
|
||||
Preprocessor *CurrentPreprocessor;
|
||||
|
||||
|
@ -75,10 +76,9 @@ private:
|
|||
|
||||
public:
|
||||
/// Create a new verifying diagnostic client, which will issue errors to \arg
|
||||
/// PrimaryClient when a diagnostic does not match what is expected (as
|
||||
/// indicated in the source file). The verifying diagnostic client takes
|
||||
/// ownership of \arg PrimaryClient.
|
||||
VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient);
|
||||
/// the currently-attached diagnostic client when a diagnostic does not match
|
||||
/// what is expected (as indicated in the source file).
|
||||
VerifyDiagnosticsClient(Diagnostic &Diags);
|
||||
~VerifyDiagnosticsClient();
|
||||
|
||||
virtual void BeginSourceFile(const LangOptions &LangOpts,
|
||||
|
|
|
@ -140,15 +140,17 @@ static void SetUpDiagnosticLog(const DiagnosticOptions &DiagOpts,
|
|||
}
|
||||
|
||||
void CompilerInstance::createDiagnostics(int Argc, const char* const *Argv,
|
||||
DiagnosticClient *Client) {
|
||||
DiagnosticClient *Client,
|
||||
bool ShouldOwnClient) {
|
||||
Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv, Client,
|
||||
&getCodeGenOpts());
|
||||
ShouldOwnClient, &getCodeGenOpts());
|
||||
}
|
||||
|
||||
llvm::IntrusiveRefCntPtr<Diagnostic>
|
||||
CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
|
||||
int Argc, const char* const *Argv,
|
||||
DiagnosticClient *Client,
|
||||
bool ShouldOwnClient,
|
||||
const CodeGenOptions *CodeGenOpts) {
|
||||
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
|
||||
llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID));
|
||||
|
@ -156,13 +158,13 @@ CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
|
|||
// Create the diagnostic client for reporting errors or for
|
||||
// implementing -verify.
|
||||
if (Client)
|
||||
Diags->setClient(Client);
|
||||
Diags->setClient(Client, ShouldOwnClient);
|
||||
else
|
||||
Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
|
||||
|
||||
// Chain in -verify checker, if requested.
|
||||
if (Opts.VerifyDiagnostics)
|
||||
Diags->setClient(new VerifyDiagnosticsClient(*Diags, Diags->takeClient()));
|
||||
Diags->setClient(new VerifyDiagnosticsClient(*Diags));
|
||||
|
||||
// Chain in -diagnostic-log-file dumper, if requested.
|
||||
if (!Opts.DiagnosticLogFile.empty())
|
||||
|
@ -659,6 +661,9 @@ static void compileModule(CompilerInstance &ImportingInstance,
|
|||
FrontendOpts.Inputs.push_back(
|
||||
std::make_pair(getSourceInputKindFromOptions(Invocation->getLangOpts()),
|
||||
UmbrellaHeader));
|
||||
|
||||
Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
|
||||
|
||||
// FIXME: Strip away all of the compilation options that won't be transferred
|
||||
// down to the module. This presumably includes -D flags, optimization
|
||||
// settings, etc.
|
||||
|
@ -667,9 +672,9 @@ static void compileModule(CompilerInstance &ImportingInstance,
|
|||
// module.
|
||||
CompilerInstance Instance;
|
||||
Instance.setInvocation(&*Invocation);
|
||||
// Instance.setDiagnostics(&ImportingInstance.getDiagnostics());
|
||||
// FIXME: Need to route diagnostics over to the same diagnostic client!
|
||||
Instance.createDiagnostics(0, 0, 0);
|
||||
Instance.createDiagnostics(/*argc=*/0, /*argv=*/0,
|
||||
&ImportingInstance.getDiagnosticClient(),
|
||||
/*ShouldOwnClient=*/false);
|
||||
|
||||
// Construct a module-generating action.
|
||||
GeneratePCHAction CreateModuleAction(true);
|
||||
|
@ -681,6 +686,12 @@ static void compileModule(CompilerInstance &ImportingInstance,
|
|||
// Tell the importing instance's file manager to forget about the module
|
||||
// file, since we've just created it.
|
||||
ImportingInstance.getFileManager().forgetFile(ModuleFile);
|
||||
|
||||
// Tell the diagnostic client that it's (re-)starting to process a source
|
||||
// file.
|
||||
ImportingInstance.getDiagnosticClient()
|
||||
.BeginSourceFile(ImportingInstance.getLangOpts(),
|
||||
&ImportingInstance.getPreprocessor());
|
||||
}
|
||||
|
||||
ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
|
||||
|
|
|
@ -20,14 +20,19 @@
|
|||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace clang;
|
||||
|
||||
VerifyDiagnosticsClient::VerifyDiagnosticsClient(Diagnostic &_Diags,
|
||||
DiagnosticClient *_Primary)
|
||||
: Diags(_Diags), PrimaryClient(_Primary),
|
||||
Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0) {
|
||||
VerifyDiagnosticsClient::VerifyDiagnosticsClient(Diagnostic &_Diags)
|
||||
: Diags(_Diags), PrimaryClient(Diags.getClient()),
|
||||
OwnsPrimaryClient(Diags.ownsClient()),
|
||||
Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0)
|
||||
{
|
||||
Diags.takeClient();
|
||||
}
|
||||
|
||||
VerifyDiagnosticsClient::~VerifyDiagnosticsClient() {
|
||||
CheckDiagnostics();
|
||||
Diags.takeClient();
|
||||
if (OwnsPrimaryClient)
|
||||
delete PrimaryClient;
|
||||
}
|
||||
|
||||
// DiagnosticClient interface.
|
||||
|
@ -477,8 +482,9 @@ void VerifyDiagnosticsClient::CheckDiagnostics() {
|
|||
ExpectedData ED;
|
||||
|
||||
// Ensure any diagnostics go to the primary client.
|
||||
bool OwnsCurClient = Diags.ownsClient();
|
||||
DiagnosticClient *CurClient = Diags.takeClient();
|
||||
Diags.setClient(PrimaryClient.get());
|
||||
Diags.setClient(PrimaryClient, false);
|
||||
|
||||
// If we have a preprocessor, scan the source for expected diagnostic
|
||||
// markers. If not then any diagnostics are unexpected.
|
||||
|
@ -513,7 +519,7 @@ void VerifyDiagnosticsClient::CheckDiagnostics() {
|
|||
}
|
||||
|
||||
Diags.takeClient();
|
||||
Diags.setClient(CurClient);
|
||||
Diags.setClient(CurClient, OwnsCurClient);
|
||||
|
||||
// Reset the buffer, we have processed all the diagnostics in it.
|
||||
Buffer.reset(new TextDiagnosticBuffer());
|
||||
|
|
|
@ -112,7 +112,7 @@ static bool checkForMigration(StringRef resourcesPath,
|
|||
// Chain in -verify checker, if requested.
|
||||
VerifyDiagnosticsClient *verifyDiag = 0;
|
||||
if (VerifyDiags) {
|
||||
verifyDiag = new VerifyDiagnosticsClient(*Diags, Diags->takeClient());
|
||||
verifyDiag = new VerifyDiagnosticsClient(*Diags);
|
||||
Diags->setClient(verifyDiag);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче