r262318 - Optionally demote fatal errors to non-fatal errors.
Manuel Klimek via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 1 02:56:20 PST 2016
Author: klimek
Date: Tue Mar 1 04:56:19 2016
New Revision: 262318
URL: http://llvm.org/viewvc/llvm-project?rev=262318&view=rev
Log:
Optionally demote fatal errors to non-fatal errors.
This behavior is enabled when the new CXTranslationUnit_KeepGoing
option is passed to clang_parseTranslationUnit{,2}. It is geared
towards use by IDEs and similar consumers of the clang-c API where
fatal errors may arise when parsing incomplete code mid-edit, or
when include paths are not properly configured yet. In such situations
one still wants to get as much information as possible about a TU.
Previously, the semantic analysis would not instantiate templates
or report additional fatal errors after the first fatal error was
encountered.
Fixes PR24268.
Patch by Milian Wolff.
Added:
cfe/trunk/test/Index/keep-going.cpp
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/lib/Basic/Diagnostic.cpp
cfe/trunk/lib/Basic/DiagnosticIDs.cpp
cfe/trunk/tools/c-index-test/c-index-test.c
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/unittests/Basic/DiagnosticTest.cpp
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Tue Mar 1 04:56:19 2016
@@ -1208,7 +1208,18 @@ enum CXTranslationUnit_Flags {
* trades runtime on the first parse (serializing the preamble takes time) for
* reduced runtime on the second parse (can now reuse the preamble).
*/
- CXTranslationUnit_CreatePreambleOnFirstParse = 0x100
+ CXTranslationUnit_CreatePreambleOnFirstParse = 0x100,
+
+ /**
+ * \brief Do not stop processing when fatal errors are encountered.
+ *
+ * When fatal errors are encountered while parsing a translation unit,
+ * semantic analysis is typically stopped early when compiling code. A common
+ * source for fatal errors are unresolvable include files. For the
+ * purposes of an IDE, this is undesirable behavior and as much information
+ * as possible should be reported. Use this flag to enable this behavior.
+ */
+ CXTranslationUnit_KeepGoing = 0x200
};
/**
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Mar 1 04:56:19 2016
@@ -173,6 +173,7 @@ private:
bool WarningsAsErrors; // Treat warnings like errors.
bool EnableAllWarnings; // Enable all warnings.
bool ErrorsAsFatal; // Treat errors like fatal errors.
+ bool FatalsAsError; // Treat fatal errors like errors.
bool SuppressSystemWarnings; // Suppress warnings in system headers.
bool SuppressAllDiagnostics; // Suppress all diagnostics.
bool ElideType; // Elide common types of templates.
@@ -455,6 +456,12 @@ public:
void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
bool getErrorsAsFatal() const { return ErrorsAsFatal; }
+ /// \brief When set to true, any fatal error reported is made an error.
+ ///
+ /// This setting takes precedence over the setErrorsAsFatal setting above.
+ void setFatalsAsError(bool Val) { FatalsAsError = Val; }
+ bool getFatalsAsError() const { return FatalsAsError; }
+
/// \brief When set to true mask warnings that come from system headers.
void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Tue Mar 1 04:56:19 2016
@@ -68,6 +68,7 @@ DiagnosticsEngine::DiagnosticsEngine(
WarningsAsErrors = false;
EnableAllWarnings = false;
ErrorsAsFatal = false;
+ FatalsAsError = false;
SuppressSystemWarnings = false;
SuppressAllDiagnostics = false;
ElideType = true;
Modified: cfe/trunk/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/DiagnosticIDs.cpp?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (original)
+++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Tue Mar 1 04:56:19 2016
@@ -462,6 +462,12 @@ DiagnosticIDs::getDiagnosticSeverity(uns
Result = diag::Severity::Fatal;
}
+ // If explicitly requested, map fatal errors to errors.
+ if (Result == diag::Severity::Fatal) {
+ if (Diag.FatalsAsError)
+ Result = diag::Severity::Error;
+ }
+
// Custom diagnostics always are emitted in system headers.
bool ShowInSystemHeader =
!GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
Added: cfe/trunk/test/Index/keep-going.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/keep-going.cpp?rev=262318&view=auto
==============================================================================
--- cfe/trunk/test/Index/keep-going.cpp (added)
+++ cfe/trunk/test/Index/keep-going.cpp Tue Mar 1 04:56:19 2016
@@ -0,0 +1,29 @@
+#include "missing1.h"
+
+template<class T>
+class A { T a; };
+
+class B : public A<int> { };
+
+#include "missing2.h"
+
+class C : public A<float> { };
+
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_KEEP_GOING=1 c-index-test -test-print-type %s 2> %t.stderr.txt | FileCheck %s
+// RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt
+
+// CHECK: inclusion directive=missing1.h ((null)) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: inclusion directive=missing2.h ((null)) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: ClassTemplate=A:4:7 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:3:16 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: FieldDecl=a:4:13 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: TypeRef=T:3:16 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: ClassDecl=B:6:7 (Definition) [type=B] [typekind=Record] [isPOD=0]
+// CHECK: C++ base class specifier=A<int>:4:7 [access=public isVirtual=false] [type=A<int>] [typekind=Unexposed] [canonicaltype=A<int>] [canonicaltypekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0] [nbFields=1]
+// CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: ClassDecl=C:10:7 (Definition) [type=C] [typekind=Record] [isPOD=0]
+// CHECK: C++ base class specifier=A<float>:4:7 [access=public isVirtual=false] [type=A<float>] [typekind=Unexposed] [canonicaltype=A<float>] [canonicaltypekind=Record] [templateargs/1= [type=float] [typekind=Float]] [isPOD=0] [nbFields=1]
+// CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
+
+// CHECK-DIAG: keep-going.cpp:1:10: error: 'missing1.h' file not found
+// CHECK-DIAG: keep-going.cpp:8:10: error: 'missing2.h' file not found
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Tue Mar 1 04:56:19 2016
@@ -80,6 +80,8 @@ static unsigned getDefaultParsingOptions
options |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
if (getenv("CINDEXTEST_CREATE_PREAMBLE_ON_FIRST_PARSE"))
options |= CXTranslationUnit_CreatePreambleOnFirstParse;
+ if (getenv("CINDEXTEST_KEEP_GOING"))
+ options |= CXTranslationUnit_KeepGoing;
return options;
}
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Mar 1 04:56:19 2016
@@ -3158,6 +3158,9 @@ clang_parseTranslationUnit_Impl(CXIndex
IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
+ if (options & CXTranslationUnit_KeepGoing)
+ Diags->setFatalsAsError(true);
+
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Modified: cfe/trunk/unittests/Basic/DiagnosticTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/DiagnosticTest.cpp?rev=262318&r1=262317&r2=262318&view=diff
==============================================================================
--- cfe/trunk/unittests/Basic/DiagnosticTest.cpp (original)
+++ cfe/trunk/unittests/Basic/DiagnosticTest.cpp Tue Mar 1 04:56:19 2016
@@ -46,4 +46,27 @@ TEST(DiagnosticTest, suppressAndTrap) {
EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred());
}
+// Check that FatalsAsErrors works as intended
+TEST(DiagnosticTest, fatalsAsErrors) {
+ DiagnosticsEngine Diags(new DiagnosticIDs(),
+ new DiagnosticOptions,
+ new IgnoringDiagConsumer());
+ Diags.setFatalsAsError(true);
+
+ // Diag that would set UncompilableErrorOccurred and ErrorOccurred.
+ Diags.Report(diag::err_target_unknown_triple) << "unknown";
+
+ // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred.
+ Diags.Report(diag::err_cannot_open_file) << "file" << "error";
+
+ // Diag that would set FatalErrorOccurred
+ // (via non-note following a fatal error).
+ Diags.Report(diag::warn_mt_message) << "warning";
+
+ EXPECT_TRUE(Diags.hasErrorOccurred());
+ EXPECT_FALSE(Diags.hasFatalErrorOccurred());
+ EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
+ EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());
+}
+
}
More information about the cfe-commits
mailing list