mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-24 23:26:06 +00:00
[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
This commit is contained in:
parent
c6ed91e100
commit
4cebc9db04
@ -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,
|
||||
|
@ -177,6 +177,9 @@ public:
|
||||
/// IdentifierInfo
|
||||
ak_identifierinfo,
|
||||
|
||||
/// Qualifiers
|
||||
ak_qual,
|
||||
|
||||
/// QualType
|
||||
ak_qualtype,
|
||||
|
||||
|
@ -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 $|"
|
||||
|
@ -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 =
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user