[cfe-commits] r147808 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp test/FixIt/fixit-cxx0x.cpp test/FixIt/fixit.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Mon Jan 9 14:31:45 PST 2012
Author: rsmith
Date: Mon Jan 9 16:31:44 2012
New Revision: 147808
URL: http://llvm.org/viewvc/llvm-project?rev=147808&view=rev
Log:
Extend the diagnostic for a ',' at the end of a declaration where a ';' was
intended to cover C++ class definitions.
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
cfe/trunk/test/FixIt/fixit.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jan 9 16:31:44 2012
@@ -1924,7 +1924,10 @@
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
SourceLocation *endLoc = 0);
- VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const;
+ VirtSpecifiers::Specifier isCXX0XVirtSpecifier(const Token &Tok) const;
+ VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const {
+ return isCXX0XVirtSpecifier(Tok);
+ }
void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS);
bool isCXX0XFinalKeyword() const;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jan 9 16:31:44 2012
@@ -994,9 +994,15 @@
case tok::amp:
case tok::ampamp:
- case tok::colon: // Might be a typo for '::'.
return getLang().CPlusPlus;
+ case tok::l_square: // Might be an attribute on an unnamed bit-field.
+ return Context == Declarator::MemberContext && getLang().CPlusPlus0x &&
+ NextToken().is(tok::l_square);
+
+ case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
+ return Context == Declarator::MemberContext || getLang().CPlusPlus;
+
case tok::identifier:
switch (NextToken().getKind()) {
case tok::code_completion:
@@ -1019,8 +1025,13 @@
case tok::colon:
// At namespace scope, 'identifier:' is probably a typo for 'identifier::'
- // and in block scope it's probably a label.
- return getLang().CPlusPlus && Context == Declarator::FileContext;
+ // and in block scope it's probably a label. Inside a class definition,
+ // this is a bit-field.
+ return Context == Declarator::MemberContext ||
+ (getLang().CPlusPlus && Context == Declarator::FileContext);
+
+ case tok::identifier: // Possible virt-specifier.
+ return getLang().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
default:
return false;
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jan 9 16:31:44 2012
@@ -1548,13 +1548,13 @@
}
}
-/// isCXX0XVirtSpecifier - Determine whether the next token is a C++0x
+/// isCXX0XVirtSpecifier - Determine whether the given token is a C++0x
/// virt-specifier.
///
/// virt-specifier:
/// override
/// final
-VirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier() const {
+VirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier(const Token &Tok) const {
if (!getLang().CPlusPlus)
return VirtSpecifiers::VS_None;
@@ -1896,6 +1896,7 @@
SmallVector<Decl *, 8> DeclsInGroup;
ExprResult BitfieldSize;
+ bool ExpectSemi = true;
while (1) {
// member-declarator:
@@ -2023,7 +2024,18 @@
break;
// Consume the comma.
- ConsumeToken();
+ SourceLocation CommaLoc = ConsumeToken();
+
+ if (Tok.isAtStartOfLine() &&
+ !MightBeDeclarator(Declarator::MemberContext)) {
+ // This comma was followed by a line-break and something which can't be
+ // the start of a declarator. The comma was probably a typo for a
+ // semicolon.
+ Diag(CommaLoc, diag::err_expected_semi_declaration)
+ << FixItHint::CreateReplacement(CommaLoc, ";");
+ ExpectSemi = false;
+ break;
+ }
// Parse the next declarator.
DeclaratorInfo.clear();
@@ -2039,7 +2051,8 @@
ParseDeclarator(DeclaratorInfo);
}
- if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
+ if (ExpectSemi &&
+ ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
// Skip to end of block or statement.
SkipUntil(tok::r_brace, true, true);
// If we stopped at a ';', eat it.
Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Mon Jan 9 16:31:44 2012
@@ -22,4 +22,18 @@
int m {},
n [[]], // expected-error {{expected ';' at end of declaration}}
int o;
+
+ struct Base {
+ virtual void f2(), f3();
+ };
+ struct MemberDeclarator : Base {
+ int k : 4,
+ //[[]] : 1, FIXME: test this once we support attributes here
+ : 9, // expected-error {{expected ';' at end of declaration}}
+ char c, // expected-error {{expected ';' at end of declaration}}
+ typedef void F(), // expected-error {{expected ';' at end of declaration}}
+ F f1,
+ f2 final,
+ f3 override, // expected-error {{expected ';' at end of declaration}}
+ };
}
Modified: cfe/trunk/test/FixIt/fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit.cpp (original)
+++ cfe/trunk/test/FixIt/fixit.cpp Mon Jan 9 16:31:44 2012
@@ -125,6 +125,19 @@
AD ad, // expected-error {{expected ';' at end of declaration}}
return ad;
}
+struct MoreAccidentalCommas {
+ int a : 5,
+ b : 7,
+ : 4, // expected-error {{expected ';' at end of declaration}}
+ char c, // expected-error {{expected ';' at end of declaration}}
+ double d, // expected-error {{expected ';' at end of declaration}}
+ MoreAccidentalCommas *next, // expected-error {{expected ';' at end of declaration}}
+public:
+ int k, // expected-error {{expected ';' at end of declaration}}
+ friend void f(MoreAccidentalCommas) {}
+ int k2, // expected-error {{expected ';' at end of declaration}}
+ virtual void g(), // expected-error {{expected ';' at end of declaration}}
+};
template<class T> struct Mystery;
template<class T> typedef Mystery<T>::type getMysteriousThing() { // \
More information about the cfe-commits
mailing list