summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-24 22:34:35 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-24 22:34:35 +0000
commit4b5a949834775b60f4e94c6ab9136c19104b48c8 (patch)
tree2806d2a1b6fe1ee814e98fb7a86dc8032aa1f29f
parent7449bda3d93e7c04615c667a605f3b690e39c25f (diff)
downloadbcm5719-llvm-4b5a949834775b60f4e94c6ab9136c19104b48c8.tar.gz
bcm5719-llvm-4b5a949834775b60f4e94c6ab9136c19104b48c8.zip
Allow virt-specifiers after GNU attributes in member-declarators. GCC doesn't
allow this, and we should warn on it, but it turns out that people were already relying on this. We should introduce a -Wgcc-compat warning for this if the attributes are known to GCC, but we don't currently track enough information about attributes to do so reliably. llvm-svn: 200045
-rw-r--r--clang/include/clang/Sema/DeclSpec.h2
-rw-r--r--clang/include/clang/Sema/Ownership.h2
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp12
-rw-r--r--clang/test/Parser/cxx0x-decl.cpp3
4 files changed, 15 insertions, 4 deletions
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index e3b78314d77..bdba54430a4 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -2142,6 +2142,8 @@ public:
bool SetSpecifier(Specifier VS, SourceLocation Loc,
const char *&PrevSpec);
+ bool isUnset() const { return Specifiers == 0; }
+
bool isOverrideSpecified() const { return Specifiers & VS_Override; }
SourceLocation getOverrideLoc() const { return VS_overrideLoc; }
diff --git a/clang/include/clang/Sema/Ownership.h b/clang/include/clang/Sema/Ownership.h
index b7d7710eb12..4bbefcb8fe1 100644
--- a/clang/include/clang/Sema/Ownership.h
+++ b/clang/include/clang/Sema/Ownership.h
@@ -158,6 +158,7 @@ namespace clang {
bool isInvalid() const { return Invalid; }
bool isUsable() const { return !Invalid && Val; }
+ bool isUnset() const { return !Invalid && !Val; }
PtrTy get() const { return Val; }
// FIXME: Replace with get.
@@ -199,6 +200,7 @@ namespace clang {
bool isInvalid() const { return PtrWithInvalid & 0x01; }
bool isUsable() const { return PtrWithInvalid > 0x01; }
+ bool isUnset() const { return PtrWithInvalid == 0; }
PtrTy get() const {
void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 86db40b28d8..083d682428e 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1926,6 +1926,13 @@ void Parser::ParseCXXMemberDeclaratorBeforeInitializer(
// If attributes exist after the declarator, but before an '{', parse them.
MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
+
+ // For compatibility with code written to older Clang, also accept a
+ // virt-specifier *after* the GNU attributes.
+ // FIXME: If we saw any attributes that are known to GCC followed by a
+ // virt-specifier, issue a GCC-compat warning.
+ if (BitfieldSize.isUnset() && VS.isUnset())
+ ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
}
/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
@@ -2142,8 +2149,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// If this has neither a name nor a bit width, something has gone seriously
// wrong. Skip until the semi-colon or }.
- if (!DeclaratorInfo.hasName() && !BitfieldSize.isInvalid() &&
- !BitfieldSize.isUsable()) {
+ if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
// If so, skip until the semi-colon or a }.
SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
TryConsumeToken(tok::semi);
@@ -2151,7 +2157,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
// Check for a member function definition.
- if (!BitfieldSize.isInvalid() && !BitfieldSize.isUsable()) {
+ if (BitfieldSize.isUnset()) {
// MSVC permits pure specifier on inline functions defined at class scope.
// Hence check for =0 before checking for function definition.
if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) &&
diff --git a/clang/test/Parser/cxx0x-decl.cpp b/clang/test/Parser/cxx0x-decl.cpp
index 84eaafeee59..a0334cdde29 100644
--- a/clang/test/Parser/cxx0x-decl.cpp
+++ b/clang/test/Parser/cxx0x-decl.cpp
@@ -119,5 +119,6 @@ namespace DuplicateSpecifier {
struct Base { virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; };
struct MemberComponentOrder : Base {
void f() override __asm__("foobar") __attribute__(( )) {}
- void g() __attribute__(( )) override; // expected-error {{expected ';'}}
+ void g() __attribute__(( )) override;
+ void h() __attribute__(( )) override {}
};
OpenPOWER on IntegriCloud