forked from OSchip/llvm-project
Implement soft reset of the diagnostics engine.
This patch implements soft reset and adds tests for soft reset success of the diagnostics engine. This allows us to recover from errors in clang-repl without resetting the pragma handlers' state. Differential revision: https://reviews.llvm.org/D126183
This commit is contained in:
parent
8c278a2781
commit
946c45a4ed
|
@ -545,6 +545,7 @@ public:
|
||||||
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
|
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
|
||||||
~DiagnosticsEngine();
|
~DiagnosticsEngine();
|
||||||
|
|
||||||
|
friend void DiagnosticsTestHelper(DiagnosticsEngine &);
|
||||||
LLVM_DUMP_METHOD void dump() const;
|
LLVM_DUMP_METHOD void dump() const;
|
||||||
LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
|
LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
|
||||||
|
|
||||||
|
@ -891,9 +892,9 @@ public:
|
||||||
LastDiagLevel = Other.LastDiagLevel;
|
LastDiagLevel = Other.LastDiagLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset the state of the diagnostic object to its initial
|
/// Reset the state of the diagnostic object to its initial configuration.
|
||||||
/// configuration.
|
/// \param[in] soft - if true, doesn't reset the diagnostic mappings and state
|
||||||
void Reset();
|
void Reset(bool soft = false);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DiagnosticsEngine classification and reporting interfaces.
|
// DiagnosticsEngine classification and reporting interfaces.
|
||||||
|
|
|
@ -130,7 +130,7 @@ bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiagnosticsEngine::Reset() {
|
void DiagnosticsEngine::Reset(bool soft /*=false*/) {
|
||||||
ErrorOccurred = false;
|
ErrorOccurred = false;
|
||||||
UncompilableErrorOccurred = false;
|
UncompilableErrorOccurred = false;
|
||||||
FatalErrorOccurred = false;
|
FatalErrorOccurred = false;
|
||||||
|
@ -145,15 +145,17 @@ void DiagnosticsEngine::Reset() {
|
||||||
LastDiagLevel = DiagnosticIDs::Ignored;
|
LastDiagLevel = DiagnosticIDs::Ignored;
|
||||||
DelayedDiagID = 0;
|
DelayedDiagID = 0;
|
||||||
|
|
||||||
// Clear state related to #pragma diagnostic.
|
if (!soft) {
|
||||||
DiagStates.clear();
|
// Clear state related to #pragma diagnostic.
|
||||||
DiagStatesByLoc.clear();
|
DiagStates.clear();
|
||||||
DiagStateOnPushStack.clear();
|
DiagStatesByLoc.clear();
|
||||||
|
DiagStateOnPushStack.clear();
|
||||||
|
|
||||||
// Create a DiagState and DiagStatePoint representing diagnostic changes
|
// Create a DiagState and DiagStatePoint representing diagnostic changes
|
||||||
// through command-line.
|
// through command-line.
|
||||||
DiagStates.emplace_back();
|
DiagStates.emplace_back();
|
||||||
DiagStatesByLoc.appendFirst(&DiagStates.back());
|
DiagStatesByLoc.appendFirst(&DiagStates.back());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
|
void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
|
||||||
|
|
|
@ -203,8 +203,8 @@ IncrementalParser::ParseOrWrapTopLevelDecl() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Do not reset the pragma handlers.
|
Diags.Reset(/*soft=*/true);
|
||||||
Diags.Reset();
|
Diags.getClient()->clear();
|
||||||
return llvm::make_error<llvm::StringError>("Parsing failed.",
|
return llvm::make_error<llvm::StringError>("Parsing failed.",
|
||||||
std::error_code());
|
std::error_code());
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,23 @@ static void LLVMErrorHandler(void *UserData, const char *Message,
|
||||||
exit(GenCrashDiag ? 70 : 1);
|
exit(GenCrashDiag ? 70 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are running with -verify a reported has to be returned as unsuccess.
|
||||||
|
// This is relevant especially for the test suite.
|
||||||
|
static int checkDiagErrors(const clang::CompilerInstance *CI) {
|
||||||
|
unsigned Errs = CI->getDiagnostics().getClient()->getNumErrors();
|
||||||
|
if (CI->getDiagnosticOpts().VerifyDiagnostics) {
|
||||||
|
// If there was an error that came from the verifier we must return 1 as
|
||||||
|
// an exit code for the process. This will make the test fail as expected.
|
||||||
|
clang::DiagnosticConsumer *Client = CI->getDiagnostics().getClient();
|
||||||
|
Client->EndSourceFile();
|
||||||
|
Errs = Client->getNumErrors();
|
||||||
|
|
||||||
|
// The interpreter expects BeginSourceFile/EndSourceFiles to be balanced.
|
||||||
|
Client->BeginSourceFile(CI->getLangOpts(), &CI->getPreprocessor());
|
||||||
|
}
|
||||||
|
return Errs ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
llvm::ExitOnError ExitOnErr;
|
llvm::ExitOnError ExitOnErr;
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv) {
|
||||||
ExitOnErr.setBanner("clang-repl: ");
|
ExitOnErr.setBanner("clang-repl: ");
|
||||||
|
@ -106,5 +123,5 @@ int main(int argc, const char **argv) {
|
||||||
|
|
||||||
llvm::llvm_shutdown();
|
llvm::llvm_shutdown();
|
||||||
|
|
||||||
return 0;
|
return checkDiagErrors(Interp->getCompilerInstance());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,15 @@
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
|
void clang::DiagnosticsTestHelper(DiagnosticsEngine &diag) {
|
||||||
|
unsigned delayedDiagID = 0U;
|
||||||
|
|
||||||
|
EXPECT_EQ(diag.DelayedDiagID, delayedDiagID);
|
||||||
|
EXPECT_FALSE(diag.DiagStates.empty());
|
||||||
|
EXPECT_TRUE(diag.DiagStatesByLoc.empty());
|
||||||
|
EXPECT_TRUE(diag.DiagStateOnPushStack.empty());
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Check that DiagnosticErrorTrap works with SuppressAllDiagnostics.
|
// Check that DiagnosticErrorTrap works with SuppressAllDiagnostics.
|
||||||
|
@ -71,6 +80,32 @@ TEST(DiagnosticTest, fatalsAsError) {
|
||||||
EXPECT_EQ(Diags.getNumWarnings(), FatalsAsError);
|
EXPECT_EQ(Diags.getNumWarnings(), FatalsAsError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that soft RESET works as intended
|
||||||
|
TEST(DiagnosticTest, softReset) {
|
||||||
|
DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
|
||||||
|
new IgnoringDiagConsumer());
|
||||||
|
|
||||||
|
unsigned numWarnings = 0U, numErrors = 0U;
|
||||||
|
|
||||||
|
Diags.Reset(true);
|
||||||
|
// Check For ErrorOccurred and TrapNumErrorsOccurred
|
||||||
|
EXPECT_FALSE(Diags.hasErrorOccurred());
|
||||||
|
EXPECT_FALSE(Diags.hasFatalErrorOccurred());
|
||||||
|
EXPECT_FALSE(Diags.hasUncompilableErrorOccurred());
|
||||||
|
// Check for UnrecoverableErrorOccurred and TrapNumUnrecoverableErrorsOccurred
|
||||||
|
EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred());
|
||||||
|
|
||||||
|
EXPECT_EQ(Diags.getNumWarnings(), numWarnings);
|
||||||
|
EXPECT_EQ(Diags.getNumErrors(), numErrors);
|
||||||
|
|
||||||
|
// Check for private variables of DiagnosticsEngine differentiating soft reset
|
||||||
|
DiagnosticsTestHelper(Diags);
|
||||||
|
|
||||||
|
EXPECT_FALSE(Diags.isDiagnosticInFlight());
|
||||||
|
EXPECT_TRUE(Diags.isLastDiagnosticIgnored());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(DiagnosticTest, diagnosticError) {
|
TEST(DiagnosticTest, diagnosticError) {
|
||||||
DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
|
DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
|
||||||
new IgnoringDiagConsumer());
|
new IgnoringDiagConsumer());
|
||||||
|
|
Loading…
Reference in New Issue