[cfe-commits] r141539 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/class.cpp
Douglas Gregor
dgregor at apple.com
Mon Oct 10 07:49:18 PDT 2011
Author: dgregor
Date: Mon Oct 10 09:49:18 2011
New Revision: 141539
URL: http://llvm.org/viewvc/llvm-project?rev=141539&view=rev
Log:
Parse the initializer for a class member after handling its
declarator, so that the declarator is in scope for the
initializer. Fixes PR9989.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/class.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=141539&r1=141538&r2=141539&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 10 09:49:18 2011
@@ -3424,8 +3424,7 @@
Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
Expr *BitfieldWidth, const VirtSpecifiers &VS,
- Expr *Init, bool HasDeferredInit,
- bool IsDefinition);
+ bool HasDeferredInit, bool IsDefinition);
void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc,
Expr *Init);
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=141539&r1=141538&r2=141539&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Mon Oct 10 09:49:18 2011
@@ -35,15 +35,22 @@
Decl *FnD;
if (D.getDeclSpec().isFriendSpecified())
- // FIXME: Friend templates
FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, true,
move(TemplateParams));
- else { // FIXME: pass template information through
+ else {
FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
move(TemplateParams), 0,
- VS, Init.release(),
- /*HasInit=*/false,
+ VS, /*HasInit=*/false,
/*IsDefinition*/true);
+ if (FnD) {
+ bool TypeSpecContainsAuto
+ = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
+ if (Init.get())
+ Actions.AddInitializerToDecl(FnD, Init.get(), false,
+ TypeSpecContainsAuto);
+ else
+ Actions.ActOnUninitializedDecl(FnD, TypeSpecContainsAuto);
+ }
}
HandleMemberFunctionDefaultArgs(D, FnD);
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=141539&r1=141538&r2=141539&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Oct 10 09:49:18 2011
@@ -1714,7 +1714,6 @@
ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
VirtSpecifiers VS;
- ExprResult Init;
// Hold late-parsed attributes so we can attach a Decl to them later.
LateParsedAttrList LateParsedAttrs;
@@ -1741,6 +1740,7 @@
// 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)) {
@@ -1848,25 +1848,19 @@
// 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 (BitfieldSize.get()) {
Diag(Tok, diag::err_bitfield_member_init);
SkipUntil(tok::comma, true, true);
} else {
+ HasInitializer = true;
HasDeferredInitializer = !DeclaratorInfo.isDeclarationOfFunction() &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_static &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_typedef;
-
- if (!HasDeferredInitializer) {
- SourceLocation EqualLoc;
- Init = ParseCXXMemberInitializer(
- DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
- if (Init.isInvalid())
- SkipUntil(tok::comma, true, true);
- }
}
}
@@ -1885,31 +1879,22 @@
DeclaratorInfo,
move(TemplateParams),
BitfieldSize.release(),
- VS, Init.release(),
- HasDeferredInitializer,
+ VS, HasDeferredInitializer,
/*IsDefinition*/ false);
}
- if (ThisDecl)
- DeclsInGroup.push_back(ThisDecl);
-
- if (DeclaratorInfo.isFunctionDeclarator() &&
- DeclaratorInfo.getDeclSpec().getStorageClassSpec()
- != DeclSpec::SCS_typedef) {
- HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
- }
-
- DeclaratorInfo.complete(ThisDecl);
-
+
// Set the Decl for any late parsed attributes
for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
LateParsedAttrs[i]->setDecl(ThisDecl);
}
LateParsedAttrs.clear();
+ // Handle the initializer.
if (HasDeferredInitializer) {
+ // The initializer was deferred; parse it and cache the tokens.
if (!getLang().CPlusPlus0x)
Diag(Tok, diag::warn_nonstatic_member_init_accepted_as_extension);
-
+
if (DeclaratorInfo.isArrayOfUnknownBound()) {
// C++0x [dcl.array]p3: An array bound may also be omitted when the
// declarator is followed by an initializer.
@@ -1922,8 +1907,36 @@
ThisDecl->setInvalidDecl();
} else
ParseCXXNonStaticMemberInitializer(ThisDecl);
+ } else if (HasInitializer) {
+ // Normal initializer.
+ SourceLocation EqualLoc;
+ ExprResult 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);
+ } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
+ // No initializer.
+ Actions.ActOnUninitializedDecl(ThisDecl,
+ DS.getTypeSpecType() == DeclSpec::TST_auto);
+ }
+
+ if (ThisDecl) {
+ Actions.FinalizeDeclaration(ThisDecl);
+ DeclsInGroup.push_back(ThisDecl);
+ }
+
+ if (DeclaratorInfo.isFunctionDeclarator() &&
+ DeclaratorInfo.getDeclSpec().getStorageClassSpec()
+ != DeclSpec::SCS_typedef) {
+ HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
}
+ DeclaratorInfo.complete(ThisDecl);
+
// If we don't have a comma, it is either the end of the list (a ';')
// or an error, bail out.
if (Tok.isNot(tok::comma))
@@ -1935,8 +1948,7 @@
// Parse the next declarator.
DeclaratorInfo.clear();
VS.clear();
- BitfieldSize = 0;
- Init = 0;
+ BitfieldSize = true;
// Attributes are only allowed on the second declarator.
MaybeParseGNUAttributes(DeclaratorInfo);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=141539&r1=141538&r2=141539&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct 10 09:49:18 2011
@@ -1428,7 +1428,7 @@
Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
Expr *BW, const VirtSpecifiers &VS,
- Expr *InitExpr, bool HasDeferredInit,
+ bool HasDeferredInit,
bool IsDefinition) {
const DeclSpec &DS = D.getDeclSpec();
DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
@@ -1440,11 +1440,9 @@
Loc = D.getSourceRange().getBegin();
Expr *BitWidth = static_cast<Expr*>(BW);
- Expr *Init = static_cast<Expr*>(InitExpr);
assert(isa<CXXRecordDecl>(CurContext));
assert(!DS.isFriendSpecified());
- assert(!Init || !HasDeferredInit);
bool isFunc = D.isDeclarationOfFunction();
@@ -1609,14 +1607,6 @@
assert((Name || isInstField) && "No identifier for non-field ?");
- if (Init)
- AddInitializerToDecl(Member, Init, false,
- DS.getTypeSpecType() == DeclSpec::TST_auto);
- else if (DS.getStorageClassSpec() == DeclSpec::SCS_static)
- ActOnUninitializedDecl(Member, DS.getTypeSpecType() == DeclSpec::TST_auto);
-
- FinalizeDeclaration(Member);
-
if (isInstField)
FieldCollector->Add(cast<FieldDecl>(Member));
return Member;
Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=141539&r1=141538&r2=141539&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Mon Oct 10 09:49:18 2011
@@ -189,3 +189,7 @@
S::c; // expected-error {{invalid use of nonstatic data member}}
}
}
+
+struct PR9989 {
+ static int const PR9989_Member = sizeof PR9989_Member;
+};
More information about the cfe-commits
mailing list