diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 30 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 43 | ||||
-rw-r--r-- | lib/Sema/SemaInit.h | 12 |
3 files changed, 55 insertions, 30 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 587c141b4b..4b960e81a5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3525,26 +3525,22 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { 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 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; + } } } diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h index 1987ad0734..85f3d2c1a3 100644 --- a/lib/Sema/SemaInit.h +++ b/lib/Sema/SemaInit.h @@ -389,7 +389,10 @@ public: 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 @@ public: /// \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 @@ public: // 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; |