/// CXXConstructExpr - Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
+public:
+ enum ConstructionKind {
+ CK_Complete,
+ CK_NonVirtualBase,
+ CK_VirtualBase
+ };
+
+private:
CXXConstructorDecl *Constructor;
SourceLocation Loc;
bool Elidable : 1;
bool ZeroInitialization : 1;
- bool BaseInitialization : 1;
+ unsigned ConstructKind : 2;
Stmt **Args;
unsigned NumArgs;
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
bool ZeroInitialization = false,
- bool BaseInitialization = false);
+ ConstructionKind ConstructKind = CK_Complete);
~CXXConstructExpr() { }
virtual void DoDestroy(ASTContext &C);
/// \brief Determines whether this constructor is actually constructing
/// a base class (rather than a complete object).
- bool isBaseInitialization() const { return BaseInitialization; }
- void setBaseInitialization(bool BI) { BaseInitialization = BI; }
+ bool isBaseInitialization() const {
+ return ConstructKind != CK_Complete;
+ }
+ void setConstructionKind(ConstructionKind CK) {
+ ConstructKind = CK;
+ }
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
bool BaseInitialization) {
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Elidable, Args, NumArgs, ZeroInitialization,
- BaseInitialization);
+ BaseInitialization ? CK_NonVirtualBase :
+ CK_Complete);
}
CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool elidable,
Expr **args, unsigned numargs,
- bool ZeroInitialization,
- bool BaseInitialization)
+ bool ZeroInitialization,
+ ConstructionKind ConstructKind)
: Expr(SC, T,
T->isDependentType(),
(T->isDependentType() ||
CallExpr::hasAnyValueDependentArguments(args, numargs))),
Constructor(D), Loc(Loc), Elidable(elidable),
- ZeroInitialization(ZeroInitialization),
- BaseInitialization(BaseInitialization), Args(0), NumArgs(numargs)
+ ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
+ Args(0), NumArgs(numargs)
{
if (NumArgs) {
Args = new (C) Stmt*[NumArgs];
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/FullExpr.h"
#include "clang/Parse/Action.h"
#include "clang/Sema/SemaDiagnostic.h"
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
/// including handling of its default argument expressions.
- OwningExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc,
- QualType DeclInitType,
- CXXConstructorDecl *Constructor,
- MultiExprArg Exprs,
- bool RequiresZeroInit = false,
- bool BaseInitialization = false);
+ OwningExprResult
+ BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+ CXXConstructorDecl *Constructor, MultiExprArg Exprs,
+ bool RequiresZeroInit = false,
+ CXXConstructExpr::ConstructionKind ConstructKind =
+ CXXConstructExpr::CK_Complete);
// FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
- OwningExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc,
- QualType DeclInitType,
- CXXConstructorDecl *Constructor,
- bool Elidable,
- MultiExprArg Exprs,
- bool RequiresZeroInit = false,
- bool BaseInitialization = false);
+ OwningExprResult
+ BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+ CXXConstructorDecl *Constructor, bool Elidable,
+ MultiExprArg Exprs, bool RequiresZeroInit = false,
+ CXXConstructExpr::ConstructionKind ConstructKind =
+ CXXConstructExpr::CK_Complete);
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
CXXConstructorDecl *Constructor,
MultiExprArg ExprArgs,
bool RequiresZeroInit,
- bool BaseInitialization) {
+ CXXConstructExpr::ConstructionKind ConstructKind) {
bool Elidable = false;
// C++0x [class.copy]p34:
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
Elidable, move(ExprArgs), RequiresZeroInit,
- BaseInitialization);
+ ConstructKind);
}
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg ExprArgs,
bool RequiresZeroInit,
- bool BaseInitialization) {
+ CXXConstructExpr::ConstructionKind ConstructKind) {
unsigned NumExprs = ExprArgs.size();
Expr **Exprs = (Expr **)ExprArgs.release();
MarkDeclarationReferenced(ConstructLoc, Constructor);
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
Constructor, Elidable, Exprs, NumExprs,
- RequiresZeroInit, BaseInitialization));
+ RequiresZeroInit, ConstructKind));
}
bool Sema::InitializeVarWithConstructor(VarDecl *VD,
NumExprs,
Kind.getParenRange().getEnd(),
ConstructorInitRequiresZeroInit));
- } else
+ } else {
+ CXXConstructExpr::ConstructionKind ConstructKind =
+ CXXConstructExpr::CK_Complete;
+
+ if (Entity.getKind() == InitializedEntity::EK_Base) {
+ ConstructKind = Entity.getBaseSpecifier()->isVirtual() ?
+ CXXConstructExpr::CK_VirtualBase :
+ CXXConstructExpr::CK_NonVirtualBase;
+ }
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
Constructor,
move_arg(ConstructorArgs),
ConstructorInitRequiresZeroInit,
- Entity.getKind() == InitializedEntity::EK_Base);
+ ConstructKind);
+ }
if (CurInit.isInvalid())
return S.ExprError();