summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp63
-rw-r--r--clang/test/Parser/cxx-attributes.cpp5
2 files changed, 36 insertions, 32 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 7a0cbda1f24..8df15ba75df 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2164,11 +2164,13 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
VS, DefinitionKind, Init);
- for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
- CommonLateParsedAttrs[i]->addDecl(FunDecl);
- }
- for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
- LateParsedAttrs[i]->addDecl(FunDecl);
+ if (FunDecl) {
+ for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
+ CommonLateParsedAttrs[i]->addDecl(FunDecl);
+ }
+ for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
+ LateParsedAttrs[i]->addDecl(FunDecl);
+ }
}
LateParsedAttrs.clear();
@@ -2262,28 +2264,19 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
TemplateParams,
BitfieldSize.release(),
VS, HasInClassInit);
- if (AccessAttrs)
+ if (ThisDecl && AccessAttrs)
Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
false, true);
}
-
- // Set the Decl for any late parsed attributes
- for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
- CommonLateParsedAttrs[i]->addDecl(ThisDecl);
- }
- for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
- LateParsedAttrs[i]->addDecl(ThisDecl);
- }
- LateParsedAttrs.clear();
// Handle the initializer.
if (HasInClassInit != ICIS_NoInit &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
DeclSpec::SCS_static) {
// The initializer was deferred; parse it and cache the tokens.
- Diag(Tok, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_nonstatic_member_init :
- diag::ext_nonstatic_member_init);
+ Diag(Tok, getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_nonstatic_member_init
+ : diag::ext_nonstatic_member_init);
if (DeclaratorInfo.isArrayOfUnknownBound()) {
// C++11 [dcl.array]p3: An array bound may also be omitted when the
@@ -2293,37 +2286,45 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// initializer in the grammar, so this is ill-formed.
Diag(Tok, diag::err_incomplete_array_member_init);
SkipUntil(tok::comma, true, true);
+
+ // Avoid later warnings about a class member of incomplete type.
if (ThisDecl)
- // Avoid later warnings about a class member of incomplete type.
ThisDecl->setInvalidDecl();
} else
ParseCXXNonStaticMemberInitializer(ThisDecl);
} else if (HasInitializer) {
// Normal initializer.
if (!Init.isUsable())
- Init = ParseCXXMemberInitializer(ThisDecl,
- DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
-
+ Init = ParseCXXMemberInitializer(
+ ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
+
if (Init.isInvalid())
SkipUntil(tok::comma, true, true);
else if (ThisDecl)
Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
DS.containsPlaceholderType());
- } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
+ } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static)
// No initializer.
Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType());
- }
-
+
if (ThisDecl) {
+ if (!ThisDecl->isInvalidDecl()) {
+ // Set the Decl for any late parsed attributes
+ for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
+ CommonLateParsedAttrs[i]->addDecl(ThisDecl);
+
+ for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
+ LateParsedAttrs[i]->addDecl(ThisDecl);
+ }
Actions.FinalizeDeclaration(ThisDecl);
DeclsInGroup.push_back(ThisDecl);
+
+ if (DeclaratorInfo.isFunctionDeclarator() &&
+ DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
+ DeclSpec::SCS_typedef)
+ HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
}
-
- if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() &&
- DeclaratorInfo.getDeclSpec().getStorageClassSpec()
- != DeclSpec::SCS_typedef) {
- HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
- }
+ LateParsedAttrs.clear();
DeclaratorInfo.complete(ThisDecl);
diff --git a/clang/test/Parser/cxx-attributes.cpp b/clang/test/Parser/cxx-attributes.cpp
index 5ea0ce22759..97380521f87 100644
--- a/clang/test/Parser/cxx-attributes.cpp
+++ b/clang/test/Parser/cxx-attributes.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
class c {
virtual void f1(const char* a, ...)
@@ -8,3 +7,7 @@ class c {
__attribute__ (( __format__(__printf__,2,3) )) {}
};
+template <typename T> class X {
+ template <typename S> void X<S>::f() __attribute__((locks_excluded())); // expected-error{{nested name specifier 'X<S>::' for declaration does not refer into a class, class template or class template partial specialization}} \
+ // expected-warning{{attribute locks_excluded ignored, because it is not attached to a declaration}}
+};
OpenPOWER on IntegriCloud