Initialization improvements: addition of string initialization and a few
small bug fixes in SemaInit, switch over SemaDecl to use it more often, and
change a bunch of diagnostics which are different with the new initialization
code.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91767 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 587c141..4b960e8 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3525,26 +3525,22 @@
Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
VDecl->setInvalidDecl();
} else if (!VDecl->isInvalidDecl()) {
- if (VDecl->getType()->isReferenceType()
- || isa<InitListExpr>(Init)) {
- InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- if (InitSeq) {
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&Init, 1),
- &DclT);
- if (Result.isInvalid()) {
- VDecl->setInvalidDecl();
- return;
- }
-
- Init = Result.takeAs<Expr>();
- } else {
- InitSeq.Diagnose(*this, Entity, Kind, &Init, 1);
+ InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+ if (InitSeq) {
+ OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, (void**)&Init, 1),
+ &DclT);
+ if (Result.isInvalid()) {
VDecl->setInvalidDecl();
return;
- }
- } else if (CheckInitializerTypes(Init, DclT, Entity, Kind))
+ }
+
+ Init = Result.takeAs<Expr>();
+ } else {
+ InitSeq.Diagnose(*this, Entity, Kind, &Init, 1);
VDecl->setInvalidDecl();
+ return;
+ }
// C++ 3.6.2p2, allow dynamic initialization of static initializers.
// Don't check invalid declarations to avoid emitting useless diagnostics.
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 6f11a87..44f6cf3 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1988,6 +1988,7 @@
case SK_ConstructorInitialization:
case SK_ZeroInitialization:
case SK_CAssignment:
+ case SK_StringInit:
break;
case SK_ConversionSequence:
@@ -2080,6 +2081,13 @@
Steps.push_back(S);
}
+void InitializationSequence::AddStringInitStep(QualType T) {
+ Step S;
+ S.Kind = SK_StringInit;
+ S.Type = T;
+ Steps.push_back(S);
+}
+
void InitializationSequence::SetOverloadFailure(FailureKind Failure,
OverloadingResult Result) {
SequenceKind = FailedSequence;
@@ -2492,7 +2500,8 @@
const InitializationKind &Kind,
Expr *Initializer,
InitializationSequence &Sequence) {
- // FIXME: Implement!
+ Sequence.setSequenceKind(InitializationSequence::StringInit);
+ Sequence.AddStringInitStep(Entity.getType().getType());
}
/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
@@ -2711,10 +2720,17 @@
}
}
}
-
+
+ SourceLocation DeclLoc = Initializer->getLocStart();
+
if (const RecordType *SourceRecordType = SourceType->getAs<RecordType>()) {
// The type we're converting from is a class type, enumerate its conversion
// functions.
+
+ // Try to force the type to be complete before enumerating the conversion
+ // functions; it's okay if this fails, though.
+ S.RequireCompleteType(DeclLoc, SourceType, 0);
+
CXXRecordDecl *SourceRecordDecl
= cast<CXXRecordDecl>(SourceRecordType->getDecl());
@@ -2746,8 +2762,6 @@
}
}
- SourceLocation DeclLoc = Initializer->getLocStart();
-
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
@@ -2876,13 +2890,6 @@
return;
}
- // Handle initialization in C
- if (!S.getLangOptions().CPlusPlus) {
- setSequenceKind(CAssignment);
- AddCAssignmentStep(DestType);
- return;
- }
-
// - Otherwise, if the destination type is an array, the program is
// ill-formed.
if (const ArrayType *AT = Context.getAsArrayType(DestType)) {
@@ -2893,6 +2900,13 @@
return;
}
+
+ // Handle initialization in C
+ if (!S.getLangOptions().CPlusPlus) {
+ setSequenceKind(CAssignment);
+ AddCAssignmentStep(DestType);
+ return;
+ }
// - If the destination type is a (possibly cv-qualified) class type:
if (DestType->isRecordType()) {
@@ -3187,6 +3201,7 @@
case SK_ConversionSequence:
case SK_ListInitialization:
case SK_CAssignment:
+ case SK_StringInit:
assert(Args.size() == 1);
CurInit = Sema::OwningExprResult(S, ((Expr **)(Args.get()))[0]->Retain());
if (CurInit.isInvalid())
@@ -3425,6 +3440,12 @@
CurInit = S.Owned(CurInitExpr);
break;
}
+
+ case SK_StringInit: {
+ QualType Ty = Step->Type;
+ CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
+ break;
+ }
}
}
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
index 1987ad0..85f3d2c 100644
--- a/lib/Sema/SemaInit.h
+++ b/lib/Sema/SemaInit.h
@@ -389,7 +389,10 @@
StandardConversion,
/// \brief C conversion sequence.
- CAssignment
+ CAssignment,
+
+ /// \brief String initialization
+ StringInit
};
/// \brief Describes the kind of a particular step in an initialization
@@ -422,7 +425,9 @@
/// \brief Zero-initialize the object
SK_ZeroInitialization,
/// \brief C assignment
- SK_CAssignment
+ SK_CAssignment,
+ /// \brief Initialization by string
+ SK_StringInit
};
/// \brief A single step in the initialization sequence.
@@ -632,6 +637,9 @@
// path. However, that isn't the case yet.
void AddCAssignmentStep(QualType T);
+ /// \brief Add a string init step.
+ void AddStringInitStep(QualType T);
+
/// \brief Note that this initialization sequence failed.
void SetFailed(FailureKind Failure) {
SequenceKind = FailedSequence;