summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-10-17 17:09:53 +0000
committerDouglas Gregor <dgregor@apple.com>2011-10-17 17:09:53 +0000
commit50cefbf212be42a9cffecca03b1790f2393cbc85 (patch)
tree3e61476b07150a2defcf9ad4729688a5490a683e /clang
parent0ade47acd0f57ac294c5ebe7a184b09d55e90604 (diff)
downloadbcm5719-llvm-50cefbf212be42a9cffecca03b1790f2393cbc85.tar.gz
bcm5719-llvm-50cefbf212be42a9cffecca03b1790f2393cbc85.zip
When we end up having to parse the initializer of a C++ member early
in -fms-extensions mode, make sure we actually use that initializer after having handled the declaration. Fixes PR11150. llvm-svn: 142195
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp4
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp23
-rw-r--r--clang/test/SemaCXX/MicrosoftExtensions.cpp7
3 files changed, 23 insertions, 11 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index c9107b466d6..04c05d0cc38 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -43,13 +43,13 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
else {
FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
move(TemplateParams), 0,
- VS, /*HasInit=*/false);
+ VS, /*HasDeferredInit=*/false);
if (FnD) {
Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs,
false, true);
bool TypeSpecContainsAuto
= D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
- if (Init.get())
+ if (Init.isUsable())
Actions.AddInitializerToDecl(FnD, Init.get(), false,
TypeSpecContainsAuto);
else
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 472c64b2215..45562d908c5 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1711,6 +1711,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Hold late-parsed attributes so we can attach a Decl to them later.
LateParsedAttrList LateParsedAttrs;
+ SourceLocation EqualLoc;
+ bool HasInitializer = false;
+ ExprResult Init;
if (Tok.isNot(tok::colon)) {
// Don't parse FOO:BAR as if it were a typo for FOO::BAR.
ColonProtectionRAIIObject X(*this);
@@ -1733,14 +1736,15 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// MSVC permits pure specifier on inline functions declared at class scope.
// Hence check for =0 before checking for function definition.
- ExprResult Init;
if (getLang().MicrosoftExt && Tok.is(tok::equal) &&
DeclaratorInfo.isFunctionDeclarator() &&
NextToken().is(tok::numeric_constant)) {
- ConsumeToken();
+ EqualLoc = ConsumeToken();
Init = ParseInitializer();
if (Init.isInvalid())
SkipUntil(tok::comma, true, true);
+ else
+ HasInitializer = true;
}
bool IsDefinition = false;
@@ -1842,9 +1846,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// goes before or after the GNU attributes and __asm__.
ParseOptionalCXX0XVirtSpecifierSeq(VS);
- bool HasInitializer = false;
bool HasDeferredInitializer = false;
- if (Tok.is(tok::equal) || Tok.is(tok::l_brace)) {
+ if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
if (BitfieldSize.get()) {
Diag(Tok, diag::err_bitfield_member_init);
SkipUntil(tok::comma, true, true);
@@ -1905,15 +1908,15 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
ParseCXXNonStaticMemberInitializer(ThisDecl);
} else if (HasInitializer) {
// Normal initializer.
- SourceLocation EqualLoc;
- ExprResult Init
- = ParseCXXMemberInitializer(DeclaratorInfo.isDeclarationOfFunction(),
- EqualLoc);
+ if (!Init.isUsable())
+ Init = ParseCXXMemberInitializer(
+ DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
+
if (Init.isInvalid())
SkipUntil(tok::comma, true, true);
else if (ThisDecl)
Actions.AddInitializerToDecl(ThisDecl, Init.get(), false,
- DS.getTypeSpecType() == DeclSpec::TST_auto);
+ DS.getTypeSpecType() == DeclSpec::TST_auto);
} else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
// No initializer.
Actions.ActOnUninitializedDecl(ThisDecl,
@@ -1945,6 +1948,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
DeclaratorInfo.clear();
VS.clear();
BitfieldSize = true;
+ Init = true;
+ HasInitializer = false;
// Attributes are only allowed on the second declarator.
MaybeParseGNUAttributes(DeclaratorInfo);
diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp
index 63e058b36da..ddf5d9d6a18 100644
--- a/clang/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp
@@ -203,3 +203,10 @@ void f()
}
+struct PR11150 {
+ class X {
+ virtual void f() = 0;
+ };
+
+ int array[__is_abstract(X)? 1 : -1];
+};
OpenPOWER on IntegriCloud