diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-01-04 11:50:36 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-01-04 11:50:36 +0000 |
commit | 4cebc9db04a29a8491b59e8178b4100d3c1a9c84 (patch) | |
tree | bc070ee7f98751dcdf5fb0d4bd0b851e3b42d6cb | |
parent | c6ed91e100fad24ccfd6602997879c0f543f4935 (diff) | |
download | bcm5719-llvm-4cebc9db04a29a8491b59e8178b4100d3c1a9c84.tar.gz bcm5719-llvm-4cebc9db04a29a8491b59e8178b4100d3c1a9c84.zip |
[Basic] Extend DiagnosticEngine to store and format Qualifiers.
Qualifiers can now be streamed into the DiagnosticEngine using
regular << operator. If Qualifiers are empty 'unqualified' will
be printed in the diagnostic otherwise regular qual syntax is
used.
Differential Revision: https://reviews.llvm.org/D56198
llvm-svn: 350386
-rw-r--r-- | clang/include/clang/AST/Type.h | 18 | ||||
-rw-r--r-- | clang/include/clang/Basic/Diagnostic.h | 3 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 24 | ||||
-rw-r--r-- | clang/lib/AST/ASTDiagnostic.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaCXX/addr-of-overloaded-function.cpp | 14 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-overloaded-virtual.cpp | 2 |
8 files changed, 51 insertions, 33 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index cff63d0926e..d4c97b1b5ef 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6701,6 +6701,24 @@ inline const Type *Type::getPointeeOrArrayElementType() const { return type; } +/// Insertion operator for diagnostics. This allows sending Qualifiers into a +/// diagnostic with <<. +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + Qualifiers Q) { + DB.AddTaggedVal(Q.getAsOpaqueValue(), + DiagnosticsEngine::ArgumentKind::ak_qual); + return DB; +} + +/// Insertion operator for partial diagnostics. This allows sending Qualifiers +/// into a diagnostic with <<. +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + Qualifiers Q) { + PD.AddTaggedVal(Q.getAsOpaqueValue(), + DiagnosticsEngine::ArgumentKind::ak_qual); + return PD; +} + /// Insertion operator for diagnostics. This allows sending QualType's into a /// diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index d7e1c628908..a516721ace6 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -177,6 +177,9 @@ public: /// IdentifierInfo ak_identifierinfo, + /// Qualifiers + ak_qual, + /// QualType ak_qualtype, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c69566a2d22..375f9515b26 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1809,11 +1809,7 @@ def err_init_conversion_failed : Error< "|: different number of parameters (%5 vs %6)" "|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7" "|: different return type%diff{ ($ vs $)|}5,6" - "|: different qualifiers (" - "%select{none|const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}5 vs " - "%select{none|const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}6)" + "|: different qualifiers (%5 vs %6)" "|: different exception specifications}4">; def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot " @@ -3593,11 +3589,7 @@ def note_ovl_candidate : Note< "| has type mismatch at %ordinal5 parameter" "%diff{ (expected $ but has $)|}6,7" "| has different return type%diff{ ($ expected but has $)|}5,6" - "| has different qualifiers (expected " - "%select{none|const|restrict|const and restrict|volatile|const and volatile" - "|volatile and restrict|const, volatile, and restrict}5 but found " - "%select{none|const|restrict|const and restrict|volatile|const and volatile" - "|volatile and restrict|const, volatile, and restrict}6)" + "| has different qualifiers (expected %5 but found %6)" "| has different exception specification}4">; def note_ovl_candidate_inherited_constructor : Note< @@ -6470,11 +6462,7 @@ def note_hidden_overloaded_virtual_declared_here : Note< "|: different number of parameters (%2 vs %3)" "|: type mismatch at %ordinal2 parameter%diff{ ($ vs $)|}3,4" "|: different return type%diff{ ($ vs $)|}2,3" - "|: different qualifiers (" - "%select{none|const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}2 vs " - "%select{none|const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}3)" + "|: different qualifiers (%2 vs %3)" "|: different exception specifications}1">; def warn_using_directive_in_header : Warning< "using namespace directive in global context in header">, @@ -6748,11 +6736,7 @@ def err_typecheck_convert_incompatible : Error< "|: different number of parameters (%5 vs %6)" "|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7" "|: different return type%diff{ ($ vs $)|}5,6" - "|: different qualifiers (" - "%select{none|const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}5 vs " - "%select{none|const|restrict|const and restrict|volatile|const and volatile|" - "volatile and restrict|const, volatile, and restrict}6)" + "|: different qualifiers (%5 vs %6)" "|: different exception specifications}4">; def err_typecheck_missing_return_type_incompatible : Error< "%diff{return type $ must match previous return type $|" diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 50d2d2999e5..dd058555857 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -334,6 +334,20 @@ void clang::FormatASTNodeDiagnosticArgument( switch (Kind) { default: llvm_unreachable("unknown ArgumentKind"); + case DiagnosticsEngine::ak_qual: { + assert(Modifier.empty() && Argument.empty() && + "Invalid modifier for Qualfiers argument"); + + Qualifiers Q(Qualifiers::fromOpaqueValue(Val)); + auto S = Q.getAsString(); + if (S.empty()) { + OS << "unqualified"; + NeedQuotes = false; + } else { + OS << Q.getAsString(); + } + break; + } case DiagnosticsEngine::ak_qualtype_pair: { TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val); QualType FromType = diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index ffe92e157e5..56c54cb9070 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -983,6 +983,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\''; break; } + case DiagnosticsEngine::ak_qual: case DiagnosticsEngine::ak_qualtype: case DiagnosticsEngine::ak_declarationname: case DiagnosticsEngine::ak_nameddecl: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 94f7979f66f..6f50dd9bccd 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2824,11 +2824,9 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, return; } - // FIXME: OpenCL: Need to consider address spaces - unsigned FromQuals = FromFunction->getTypeQuals().getCVRUQualifiers(); - unsigned ToQuals = ToFunction->getTypeQuals().getCVRUQualifiers(); - if (FromQuals != ToQuals) { - PDiag << ft_qualifer_mismatch << ToQuals << FromQuals; + if (FromFunction->getTypeQuals() != ToFunction->getTypeQuals()) { + PDiag << ft_qualifer_mismatch << ToFunction->getTypeQuals() + << FromFunction->getTypeQuals(); return; } diff --git a/clang/test/SemaCXX/addr-of-overloaded-function.cpp b/clang/test/SemaCXX/addr-of-overloaded-function.cpp index cca847b4d2c..6b6734bae17 100644 --- a/clang/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/clang/test/SemaCXX/addr-of-overloaded-function.cpp @@ -221,13 +221,13 @@ namespace test1 { void QualifierTest() { void (Qualifiers::*X)(); - X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (none vs const)}} - X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (none vs volatile)}} - X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (none vs restrict)}} - X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (none vs const and volatile)}} - X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (none vs const and restrict)}} - X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (none vs volatile and restrict)}} - X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (none vs const, volatile, and restrict)}} + X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (unqualified vs 'const')}} + X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (unqualified vs 'volatile')}} + X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (unqualified vs '__restrict')}} + X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (unqualified vs 'const volatile')}} + X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (unqualified vs 'const __restrict')}} + X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (unqualified vs 'volatile __restrict')}} + X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (unqualified vs 'const volatile __restrict')}} } struct Dummy { diff --git a/clang/test/SemaCXX/warn-overloaded-virtual.cpp b/clang/test/SemaCXX/warn-overloaded-virtual.cpp index 6204826192d..271416d04d5 100644 --- a/clang/test/SemaCXX/warn-overloaded-virtual.cpp +++ b/clang/test/SemaCXX/warn-overloaded-virtual.cpp @@ -130,7 +130,7 @@ namespace { virtual int foo(int*) const; // expected-note@-1{{type mismatch at 1st parameter ('int *' vs 'int')}} virtual int foo(int) volatile; - // expected-note@-1{{different qualifiers (volatile vs const)}} + // expected-note@-1{{different qualifiers ('volatile' vs 'const')}} }; class B : public A { |