[cfe-commits] r158288 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Sema/ lib/AST/ lib/CodeGen/ lib/Parse/ lib/Rewrite/ lib/Sema/ lib/Serialization/ test/PCH/ test/SemaTemplate/
Richard Smith
richard-llvm at metafoo.co.uk
Sat Jun 9 20:12:01 PDT 2012
Author: rsmith
Date: Sat Jun 9 22:12:00 2012
New Revision: 158288
URL: http://llvm.org/viewvc/llvm-project?rev=158288&view=rev
Log:
PR13064: Store whether an in-class initializer uses direct or copy
initialization, and use that information to produce the right kind of
initialization during template instantiation.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/Basic/Specifiers.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclPrinter.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
cfe/trunk/lib/Rewrite/RewriteObjC.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/test/PCH/cxx-member-init.cpp
cfe/trunk/test/SemaTemplate/instantiate-init.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Jun 9 22:12:00 2012
@@ -2093,25 +2093,26 @@
bool Mutable : 1;
mutable unsigned CachedFieldIndex : 31;
- /// \brief A pointer to either the in-class initializer for this field (if
- /// the boolean value is false), or the bit width expression for this bit
- /// field (if the boolean value is true).
+ /// \brief An InClassInitStyle value, and either a bit width expression (if
+ /// the InClassInitStyle value is ICIS_NoInit), or a pointer to the in-class
+ /// initializer for this field (otherwise).
///
/// We can safely combine these two because in-class initializers are not
/// permitted for bit-fields.
///
- /// If the boolean is false and the initializer is null, then this field has
- /// an in-class initializer which has not yet been parsed and attached.
- llvm::PointerIntPair<Expr *, 1, bool> InitializerOrBitWidth;
+ /// If the InClassInitStyle is not ICIS_NoInit and the initializer is null,
+ /// then this field has an in-class initializer which has not yet been parsed
+ /// and attached.
+ llvm::PointerIntPair<Expr *, 2, unsigned> InitializerOrBitWidth;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- bool HasInit)
+ InClassInitStyle InitStyle)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0),
- InitializerOrBitWidth(BW, !HasInit) {
- assert(!(BW && HasInit) && "got initializer for bitfield");
+ InitializerOrBitWidth(BW, InitStyle) {
+ assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
}
public:
@@ -2119,7 +2120,7 @@
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- bool HasInit);
+ InClassInitStyle InitStyle);
static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2130,12 +2131,10 @@
/// isMutable - Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
- /// \brief Set whether this field is mutable (C++ only).
- void setMutable(bool M) { Mutable = M; }
-
/// isBitfield - Determines whether this field is a bitfield.
bool isBitField() const {
- return InitializerOrBitWidth.getInt() && InitializerOrBitWidth.getPointer();
+ return getInClassInitStyle() == ICIS_NoInit &&
+ InitializerOrBitWidth.getPointer();
}
/// @brief Determines whether this is an unnamed bitfield.
@@ -2151,39 +2150,34 @@
return isBitField() ? InitializerOrBitWidth.getPointer() : 0;
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
- void setBitWidth(Expr *BW) {
- assert(!InitializerOrBitWidth.getPointer() &&
- "bit width or initializer already set");
- InitializerOrBitWidth.setPointer(BW);
- InitializerOrBitWidth.setInt(1);
- }
- /// removeBitWidth - Remove the bitfield width from this member.
- void removeBitWidth() {
- assert(isBitField() && "no bit width to remove");
- InitializerOrBitWidth.setPointer(0);
+
+ /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
+ /// this field has.
+ InClassInitStyle getInClassInitStyle() const {
+ return static_cast<InClassInitStyle>(InitializerOrBitWidth.getInt());
}
- /// hasInClassInitializer - Determine whether this member has a C++0x in-class
+ /// hasInClassInitializer - Determine whether this member has a C++11 in-class
/// initializer.
bool hasInClassInitializer() const {
- return !InitializerOrBitWidth.getInt();
+ return getInClassInitStyle() != ICIS_NoInit;
}
- /// getInClassInitializer - Get the C++0x in-class initializer for this
+ /// getInClassInitializer - Get the C++11 in-class initializer for this
/// member, or null if one has not been set. If a valid declaration has an
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0;
}
- /// setInClassInitializer - Set the C++0x in-class initializer for this
+ /// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
void setInClassInitializer(Expr *Init);
- /// removeInClassInitializer - Remove the C++0x in-class initializer from this
+ /// removeInClassInitializer - Remove the C++11 in-class initializer from this
/// member.
void removeInClassInitializer() {
- assert(!InitializerOrBitWidth.getInt() && "no initializer to remove");
+ assert(hasInClassInitializer() && "no initializer to remove");
InitializerOrBitWidth.setPointer(0);
- InitializerOrBitWidth.setInt(1);
+ InitializerOrBitWidth.setInt(ICIS_NoInit);
}
/// getParent - Returns the parent of this field declaration, which
@@ -2202,6 +2196,9 @@
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// EnumConstantDecl - An instance of this object exists for each enum constant
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sat Jun 9 22:12:00 2012
@@ -1016,7 +1016,7 @@
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
- /*Mutable=*/false, /*HasInit=*/false),
+ /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
@@ -1074,7 +1074,7 @@
QualType T, Expr *BW)
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
/*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
- BW, /*Mutable=*/false, /*HasInit=*/false) {}
+ BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
public:
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
Modified: cfe/trunk/include/clang/Basic/Specifiers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Specifiers.h (original)
+++ cfe/trunk/include/clang/Basic/Specifiers.h Sat Jun 9 22:12:00 2012
@@ -168,6 +168,13 @@
inline bool isLegalForVariable(StorageClass SC) {
return true;
}
+
+ /// \brief In-class initialization styles for non-static data members.
+ enum InClassInitStyle {
+ ICIS_NoInit, ///< No in-class initializer.
+ ICIS_CopyInit, ///< Copy initialization.
+ ICIS_ListInit ///< Direct list-initialization.
+ };
} // end namespace clang
#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Jun 9 22:12:00 2012
@@ -1420,13 +1420,15 @@
Declarator &D, Expr *BitfieldWidth);
FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth, bool HasInit,
+ Declarator &D, Expr *BitfieldWidth,
+ InClassInitStyle InitStyle,
AccessSpecifier AS);
FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo,
RecordDecl *Record, SourceLocation Loc,
- bool Mutable, Expr *BitfieldWidth, bool HasInit,
+ bool Mutable, Expr *BitfieldWidth,
+ InClassInitStyle InitStyle,
SourceLocation TSSL,
AccessSpecifier AS, NamedDecl *PrevDecl,
Declarator *D = 0);
@@ -4141,7 +4143,7 @@
Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
Expr *BitfieldWidth, const VirtSpecifiers &VS,
- bool HasDeferredInit);
+ InClassInitStyle InitStyle);
void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc,
Expr *Init);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Jun 9 22:12:00 2012
@@ -3813,7 +3813,7 @@
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
CFConstantStringTypeDecl->addDecl(Field);
}
@@ -3857,7 +3857,7 @@
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
T->addDecl(Field);
}
@@ -3900,7 +3900,7 @@
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
T->addDecl(Field);
}
@@ -3976,7 +3976,7 @@
&Idents.get(FieldNames[i]),
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
T->addDecl(Field);
}
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sat Jun 9 22:12:00 2012
@@ -2662,7 +2662,7 @@
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, BitWidth, D->isMutable(),
- D->hasInClassInitializer());
+ D->getInClassInitStyle());
ToField->setAccess(D->getAccess());
ToField->setLexicalDeclContext(LexicalDC);
if (ToField->hasInClassInitializer())
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sat Jun 9 22:12:00 2012
@@ -2465,15 +2465,15 @@
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- bool HasInit) {
+ InClassInitStyle InitStyle) {
return new (C) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
- BW, Mutable, HasInit);
+ BW, Mutable, InitStyle);
}
FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FieldDecl));
return new (Mem) FieldDecl(Field, 0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0, 0, false, false);
+ 0, QualType(), 0, 0, false, ICIS_NoInit);
}
bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -2525,10 +2525,9 @@
}
void FieldDecl::setInClassInitializer(Expr *Init) {
- assert(!InitializerOrBitWidth.getPointer() &&
+ assert(!InitializerOrBitWidth.getPointer() && hasInClassInitializer() &&
"bit width or initializer already set");
InitializerOrBitWidth.setPointer(Init);
- InitializerOrBitWidth.setInt(0);
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Sat Jun 9 22:12:00 2012
@@ -582,7 +582,10 @@
Expr *Init = D->getInClassInitializer();
if (!Policy.SuppressInitializers && Init) {
- Out << " = ";
+ if (D->getInClassInitStyle() == ICIS_ListInit)
+ Out << " ";
+ else
+ Out << " = ";
Init->printPretty(Out, Context, 0, Policy, Indentation);
}
prettyPrintAttributes(D);
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sat Jun 9 22:12:00 2012
@@ -4386,9 +4386,10 @@
SourceLocation(), SourceLocation(),
&Ctx.Idents.get("_objc_super"));
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
- Ctx.getObjCIdType(), 0, 0, false, false));
+ Ctx.getObjCIdType(), 0, 0, false, ICIS_NoInit));
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
- Ctx.getObjCClassType(), 0, 0, false, false));
+ Ctx.getObjCClassType(), 0, 0, false,
+ ICIS_NoInit));
RD->completeDefinition();
SuperCTy = Ctx.getTagDeclType(RD);
@@ -4767,9 +4768,10 @@
SourceLocation(), SourceLocation(),
&Ctx.Idents.get("_message_ref_t"));
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
- Ctx.VoidPtrTy, 0, 0, false, false));
+ Ctx.VoidPtrTy, 0, 0, false, ICIS_NoInit));
RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
- Ctx.getObjCSelType(), 0, 0, false, false));
+ Ctx.getObjCSelType(), 0, 0, false,
+ ICIS_NoInit));
RD->completeDefinition();
MessageRefCTy = Ctx.getTagDeclType(RD);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Jun 9 22:12:00 2012
@@ -2127,7 +2127,7 @@
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
@@ -2202,7 +2202,7 @@
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false);
+ ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Sat Jun 9 22:12:00 2012
@@ -46,7 +46,7 @@
else {
FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
move(TemplateParams), 0,
- VS, /*HasDeferredInit=*/false);
+ VS, ICIS_NoInit);
if (FnD) {
Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs,
false, true);
@@ -493,7 +493,7 @@
ConsumeAnyToken();
SourceLocation EqualLoc;
-
+
ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,
EqualLoc);
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sat Jun 9 22:12:00 2012
@@ -1991,18 +1991,19 @@
// goes before or after the GNU attributes and __asm__.
ParseOptionalCXX0XVirtSpecifierSeq(VS);
- bool HasDeferredInitializer = false;
+ InClassInitStyle HasInClassInit = ICIS_NoInit;
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);
} else {
HasInitializer = true;
- HasDeferredInitializer = !DeclaratorInfo.isDeclarationOfFunction() &&
- DeclaratorInfo.getDeclSpec().getStorageClassSpec()
- != DeclSpec::SCS_static &&
- DeclaratorInfo.getDeclSpec().getStorageClassSpec()
- != DeclSpec::SCS_typedef;
+ if (!DeclaratorInfo.isDeclarationOfFunction() &&
+ DeclaratorInfo.getDeclSpec().getStorageClassSpec()
+ != DeclSpec::SCS_static &&
+ DeclaratorInfo.getDeclSpec().getStorageClassSpec()
+ != DeclSpec::SCS_typedef)
+ HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;
}
}
@@ -2020,7 +2021,7 @@
DeclaratorInfo,
move(TemplateParams),
BitfieldSize.release(),
- VS, HasDeferredInitializer);
+ VS, HasInClassInit);
if (AccessAttrs)
Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
false, true);
@@ -2036,15 +2037,15 @@
LateParsedAttrs.clear();
// Handle the initializer.
- if (HasDeferredInitializer) {
+ if (HasInClassInit != ICIS_NoInit) {
// The initializer was deferred; parse it and cache the tokens.
Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_nonstatic_member_init :
diag::ext_nonstatic_member_init);
if (DeclaratorInfo.isArrayOfUnknownBound()) {
- // C++0x [dcl.array]p3: An array bound may also be omitted when the
- // declarator is followed by an initializer.
+ // C++11 [dcl.array]p3: An array bound may also be omitted when the
+ // declarator is followed by an initializer.
//
// A brace-or-equal-initializer for a member-declarator is not an
// initializer in the grammar, so this is ill-formed.
Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Sat Jun 9 22:12:00 2012
@@ -823,7 +823,7 @@
&Context->Idents.get(D->getNameAsString()),
IvarT, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
FD->getType(), VK_LValue,
OK_Ordinary);
@@ -2720,7 +2720,7 @@
&Context->Idents.get("arr"),
Context->getPointerType(Context->VoidPtrTy), 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ArrayLiteralME =
new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD,
SourceLocation(),
@@ -2867,7 +2867,7 @@
&Context->Idents.get("arr"),
Context->getPointerType(Context->VoidPtrTy), 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *DictLiteralValueME =
new (Context) MemberExpr(NSValueCallExpr, false, ARRFD,
SourceLocation(),
@@ -3014,7 +3014,7 @@
FieldTypes[i], 0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false));
+ ICIS_NoInit));
}
SuperStructDecl->completeDefinition();
@@ -3047,7 +3047,7 @@
FieldTypes[i], 0,
/*BitWidth=*/0,
/*Mutable=*/true,
- /*HasInit=*/false));
+ ICIS_NoInit));
}
ConstantStringDecl->completeDefinition();
@@ -4491,7 +4491,7 @@
&Context->Idents.get("FuncPtr"),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
FD->getType(), VK_LValue,
OK_Ordinary);
@@ -4540,7 +4540,7 @@
&Context->Idents.get("__forwarding"),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
FD, SourceLocation(),
FD->getType(), VK_LValue,
@@ -4551,7 +4551,7 @@
&Context->Idents.get(Name),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
DeclRefExp->getType(), VK_LValue, OK_Ordinary);
@@ -7436,7 +7436,7 @@
&Context->Idents.get(D->getNameAsString()),
IvarT, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
FD->getType(), VK_LValue,
OK_Ordinary);
Modified: cfe/trunk/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteObjC.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteObjC.cpp Sat Jun 9 22:12:00 2012
@@ -2592,7 +2592,7 @@
FieldTypes[i], 0,
/*BitWidth=*/0,
/*Mutable=*/false,
- /*HasInit=*/false));
+ ICIS_NoInit));
}
SuperStructDecl->completeDefinition();
@@ -2625,7 +2625,7 @@
FieldTypes[i], 0,
/*BitWidth=*/0,
/*Mutable=*/true,
- /*HasInit=*/false));
+ ICIS_NoInit));
}
ConstantStringDecl->completeDefinition();
@@ -3887,7 +3887,7 @@
&Context->Idents.get("FuncPtr"),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
FD->getType(), VK_LValue,
OK_Ordinary);
@@ -3936,7 +3936,7 @@
&Context->Idents.get("__forwarding"),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
FD, SourceLocation(),
FD->getType(), VK_LValue,
@@ -3947,7 +3947,7 @@
&Context->Idents.get(Name),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true,
- /*HasInit=*/false);
+ ICIS_NoInit);
ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
DeclRefExp->getType(), VK_LValue, OK_Ordinary);
@@ -6015,4 +6015,3 @@
ReplaceStmtWithRange(IV, Replacement, OldRange);
return Replacement;
}
-
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jun 9 22:12:00 2012
@@ -2969,7 +2969,7 @@
Context.getTypeDeclType(Record),
TInfo,
/*BitWidth=*/0, /*Mutable=*/false,
- /*HasInit=*/false);
+ /*InitStyle=*/ICIS_NoInit);
Anon->setAccess(AS);
if (getLangOpts().CPlusPlus)
FieldCollector->Add(cast<FieldDecl>(Anon));
@@ -3066,7 +3066,7 @@
Context.getTypeDeclType(Record),
TInfo,
/*BitWidth=*/0, /*Mutable=*/false,
- /*HasInit=*/false);
+ /*InitStyle=*/ICIS_NoInit);
Anon->setImplicit();
// Add the anonymous struct object to the current context.
@@ -8975,7 +8975,7 @@
Declarator &D, Expr *BitfieldWidth) {
FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD),
DeclStart, D, static_cast<Expr*>(BitfieldWidth),
- /*HasInit=*/false, AS_public);
+ /*InitStyle=*/ICIS_NoInit, AS_public);
return Res;
}
@@ -8983,7 +8983,8 @@
///
FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
SourceLocation DeclStart,
- Declarator &D, Expr *BitWidth, bool HasInit,
+ Declarator &D, Expr *BitWidth,
+ InClassInitStyle InitStyle,
AccessSpecifier AS) {
IdentifierInfo *II = D.getIdentifier();
SourceLocation Loc = DeclStart;
@@ -9045,7 +9046,7 @@
= (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable);
SourceLocation TSSL = D.getLocStart();
FieldDecl *NewFD
- = CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, HasInit,
+ = CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, InitStyle,
TSSL, AS, PrevDecl, &D);
if (NewFD->isInvalidDecl())
@@ -9078,7 +9079,8 @@
FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo,
RecordDecl *Record, SourceLocation Loc,
- bool Mutable, Expr *BitWidth, bool HasInit,
+ bool Mutable, Expr *BitWidth,
+ InClassInitStyle InitStyle,
SourceLocation TSSL,
AccessSpecifier AS, NamedDecl *PrevDecl,
Declarator *D) {
@@ -9168,7 +9170,7 @@
}
FieldDecl *NewFD = FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo,
- BitWidth, Mutable, HasInit);
+ BitWidth, Mutable, InitStyle);
if (InvalidDecl)
NewFD->setInvalidDecl();
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Jun 9 22:12:00 2012
@@ -1453,13 +1453,13 @@
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
/// bitfield width if there is one, 'InitExpr' specifies the initializer if
-/// one has been parsed, and 'HasDeferredInit' is true if an initializer is
-/// present but parsing it has been deferred.
+/// one has been parsed, and 'InitStyle' is set if an in-class initializer is
+/// present (but parsing it has been deferred).
Decl *
Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
Expr *BW, const VirtSpecifiers &VS,
- bool HasDeferredInit) {
+ InClassInitStyle InitStyle) {
const DeclSpec &DS = D.getDeclSpec();
DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
DeclarationName Name = NameInfo.getName();
@@ -1563,10 +1563,10 @@
}
Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
- HasDeferredInit, AS);
+ InitStyle, AS);
assert(Member && "HandleField never returns null");
} else {
- assert(!HasDeferredInit);
+ assert(InitStyle == ICIS_NoInit);
Member = HandleDeclarator(S, D, move(TemplateParameterLists));
if (!Member) {
@@ -1660,9 +1660,11 @@
/// instantiating an in-class initializer in a class template. Such actions
/// are deferred until the class is complete.
void
-Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation EqualLoc,
+Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation InitLoc,
Expr *InitExpr) {
FieldDecl *FD = cast<FieldDecl>(D);
+ assert(FD->getInClassInitStyle() != ICIS_NoInit &&
+ "must set init style when field is created");
if (!InitExpr) {
FD->setInvalidDecl();
@@ -1685,9 +1687,9 @@
Expr **Inits = &InitExpr;
unsigned NumInits = 1;
InitializedEntity Entity = InitializedEntity::InitializeMember(FD);
- InitializationKind Kind = EqualLoc.isInvalid()
+ InitializationKind Kind = FD->getInClassInitStyle() == ICIS_ListInit
? InitializationKind::CreateDirectList(InitExpr->getLocStart())
- : InitializationKind::CreateCopy(InitExpr->getLocStart(), EqualLoc);
+ : InitializationKind::CreateCopy(InitExpr->getLocStart(), InitLoc);
InitializationSequence Seq(*this, Entity, Kind, Inits, NumInits);
Init = Seq.Perform(*this, Entity, Kind, MultiExprArg(Inits, NumInits));
if (Init.isInvalid()) {
@@ -1695,7 +1697,7 @@
return;
}
- CheckImplicitConversions(Init.get(), EqualLoc);
+ CheckImplicitConversions(Init.get(), InitLoc);
}
// C++0x [class.base.init]p7:
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jun 9 22:12:00 2012
@@ -10206,7 +10206,7 @@
FieldDecl *Field
= FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType,
S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
- 0, false, false);
+ 0, false, ICIS_NoInit);
Field->setImplicit(true);
Field->setAccess(AS_private);
Lambda->addDecl(Field);
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Jun 9 22:12:00 2012
@@ -740,7 +740,7 @@
FieldDecl *Field
= FieldDecl::Create(Context, Lambda, Loc, Loc, 0, ThisTy,
Context.getTrivialTypeSourceInfo(ThisTy, Loc),
- 0, false, false);
+ 0, false, ICIS_NoInit);
Field->setImplicit(true);
Field->setAccess(AS_private);
Lambda->addDecl(Field);
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Jun 9 22:12:00 2012
@@ -1963,9 +1963,7 @@
Expr *Init = NewInit.take();
assert(Init && "no-argument initializer in class");
assert(!isa<ParenListExpr>(Init) && "call-style init in class");
- ActOnCXXInClassMemberInitializer(NewField,
- Init->getSourceRange().getBegin(),
- Init);
+ ActOnCXXInClassMemberInitializer(NewField, Init->getLocStart(), Init);
}
}
}
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Jun 9 22:12:00 2012
@@ -430,7 +430,7 @@
D->getLocation(),
D->isMutable(),
BitWidth,
- D->hasInClassInitializer(),
+ D->getInClassInitStyle(),
D->getInnerLocStart(),
D->getAccess(),
0);
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sat Jun 9 22:12:00 2012
@@ -865,12 +865,11 @@
void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
VisitDeclaratorDecl(FD);
- FD->setMutable(Record[Idx++]);
- int BitWidthOrInitializer = Record[Idx++];
- if (BitWidthOrInitializer == 1)
- FD->setBitWidth(Reader.ReadExpr(F));
- else if (BitWidthOrInitializer == 2)
- FD->setInClassInitializer(Reader.ReadExpr(F));
+ FD->Mutable = Record[Idx++];
+ if (int BitWidthOrInitializer = Record[Idx++]) {
+ FD->InitializerOrBitWidth.setInt(BitWidthOrInitializer - 1);
+ FD->InitializerOrBitWidth.setPointer(Reader.ReadExpr(F));
+ }
if (!FD->getDeclName()) {
if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx))
Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Sat Jun 9 22:12:00 2012
@@ -626,11 +626,13 @@
void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
VisitDeclaratorDecl(D);
Record.push_back(D->isMutable());
- Record.push_back(D->getBitWidth()? 1 : D->hasInClassInitializer() ? 2 : 0);
- if (D->getBitWidth())
- Writer.AddStmt(D->getBitWidth());
- else if (D->hasInClassInitializer())
- Writer.AddStmt(D->getInClassInitializer());
+ if (D->InitializerOrBitWidth.getInt() != ICIS_NoInit ||
+ D->InitializerOrBitWidth.getPointer()) {
+ Record.push_back(D->InitializerOrBitWidth.getInt() + 1);
+ Writer.AddStmt(D->InitializerOrBitWidth.getPointer());
+ } else {
+ Record.push_back(0);
+ }
if (!D->getDeclName())
Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record);
Modified: cfe/trunk/test/PCH/cxx-member-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-member-init.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-member-init.cpp (original)
+++ cfe/trunk/test/PCH/cxx-member-init.cpp Sat Jun 9 22:12:00 2012
@@ -12,10 +12,14 @@
int &m = n;
S *that = this;
};
+template<typename T> struct X { T t {0}; };
#endif
#ifdef SOURCE
S s;
+
+struct E { explicit E(int); };
+X<E> x;
#elif HEADER
#undef HEADER
#define SOURCE
Modified: cfe/trunk/test/SemaTemplate/instantiate-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=158288&r1=158287&r2=158288&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-init.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-init.cpp Sat Jun 9 22:12:00 2012
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-struct X0 { // expected-note 4{{candidate}}
+struct X0 { // expected-note 8{{candidate}}
X0(int*, float*); // expected-note 4{{candidate}}
};
@@ -107,3 +107,14 @@
array_lengthof(Description<float*>::data); // expected-error{{no matching function for call to 'array_lengthof'}}
}
}
+
+namespace PR13064 {
+ // Ensure that in-class direct-initialization is instantiated as
+ // direct-initialization and likewise copy-initialization is instantiated as
+ // copy-initialization.
+ struct A { explicit A(int); }; // expected-note{{here}}
+ template<typename T> struct B { T a { 0 }; };
+ B<A> b;
+ template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
+ C<A> c; // expected-note{{here}}
+}
More information about the cfe-commits
mailing list