r233070 - Diagnose ref-qualifiers occuring after virt-specifier-seq and generate fixit hints
Ehsan Akhgari
ehsan.akhgari at gmail.com
Tue Mar 24 06:02:50 PDT 2015
Author: ehsan
Date: Tue Mar 24 08:02:50 2015
New Revision: 233070
URL: http://llvm.org/viewvc/llvm-project?rev=233070&view=rev
Log:
Diagnose ref-qualifiers occuring after virt-specifier-seq and generate fixit hints
Summary: Follow-up to the fix of PR22075.
Reviewers: rsmith
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D7012
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/test/FixIt/fixit-cxx0x.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=233070&r1=233069&r2=233070&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Mar 24 08:02:50 2015
@@ -2214,6 +2214,8 @@ private:
BalancedDelimiterTracker &Tracker,
bool IsAmbiguous,
bool RequiresArg = false);
+ bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
+ SourceLocation &RefQualifierLoc);
bool isFunctionDeclaratorIdentifierList();
void ParseFunctionDeclaratorIdentifierList(
Declarator &D,
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=233070&r1=233069&r2=233070&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Mar 24 08:02:50 2015
@@ -5342,15 +5342,8 @@ void Parser::ParseFunctionDeclarator(Dec
}
// 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;
- }
// C++11 [expr.prim.general]p3:
// If a declaration declares a member function or member function
@@ -5446,6 +5439,22 @@ void Parser::ParseFunctionDeclarator(Dec
FnAttrs, EndLoc);
}
+/// ParseRefQualifier - Parses a member function ref-qualifier. Returns
+/// true if a ref-qualifier is found.
+bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
+ SourceLocation &RefQualifierLoc) {
+ 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();
+ return true;
+ }
+ return false;
+}
+
/// isFunctionDeclaratorIdentifierList - This parameter list may have an
/// identifier list form for a K&R-style function: void foo(a,b,c)
///
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=233070&r1=233069&r2=233070&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Mar 24 08:02:50 2015
@@ -2100,13 +2100,13 @@ void Parser::MaybeParseAndDiagnoseDeclSp
ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, false);
D.ExtendWithDeclSpec(DS);
+ auto &Function = D.getFunctionTypeInfo();
if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
auto DeclSpecCheck = [&] (DeclSpec::TQ TypeQual,
const char *FixItName,
SourceLocation SpecLoc,
unsigned* QualifierLoc) {
FixItHint Insertion;
- auto &Function = D.getFunctionTypeInfo();
if (DS.getTypeQualifiers() & TypeQual) {
if (!(Function.TypeQuals & TypeQual)) {
std::string Name(FixItName);
@@ -2122,7 +2122,6 @@ void Parser::MaybeParseAndDiagnoseDeclSp
<< Insertion;
}
};
- auto &Function = D.getFunctionTypeInfo();
DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc(),
&Function.ConstQualifierLoc);
DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc(),
@@ -2130,6 +2129,23 @@ void Parser::MaybeParseAndDiagnoseDeclSp
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);
+ }
}
/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=233070&r1=233069&r2=233070&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Tue Mar 24 08:02:50 2015
@@ -159,7 +159,7 @@ namespace MisplacedParameterPack {
void redundantEllipsisInNonTypeTemplateParameter();
}
-namespace MisplacedDeclSpecAfterVirtSpec {
+namespace MisplacedDeclAndRefSpecAfterVirtSpec {
struct B {
virtual void f();
virtual void f() volatile const;
@@ -168,4 +168,12 @@ namespace MisplacedDeclSpecAfterVirtSpec
virtual void f() override;
virtual void f() override final const volatile; // expected-error {{'const' qualifier may not appear after the virtual specifier 'final'}} expected-error {{'volatile' qualifier may not appear after the virtual specifier 'final'}}
};
+ struct B2 {
+ virtual void f() &;
+ virtual void f() volatile const &&;
+ };
+ struct D2 : B2 {
+ virtual void f() override &; // expected-error {{'&' qualifier may not appear after the virtual specifier 'override'}}
+ virtual void f() override final const volatile &&; // expected-error {{'const' qualifier may not appear after the virtual specifier 'final'}} expected-error {{'volatile' qualifier may not appear after the virtual specifier 'final'}} expected-error {{'&&' qualifier may not appear after the virtual specifier 'final'}}
+ };
}
More information about the cfe-commits
mailing list