forked from OSchip/llvm-project
More anonymous struct/union redesign. This one deals with anonymous field used in a constructor initializer list:
struct X { X() : au_i1(123) {} union { int au_i1; float au_f1; }; }; clang will now deal with au_i1 explicitly as an IndirectFieldDecl. llvm-svn: 120900
This commit is contained in:
parent
211e699754
commit
d583da04d0
|
@ -1108,9 +1108,9 @@ public:
|
|||
/// };
|
||||
/// @endcode
|
||||
class CXXBaseOrMemberInitializer {
|
||||
/// \brief Either the base class name (stored as a TypeSourceInfo*) or the
|
||||
/// field being initialized.
|
||||
llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember;
|
||||
/// \brief Either the base class name (stored as a TypeSourceInfo*), an normal
|
||||
/// field (FieldDecl) or an anonymous field (IndirectFieldDecl*) being initialized.
|
||||
llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *> BaseOrMember;
|
||||
|
||||
/// \brief The source location for the field name.
|
||||
SourceLocation MemberLocation;
|
||||
|
@ -1118,26 +1118,6 @@ class CXXBaseOrMemberInitializer {
|
|||
/// \brief The argument used to initialize the base or member, which may
|
||||
/// end up constructing an object (when multiple arguments are involved).
|
||||
Stmt *Init;
|
||||
|
||||
/// \brief Stores either the constructor to call to initialize this base or
|
||||
/// member (a CXXConstructorDecl pointer), or stores the anonymous union of
|
||||
/// which the initialized value is a member.
|
||||
///
|
||||
/// When the value is a FieldDecl pointer, 'BaseOrMember' is class's
|
||||
/// anonymous union data member, this field holds the FieldDecl for the
|
||||
/// member of the anonymous union being initialized.
|
||||
/// @code
|
||||
/// struct X {
|
||||
/// X() : au_i1(123) {}
|
||||
/// union {
|
||||
/// int au_i1;
|
||||
/// float au_f1;
|
||||
/// };
|
||||
/// };
|
||||
/// @endcode
|
||||
/// In above example, BaseOrMember holds the field decl. for anonymous union
|
||||
/// and AnonUnionMember holds field decl for au_i1.
|
||||
FieldDecl *AnonUnionMember;
|
||||
|
||||
/// LParenLoc - Location of the left paren of the ctor-initializer.
|
||||
SourceLocation LParenLoc;
|
||||
|
@ -1152,6 +1132,7 @@ class CXXBaseOrMemberInitializer {
|
|||
/// IsWritten - Whether or not the initializer is explicitly written
|
||||
/// in the sources.
|
||||
bool IsWritten : 1;
|
||||
|
||||
/// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
|
||||
/// number keeps track of the textual order of this initializer in the
|
||||
/// original sources, counting from 0; otherwise, if IsWritten is false,
|
||||
|
@ -1184,6 +1165,14 @@ public:
|
|||
Expr *Init,
|
||||
SourceLocation R);
|
||||
|
||||
explicit
|
||||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
IndirectFieldDecl *Member,
|
||||
SourceLocation MemberLoc,
|
||||
SourceLocation L,
|
||||
Expr *Init,
|
||||
SourceLocation R);
|
||||
|
||||
/// \brief Creates a new member initializer that optionally contains
|
||||
/// array indices used to describe an elementwise initialization.
|
||||
static CXXBaseOrMemberInitializer *Create(ASTContext &Context,
|
||||
|
@ -1203,6 +1192,14 @@ public:
|
|||
/// initializing a non-static data member.
|
||||
bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
|
||||
|
||||
bool isAnyMemberInitializer() const {
|
||||
return isMemberInitializer() || isIndirectMemberInitializer();
|
||||
}
|
||||
|
||||
bool isIndirectMemberInitializer() const {
|
||||
return BaseOrMember.is<IndirectFieldDecl*>();
|
||||
}
|
||||
|
||||
/// If this is a base class initializer, returns the type of the
|
||||
/// base class with location information. Otherwise, returns an NULL
|
||||
/// type location.
|
||||
|
@ -1234,15 +1231,25 @@ public:
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
FieldDecl *getAnyMember() const {
|
||||
if (isMemberInitializer())
|
||||
return BaseOrMember.get<FieldDecl*>();
|
||||
else if (isIndirectMemberInitializer())
|
||||
return BaseOrMember.get<IndirectFieldDecl*>()->getAnonField();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
IndirectFieldDecl *getIndirectMember() const {
|
||||
if (isIndirectMemberInitializer())
|
||||
return BaseOrMember.get<IndirectFieldDecl*>();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
SourceLocation getMemberLocation() const {
|
||||
return MemberLocation;
|
||||
}
|
||||
|
||||
void setMember(FieldDecl *Member) {
|
||||
assert(isMemberInitializer());
|
||||
BaseOrMember = Member;
|
||||
}
|
||||
|
||||
/// \brief Determine the source location of the initializer.
|
||||
SourceLocation getSourceLocation() const;
|
||||
|
@ -1273,15 +1280,7 @@ public:
|
|||
IsWritten = true;
|
||||
SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
|
||||
}
|
||||
|
||||
FieldDecl *getAnonUnionMember() const {
|
||||
return AnonUnionMember;
|
||||
}
|
||||
void setAnonUnionMember(FieldDecl *anonMember) {
|
||||
AnonUnionMember = anonMember;
|
||||
}
|
||||
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
|
||||
|
|
|
@ -217,6 +217,12 @@ public:
|
|||
return InitializedEntity(Member, Parent);
|
||||
}
|
||||
|
||||
/// \brief Create the initialization entity for a member subobject.
|
||||
static InitializedEntity InitializeMember(IndirectFieldDecl *Member,
|
||||
const InitializedEntity *Parent = 0) {
|
||||
return InitializedEntity(Member->getAnonField(), Parent);
|
||||
}
|
||||
|
||||
/// \brief Create the initialization entity for an array element.
|
||||
static InitializedEntity InitializeElement(ASTContext &Context,
|
||||
unsigned Index,
|
||||
|
|
|
@ -2530,7 +2530,8 @@ public:
|
|||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
|
||||
template<typename T>
|
||||
MemInitResult BuildMemberInitializer(T *Member, Expr **Args,
|
||||
unsigned NumArgs, SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc);
|
||||
|
|
|
@ -1004,7 +1004,7 @@ CXXBaseOrMemberInitializer::
|
|||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
TypeSourceInfo *TInfo, bool IsVirtual,
|
||||
SourceLocation L, Expr *Init, SourceLocation R)
|
||||
: BaseOrMember(TInfo), Init(Init), AnonUnionMember(0),
|
||||
: BaseOrMember(TInfo), Init(Init),
|
||||
LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false),
|
||||
SourceOrderOrNumArrayIndices(0)
|
||||
{
|
||||
|
@ -1015,7 +1015,17 @@ CXXBaseOrMemberInitializer(ASTContext &Context,
|
|||
FieldDecl *Member, SourceLocation MemberLoc,
|
||||
SourceLocation L, Expr *Init, SourceLocation R)
|
||||
: BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
|
||||
AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
|
||||
LParenLoc(L), RParenLoc(R), IsVirtual(false),
|
||||
IsWritten(false), SourceOrderOrNumArrayIndices(0)
|
||||
{
|
||||
}
|
||||
|
||||
CXXBaseOrMemberInitializer::
|
||||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
IndirectFieldDecl *Member, SourceLocation MemberLoc,
|
||||
SourceLocation L, Expr *Init, SourceLocation R)
|
||||
: BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
|
||||
LParenLoc(L), RParenLoc(R), IsVirtual(false),
|
||||
IsWritten(false), SourceOrderOrNumArrayIndices(0)
|
||||
{
|
||||
}
|
||||
|
@ -1027,7 +1037,7 @@ CXXBaseOrMemberInitializer(ASTContext &Context,
|
|||
VarDecl **Indices,
|
||||
unsigned NumIndices)
|
||||
: BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
|
||||
AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
|
||||
LParenLoc(L), RParenLoc(R), IsVirtual(false),
|
||||
IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
|
||||
{
|
||||
VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
|
||||
|
@ -1072,7 +1082,7 @@ const Type *CXXBaseOrMemberInitializer::getBaseClass() const {
|
|||
}
|
||||
|
||||
SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
|
||||
if (isMemberInitializer())
|
||||
if (isAnyMemberInitializer())
|
||||
return getMemberLocation();
|
||||
|
||||
return getBaseClassLoc().getLocalSourceRange().getBegin();
|
||||
|
|
|
@ -436,8 +436,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
|
|||
CXXBaseOrMemberInitializer * BMInitializer = (*B);
|
||||
if (B != CDecl->init_begin())
|
||||
Out << ", ";
|
||||
if (BMInitializer->isMemberInitializer()) {
|
||||
FieldDecl *FD = BMInitializer->getMember();
|
||||
if (BMInitializer->isAnyMemberInitializer()) {
|
||||
FieldDecl *FD = BMInitializer->getAnyMember();
|
||||
Out << FD;
|
||||
} else {
|
||||
Out << QualType(BMInitializer->getBaseClass(),
|
||||
|
|
|
@ -553,7 +553,7 @@ CFGBlock *CFGBuilder::addInitializer(CXXBaseOrMemberInitializer *I) {
|
|||
// after initialization finishes.
|
||||
Expr *Init = I->getInit();
|
||||
if (Init) {
|
||||
if (FieldDecl *FD = I->getMember())
|
||||
if (FieldDecl *FD = I->getAnyMember())
|
||||
IsReference = FD->getType()->isReferenceType();
|
||||
HasTemporaries = isa<CXXExprWithTemporaries>(Init);
|
||||
|
||||
|
@ -3093,7 +3093,7 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
|
|||
CXXBaseOrMemberInitializer* I = IE;
|
||||
if (I->isBaseInitializer())
|
||||
OS << I->getBaseClass()->getAsCXXRecordDecl()->getName();
|
||||
else OS << I->getMember()->getName();
|
||||
else OS << I->getAnyMember()->getName();
|
||||
|
||||
OS << "(";
|
||||
if (Expr* IE = I->getInit())
|
||||
|
|
|
@ -687,7 +687,7 @@ void GRExprEngine::ProcessInitializer(const CFGInitializer Init,
|
|||
ExplodedNode *Pred = builder.getBasePredecessor();
|
||||
const LocationContext *LC = Pred->getLocationContext();
|
||||
|
||||
if (BMI->isMemberInitializer()) {
|
||||
if (BMI->isAnyMemberInitializer()) {
|
||||
ExplodedNodeSet Dst;
|
||||
|
||||
// Evaluate the initializer.
|
||||
|
@ -697,7 +697,7 @@ void GRExprEngine::ProcessInitializer(const CFGInitializer Init,
|
|||
ExplodedNode *Pred = *I;
|
||||
const GRState *state = Pred->getState();
|
||||
|
||||
const FieldDecl *FD = BMI->getMember();
|
||||
const FieldDecl *FD = BMI->getAnyMember();
|
||||
const RecordDecl *RD = FD->getParent();
|
||||
const CXXThisRegion *ThisR = getCXXThisRegion(cast<CXXRecordDecl>(RD),
|
||||
cast<StackFrameContext>(LC));
|
||||
|
|
|
@ -512,21 +512,21 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
|
|||
CXXBaseOrMemberInitializer *MemberInit,
|
||||
const CXXConstructorDecl *Constructor,
|
||||
FunctionArgList &Args) {
|
||||
assert(MemberInit->isMemberInitializer() &&
|
||||
assert(MemberInit->isAnyMemberInitializer() &&
|
||||
"Must have member initializer!");
|
||||
|
||||
// non-static data member initializers.
|
||||
FieldDecl *Field = MemberInit->getMember();
|
||||
FieldDecl *Field = MemberInit->getAnyMember();
|
||||
QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
|
||||
|
||||
llvm::Value *ThisPtr = CGF.LoadCXXThis();
|
||||
LValue LHS;
|
||||
|
||||
// If we are initializing an anonymous union field, drill down to the field.
|
||||
if (MemberInit->getAnonUnionMember()) {
|
||||
Field = MemberInit->getAnonUnionMember();
|
||||
LHS = CGF.EmitLValueForAnonRecordField(ThisPtr, Field, 0);
|
||||
FieldType = Field->getType();
|
||||
if (MemberInit->isIndirectMemberInitializer()) {
|
||||
LHS = CGF.EmitLValueForAnonRecordField(ThisPtr,
|
||||
MemberInit->getIndirectMember(), 0);
|
||||
FieldType = MemberInit->getIndirectMember()->getAnonField()->getType();
|
||||
} else {
|
||||
LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
|
||||
}
|
||||
|
|
|
@ -1574,23 +1574,13 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue,
|
|||
/// that the base value is a pointer to the enclosing record, derive
|
||||
/// an lvalue for the ultimate field.
|
||||
LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
|
||||
const FieldDecl *Field,
|
||||
const IndirectFieldDecl *Field,
|
||||
unsigned CVRQualifiers) {
|
||||
llvm::SmallVector<const FieldDecl *, 8> Path;
|
||||
Path.push_back(Field);
|
||||
|
||||
while (Field->getParent()->isAnonymousStructOrUnion()) {
|
||||
const ValueDecl *VD = Field->getParent()->getAnonymousStructOrUnionObject();
|
||||
if (!isa<FieldDecl>(VD)) break;
|
||||
Field = cast<FieldDecl>(VD);
|
||||
Path.push_back(Field);
|
||||
}
|
||||
|
||||
llvm::SmallVectorImpl<const FieldDecl*>::reverse_iterator
|
||||
I = Path.rbegin(), E = Path.rend();
|
||||
IndirectFieldDecl::chain_iterator I = Field->chain_begin(),
|
||||
IEnd = Field->chain_end();
|
||||
while (true) {
|
||||
LValue LV = EmitLValueForField(BaseValue, *I, CVRQualifiers);
|
||||
if (++I == E) return LV;
|
||||
LValue LV = EmitLValueForField(BaseValue, cast<FieldDecl>(*I), CVRQualifiers);
|
||||
if (++I == IEnd) return LV;
|
||||
|
||||
assert(LV.isSimple());
|
||||
BaseValue = LV.getAddress();
|
||||
|
|
|
@ -432,7 +432,7 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
|
|||
if (ctor) {
|
||||
for (unsigned I = 0, E = IvarInitializers.size(); I != E; ++I) {
|
||||
CXXBaseOrMemberInitializer *IvarInit = IvarInitializers[I];
|
||||
FieldDecl *Field = IvarInit->getMember();
|
||||
FieldDecl *Field = IvarInit->getAnyMember();
|
||||
QualType FieldType = Field->getType();
|
||||
ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
|
||||
LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
|
||||
|
@ -448,7 +448,7 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
|
|||
} else {
|
||||
// dtor
|
||||
for (size_t i = IvarInitializers.size(); i > 0; --i) {
|
||||
FieldDecl *Field = IvarInitializers[i - 1]->getMember();
|
||||
FieldDecl *Field = IvarInitializers[i - 1]->getAnyMember();
|
||||
QualType FieldType = Field->getType();
|
||||
const ConstantArrayType *Array =
|
||||
getContext().getAsConstantArrayType(FieldType);
|
||||
|
|
|
@ -1429,7 +1429,7 @@ public:
|
|||
llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
|
||||
const ObjCIvarDecl *Ivar);
|
||||
LValue EmitLValueForAnonRecordField(llvm::Value* Base,
|
||||
const FieldDecl* Field,
|
||||
const IndirectFieldDecl* Field,
|
||||
unsigned CVRQualifiers);
|
||||
LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field,
|
||||
unsigned CVRQualifiers);
|
||||
|
|
|
@ -3608,7 +3608,8 @@ void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
|
|||
InitializedBases.insert(
|
||||
Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
|
||||
else
|
||||
InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
|
||||
InitializedFields.insert(cast<FieldDecl>(
|
||||
Initializers[I]->getAnyMember()));
|
||||
}
|
||||
|
||||
// Add completions for base classes.
|
||||
|
@ -3670,8 +3671,8 @@ void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
|
|||
if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
|
||||
SawLastInitializer
|
||||
= NumInitializers > 0 &&
|
||||
Initializers[NumInitializers - 1]->isMemberInitializer() &&
|
||||
Initializers[NumInitializers - 1]->getMember() == *Field;
|
||||
Initializers[NumInitializers - 1]->isAnyMemberInitializer() &&
|
||||
Initializers[NumInitializers - 1]->getAnyMember() == *Field;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1070,16 +1070,16 @@ Sema::ActOnMemInitializer(Decl *ConstructorD,
|
|||
if (Result.first != Result.second) {
|
||||
Member = dyn_cast<FieldDecl>(*Result.first);
|
||||
|
||||
// Handle anonymous union case.
|
||||
if (!Member)
|
||||
if (IndirectFieldDecl* IndirectField
|
||||
= dyn_cast<IndirectFieldDecl>(*Result.first))
|
||||
Member = IndirectField->getAnonField();
|
||||
}
|
||||
|
||||
if (Member)
|
||||
return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
|
||||
if (Member)
|
||||
return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
|
||||
LParenLoc, RParenLoc);
|
||||
// Handle anonymous union case.
|
||||
if (IndirectFieldDecl* IndirectField
|
||||
= dyn_cast<IndirectFieldDecl>(*Result.first))
|
||||
return BuildMemberInitializer(IndirectField, (Expr**)Args,
|
||||
NumArgs, IdLoc,
|
||||
LParenLoc, RParenLoc);
|
||||
}
|
||||
}
|
||||
// It didn't name a member, so see if it names a class.
|
||||
QualType BaseType;
|
||||
|
@ -1195,8 +1195,10 @@ Sema::ActOnMemInitializer(Decl *ConstructorD,
|
|||
/// uninitialized field was used an updates the SourceLocation parameter; false
|
||||
/// otherwise.
|
||||
static bool InitExprContainsUninitializedFields(const Stmt *S,
|
||||
const FieldDecl *LhsField,
|
||||
const ValueDecl *LhsField,
|
||||
SourceLocation *L) {
|
||||
assert(isa<FieldDecl>(LhsField) || isa<IndirectFieldDecl>(LhsField));
|
||||
|
||||
if (isa<CallExpr>(S)) {
|
||||
// Do not descend into function calls or constructors, as the use
|
||||
// of an uninitialized field may be valid. One would have to inspect
|
||||
|
@ -1257,11 +1259,15 @@ static bool InitExprContainsUninitializedFields(const Stmt *S,
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MemInitResult
|
||||
Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
|
||||
Sema::BuildMemberInitializer(T *Member, Expr **Args,
|
||||
unsigned NumArgs, SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc) {
|
||||
assert((isa<FieldDecl>(Member) || isa<IndirectFieldDecl>(Member)) ||
|
||||
"Member must be a FieldDecl or IndirectFieldDecl");
|
||||
|
||||
if (Member->isInvalidDecl())
|
||||
return true;
|
||||
|
||||
|
@ -1750,26 +1756,12 @@ struct BaseAndFieldInfo {
|
|||
};
|
||||
}
|
||||
|
||||
static void RecordFieldInitializer(BaseAndFieldInfo &Info,
|
||||
FieldDecl *Top, FieldDecl *Field,
|
||||
CXXBaseOrMemberInitializer *Init) {
|
||||
// If the member doesn't need to be initialized, Init will still be null.
|
||||
if (!Init)
|
||||
return;
|
||||
|
||||
Info.AllToInit.push_back(Init);
|
||||
if (Field != Top) {
|
||||
Init->setMember(Top);
|
||||
Init->setAnonUnionMember(Field);
|
||||
}
|
||||
}
|
||||
|
||||
static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
|
||||
FieldDecl *Top, FieldDecl *Field) {
|
||||
|
||||
// Overwhelmingly common case: we have a direct initializer for this field.
|
||||
if (CXXBaseOrMemberInitializer *Init = Info.AllBaseFields.lookup(Field)) {
|
||||
RecordFieldInitializer(Info, Top, Field, Init);
|
||||
Info.AllToInit.push_back(Init);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1789,7 +1781,7 @@ static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
|
|||
for (RecordDecl::field_iterator FA = FieldClassDecl->field_begin(),
|
||||
EA = FieldClassDecl->field_end(); FA != EA; FA++) {
|
||||
if (CXXBaseOrMemberInitializer *Init = Info.AllBaseFields.lookup(*FA)) {
|
||||
RecordFieldInitializer(Info, Top, *FA, Init);
|
||||
Info.AllToInit.push_back(Init);
|
||||
|
||||
// Once we've initialized a field of an anonymous union, the union
|
||||
// field in the class is also initialized, so exit immediately.
|
||||
|
@ -1826,7 +1818,9 @@ static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
|
|||
if (BuildImplicitMemberInitializer(Info.S, Info.Ctor, Info.IIK, Field, Init))
|
||||
return true;
|
||||
|
||||
RecordFieldInitializer(Info, Top, Field, Init);
|
||||
if (Init)
|
||||
Info.AllToInit.push_back(Init);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1866,7 +1860,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
if (Member->isBaseInitializer())
|
||||
Info.AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member;
|
||||
else
|
||||
Info.AllBaseFields[Member->getMember()] = Member;
|
||||
Info.AllBaseFields[Member->getAnyMember()] = Member;
|
||||
}
|
||||
|
||||
// Keep track of the direct virtual bases.
|
||||
|
@ -1965,21 +1959,14 @@ static void *GetKeyForBase(ASTContext &Context, QualType BaseType) {
|
|||
}
|
||||
|
||||
static void *GetKeyForMember(ASTContext &Context,
|
||||
CXXBaseOrMemberInitializer *Member,
|
||||
bool MemberMaybeAnon = false) {
|
||||
if (!Member->isMemberInitializer())
|
||||
CXXBaseOrMemberInitializer *Member) {
|
||||
if (!Member->isAnyMemberInitializer())
|
||||
return GetKeyForBase(Context, QualType(Member->getBaseClass(), 0));
|
||||
|
||||
// For fields injected into the class via declaration of an anonymous union,
|
||||
// use its anonymous union class declaration as the unique key.
|
||||
FieldDecl *Field = Member->getMember();
|
||||
|
||||
// After SetBaseOrMemberInitializers call, Field is the anonymous union
|
||||
// data member of the class. Data member used in the initializer list is
|
||||
// in AnonUnionMember field.
|
||||
if (MemberMaybeAnon && Field->isAnonymousStructOrUnion())
|
||||
Field = Member->getAnonUnionMember();
|
||||
|
||||
FieldDecl *Field = Member->getAnyMember();
|
||||
|
||||
// If the field is a member of an anonymous struct or union, our key
|
||||
// is the anonymous record decl that's a direct child of the class.
|
||||
RecordDecl *RD = Field->getParent();
|
||||
|
@ -2042,7 +2029,7 @@ DiagnoseBaseOrMemInitializerOrder(Sema &SemaRef,
|
|||
CXXBaseOrMemberInitializer *PrevInit = 0;
|
||||
for (unsigned InitIndex = 0; InitIndex != NumInits; ++InitIndex) {
|
||||
CXXBaseOrMemberInitializer *Init = Inits[InitIndex];
|
||||
void *InitKey = GetKeyForMember(SemaRef.Context, Init, true);
|
||||
void *InitKey = GetKeyForMember(SemaRef.Context, Init);
|
||||
|
||||
// Scan forward to try to find this initializer in the idealized
|
||||
// initializers list.
|
||||
|
@ -2058,13 +2045,13 @@ DiagnoseBaseOrMemInitializerOrder(Sema &SemaRef,
|
|||
SemaRef.Diag(PrevInit->getSourceLocation(),
|
||||
diag::warn_initializer_out_of_order);
|
||||
|
||||
if (PrevInit->isMemberInitializer())
|
||||
D << 0 << PrevInit->getMember()->getDeclName();
|
||||
if (PrevInit->isAnyMemberInitializer())
|
||||
D << 0 << PrevInit->getAnyMember()->getDeclName();
|
||||
else
|
||||
D << 1 << PrevInit->getBaseClassInfo()->getType();
|
||||
|
||||
if (Init->isMemberInitializer())
|
||||
D << 0 << Init->getMember()->getDeclName();
|
||||
if (Init->isAnyMemberInitializer())
|
||||
D << 0 << Init->getAnyMember()->getDeclName();
|
||||
else
|
||||
D << 1 << Init->getBaseClassInfo()->getType();
|
||||
|
||||
|
@ -2115,7 +2102,7 @@ typedef llvm::DenseMap<RecordDecl*, UnionEntry> RedundantUnionMap;
|
|||
bool CheckRedundantUnionInit(Sema &S,
|
||||
CXXBaseOrMemberInitializer *Init,
|
||||
RedundantUnionMap &Unions) {
|
||||
FieldDecl *Field = Init->getMember();
|
||||
FieldDecl *Field = Init->getAnyMember();
|
||||
RecordDecl *Parent = Field->getParent();
|
||||
if (!Parent->isAnonymousStructOrUnion())
|
||||
return false;
|
||||
|
@ -2182,8 +2169,8 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
|
|||
// Set the source order index.
|
||||
Init->setSourceOrder(i);
|
||||
|
||||
if (Init->isMemberInitializer()) {
|
||||
FieldDecl *Field = Init->getMember();
|
||||
if (Init->isAnyMemberInitializer()) {
|
||||
FieldDecl *Field = Init->getAnyMember();
|
||||
if (CheckRedundantInit(*this, Init, Members[Field]) ||
|
||||
CheckRedundantUnionInit(*this, Init, MemberUnions))
|
||||
HadError = true;
|
||||
|
|
|
@ -2341,22 +2341,27 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
|
|||
Init->getRParenLoc(),
|
||||
New->getParent());
|
||||
} else if (Init->isMemberInitializer()) {
|
||||
FieldDecl *Member;
|
||||
|
||||
// Is this an anonymous union?
|
||||
if (FieldDecl *UnionInit = Init->getAnonUnionMember())
|
||||
Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMemberLocation(),
|
||||
UnionInit, TemplateArgs));
|
||||
else
|
||||
Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMemberLocation(),
|
||||
Init->getMember(),
|
||||
TemplateArgs));
|
||||
FieldDecl *Member = cast<FieldDecl>(FindInstantiatedDecl(
|
||||
Init->getMemberLocation(),
|
||||
Init->getMember(),
|
||||
TemplateArgs));
|
||||
|
||||
NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(),
|
||||
NewArgs.size(),
|
||||
Init->getSourceLocation(),
|
||||
Init->getLParenLoc(),
|
||||
Init->getRParenLoc());
|
||||
} else if (Init->isIndirectMemberInitializer()) {
|
||||
IndirectFieldDecl *IndirectMember =
|
||||
cast<IndirectFieldDecl>(FindInstantiatedDecl(
|
||||
Init->getMemberLocation(),
|
||||
Init->getIndirectMember(), TemplateArgs));
|
||||
|
||||
NewInit = BuildMemberInitializer(IndirectMember, (Expr **)NewArgs.data(),
|
||||
NewArgs.size(),
|
||||
Init->getSourceLocation(),
|
||||
Init->getLParenLoc(),
|
||||
Init->getRParenLoc());
|
||||
}
|
||||
|
||||
if (NewInit.isInvalid()) {
|
||||
|
|
|
@ -4270,18 +4270,21 @@ ASTReader::ReadCXXBaseOrMemberInitializers(PerFileData &F,
|
|||
TypeSourceInfo *BaseClassInfo = 0;
|
||||
bool IsBaseVirtual = false;
|
||||
FieldDecl *Member = 0;
|
||||
IndirectFieldDecl *IndirectMember = 0;
|
||||
|
||||
bool IsBaseInitializer = Record[Idx++];
|
||||
if (IsBaseInitializer) {
|
||||
BaseClassInfo = GetTypeSourceInfo(F, Record, Idx);
|
||||
IsBaseVirtual = Record[Idx++];
|
||||
} else {
|
||||
Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
|
||||
bool IsIndirectMemberInitializer = Record[Idx++];
|
||||
if (IsIndirectMemberInitializer)
|
||||
IndirectMember = cast<IndirectFieldDecl>(GetDecl(Record[Idx++]));
|
||||
else
|
||||
Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
|
||||
}
|
||||
SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx);
|
||||
Expr *Init = ReadExpr(F);
|
||||
FieldDecl *AnonUnionMember
|
||||
= cast_or_null<FieldDecl>(GetDecl(Record[Idx++]));
|
||||
SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);
|
||||
SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
|
||||
bool IsWritten = Record[Idx++];
|
||||
|
@ -4302,8 +4305,14 @@ ASTReader::ReadCXXBaseOrMemberInitializers(PerFileData &F,
|
|||
IsBaseVirtual, LParenLoc,
|
||||
Init, RParenLoc);
|
||||
} else if (IsWritten) {
|
||||
BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
|
||||
LParenLoc, Init, RParenLoc);
|
||||
if (Member)
|
||||
BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc,
|
||||
LParenLoc, Init,
|
||||
RParenLoc);
|
||||
else
|
||||
BOMInit = new (C) CXXBaseOrMemberInitializer(C, IndirectMember,
|
||||
MemberLoc, LParenLoc,
|
||||
Init, RParenLoc);
|
||||
} else {
|
||||
BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc,
|
||||
LParenLoc, Init, RParenLoc,
|
||||
|
@ -4313,7 +4322,6 @@ ASTReader::ReadCXXBaseOrMemberInitializers(PerFileData &F,
|
|||
|
||||
if (IsWritten)
|
||||
BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices);
|
||||
BOMInit->setAnonUnionMember(AnonUnionMember);
|
||||
BaseOrMemberInitializers[i] = BOMInit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3255,11 +3255,15 @@ void ASTWriter::AddCXXBaseOrMemberInitializers(
|
|||
AddTypeSourceInfo(Init->getBaseClassInfo(), Record);
|
||||
Record.push_back(Init->isBaseVirtual());
|
||||
} else {
|
||||
AddDeclRef(Init->getMember(), Record);
|
||||
Record.push_back(Init->isIndirectMemberInitializer());
|
||||
if (Init->isIndirectMemberInitializer())
|
||||
AddDeclRef(Init->getIndirectMember(), Record);
|
||||
else
|
||||
AddDeclRef(Init->getMember(), Record);
|
||||
}
|
||||
|
||||
AddSourceLocation(Init->getMemberLocation(), Record);
|
||||
AddStmt(Init->getInit());
|
||||
AddDeclRef(Init->getAnonUnionMember(), Record);
|
||||
AddSourceLocation(Init->getLParenLoc(), Record);
|
||||
AddSourceLocation(Init->getRParenLoc(), Record);
|
||||
Record.push_back(Init->isWritten());
|
||||
|
|
|
@ -740,8 +740,8 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
|
|||
// Visit the initializers in source order
|
||||
for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
|
||||
CXXBaseOrMemberInitializer *Init = WrittenInits[I];
|
||||
if (Init->isMemberInitializer()) {
|
||||
if (Visit(MakeCursorMemberRef(Init->getMember(),
|
||||
if (Init->isAnyMemberInitializer()) {
|
||||
if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
|
||||
Init->getMemberLocation(), TU)))
|
||||
return true;
|
||||
} else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
|
||||
|
|
Loading…
Reference in New Issue