aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp36
1 files changed, 27 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c124c469ad..8ba6f31da8 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1120,13 +1120,22 @@ Sema::DeclTy *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
return Anon;
}
-bool Sema::CheckSingleInitializer(Expr *&Init, QualType DeclType) {
+bool Sema::CheckSingleInitializer(Expr *&Init, QualType DeclType,
+ bool DirectInit) {
// Get the type before calling CheckSingleAssignmentConstraints(), since
// it can promote the expression.
QualType InitType = Init->getType();
- if (getLangOptions().CPlusPlus)
- return PerformCopyInitialization(Init, DeclType, "initializing");
+ if (getLangOptions().CPlusPlus) {
+ // FIXME: I dislike this error message. A lot.
+ if (PerformImplicitConversion(Init, DeclType, "initializing", DirectInit))
+ return Diag(Init->getSourceRange().getBegin(),
+ diag::err_typecheck_convert_incompatible)
+ << DeclType << Init->getType() << "initializing"
+ << Init->getSourceRange();
+
+ return false;
+ }
AssignConvertType ConvTy = CheckSingleAssignmentConstraints(DeclType, Init);
return DiagnoseAssignmentResult(ConvTy, Init->getLocStart(), DeclType,
@@ -1169,7 +1178,8 @@ StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) {
bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
SourceLocation InitLoc,
- DeclarationName InitEntity) {
+ DeclarationName InitEntity,
+ bool DirectInit) {
if (DeclType->isDependentType() || Init->isTypeDependent())
return false;
@@ -1178,7 +1188,7 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
// (8.3.2), shall be initialized by an object, or function, of
// type T or by an object that can be converted into a T.
if (DeclType->isReferenceType())
- return CheckReferenceInit(Init, DeclType);
+ return CheckReferenceInit(Init, DeclType, 0, false, DirectInit);
// C99 6.7.8p3: The type of the entity to be initialized shall be an array
// of unknown size ("[]") or an object type that is not a variable array type.
@@ -1208,7 +1218,8 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
CXXConstructorDecl *Constructor
= PerformInitializationByConstructor(DeclType, &Init, 1,
InitLoc, Init->getSourceRange(),
- InitEntity, IK_Copy);
+ InitEntity,
+ DirectInit? IK_Direct : IK_Copy);
return Constructor == 0;
}
@@ -1244,7 +1255,7 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
return Diag(Init->getLocStart(), diag::err_array_init_list_required)
<< Init->getSourceRange();
- return CheckSingleInitializer(Init, DeclType);
+ return CheckSingleInitializer(Init, DeclType, DirectInit);
} else if (getLangOptions().CPlusPlus) {
// C++ [dcl.init]p14:
// [...] If the class is an aggregate (8.5.1), and the initializer
@@ -2366,6 +2377,13 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
}
void Sema::AddInitializerToDecl(DeclTy *dcl, ExprArg init) {
+ AddInitializerToDecl(dcl, move(init), /*DirectInit=*/false);
+}
+
+/// AddInitializerToDecl - Adds the initializer Init to the
+/// declaration dcl. If DirectInit is true, this is C++ direct
+/// initialization rather than copy initialization.
+void Sema::AddInitializerToDecl(DeclTy *dcl, ExprArg init, bool DirectInit) {
Decl *RealDecl = static_cast<Decl *>(dcl);
Expr *Init = static_cast<Expr *>(init.release());
assert(Init && "missing initializer");
@@ -2394,7 +2412,7 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprArg init) {
VDecl->setInvalidDecl();
} else if (!VDecl->isInvalidDecl()) {
if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(),
- VDecl->getDeclName()))
+ VDecl->getDeclName(), DirectInit))
VDecl->setInvalidDecl();
// C++ 3.6.2p2, allow dynamic initialization of static initializers.
@@ -2408,7 +2426,7 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprArg init) {
Diag(VDecl->getLocation(), diag::warn_extern_init);
if (!VDecl->isInvalidDecl())
if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(),
- VDecl->getDeclName()))
+ VDecl->getDeclName(), DirectInit))
VDecl->setInvalidDecl();
// C++ 3.6.2p2, allow dynamic initialization of static initializers.