aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r--lib/Sema/SemaInit.cpp43
1 files changed, 32 insertions, 11 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 6f11a87d11..44f6cf3d74 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1988,6 +1988,7 @@ void InitializationSequence::Step::Destroy() {
case SK_ConstructorInitialization:
case SK_ZeroInitialization:
case SK_CAssignment:
+ case SK_StringInit:
break;
case SK_ConversionSequence:
@@ -2080,6 +2081,13 @@ void InitializationSequence::AddCAssignmentStep(QualType T) {
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 @@ static void TryStringLiteralInitialization(Sema &S,
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 @@ static void TryUserDefinedConversion(Sema &S,
}
}
}
-
+
+ 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 @@ static void TryUserDefinedConversion(Sema &S,
}
}
- SourceLocation DeclLoc = Initializer->getLocStart();
-
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
@@ -2876,13 +2890,6 @@ InitializationSequence::InitializationSequence(Sema &S,
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 @@ InitializationSequence::InitializationSequence(Sema &S,
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 @@ InitializationSequence::Perform(Sema &S,
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 @@ InitializationSequence::Perform(Sema &S,
CurInit = S.Owned(CurInitExpr);
break;
}
+
+ case SK_StringInit: {
+ QualType Ty = Step->Type;
+ CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
+ break;
+ }
}
}