[PATCH] Diagnose ref-qualifiers occuring after virt-specifier-seq and generate fixit hints
Richard Smith
richard at metafoo.co.uk
Fri Jan 16 18:14:37 PST 2015
Looks good, thanks!
================
Comment at: lib/Parse/ParseDecl.cpp:5319-5321
@@ -5318,11 +5318,5 @@
// Parse ref-qualifier[opt].
- if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
- Diag(Tok, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_ref_qualifier :
- diag::ext_ref_qualifier);
-
- RefQualifierIsLValueRef = Tok.is(tok::amp);
- RefQualifierLoc = ConsumeToken();
+ if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
EndLoc = RefQualifierLoc;
}
----------------
Remove braces here, please.
================
Comment at: lib/Parse/ParseDeclCXX.cpp:2100-2139
@@ +2099,42 @@
+ unsigned* QualifierLoc) {
+ FixItHint Insertion;
+ if (DS.getTypeQualifiers() & TypeQual) {
+ if (!(Function.TypeQuals & TypeQual)) {
+ std::string Name(FixItName);
+ Name += " ";
+ Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name.c_str());
+ Function.TypeQuals |= TypeQual;
+ *QualifierLoc = SpecLoc.getRawEncoding();
+ }
+ Diag(SpecLoc, diag::err_declspec_after_virtspec)
+ << FixItName
+ << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
+ << FixItHint::CreateRemoval(SpecLoc)
+ << Insertion;
+ }
+ };
+ DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc(),
+ &Function.ConstQualifierLoc);
+ DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc(),
+ &Function.VolatileQualifierLoc);
+ DeclSpecCheck(DeclSpec::TQ_restrict, "restrict", DS.getRestrictSpecLoc(),
+ &Function.RestrictQualifierLoc);
+ }
+
+ // Parse ref-qualifiers.
+ bool RefQualifierIsLValueRef = true;
+ SourceLocation RefQualifierLoc;
+ if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
+ const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");
+ FixItHint Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
+ Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
+ Function.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
+
+ Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
+ << (RefQualifierIsLValueRef ? "&" : "&&")
+ << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
+ << FixItHint::CreateRemoval(RefQualifierLoc)
+ << Insertion;
+ D.SetRangeEnd(RefQualifierLoc);
+ }
+}
----------------
Maybe only produce a single diagnostic no matter how many specifiers were provided? You can then also use `FixItHint::CreateInsertionFromRange` to produce a fixit that copies the complete range of specifiers from after the virt-specifier to before (this will preserve things like macro names and whitespace between the tokens).
http://reviews.llvm.org/D7012
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the cfe-commits
mailing list