diff options
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 163 |
1 files changed, 69 insertions, 94 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2740259..0919bc5 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -410,33 +410,13 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc); } -/// Retrieve the UuidAttr associated with QT. -static UuidAttr *GetUuidAttrOfType(QualType QT) { - // Optionally remove one level of pointer, reference or array indirection. - const Type *Ty = QT.getTypePtr();; - if (QT->isPointerType() || QT->isReferenceType()) - Ty = QT->getPointeeType().getTypePtr(); - else if (QT->isArrayType()) - Ty = cast<ArrayType>(QT)->getElementType().getTypePtr(); - - // Loop all record redeclaration looking for an uuid attribute. - CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); - for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), - E = RD->redecls_end(); I != E; ++I) { - if (UuidAttr *Uuid = I->getAttr<UuidAttr>()) - return Uuid; - } - - return 0; -} - /// \brief Build a Microsoft __uuidof expression with a type operand. ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc) { if (!Operand->getType()->isDependentType()) { - if (!GetUuidAttrOfType(Operand->getType())) + if (!CXXUuidofExpr::GetUuidAttrOfType(Operand->getType())) return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); } @@ -452,7 +432,7 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, Expr *E, SourceLocation RParenLoc) { if (!E->getType()->isDependentType()) { - if (!GetUuidAttrOfType(E->getType()) && + if (!CXXUuidofExpr::GetUuidAttrOfType(E->getType()) && !E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); } @@ -808,21 +788,18 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, MultiExprArg exprs, SourceLocation RParenLoc) { QualType Ty = TInfo->getType(); - unsigned NumExprs = exprs.size(); - Expr **Exprs = (Expr**)exprs.get(); SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); - if (Ty->isDependentType() || - CallExpr::hasAnyTypeDependentArguments( - llvm::makeArrayRef(Exprs, NumExprs))) { - exprs.release(); - + if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(exprs)) { return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, - Exprs, NumExprs, + exprs, RParenLoc)); } + unsigned NumExprs = exprs.size(); + Expr **Exprs = exprs.data(); + bool ListInitialization = LParenLoc.isInvalid(); assert((!ListInitialization || (NumExprs == 1 && isa<InitListExpr>(Exprs[0]))) && "List initialization must have initializer list as expression."); @@ -835,7 +812,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // corresponding cast expression. if (NumExprs == 1 && !ListInitialization) { Expr *Arg = Exprs[0]; - exprs.release(); return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc); } @@ -865,7 +841,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, : InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc); InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs)); + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, exprs); if (!Result.isInvalid() && ListInitialization && isa<InitListExpr>(Result.get())) { @@ -881,7 +857,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, } // FIXME: Improve AST representation? - return move(Result); + return Result; } /// doesUsualArrayDeleteWantSize - Answers whether the usual @@ -1011,9 +987,9 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer)) DirectInitRange = List->getSourceRange(); - return BuildCXXNew(StartLoc, UseGlobal, + return BuildCXXNew(SourceRange(StartLoc, D.getLocEnd()), UseGlobal, PlacementLParen, - move(PlacementArgs), + PlacementArgs, PlacementRParen, TypeIdParens, AllocType, @@ -1044,7 +1020,7 @@ static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style, } ExprResult -Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, +Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, @@ -1056,6 +1032,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, Expr *Initializer, bool TypeMayContainAuto) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); + SourceLocation StartLoc = Range.getBegin(); CXXNewExpr::InitializationStyle initStyle; if (DirectInitRange.isValid()) { @@ -1279,21 +1256,13 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, } } - // ARC: warn about ABI issues. - if (getLangOpts().ObjCAutoRefCount) { - QualType BaseAllocType = Context.getBaseElementType(AllocType); - if (BaseAllocType.hasStrongOrWeakObjCLifetime()) - Diag(StartLoc, diag::warn_err_new_delete_object_array) - << 0 << BaseAllocType; - } - // Note that we do *not* convert the argument in any way. It can // be signed, larger than size_t, whatever. } FunctionDecl *OperatorNew = 0; FunctionDecl *OperatorDelete = 0; - Expr **PlaceArgs = (Expr**)PlacementArgs.get(); + Expr **PlaceArgs = PlacementArgs.data(); unsigned NumPlaceArgs = PlacementArgs.size(); if (!AllocType->isDependentType() && @@ -1432,15 +1401,14 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, } } - PlacementArgs.release(); - return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete, UsualArrayDeleteWantsSize, - PlaceArgs, NumPlaceArgs, TypeIdParens, + llvm::makeArrayRef(PlaceArgs, NumPlaceArgs), + TypeIdParens, ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo, - StartLoc, DirectInitRange)); + Range, DirectInitRange)); } /// \brief Checks that a type is suitable as the allocated type @@ -1638,7 +1606,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, = dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) { // Perform template argument deduction to try to match the // expected function type. - TemplateDeductionInfo Info(Context, StartLoc); + TemplateDeductionInfo Info(StartLoc); if (DeduceTemplateArguments(FnTmpl, 0, ExpectedFunctionType, Fn, Info)) continue; } else @@ -2100,7 +2068,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, ObjectPtrConversions.front()->getConversionType(), AA_Converting); if (Res.isUsable()) { - Ex = move(Res); + Ex = Res; Type = Ex.get()->getType(); } } @@ -2211,13 +2179,6 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, } } - } else if (getLangOpts().ObjCAutoRefCount && - PointeeElem->isObjCLifetimeType() && - (PointeeElem.getObjCLifetime() == Qualifiers::OCL_Strong || - PointeeElem.getObjCLifetime() == Qualifiers::OCL_Weak) && - ArrayForm) { - Diag(StartLoc, diag::warn_err_new_delete_object_array) - << 1 << PointeeElem; } if (!OperatorDelete) { @@ -2287,7 +2248,7 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, return ExprError(); } - return move(Condition); + return Condition; } /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. @@ -2354,11 +2315,9 @@ static ExprResult BuildCXXCastArgument(Sema &S, default: llvm_unreachable("Unhandled cast kind!"); case CK_ConstructorConversion: { CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Method); - ASTOwningVector<Expr*> ConstructorArgs(S); + SmallVector<Expr*, 8> ConstructorArgs; - if (S.CompleteConstructorCall(Constructor, - MultiExprArg(&From, 1), - CastLoc, ConstructorArgs)) + if (S.CompleteConstructorCall(Constructor, From, CastLoc, ConstructorArgs)) return ExprError(); S.CheckConstructorAccess(CastLoc, Constructor, @@ -2367,7 +2326,7 @@ static ExprResult BuildCXXCastArgument(Sema &S, ExprResult Result = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), - move_arg(ConstructorArgs), + ConstructorArgs, HadMultipleCandidates, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); if (Result.isInvalid()) @@ -2511,15 +2470,14 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, // FIXME: When can ToType be a reference type? assert(!ToType->isReferenceType()); if (SCS.Second == ICK_Derived_To_Base) { - ASTOwningVector<Expr*> ConstructorArgs(*this); + SmallVector<Expr*, 8> ConstructorArgs; if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor), - MultiExprArg(*this, &From, 1), - /*FIXME:ConstructLoc*/SourceLocation(), + From, /*FIXME:ConstructLoc*/SourceLocation(), ConstructorArgs)) return ExprError(); return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), ToType, SCS.CopyConstructor, - move_arg(ConstructorArgs), + ConstructorArgs, /*HadMultipleCandidates*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, @@ -2527,8 +2485,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), ToType, SCS.CopyConstructor, - MultiExprArg(*this, &From, 1), - /*HadMultipleCandidates*/ false, + From, /*HadMultipleCandidates*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); @@ -2602,8 +2559,16 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Integral_Promotion: case ICK_Integral_Conversion: - From = ImpCastExprToType(From, ToType, CK_IntegralCast, - VK_RValue, /*BasePath=*/0, CCK).take(); + if (ToType->isBooleanType()) { + assert(FromType->castAs<EnumType>()->getDecl()->isFixed() && + SCS.Second == ICK_Integral_Promotion && + "only enums with fixed underlying type can promote to bool"); + From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean, + VK_RValue, /*BasePath=*/0, CCK).take(); + } else { + From = ImpCastExprToType(From, ToType, CK_IntegralCast, + VK_RValue, /*BasePath=*/0, CCK).take(); + } break; case ICK_Floating_Promotion: @@ -2943,6 +2908,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, case UTT_IsEmpty: case UTT_IsPolymorphic: case UTT_IsAbstract: + case UTT_IsInterfaceClass: // Fall-through // These traits require a complete type. @@ -3007,7 +2973,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, case UTT_IsUnion: return T->isUnionType(); case UTT_IsClass: - return T->isClassType() || T->isStructureType(); + return T->isClassType() || T->isStructureType() || T->isInterfaceType(); case UTT_IsFunction: return T->isFunctionType(); @@ -3073,6 +3039,10 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->isAbstract(); return false; + case UTT_IsInterfaceClass: + if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + return RD->isInterface(); + return false; case UTT_IsFinal: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasAttr<FinalAttr>(); @@ -3417,9 +3387,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, if (Init.Failed()) return false; - ExprResult Result = Init.Perform(S, To, InitKind, - MultiExprArg(ArgExprs.data(), - ArgExprs.size())); + ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs); if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; @@ -3577,7 +3545,7 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, if (Init.Failed()) return false; - ExprResult Result = Init.Perform(Self, To, Kind, MultiExprArg(&FromPtr, 1)); + ExprResult Result = Init.Perform(Self, To, Kind, FromPtr); return !Result.isInvalid() && !SFINAE.hasErrorOccurred(); } @@ -3774,7 +3742,7 @@ ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen); - return move(Result); + return Result; } static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) { @@ -4056,14 +4024,14 @@ static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS Best->Conversions[0], Sema::AA_Converting); if (LHSRes.isInvalid()) break; - LHS = move(LHSRes); + LHS = LHSRes; ExprResult RHSRes = Self.PerformImplicitConversion(RHS.get(), Best->BuiltinTypes.ParamTypes[1], Best->Conversions[1], Sema::AA_Converting); if (RHSRes.isInvalid()) break; - RHS = move(RHSRes); + RHS = RHSRes; if (Best->Function) Self.MarkFunctionReferenced(QuestionLoc, Best->Function); return false; @@ -4104,7 +4072,7 @@ static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) { SourceLocation()); Expr *Arg = E.take(); InitializationSequence InitSeq(Self, Entity, Kind, &Arg, 1); - ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&Arg, 1)); + ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg); if (Result.isInvalid()) return true; @@ -4129,7 +4097,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult CondRes = CheckCXXBooleanCondition(Cond.take()); if (CondRes.isInvalid()) return QualType(); - Cond = move(CondRes); + Cond = CondRes; } // Assume r-value. @@ -4160,6 +4128,9 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult &NonVoid = LVoid ? RHS : LHS; if (NonVoid.get()->getType()->isRecordType() && NonVoid.get()->isGLValue()) { + if (RequireNonAbstractType(QuestionLoc, NonVoid.get()->getType(), + diag::err_allocation_of_abstract_type)) + return QualType(); InitializedEntity Entity = InitializedEntity::InitializeTemporary(NonVoid.get()->getType()); NonVoid = PerformCopyInitialization(Entity, SourceLocation(), NonVoid); @@ -4302,7 +4273,11 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) { if (LTy->isRecordType()) { // The operands have class type. Make a temporary copy. + if (RequireNonAbstractType(QuestionLoc, LTy, + diag::err_allocation_of_abstract_type)) + return QualType(); InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy); + ExprResult LHSCopy = PerformCopyInitialization(Entity, SourceLocation(), LHS); @@ -4566,14 +4541,14 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, // Convert E1 to Composite1 ExprResult E1Result - = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E1,1)); + = E1ToC1.Perform(*this, Entity1, Kind, E1); if (E1Result.isInvalid()) return QualType(); E1 = E1Result.takeAs<Expr>(); // Convert E2 to Composite1 ExprResult E2Result - = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E2,1)); + = E2ToC1.Perform(*this, Entity1, Kind, E2); if (E2Result.isInvalid()) return QualType(); E2 = E2Result.takeAs<Expr>(); @@ -4591,14 +4566,14 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, // Convert E1 to Composite2 ExprResult E1Result - = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E1, 1)); + = E1ToC2.Perform(*this, Entity2, Kind, E1); if (E1Result.isInvalid()) return QualType(); E1 = E1Result.takeAs<Expr>(); // Convert E2 to Composite2 ExprResult E2Result - = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1)); + = E2ToC2.Perform(*this, Entity2, Kind, E2); if (E2Result.isInvalid()) return QualType(); E2 = E2Result.takeAs<Expr>(); @@ -4839,7 +4814,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { BO_Comma, BO->getType(), BO->getValueKind(), BO->getObjectKind(), - BO->getOperatorLoc())); + BO->getOperatorLoc(), + BO->isFPContractable())); } } @@ -4991,7 +4967,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, // type C (or of pointer to a class type C), the unqualified-id is looked // up in the scope of class C. [...] ObjectType = ParsedType::make(BaseType); - return move(Base); + return Base; } ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc, @@ -5056,7 +5032,8 @@ ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); - if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) { + if (!ObjectType->isDependentType() && !ObjectType->isScalarType() && + !ObjectType->isVectorType()) { if (getLangOpts().MicrosoftMode && ObjectType->isVoidType()) Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange(); else @@ -5203,8 +5180,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, } else { // Resolve the template-id to a type. TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId; - ASTTemplateArgsPtr TemplateArgsPtr(*this, - TemplateId->getTemplateArgs(), + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTemplateIdType(TemplateId->SS, TemplateId->TemplateKWLoc, @@ -5253,8 +5229,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, } else { // Resolve the template-id to a type. TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId; - ASTTemplateArgsPtr TemplateArgsPtr(*this, - TemplateId->getTemplateArgs(), + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTemplateIdType(TemplateId->SS, TemplateId->TemplateKWLoc, @@ -5353,7 +5328,7 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, MarkFunctionReferenced(Exp.get()->getLocStart(), Method); CXXMemberCallExpr *CE = - new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, VK, + new (Context) CXXMemberCallExpr(Context, ME, MultiExprArg(), ResultType, VK, Exp.get()->getLocEnd()); return CE; } |