forked from OSchip/llvm-project
Improve source location information for C++ member initializers in a
constructor, by keeping the DeclaratorInfo* rather than just the type and a single location. llvm-svn: 90355
This commit is contained in:
parent
a3b825edd1
commit
c8c44b5d67
|
@ -888,12 +888,13 @@ public:
|
|||
/// };
|
||||
/// @endcode
|
||||
class CXXBaseOrMemberInitializer {
|
||||
/// BaseOrMember - This points to the entity being initialized,
|
||||
/// which is either a base class (a Type) or a non-static data
|
||||
/// member. When the low bit is 1, it's a base
|
||||
/// class; when the low bit is 0, it's a member.
|
||||
uintptr_t BaseOrMember;
|
||||
|
||||
/// \brief Either the base class name (stored as a DeclaratorInfo*) or the
|
||||
/// field being initialized.
|
||||
llvm::PointerUnion<DeclaratorInfo *, FieldDecl *> BaseOrMember;
|
||||
|
||||
/// \brief The source location for the field name.
|
||||
SourceLocation MemberLocation;
|
||||
|
||||
/// Args - The arguments used to initialize the base or member.
|
||||
Stmt **Args;
|
||||
unsigned NumArgs;
|
||||
|
@ -918,8 +919,8 @@ class CXXBaseOrMemberInitializer {
|
|||
/// and AnonUnionMember holds field decl for au_i1.
|
||||
llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
|
||||
|
||||
/// IdLoc - Location of the id in ctor-initializer list.
|
||||
SourceLocation IdLoc;
|
||||
/// LParenLoc - Location of the left paren of the ctor-initializer.
|
||||
SourceLocation LParenLoc;
|
||||
|
||||
/// RParenLoc - Location of the right paren of the ctor-initializer.
|
||||
SourceLocation RParenLoc;
|
||||
|
@ -927,18 +928,22 @@ class CXXBaseOrMemberInitializer {
|
|||
public:
|
||||
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
|
||||
explicit
|
||||
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
|
||||
CXXConstructorDecl *C,
|
||||
SourceLocation L, SourceLocation R);
|
||||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
DeclaratorInfo *DInfo, CXXConstructorDecl *C,
|
||||
SourceLocation L,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation R);
|
||||
|
||||
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
|
||||
explicit
|
||||
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
|
||||
CXXConstructorDecl *C,
|
||||
SourceLocation L, SourceLocation R);
|
||||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
FieldDecl *Member, SourceLocation MemberLoc,
|
||||
CXXConstructorDecl *C, SourceLocation L,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation R);
|
||||
|
||||
/// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
|
||||
~CXXBaseOrMemberInitializer();
|
||||
/// \brief Destroy the base or member initializer.
|
||||
void Destroy(ASTContext &Context);
|
||||
|
||||
/// arg_iterator - Iterates through the member initialization
|
||||
/// arguments.
|
||||
|
@ -948,54 +953,54 @@ public:
|
|||
/// arguments.
|
||||
typedef ConstExprIterator const_arg_iterator;
|
||||
|
||||
/// getBaseOrMember - get the generic 'member' representing either the field
|
||||
/// or a base class.
|
||||
void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); }
|
||||
|
||||
/// isBaseInitializer - Returns true when this initializer is
|
||||
/// initializing a base class.
|
||||
bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
|
||||
bool isBaseInitializer() const { return BaseOrMember.is<DeclaratorInfo*>(); }
|
||||
|
||||
/// isMemberInitializer - Returns true when this initializer is
|
||||
/// initializing a non-static data member.
|
||||
bool isMemberInitializer() const { return (BaseOrMember & 0x1) == 0; }
|
||||
bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
|
||||
|
||||
/// getBaseClass - If this is a base class initializer, returns the
|
||||
/// type used to specify the initializer. The resulting type will be
|
||||
/// a class type or a typedef of a class type. If this is not a base
|
||||
/// class initializer, returns NULL.
|
||||
Type *getBaseClass() {
|
||||
if (isBaseInitializer())
|
||||
return reinterpret_cast<Type*>(BaseOrMember & ~0x01);
|
||||
else
|
||||
return 0;
|
||||
/// If this is a base class initializer, returns the type of the
|
||||
/// base class with location information. Otherwise, returns an NULL
|
||||
/// type location.
|
||||
TypeLoc getBaseClassLoc() const;
|
||||
|
||||
/// If this is a base class initializer, returns the type of the base class.
|
||||
/// Otherwise, returns NULL.
|
||||
const Type *getBaseClass() const;
|
||||
Type *getBaseClass();
|
||||
|
||||
/// \brief Returns the declarator information for a base class initializer.
|
||||
DeclaratorInfo *getBaseClassInfo() const {
|
||||
return BaseOrMember.dyn_cast<DeclaratorInfo *>();
|
||||
}
|
||||
|
||||
/// getBaseClass - If this is a base class initializer, returns the
|
||||
/// type used to specify the initializer. The resulting type will be
|
||||
/// a class type or a typedef of a class type. If this is not a base
|
||||
/// class initializer, returns NULL.
|
||||
const Type *getBaseClass() const {
|
||||
if (isBaseInitializer())
|
||||
return reinterpret_cast<const Type*>(BaseOrMember & ~0x01);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// getMember - If this is a member initializer, returns the
|
||||
/// declaration of the non-static data member being
|
||||
/// initialized. Otherwise, returns NULL.
|
||||
FieldDecl *getMember() {
|
||||
if (isMemberInitializer())
|
||||
return reinterpret_cast<FieldDecl *>(BaseOrMember);
|
||||
return BaseOrMember.get<FieldDecl*>();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setMember(FieldDecl * anonUnionField) {
|
||||
BaseOrMember = reinterpret_cast<uintptr_t>(anonUnionField);
|
||||
SourceLocation getMemberLocation() const {
|
||||
return MemberLocation;
|
||||
}
|
||||
|
||||
void setMember(FieldDecl *Member) {
|
||||
assert(isMemberInitializer());
|
||||
BaseOrMember = Member;
|
||||
}
|
||||
|
||||
/// \brief Determine the source location of the initializer.
|
||||
SourceLocation getSourceLocation() const;
|
||||
|
||||
/// \brief Determine the source range covering the entire initializer.
|
||||
SourceRange getSourceRange() const;
|
||||
|
||||
FieldDecl *getAnonUnionMember() const {
|
||||
return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
|
||||
}
|
||||
|
@ -1007,7 +1012,7 @@ public:
|
|||
return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
|
||||
}
|
||||
|
||||
SourceLocation getSourceLocation() const { return IdLoc; }
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
|
||||
/// arg_begin() - Retrieve an iterator to the first initializer argument.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
|
@ -630,43 +631,76 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
|
|||
}
|
||||
|
||||
CXXBaseOrMemberInitializer::
|
||||
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
|
||||
CXXConstructorDecl *C,
|
||||
SourceLocation L, SourceLocation R)
|
||||
: Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
|
||||
BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
|
||||
assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
|
||||
BaseOrMember |= 0x01;
|
||||
|
||||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
DeclaratorInfo *DInfo, CXXConstructorDecl *C,
|
||||
SourceLocation L,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation R)
|
||||
: BaseOrMember(DInfo), Args(0), NumArgs(0), CtorOrAnonUnion(C),
|
||||
LParenLoc(L), RParenLoc(R)
|
||||
{
|
||||
if (NumArgs > 0) {
|
||||
this->NumArgs = NumArgs;
|
||||
// FIXME. Allocation via Context
|
||||
this->Args = new Stmt*[NumArgs];
|
||||
this->Args = new (Context) Stmt*[NumArgs];
|
||||
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
|
||||
this->Args[Idx] = Args[Idx];
|
||||
}
|
||||
CtorOrAnonUnion = C;
|
||||
}
|
||||
|
||||
CXXBaseOrMemberInitializer::
|
||||
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
|
||||
CXXConstructorDecl *C,
|
||||
SourceLocation L, SourceLocation R)
|
||||
: Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
|
||||
BaseOrMember = reinterpret_cast<uintptr_t>(Member);
|
||||
assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
|
||||
|
||||
CXXBaseOrMemberInitializer(ASTContext &Context,
|
||||
FieldDecl *Member, SourceLocation MemberLoc,
|
||||
CXXConstructorDecl *C, SourceLocation L,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation R)
|
||||
: BaseOrMember(Member), MemberLocation(MemberLoc), Args(0), NumArgs(0),
|
||||
CtorOrAnonUnion(C), LParenLoc(L), RParenLoc(R)
|
||||
{
|
||||
if (NumArgs > 0) {
|
||||
this->NumArgs = NumArgs;
|
||||
this->Args = new Stmt*[NumArgs];
|
||||
this->Args = new (Context) Stmt*[NumArgs];
|
||||
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
|
||||
this->Args[Idx] = Args[Idx];
|
||||
}
|
||||
CtorOrAnonUnion = C;
|
||||
}
|
||||
|
||||
CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
|
||||
delete [] Args;
|
||||
void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
|
||||
for (unsigned I = 0; I != NumArgs; ++I)
|
||||
Args[I]->Destroy(Context);
|
||||
Context.Deallocate(Args);
|
||||
this->~CXXBaseOrMemberInitializer();
|
||||
}
|
||||
|
||||
TypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
|
||||
if (isBaseInitializer())
|
||||
return BaseOrMember.get<DeclaratorInfo*>()->getTypeLoc();
|
||||
else
|
||||
return TypeLoc();
|
||||
}
|
||||
|
||||
Type *CXXBaseOrMemberInitializer::getBaseClass() {
|
||||
if (isBaseInitializer())
|
||||
return BaseOrMember.get<DeclaratorInfo*>()->getType().getTypePtr();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Type *CXXBaseOrMemberInitializer::getBaseClass() const {
|
||||
if (isBaseInitializer())
|
||||
return BaseOrMember.get<DeclaratorInfo*>()->getType().getTypePtr();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
|
||||
if (isMemberInitializer())
|
||||
return getMemberLocation();
|
||||
|
||||
return getBaseClassLoc().getSourceRange().getBegin();
|
||||
}
|
||||
|
||||
SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
|
||||
return SourceRange(getSourceLocation(), getRParenLoc());
|
||||
}
|
||||
|
||||
CXXConstructorDecl *
|
||||
|
|
|
@ -2110,10 +2110,13 @@ public:
|
|||
|
||||
MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
|
||||
unsigned NumArgs, SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
MemInitResult BuildBaseInitializer(QualType BaseType, Expr **Args,
|
||||
unsigned NumArgs, SourceLocation IdLoc,
|
||||
MemInitResult BuildBaseInitializer(QualType BaseType,
|
||||
DeclaratorInfo *BaseDInfo,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc,
|
||||
CXXRecordDecl *ClassDecl);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/CXXInheritance.h"
|
||||
#include "clang/AST/DeclVisitor.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/AST/TypeOrdering.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
|
@ -977,19 +978,26 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
|||
|
||||
if (Member)
|
||||
return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
|
||||
RParenLoc);
|
||||
LParenLoc, RParenLoc);
|
||||
}
|
||||
// It didn't name a member, so see if it names a class.
|
||||
TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy
|
||||
: getTypeName(*MemberOrBase, IdLoc, S, &SS);
|
||||
if (!BaseTy)
|
||||
QualType BaseType;
|
||||
|
||||
DeclaratorInfo *DInfo = 0;
|
||||
if (TemplateTypeTy)
|
||||
BaseType = GetTypeFromParser(TemplateTypeTy, &DInfo);
|
||||
else
|
||||
BaseType = QualType::getFromOpaquePtr(getTypeName(*MemberOrBase, IdLoc,
|
||||
S, &SS));
|
||||
if (BaseType.isNull())
|
||||
return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
|
||||
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
|
||||
|
||||
QualType BaseType = GetTypeFromParser(BaseTy);
|
||||
if (!DInfo)
|
||||
DInfo = Context.getTrivialDeclaratorInfo(BaseType, IdLoc);
|
||||
|
||||
return BuildBaseInitializer(BaseType, (Expr **)Args, NumArgs, IdLoc,
|
||||
RParenLoc, ClassDecl);
|
||||
return BuildBaseInitializer(BaseType, DInfo, (Expr **)Args, NumArgs,
|
||||
LParenLoc, RParenLoc, ClassDecl);
|
||||
}
|
||||
|
||||
/// Checks an initializer expression for use of uninitialized fields, such as
|
||||
|
@ -1038,6 +1046,7 @@ static bool InitExprContainsUninitializedFields(const Stmt* S,
|
|||
Sema::MemInitResult
|
||||
Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
|
||||
unsigned NumArgs, SourceLocation IdLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc) {
|
||||
// FIXME: CXXBaseOrMemberInitializer should only contain a single
|
||||
// subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
|
||||
|
@ -1119,22 +1128,25 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
|
|||
ExprTemporaries.clear();
|
||||
|
||||
// FIXME: Perform direct initialization of the member.
|
||||
return new (Context) CXXBaseOrMemberInitializer(Member, (Expr **)Args,
|
||||
NumArgs, C, IdLoc, RParenLoc);
|
||||
return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
|
||||
C, LParenLoc, (Expr **)Args,
|
||||
NumArgs, RParenLoc);
|
||||
}
|
||||
|
||||
Sema::MemInitResult
|
||||
Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
|
||||
unsigned NumArgs, SourceLocation IdLoc,
|
||||
SourceLocation RParenLoc, CXXRecordDecl *ClassDecl) {
|
||||
Sema::BuildBaseInitializer(QualType BaseType, DeclaratorInfo *BaseDInfo,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation LParenLoc, SourceLocation RParenLoc,
|
||||
CXXRecordDecl *ClassDecl) {
|
||||
bool HasDependentArg = false;
|
||||
for (unsigned i = 0; i < NumArgs; i++)
|
||||
HasDependentArg |= Args[i]->isTypeDependent();
|
||||
|
||||
SourceLocation BaseLoc = BaseDInfo->getTypeLoc().getSourceRange().getBegin();
|
||||
if (!BaseType->isDependentType()) {
|
||||
if (!BaseType->isRecordType())
|
||||
return Diag(IdLoc, diag::err_base_init_does_not_name_class)
|
||||
<< BaseType << SourceRange(IdLoc, RParenLoc);
|
||||
return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
|
||||
<< BaseType << BaseDInfo->getTypeLoc().getSourceRange();
|
||||
|
||||
// C++ [class.base.init]p2:
|
||||
// [...] Unless the mem-initializer-id names a nonstatic data
|
||||
|
@ -1180,16 +1192,16 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
|
|||
// a direct non-virtual base class and an inherited virtual base
|
||||
// class, the mem-initializer is ill-formed.
|
||||
if (DirectBaseSpec && VirtualBaseSpec)
|
||||
return Diag(IdLoc, diag::err_base_init_direct_and_virtual)
|
||||
<< BaseType << SourceRange(IdLoc, RParenLoc);
|
||||
return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
|
||||
<< BaseType << BaseDInfo->getTypeLoc().getSourceRange();
|
||||
// C++ [base.class.init]p2:
|
||||
// Unless the mem-initializer-id names a nonstatic data membeer of the
|
||||
// constructor's class ot a direst or virtual base of that class, the
|
||||
// mem-initializer is ill-formed.
|
||||
if (!DirectBaseSpec && !VirtualBaseSpec)
|
||||
return Diag(IdLoc, diag::err_not_direct_base_or_virtual)
|
||||
<< BaseType << ClassDecl->getNameAsCString()
|
||||
<< SourceRange(IdLoc, RParenLoc);
|
||||
return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
|
||||
<< BaseType << ClassDecl->getNameAsCString()
|
||||
<< BaseDInfo->getTypeLoc().getSourceRange();
|
||||
}
|
||||
|
||||
CXXConstructorDecl *C = 0;
|
||||
|
@ -1201,7 +1213,8 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
|
|||
C = PerformInitializationByConstructor(BaseType,
|
||||
MultiExprArg(*this,
|
||||
(void**)Args, NumArgs),
|
||||
IdLoc, SourceRange(IdLoc, RParenLoc),
|
||||
BaseLoc,
|
||||
SourceRange(BaseLoc, RParenLoc),
|
||||
Name, IK_Direct,
|
||||
ConstructorArgs);
|
||||
if (C) {
|
||||
|
@ -1215,8 +1228,9 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
|
|||
// subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
|
||||
ExprTemporaries.clear();
|
||||
|
||||
return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args,
|
||||
NumArgs, C, IdLoc, RParenLoc);
|
||||
return new (Context) CXXBaseOrMemberInitializer(Context, BaseDInfo, C,
|
||||
LParenLoc, (Expr **)Args,
|
||||
NumArgs, RParenLoc);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1278,7 +1292,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
}
|
||||
else {
|
||||
CXXRecordDecl *VBaseDecl =
|
||||
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
||||
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
||||
assert(VBaseDecl && "SetBaseOrMemberInitializers - VBaseDecl null");
|
||||
CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context);
|
||||
if (!Ctor) {
|
||||
|
@ -1299,13 +1313,18 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
|
||||
// FIXME: CXXBaseOrMemberInitializer should only contain a single
|
||||
// subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
|
||||
// subexpression so we can wrap it in a CXXExprWithTemporaries if
|
||||
// necessary.
|
||||
// FIXME: Is there any better source-location information we can give?
|
||||
ExprTemporaries.clear();
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
new (Context) CXXBaseOrMemberInitializer(VBase->getType(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(), Ctor,
|
||||
new (Context) CXXBaseOrMemberInitializer(Context,
|
||||
Context.getTrivialDeclaratorInfo(VBase->getType(),
|
||||
SourceLocation()),
|
||||
Ctor,
|
||||
SourceLocation(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(),
|
||||
SourceLocation());
|
||||
AllToInit.push_back(Member);
|
||||
}
|
||||
|
@ -1347,13 +1366,18 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
|
||||
// FIXME: CXXBaseOrMemberInitializer should only contain a single
|
||||
// subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
|
||||
// subexpression so we can wrap it in a CXXExprWithTemporaries if
|
||||
// necessary.
|
||||
// FIXME: Is there any better source-location information we can give?
|
||||
ExprTemporaries.clear();
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
new (Context) CXXBaseOrMemberInitializer(Base->getType(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(), Ctor,
|
||||
new (Context) CXXBaseOrMemberInitializer(Context,
|
||||
Context.getTrivialDeclaratorInfo(Base->getType(),
|
||||
SourceLocation()),
|
||||
Ctor,
|
||||
SourceLocation(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(),
|
||||
SourceLocation());
|
||||
AllToInit.push_back(Member);
|
||||
}
|
||||
|
@ -1428,9 +1452,12 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
// subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
|
||||
ExprTemporaries.clear();
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
new (Context) CXXBaseOrMemberInitializer(*Field,CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(), Ctor,
|
||||
new (Context) CXXBaseOrMemberInitializer(Context,
|
||||
*Field, SourceLocation(),
|
||||
Ctor,
|
||||
SourceLocation(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(),
|
||||
SourceLocation());
|
||||
|
||||
AllToInit.push_back(Member);
|
||||
|
@ -1538,13 +1565,15 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
|
|||
if (FieldDecl *Field = Member->getMember())
|
||||
Diag(Member->getSourceLocation(),
|
||||
diag::error_multiple_mem_initialization)
|
||||
<< Field->getNameAsString();
|
||||
<< Field->getNameAsString()
|
||||
<< Member->getSourceRange();
|
||||
else {
|
||||
Type *BaseClass = Member->getBaseClass();
|
||||
assert(BaseClass && "ActOnMemInitializers - neither field or base");
|
||||
Diag(Member->getSourceLocation(),
|
||||
diag::error_multiple_base_initialization)
|
||||
<< QualType(BaseClass, 0);
|
||||
<< QualType(BaseClass, 0)
|
||||
<< Member->getSourceRange();
|
||||
}
|
||||
Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer)
|
||||
<< 0;
|
||||
|
|
|
@ -1620,14 +1620,19 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
|
|||
MemInitResult NewInit;
|
||||
|
||||
if (Init->isBaseInitializer()) {
|
||||
QualType BaseType(Init->getBaseClass(), 0);
|
||||
BaseType = SubstType(BaseType, TemplateArgs, Init->getSourceLocation(),
|
||||
New->getDeclName());
|
||||
|
||||
NewInit = BuildBaseInitializer(BaseType,
|
||||
DeclaratorInfo *BaseDInfo = SubstType(Init->getBaseClassInfo(),
|
||||
TemplateArgs,
|
||||
Init->getSourceLocation(),
|
||||
New->getDeclName());
|
||||
if (!BaseDInfo) {
|
||||
New->setInvalidDecl();
|
||||
continue;
|
||||
}
|
||||
|
||||
NewInit = BuildBaseInitializer(BaseDInfo->getType(), BaseDInfo,
|
||||
(Expr **)NewArgs.data(),
|
||||
NewArgs.size(),
|
||||
Init->getSourceLocation(),
|
||||
Init->getLParenLoc(),
|
||||
Init->getRParenLoc(),
|
||||
New->getParent());
|
||||
} else if (Init->isMemberInitializer()) {
|
||||
|
@ -1643,6 +1648,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
|
|||
NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(),
|
||||
NewArgs.size(),
|
||||
Init->getSourceLocation(),
|
||||
Init->getLParenLoc(),
|
||||
Init->getRParenLoc());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue