diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp | 1162 |
1 files changed, 572 insertions, 590 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp index 20118b5..0dabdca 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp @@ -15,6 +15,7 @@ #include "clang/Sema/SemaInternal.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" @@ -106,7 +107,7 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, // For this reason, we're currently only doing the C++03 version of this // code; the C++0x version has to wait until we get a proper spec. QualType SearchType; - DeclContext *LookupCtx = 0; + DeclContext *LookupCtx = nullptr; bool isDependent = false; bool LookInScope = false; @@ -117,38 +118,33 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, SearchType = GetTypeFromParser(ObjectTypePtr); if (SS.isSet()) { - NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); + NestedNameSpecifier *NNS = SS.getScopeRep(); bool AlreadySearched = false; bool LookAtPrefix = true; - // C++ [basic.lookup.qual]p6: + // C++11 [basic.lookup.qual]p6: // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, // the type-names are looked up as types in the scope designated by the - // nested-name-specifier. In a qualified-id of the form: + // nested-name-specifier. Similarly, in a qualified-id of the form: // - // ::[opt] nested-name-specifier ~ class-name + // nested-name-specifier[opt] class-name :: ~ class-name // - // where the nested-name-specifier designates a namespace scope, and in - // a qualified-id of the form: + // the second class-name is looked up in the same scope as the first. // - // ::opt nested-name-specifier class-name :: ~ class-name - // - // the class-names are looked up as types in the scope designated by - // the nested-name-specifier. - // - // Here, we check the first case (completely) and determine whether the - // code below is permitted to look at the prefix of the - // nested-name-specifier. + // Here, we determine whether the code below is permitted to look at the + // prefix of the nested-name-specifier. DeclContext *DC = computeDeclContext(SS, EnteringContext); if (DC && DC->isFileContext()) { AlreadySearched = true; LookupCtx = DC; isDependent = false; - } else if (DC && isa<CXXRecordDecl>(DC)) + } else if (DC && isa<CXXRecordDecl>(DC)) { LookAtPrefix = false; + LookInScope = true; + } // The second case from the C++03 rules quoted further above. - NestedNameSpecifier *Prefix = 0; + NestedNameSpecifier *Prefix = nullptr; if (AlreadySearched) { // Nothing left to do. } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) { @@ -163,8 +159,6 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, LookupCtx = computeDeclContext(SS, EnteringContext); isDependent = LookupCtx && LookupCtx->isDependentContext(); } - - LookInScope = false; } else if (ObjectTypePtr) { // C++ [basic.lookup.classref]p3: // If the unqualified-id is ~type-name, the type-name is looked up @@ -184,7 +178,7 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, LookInScope = true; } - TypeDecl *NonMatchingTypeDecl = 0; + TypeDecl *NonMatchingTypeDecl = nullptr; LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName); for (unsigned Step = 0; Step != 2; ++Step) { // Look for the name first in the computed lookup context (if we @@ -209,7 +203,8 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, Context.hasSameUnqualifiedType(T, SearchType)) { // We found our type! - return ParsedType::make(T); + return CreateParsedType(T, + Context.getTrivialTypeSourceInfo(T, NameLoc)); } if (!SearchType.isNull()) @@ -245,7 +240,9 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) { if (Spec->getSpecializedTemplate()->getCanonicalDecl() == Template->getCanonicalDecl()) - return ParsedType::make(MemberOfType); + return CreateParsedType( + MemberOfType, + Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); } continue; @@ -264,7 +261,9 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, // specialized. if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) { if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl()) - return ParsedType::make(MemberOfType); + return CreateParsedType( + MemberOfType, + Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); continue; } @@ -275,7 +274,9 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, = SpecName.getAsDependentTemplateName()) { if (DepTemplate->isIdentifier() && DepTemplate->getIdentifier() == Template->getIdentifier()) - return ParsedType::make(MemberOfType); + return CreateParsedType( + MemberOfType, + Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); continue; } @@ -333,6 +334,34 @@ ParsedType Sema::getDestructorType(const DeclSpec& DS, ParsedType ObjectType) { return ParsedType(); } +bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS, + const UnqualifiedId &Name) { + assert(Name.getKind() == UnqualifiedId::IK_LiteralOperatorId); + + if (!SS.isValid()) + return false; + + switch (SS.getScopeRep()->getKind()) { + case NestedNameSpecifier::Identifier: + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + // Per C++11 [over.literal]p2, literal operators can only be declared at + // namespace scope. Therefore, this unqualified-id cannot name anything. + // Reject it early, because we have no AST representation for this in the + // case where the scope is dependent. + Diag(Name.getLocStart(), diag::err_literal_operator_id_outside_namespace) + << SS.getScopeRep(); + return true; + + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + return false; + } + + llvm_unreachable("unknown nested name specifier kind"); +} + /// \brief Build a C++ typeid expression with a type operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, @@ -351,9 +380,8 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) return ExprError(); - return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(), - Operand, - SourceRange(TypeidLoc, RParenLoc))); + return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand, + SourceRange(TypeidLoc, RParenLoc)); } /// \brief Build a C++ typeid expression with an expression operand. @@ -365,7 +393,7 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, if (E->getType()->isPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); if (result.isInvalid()) return ExprError(); - E = result.take(); + E = result.get(); } QualType T = E->getType(); @@ -386,7 +414,7 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, // and recheck the subexpression. ExprResult Result = TransformToPotentiallyEvaluated(E); if (Result.isInvalid()) return ExprError(); - E = Result.take(); + E = Result.get(); // We require a vtable to query the type at run time. MarkVTableUsed(TypeidLoc, RecordD); @@ -402,13 +430,12 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals); if (!Context.hasSameType(T, UnqualT)) { T = UnqualT; - E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).take(); + E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get(); } } - return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(), - E, - SourceRange(TypeidLoc, RParenLoc))); + return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E, + SourceRange(TypeidLoc, RParenLoc)); } /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression); @@ -426,7 +453,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, CXXTypeInfoDecl = R.getAsSingle<RecordDecl>(); // Microsoft's typeinfo doesn't have type_info in std but in the global // namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153. - if (!CXXTypeInfoDecl && LangOpts.MicrosoftMode) { + if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) { LookupQualifiedName(R, Context.getTranslationUnitDecl()); CXXTypeInfoDecl = R.getAsSingle<RecordDecl>(); } @@ -442,7 +469,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, if (isType) { // The operand is a type; handle it as such. - TypeSourceInfo *TInfo = 0; + TypeSourceInfo *TInfo = nullptr; QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), &TInfo); if (T.isNull()) @@ -474,9 +501,8 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, } } - return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(), - Operand, - SourceRange(TypeidLoc, RParenLoc))); + return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, + SourceRange(TypeidLoc, RParenLoc)); } /// \brief Build a Microsoft __uuidof expression with an expression operand. @@ -495,9 +521,8 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, } } - return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(), - E, - SourceRange(TypeidLoc, RParenLoc))); + return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, + SourceRange(TypeidLoc, RParenLoc)); } /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression); @@ -518,7 +543,7 @@ Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, if (isType) { // The operand is a type; handle it as such. - TypeSourceInfo *TInfo = 0; + TypeSourceInfo *TInfo = nullptr; QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), &TInfo); if (T.isNull()) @@ -539,14 +564,14 @@ ExprResult Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { assert((Kind == tok::kw_true || Kind == tok::kw_false) && "Unknown C++ Boolean value!"); - return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true, - Context.BoolTy, OpLoc)); + return new (Context) + CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc); } /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. ExprResult Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) { - return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc)); + return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc); } /// ActOnCXXThrow - Parse throw expressions. @@ -593,16 +618,19 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, if (!getLangOpts().CXXExceptions && !getSourceManager().isInSystemHeader(OpLoc)) Diag(OpLoc, diag::err_exceptions_disabled) << "throw"; - + + if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) + Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw"; + if (Ex && !Ex->isTypeDependent()) { ExprResult ExRes = CheckCXXThrowOperand(OpLoc, Ex, IsThrownVarInScope); if (ExRes.isInvalid()) return ExprError(); - Ex = ExRes.take(); + Ex = ExRes.get(); } - return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc, - IsThrownVarInScope)); + return new (Context) + CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope); } /// CheckCXXThrowOperand - Validate the operand of a throw. @@ -616,12 +644,12 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, // or "pointer to function returning T", [...] if (E->getType().hasQualifiers()) E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp, - E->getValueKind()).take(); + E->getValueKind()).get(); ExprResult Res = DefaultFunctionArrayConversion(E); if (Res.isInvalid()) return ExprError(); - E = Res.take(); + E = Res.get(); // If the type of the exception would be an incomplete type or a pointer // to an incomplete type other than (cv) void the program is ill-formed. @@ -657,24 +685,24 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, // operation from the operand to the exception object (15.1) can be // omitted by constructing the automatic object directly into the // exception object - const VarDecl *NRVOVariable = 0; + const VarDecl *NRVOVariable = nullptr; if (IsThrownVarInScope) NRVOVariable = getCopyElisionCandidate(QualType(), E, false); - + InitializedEntity Entity = InitializedEntity::InitializeException(ThrowLoc, E->getType(), - /*NRVO=*/NRVOVariable != 0); + /*NRVO=*/NRVOVariable != nullptr); Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable, QualType(), E, IsThrownVarInScope); if (Res.isInvalid()) return ExprError(); - E = Res.take(); + E = Res.get(); // If the exception has class type, we need additional handling. const RecordType *RecordTy = Ty->getAs<RecordType>(); if (!RecordTy) - return Owned(E); + return E; CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); // If we are throwing a polymorphic class type or pointer thereof, @@ -683,22 +711,22 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, // If a pointer is thrown, the referenced object will not be destroyed. if (isPointer) - return Owned(E); + return E; // If the class has a destructor, we must be able to call it. if (RD->hasIrrelevantDestructor()) - return Owned(E); + return E; CXXDestructorDecl *Destructor = LookupDestructor(RD); if (!Destructor) - return Owned(E); + return E; MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_exception) << Ty); if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) return ExprError(); - return Owned(E); + return E; } QualType Sema::getCurrentThisType() { @@ -708,7 +736,20 @@ QualType Sema::getCurrentThisType() { if (method && method->isInstance()) ThisTy = method->getThisType(Context); } - + if (ThisTy.isNull()) { + if (isGenericLambdaCallOperatorSpecialization(CurContext) && + CurContext->getParent()->getParent()->isRecord()) { + // This is a generic lambda call operator that is being instantiated + // within a default initializer - so use the enclosing class as 'this'. + // There is no enclosing member function to retrieve the 'this' pointer + // from. + QualType ClassTy = Context.getTypeDeclType( + cast<CXXRecordDecl>(CurContext->getParent()->getParent())); + // There are no cv-qualifiers for 'this' within default initializers, + // per [expr.prim.general]p4. + return Context.getPointerType(ClassTy); + } + } return ThisTy; } @@ -720,8 +761,8 @@ Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, { if (!Enabled || !ContextDecl) return; - - CXXRecordDecl *Record = 0; + + CXXRecordDecl *Record = nullptr; if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(ContextDecl)) Record = Template->getTemplatedDecl(); else @@ -744,9 +785,9 @@ Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { static Expr *captureThis(ASTContext &Context, RecordDecl *RD, QualType ThisTy, SourceLocation Loc) { FieldDecl *Field - = FieldDecl::Create(Context, RD, Loc, Loc, 0, ThisTy, + = FieldDecl::Create(Context, RD, Loc, Loc, nullptr, ThisTy, Context.getTrivialTypeSourceInfo(ThisTy, Loc), - 0, false, ICIS_NoInit); + nullptr, false, ICIS_NoInit); Field->setImplicit(true); Field->setAccess(AS_private); RD->addDecl(Field); @@ -801,7 +842,7 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit, for (unsigned idx = MaxFunctionScopesIndex; NumClosures; --idx, --NumClosures) { CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]); - Expr *ThisExpr = 0; + Expr *ThisExpr = nullptr; QualType ThisTy = getCurrentThisType(); if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) // For lambda expressions, build a field and an initializing expression. @@ -825,7 +866,7 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use); CheckCXXThisCapture(Loc); - return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false)); + return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false); } bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) { @@ -869,10 +910,8 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) { - return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo, - LParenLoc, - Exprs, - RParenLoc)); + return CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, Exprs, + RParenLoc); } bool ListInitialization = LParenLoc.isInvalid(); @@ -928,9 +967,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // want, since it will be treated as an initializer list in further // processing. Explicitly insert a cast here. QualType ResultType = Result.get()->getType(); - Result = Owned(CXXFunctionalCastExpr::Create( + Result = CXXFunctionalCastExpr::Create( Context, ResultType, Expr::getValueKindForType(TInfo->getType()), TInfo, - CK_NoOp, Result.take(), /*Path=*/ 0, LParenLoc, RParenLoc)); + CK_NoOp, Result.get(), /*Path=*/nullptr, LParenLoc, RParenLoc); } // FIXME: Improve AST representation? @@ -1016,7 +1055,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, Declarator &D, Expr *Initializer) { bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType(); - Expr *ArraySize = 0; + Expr *ArraySize = nullptr; // If the specified type is an array, unwrap it and save the expression. if (D.getNumTypeObjects() > 0 && D.getTypeObject(0).Kind == DeclaratorChunk::Array) { @@ -1054,12 +1093,12 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, Array.NumElts = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value, CCEK_NewExpr) - .take(); + .get(); } else { Array.NumElts - = VerifyIntegerConstantExpression(NumElts, 0, + = VerifyIntegerConstantExpression(NumElts, nullptr, diag::err_new_array_nonconst) - .take(); + .get(); } if (!Array.NumElts) return ExprError(); @@ -1068,7 +1107,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, } } - TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0); + TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/nullptr); QualType AllocType = TInfo->getType(); if (D.isInvalidType()) return ExprError(); @@ -1145,22 +1184,15 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, NumInits = List->getNumExprs(); } - // Determine whether we've already built the initializer. - bool HaveCompleteInit = false; - if (Initializer && isa<CXXConstructExpr>(Initializer) && - !isa<CXXTemporaryObjectExpr>(Initializer)) - HaveCompleteInit = true; - else if (Initializer && isa<ImplicitValueInitExpr>(Initializer)) - HaveCompleteInit = true; - - // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. + // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. if (TypeMayContainAuto && AllocType->isUndeducedType()) { if (initStyle == CXXNewExpr::NoInit || NumInits == 0) return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) << AllocType << TypeRange); - if (initStyle == CXXNewExpr::ListInit) + if (initStyle == CXXNewExpr::ListInit || + (NumInits == 1 && isa<InitListExpr>(Inits[0]))) return ExprError(Diag(Inits[0]->getLocStart(), - diag::err_auto_new_requires_parens) + diag::err_auto_new_list_init) << AllocType << TypeRange); if (NumInits > 1) { Expr *FirstBad = Inits[1]; @@ -1194,7 +1226,8 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) return ExprError(); - if (initStyle == CXXNewExpr::ListInit && isStdInitializerList(AllocType, 0)) { + if (initStyle == CXXNewExpr::ListInit && + isStdInitializerList(AllocType, nullptr)) { Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(), diag::warn_dangling_std_initializer_list) << /*at end of FE*/0 << Inits[0]->getSourceRange(); @@ -1213,7 +1246,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(ArraySize); if (result.isInvalid()) return ExprError(); - ArraySize = result.take(); + ArraySize = result.get(); } // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have // integral or enumeration type with a non-negative value." @@ -1225,9 +1258,8 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (ArraySize && !ArraySize->isTypeDependent()) { ExprResult ConvertedSize; if (getLangOpts().CPlusPlus1y) { - unsigned IntWidth = Context.getTargetInfo().getIntWidth(); - assert(IntWidth && "Builtin type of size 0?"); - llvm::APSInt Value(IntWidth); + assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?"); + ConvertedSize = PerformImplicitConversion(ArraySize, Context.getSizeType(), AA_Converting); @@ -1245,43 +1277,43 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SizeConvertDiagnoser(Expr *ArraySize) : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false), ArraySize(ArraySize) {} - - virtual SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, - QualType T) { + + SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, + QualType T) override { return S.Diag(Loc, diag::err_array_size_not_integral) << S.getLangOpts().CPlusPlus11 << T; } - - virtual SemaDiagnosticBuilder diagnoseIncomplete( - Sema &S, SourceLocation Loc, QualType T) { + + SemaDiagnosticBuilder diagnoseIncomplete( + Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_incomplete_type) << T << ArraySize->getSourceRange(); } - - virtual SemaDiagnosticBuilder diagnoseExplicitConv( - Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) { + + SemaDiagnosticBuilder diagnoseExplicitConv( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy; } - - virtual SemaDiagnosticBuilder noteExplicitConv( - Sema &S, CXXConversionDecl *Conv, QualType ConvTy) { + + SemaDiagnosticBuilder noteExplicitConv( + Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) << ConvTy->isEnumeralType() << ConvTy; } - - virtual SemaDiagnosticBuilder diagnoseAmbiguous( - Sema &S, SourceLocation Loc, QualType T) { + + SemaDiagnosticBuilder diagnoseAmbiguous( + Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T; } - - virtual SemaDiagnosticBuilder noteAmbiguous( - Sema &S, CXXConversionDecl *Conv, QualType ConvTy) { + + SemaDiagnosticBuilder noteAmbiguous( + Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) << ConvTy->isEnumeralType() << ConvTy; } virtual SemaDiagnosticBuilder diagnoseConversion( - Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) { + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, S.getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_array_size_conversion @@ -1296,7 +1328,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (ConvertedSize.isInvalid()) return ExprError(); - ArraySize = ConvertedSize.take(); + ArraySize = ConvertedSize.get(); QualType SizeType = ArraySize->getType(); if (!SizeType->isIntegralOrUnscopedEnumerationType()) @@ -1359,8 +1391,8 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // be signed, larger than size_t, whatever. } - FunctionDecl *OperatorNew = 0; - FunctionDecl *OperatorDelete = 0; + FunctionDecl *OperatorNew = nullptr; + FunctionDecl *OperatorDelete = nullptr; if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlacementArgs) && @@ -1379,12 +1411,14 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SmallVector<Expr *, 8> AllPlaceArgs; if (OperatorNew) { - // Add default arguments, if any. const FunctionProtoType *Proto = - OperatorNew->getType()->getAs<FunctionProtoType>(); - VariadicCallType CallType = - Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply; + OperatorNew->getType()->getAs<FunctionProtoType>(); + VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction + : VariadicDoesNotApply; + // We've already converted the placement args, just fill in any default + // arguments. Skip the first parameter because we don't have a corresponding + // argument. if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto, 1, PlacementArgs, AllPlaceArgs, CallType)) return ExprError(); @@ -1392,6 +1426,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (!AllPlaceArgs.empty()) PlacementArgs = AllPlaceArgs; + // FIXME: This is wrong: PlacementArgs misses out the first (size) argument. DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs); // FIXME: Missing call to CheckFunctionCall or equivalent @@ -1438,8 +1473,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // do it now. if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments( - llvm::makeArrayRef(Inits, NumInits)) && - !HaveCompleteInit) { + llvm::makeArrayRef(Inits, NumInits))) { // C++11 [expr.new]p15: // A new-expression that creates an object of type T initializes that // object as follows: @@ -1469,9 +1503,9 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // we don't want the initialized object to be destructed. if (CXXBindTemporaryExpr *Binder = dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get())) - FullInit = Owned(Binder->getSubExpr()); + FullInit = Binder->getSubExpr(); - Initializer = FullInit.take(); + Initializer = FullInit.get(); } // Mark the new and delete operators as referenced. @@ -1504,13 +1538,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, } } - return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew, - OperatorDelete, - UsualArrayDeleteWantsSize, - PlacementArgs, TypeIdParens, - ArraySize, initStyle, Initializer, - ResultType, AllocTypeInfo, - Range, DirectInitRange)); + return new (Context) + CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete, + UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, + ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo, + Range, DirectInitRange); } /// \brief Checks that a type is suitable as the allocated type @@ -1623,7 +1655,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // Didn't find a member overload. Look for a global one. DeclareGlobalNewDelete(); DeclContext *TUDecl = Context.getTranslationUnitDecl(); - bool FallbackEnabled = IsArray && Context.getLangOpts().MicrosoftMode; + bool FallbackEnabled = IsArray && Context.getLangOpts().MSVCCompat; if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, TUDecl, /*AllowMissing=*/FallbackEnabled, OperatorNew, /*Diagnose=*/!FallbackEnabled)) { @@ -1645,15 +1677,10 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // We don't need an operator delete if we're running under // -fno-exceptions. if (!getLangOpts().Exceptions) { - OperatorDelete = 0; + OperatorDelete = nullptr; return false; } - // FindAllocationOverload can change the passed in arguments, so we need to - // copy them back. - if (!PlaceArgs.empty()) - std::copy(AllocArgs.begin() + 1, AllocArgs.end(), PlaceArgs.data()); - // C++ [expr.new]p19: // // If the new-expression begins with a unary :: operator, the @@ -1708,8 +1735,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, SmallVector<QualType, 4> ArgTypes; ArgTypes.push_back(Context.VoidPtrTy); - for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I) - ArgTypes.push_back(Proto->getArgType(I)); + for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I) + ArgTypes.push_back(Proto->getParamType(I)); FunctionProtoType::ExtProtoInfo EPI; EPI.Variadic = Proto->isVariadic(); @@ -1721,13 +1748,14 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, for (LookupResult::iterator D = FoundDelete.begin(), DEnd = FoundDelete.end(); D != DEnd; ++D) { - FunctionDecl *Fn = 0; + FunctionDecl *Fn = nullptr; if (FunctionTemplateDecl *FnTmpl = dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) { // Perform template argument deduction to try to match the // expected function type. TemplateDeductionInfo Info(StartLoc); - if (DeduceTemplateArguments(FnTmpl, 0, ExpectedFunctionType, Fn, Info)) + if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn, + Info)) continue; } else Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl()); @@ -1763,7 +1791,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, else Matches.erase(Matches.begin() + 1); assert(Matches[0].second->getNumParams() == 2 && - "found an unexpected uusal deallocation function"); + "found an unexpected usual deallocation function"); } } @@ -1797,8 +1825,22 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, return false; } -/// FindAllocationOverload - Find an fitting overload for the allocation -/// function in the specified scope. +/// \brief Find an fitting overload for the allocation function +/// in the specified scope. +/// +/// \param StartLoc The location of the 'new' token. +/// \param Range The range of the placement arguments. +/// \param Name The name of the function ('operator new' or 'operator new[]'). +/// \param Args The placement arguments specified. +/// \param Ctx The scope in which we should search; either a class scope or the +/// translation unit. +/// \param AllowMissing If \c true, report an error if we can't find any +/// allocation functions. Otherwise, succeed but don't fill in \p +/// Operator. +/// \param Operator Filled in with the found allocation function. Unchanged if +/// no allocation function was found. +/// \param Diagnose If \c true, issue errors if the allocation function is not +/// usable. bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, DeclarationName Name, MultiExprArg Args, DeclContext *Ctx, @@ -1818,7 +1860,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, R.suppressDiagnostics(); - OverloadCandidateSet Candidates(StartLoc); + OverloadCandidateSet Candidates(StartLoc, OverloadCandidateSet::CSK_Normal); for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { // Even member operator new/delete are implicitly treated as @@ -1827,7 +1869,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) { AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(), - /*ExplicitTemplateArgs=*/0, + /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, /*SuppressUserConversions=*/false); continue; @@ -1844,33 +1886,11 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, case OR_Success: { // Got one! FunctionDecl *FnDecl = Best->Function; - MarkFunctionReferenced(StartLoc, FnDecl); - // The first argument is size_t, and the first parameter must be size_t, - // too. This is checked on declaration and can be assumed. (It can't be - // asserted on, though, since invalid decls are left in there.) - // Watch out for variadic allocator function. - unsigned NumArgsInFnDecl = FnDecl->getNumParams(); - for (unsigned i = 0; (i < Args.size() && i < NumArgsInFnDecl); ++i) { - InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, - FnDecl->getParamDecl(i)); - - if (!Diagnose && !CanPerformCopyInitialization(Entity, Owned(Args[i]))) - return true; - - ExprResult Result - = PerformCopyInitialization(Entity, SourceLocation(), Owned(Args[i])); - if (Result.isInvalid()) - return true; - - Args[i] = Result.takeAs<Expr>(); - } - - Operator = FnDecl; - if (CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl, Diagnose) == AR_inaccessible) return true; + Operator = FnDecl; return false; } @@ -1970,7 +1990,7 @@ void Sema::DeclareGlobalNewDelete() { getOrCreateStdNamespace(), SourceLocation(), SourceLocation(), &PP.getIdentifierTable().get("bad_alloc"), - 0); + nullptr); getStdBadAlloc()->setImplicit(true); } @@ -2031,8 +2051,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, if (InitialParam1Type == Param1 && (NumParams == 1 || InitialParam2Type == Param2)) { if (AddMallocAttr && !Func->hasAttr<MallocAttr>()) - Func->addAttr(::new (Context) MallocAttr(SourceLocation(), - Context)); + Func->addAttr(MallocAttr::CreateImplicit(Context)); // Make the function visible to name lookup, even if we found it in // an unimported module. It either is an implicitly-declared global // allocation function, or is suppressing that function. @@ -2043,18 +2062,16 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, } } + FunctionProtoType::ExtProtoInfo EPI; + QualType BadAllocType; bool HasBadAllocExceptionSpec = (Name.getCXXOverloadedOperator() == OO_New || Name.getCXXOverloadedOperator() == OO_Array_New); - if (HasBadAllocExceptionSpec && !getLangOpts().CPlusPlus11) { - assert(StdBadAlloc && "Must have std::bad_alloc declared"); - BadAllocType = Context.getTypeDeclType(getStdBadAlloc()); - } - - FunctionProtoType::ExtProtoInfo EPI; if (HasBadAllocExceptionSpec) { if (!getLangOpts().CPlusPlus11) { + BadAllocType = Context.getTypeDeclType(getStdBadAlloc()); + assert(StdBadAlloc && "Must have std::bad_alloc declared"); EPI.ExceptionSpecType = EST_Dynamic; EPI.NumExceptions = 1; EPI.Exceptions = &BadAllocType; @@ -2071,24 +2088,24 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, FunctionDecl *Alloc = FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, - FnType, /*TInfo=*/0, SC_None, false, true); + FnType, /*TInfo=*/nullptr, SC_None, false, true); Alloc->setImplicit(); if (AddMallocAttr) - Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context)); + Alloc->addAttr(MallocAttr::CreateImplicit(Context)); ParmVarDecl *ParamDecls[2]; - for (unsigned I = 0; I != NumParams; ++I) + for (unsigned I = 0; I != NumParams; ++I) { ParamDecls[I] = ParmVarDecl::Create(Context, Alloc, SourceLocation(), - SourceLocation(), 0, - Params[I], /*TInfo=*/0, - SC_None, 0); + SourceLocation(), nullptr, + Params[I], /*TInfo=*/nullptr, + SC_None, nullptr); + ParamDecls[I]->setImplicit(); + } Alloc->setParams(ArrayRef<ParmVarDecl*>(ParamDecls, NumParams)); - // FIXME: Also add this declaration to the IdentifierResolver, but - // make sure it is at the end of the chain to coincide with the - // global scope. Context.getTranslationUnitDecl()->addDecl(Alloc); + IdResolver.tryAddTopLevelDecl(Alloc, Name); } FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc, @@ -2125,7 +2142,7 @@ FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc, else Matches.erase(Matches.begin() + 1); assert(Matches[0]->getNumParams() == NumArgs && - "found an unexpected uusal deallocation function"); + "found an unexpected usual deallocation function"); } assert(Matches.size() == 1 && @@ -2206,7 +2223,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, return true; } - Operator = 0; + Operator = nullptr; return false; } @@ -2224,14 +2241,14 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // // DR599 amends "pointer type" to "pointer to object type" in both cases. - ExprResult Ex = Owned(ExE); - FunctionDecl *OperatorDelete = 0; + ExprResult Ex = ExE; + FunctionDecl *OperatorDelete = nullptr; bool ArrayFormAsWritten = ArrayForm; bool UsualArrayDeleteWantsSize = false; if (!Ex.get()->isTypeDependent()) { // Perform lvalue-to-rvalue cast, if needed. - Ex = DefaultLvalueConversion(Ex.take()); + Ex = DefaultLvalueConversion(Ex.get()); if (Ex.isInvalid()) return ExprError(); @@ -2241,7 +2258,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, public: DeleteConverter() : ContextualImplicitConverter(false, true) {} - bool match(QualType ConvType) { + bool match(QualType ConvType) override { // FIXME: If we have an operator T* and an operator void*, we must pick // the operator T*. if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) @@ -2251,44 +2268,46 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, } SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, - QualType T) { + QualType T) override { return S.Diag(Loc, diag::err_delete_operand) << T; } SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, - QualType T) { + QualType T) override { return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T; } SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, - QualType T, QualType ConvTy) { + QualType T, + QualType ConvTy) override { return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy; } SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, - QualType ConvTy) { + QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_delete_conversion) << ConvTy; } SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, - QualType T) { + QualType T) override { return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T; } SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, - QualType ConvTy) { + QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_delete_conversion) << ConvTy; } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, - QualType T, QualType ConvTy) { + QualType T, + QualType ConvTy) override { llvm_unreachable("conversion functions are permitted"); } } Converter; - Ex = PerformContextualImplicitConversion(StartLoc, Ex.take(), Converter); + Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter); if (Ex.isInvalid()) return ExprError(); Type = Ex.get()->getType(); @@ -2305,7 +2324,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, diag::err_address_space_qualified_delete) << Pointee.getUnqualifiedType() << AddressSpace; - CXXRecordDecl *PointeeRD = 0; + CXXRecordDecl *PointeeRD = nullptr; if (Pointee->isVoidType() && !isSFINAEContext()) { // The C++ standard bans deleting a pointer to a non-object type, which // effectively bans deletion of "void*". However, most compilers support @@ -2413,10 +2432,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, } } - return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm, - ArrayFormAsWritten, - UsualArrayDeleteWantsSize, - OperatorDelete, Ex.take(), StartLoc)); + return new (Context) CXXDeleteExpr( + Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten, + UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc); } /// \brief Check the use of the given variable as a C++ condition in an if, @@ -2440,19 +2458,15 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, diag::err_invalid_use_of_array_type) << ConditionVar->getSourceRange()); - ExprResult Condition = - Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), - SourceLocation(), - ConditionVar, - /*enclosing*/ false, - ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType(), - VK_LValue)); + ExprResult Condition = DeclRefExpr::Create( + Context, NestedNameSpecifierLoc(), SourceLocation(), ConditionVar, + /*enclosing*/ false, ConditionVar->getLocation(), + ConditionVar->getType().getNonReferenceType(), VK_LValue); MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get())); if (ConvertToBoolean) { - Condition = CheckBooleanCondition(Condition.take(), StmtLoc); + Condition = CheckBooleanCondition(Condition.get(), StmtLoc); if (Condition.isInvalid()) return ExprError(); } @@ -2537,15 +2551,15 @@ static ExprResult BuildCXXCastArgument(Sema &S, InitializedEntity::InitializeTemporary(Ty), Constructor->getAccess()); - ExprResult Result - = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), - ConstructorArgs, HadMultipleCandidates, - /*ListInit*/ false, /*ZeroInit*/ false, - CXXConstructExpr::CK_Complete, SourceRange()); + ExprResult Result = S.BuildCXXConstructExpr( + CastLoc, Ty, cast<CXXConstructorDecl>(Method), + ConstructorArgs, HadMultipleCandidates, + /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, + CXXConstructExpr::CK_Complete, SourceRange()); if (Result.isInvalid()) return ExprError(); - return S.MaybeBindToTemporary(Result.takeAs<Expr>()); + return S.MaybeBindToTemporary(Result.getAs<Expr>()); } case CK_UserDefinedConversion: { @@ -2558,13 +2572,11 @@ static ExprResult BuildCXXCastArgument(Sema &S, if (Result.isInvalid()) return ExprError(); // Record usage of conversion in an implicit cast. - Result = S.Owned(ImplicitCastExpr::Create(S.Context, - Result.get()->getType(), - CK_UserDefinedConversion, - Result.get(), 0, - Result.get()->getValueKind())); + Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(), + CK_UserDefinedConversion, Result.get(), + nullptr, Result.get()->getValueKind()); - S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ 0, FoundDecl); + S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl); return S.MaybeBindToTemporary(Result.get()); } @@ -2587,7 +2599,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, Action, CCK); if (Res.isInvalid()) return ExprError(); - From = Res.take(); + From = Res.get(); break; } @@ -2623,7 +2635,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, CCK); if (Res.isInvalid()) return ExprError(); - From = Res.take(); + From = Res.get(); } ExprResult CastArg @@ -2638,7 +2650,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (CastArg.isInvalid()) return ExprError(); - From = CastArg.take(); + From = CastArg.get(); return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, AA_Converting, CCK); @@ -2658,7 +2670,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } // Everything went well. - return Owned(From); + return From; } /// PerformImplicitConversion - Perform an implicit conversion of the @@ -2688,20 +2700,17 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, From, /*FIXME:ConstructLoc*/SourceLocation(), ConstructorArgs)) return ExprError(); - return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), - ToType, SCS.CopyConstructor, - ConstructorArgs, - /*HadMultipleCandidates*/ false, - /*ListInit*/ false, /*ZeroInit*/ false, - CXXConstructExpr::CK_Complete, - SourceRange()); + return BuildCXXConstructExpr( + /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor, + ConstructorArgs, /*HadMultipleCandidates*/ false, + /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, + CXXConstructExpr::CK_Complete, SourceRange()); } - return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), - ToType, SCS.CopyConstructor, - From, /*HadMultipleCandidates*/ false, - /*ListInit*/ false, /*ZeroInit*/ false, - CXXConstructExpr::CK_Complete, - SourceRange()); + return BuildCXXConstructExpr( + /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor, + From, /*HadMultipleCandidates*/ false, + /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, + CXXConstructExpr::CK_Complete, SourceRange()); } // Resolve overloaded function references. @@ -2738,20 +2747,20 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, FromType = FromType.getUnqualifiedType(); ExprResult FromRes = DefaultLvalueConversion(From); assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!"); - From = FromRes.take(); + From = FromRes.get(); break; } case ICK_Array_To_Pointer: FromType = Context.getArrayDecayedType(FromType); From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Function_To_Pointer: FromType = Context.getPointerType(FromType); From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; default: @@ -2775,7 +2784,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, return ExprError(); From = ImpCastExprToType(From, ToType, CK_NoOp, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Integral_Promotion: @@ -2785,17 +2794,17 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, 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(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); } else { From = ImpCastExprToType(From, ToType, CK_IntegralCast, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); } break; case ICK_Floating_Promotion: case ICK_Floating_Conversion: From = ImpCastExprToType(From, ToType, CK_FloatingCast, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Complex_Promotion: @@ -2814,22 +2823,22 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, CK = CK_IntegralComplexCast; } From = ImpCastExprToType(From, ToType, CK, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_Floating_Integral: if (ToType->isRealFloatingType()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); else From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Compatible_Conversion: From = ImpCastExprToType(From, ToType, CK_NoOp, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Writeback_Conversion: @@ -2874,12 +2883,12 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (Kind == CK_BlockPointerToObjCPointerCast) { ExprResult E = From; (void) PrepareCastToObjCObjectPointer(E); - From = E.take(); + From = E.get(); } if (getLangOpts().ObjCAutoRefCount) CheckObjCARCConversion(SourceRange(), ToType, From, CCK); From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) - .take(); + .get(); break; } @@ -2891,20 +2900,20 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) - .take(); + .get(); break; } case ICK_Boolean_Conversion: // Perform half-to-boolean conversion via float. if (From->getType()->isHalfType()) { - From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).take(); + From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get(); FromType = Context.FloatTy; } From = ImpCastExprToType(From, Context.BoolTy, ScalarTypeToBooleanCastKind(FromType), - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Derived_To_Base: { @@ -2919,18 +2928,18 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, From = ImpCastExprToType(From, ToType.getNonReferenceType(), CK_DerivedToBase, From->getValueKind(), - &BasePath, CCK).take(); + &BasePath, CCK).get(); break; } case ICK_Vector_Conversion: From = ImpCastExprToType(From, ToType, CK_BitCast, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Vector_Splat: From = ImpCastExprToType(From, ToType, CK_VectorSplat, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Complex_Real: @@ -2944,16 +2953,16 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, // do nothing } else if (From->getType()->isRealFloatingType()) { From = ImpCastExprToType(From, ElType, - isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take(); + isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get(); } else { assert(From->getType()->isIntegerType()); From = ImpCastExprToType(From, ElType, - isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take(); + isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get(); } // y -> _Complex y From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingRealToComplex - : CK_IntegralRealToComplex).take(); + : CK_IntegralRealToComplex).get(); // Case 2. _Complex x -> y } else { @@ -2967,7 +2976,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_FloatingComplexToReal : CK_IntegralComplexToReal, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); // x -> y if (Context.hasSameUnqualifiedType(ElType, ToType)) { @@ -2975,29 +2984,29 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } else if (ToType->isRealFloatingType()) { From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); } else { assert(ToType->isIntegerType()); From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); } } break; case ICK_Block_Pointer_Conversion: { From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast, - VK_RValue, /*BasePath=*/0, CCK).take(); + VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_TransparentUnionConversion: { - ExprResult FromRes = Owned(From); + ExprResult FromRes = From; Sema::AssignConvertType ConvTy = CheckTransparentUnionArgumentConstraints(ToType, FromRes); if (FromRes.isInvalid()) return ExprError(); - From = FromRes.take(); + From = FromRes.get(); assert ((ConvTy == Sema::Compatible) && "Improper transparent union conversion"); (void)ConvTy; @@ -3007,7 +3016,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Zero_Event_Conversion: From = ImpCastExprToType(From, ToType, CK_ZeroToOCLEvent, - From->getValueKind()).take(); + From->getValueKind()).get(); break; case ICK_Lvalue_To_Rvalue: @@ -3029,12 +3038,15 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, ExprValueKind VK = ToType->isReferenceType() ? From->getValueKind() : VK_RValue; From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), - CK_NoOp, VK, /*BasePath=*/0, CCK).take(); + CK_NoOp, VK, /*BasePath=*/nullptr, CCK).get(); if (SCS.DeprecatedStringLiteralToCharPtr && - !getLangOpts().WritableStrings) - Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion) + !getLangOpts().WritableStrings) { + Diag(From->getLocStart(), getLangOpts().CPlusPlus11 + ? diag::ext_deprecated_string_literal_conversion + : diag::warn_deprecated_string_literal_conversion) << ToType.getNonReferenceType(); + } break; } @@ -3049,22 +3061,10 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, assert(Context.hasSameType( ToAtomicType->castAs<AtomicType>()->getValueType(), From->getType())); From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic, - VK_RValue, 0, CCK).take(); + VK_RValue, nullptr, CCK).get(); } - return Owned(From); -} - -ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait UTT, - SourceLocation KWLoc, - ParsedType Ty, - SourceLocation RParen) { - TypeSourceInfo *TSInfo; - QualType T = GetTypeFromParser(Ty, &TSInfo); - - if (!TSInfo) - TSInfo = Context.getTrivialTypeSourceInfo(T); - return BuildUnaryTypeTrait(UTT, KWLoc, TSInfo, RParen); + return From; } /// \brief Check the completeness of a type in a unary type trait. @@ -3073,8 +3073,7 @@ ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait UTT, /// it. If completing the type fails, a diagnostic is emitted and false /// returned. If completing the type succeeds or no completion was required, /// returns true. -static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, - UnaryTypeTrait UTT, +static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, SourceLocation Loc, QualType ArgTy) { // C++0x [meta.unary.prop]p3: @@ -3087,6 +3086,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, // these class templates. We also try to follow any GCC documented behavior // in these expressions to ensure portability of standard libraries. switch (UTT) { + default: llvm_unreachable("not a UTT"); // is_complete_type somewhat obviously cannot require a complete type. case UTT_IsCompleteType: // Fall-through @@ -3139,6 +3139,8 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, case UTT_IsPolymorphic: case UTT_IsAbstract: case UTT_IsInterfaceClass: + case UTT_IsDestructible: + case UTT_IsNothrowDestructible: // Fall-through // These traits require a complete type. @@ -3173,7 +3175,6 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, return !S.RequireCompleteType( Loc, ElTy, diag::err_incomplete_type_used_in_type_trait_expr); } - llvm_unreachable("Type trait not handled by switch"); } static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, @@ -3203,7 +3204,7 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, const FunctionProtoType *CPT = Operator->getType()->getAs<FunctionProtoType>(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); - if (!CPT || !CPT->isNothrow(Self.Context)) + if (!CPT || !CPT->isNothrow(C)) return false; } } @@ -3212,12 +3213,13 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, return false; } -static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, +static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, QualType T) { assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); ASTContext &C = Self.Context; switch(UTT) { + default: llvm_unreachable("not a UTT"); // Type trait expressions corresponding to the primary type category // predicates in C++0x [meta.unary.cat]. case UTT_IsVoid: @@ -3404,8 +3406,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, return RD->hasTrivialCopyAssignment() && !RD->hasNonTrivialCopyAssignment(); return false; + case UTT_IsDestructible: + case UTT_IsNothrowDestructible: + // FIXME: Implement UTT_IsDestructible and UTT_IsNothrowDestructible. + // For now, let's fall through. case UTT_HasTrivialDestructor: - // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: + // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __is_pod (type) is true or type is a reference type // then the trait is true, else if type is a cv class or union // type (or array thereof) with a trivial destructor @@ -3488,9 +3494,9 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT) return false; - // FIXME: check whether evaluating default arguments can throw. + // TODO: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. - if (!CPT->isNothrow(Self.Context) || CPT->getNumArgs() > 1) + if (!CPT->isNothrow(Self.Context) || CPT->getNumParams() > 1) return false; } } @@ -3499,7 +3505,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, } return false; case UTT_HasNothrowConstructor: - // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: + // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __has_trivial_constructor (type) is true then the trait is // true, else if type is a cv class or union type (or array // thereof) with a default constructor that is known not to @@ -3511,6 +3517,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, !RD->hasNonTrivialDefaultConstructor()) return true; + bool FoundConstructor = false; DeclContext::lookup_const_result R = Self.LookupConstructors(RD); for (DeclContext::lookup_const_iterator Con = R.begin(), ConEnd = R.end(); Con != ConEnd; ++Con) { @@ -3519,16 +3526,19 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, continue; CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); if (Constructor->isDefaultConstructor()) { + FoundConstructor = true; const FunctionProtoType *CPT = Constructor->getType()->getAs<FunctionProtoType>(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT) return false; - // TODO: check whether evaluating default arguments can throw. + // FIXME: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. - return CPT->isNothrow(Self.Context) && CPT->getNumArgs() == 0; + if (!CPT->isNothrow(Self.Context) || CPT->getNumParams() > 0) + return false; } } + return FoundConstructor; } return false; case UTT_HasVirtualDestructor: @@ -3549,41 +3559,6 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, // function call. return !T->isIncompleteType(); } - llvm_unreachable("Type trait not covered by switch"); -} - -ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, - SourceLocation KWLoc, - TypeSourceInfo *TSInfo, - SourceLocation RParen) { - QualType T = TSInfo->getType(); - if (!CheckUnaryTypeTraitTypeCompleteness(*this, UTT, KWLoc, T)) - return ExprError(); - - bool Value = false; - if (!T->isDependentType()) - Value = EvaluateUnaryTypeTrait(*this, UTT, KWLoc, T); - - return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, UTT, TSInfo, Value, - RParen, Context.BoolTy)); -} - -ExprResult Sema::ActOnBinaryTypeTrait(BinaryTypeTrait BTT, - SourceLocation KWLoc, - ParsedType LhsTy, - ParsedType RhsTy, - SourceLocation RParen) { - TypeSourceInfo *LhsTSInfo; - QualType LhsT = GetTypeFromParser(LhsTy, &LhsTSInfo); - if (!LhsTSInfo) - LhsTSInfo = Context.getTrivialTypeSourceInfo(LhsT); - - TypeSourceInfo *RhsTSInfo; - QualType RhsT = GetTypeFromParser(RhsTy, &RhsTSInfo); - if (!RhsTSInfo) - RhsTSInfo = Context.getTrivialTypeSourceInfo(RhsT); - - return BuildBinaryTypeTrait(BTT, KWLoc, LhsTSInfo, RhsTSInfo, RParen); } /// \brief Determine whether T has a non-trivial Objective-C lifetime in @@ -3605,10 +3580,22 @@ static bool hasNontrivialObjCLifetime(QualType T) { llvm_unreachable("Unknown ObjC lifetime qualifier"); } +static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, + QualType RhsT, SourceLocation KeyLoc); + static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc) { + if (Kind <= UTT_Last) + return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType()); + + if (Kind <= BTT_Last) + return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(), + Args[1]->getType(), RParenLoc); + switch (Kind) { + case clang::TT_IsConstructible: + case clang::TT_IsNothrowConstructible: case clang::TT_IsTriviallyConstructible: { // C++11 [meta.unary.prop]: // is_trivially_constructible is defined as: @@ -3623,11 +3610,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, // variable t: // // T t(create<Args>()...); - if (Args.empty()) { - S.Diag(KWLoc, diag::err_type_trait_arity) - << 1 << 1 << 1 << (int)Args.size(); - return false; - } + assert(!Args.empty()); // Precondition: T and all types in the parameter pack Args shall be // complete types, (possibly cv-qualified) void, or arrays of @@ -3646,6 +3629,11 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, if (Args[0]->getType()->isIncompleteType()) return false; + // Make sure the first argument is not an abstract type. + CXXRecordDecl *RD = Args[0]->getType()->getAsCXXRecordDecl(); + if (RD && RD->isAbstract()) + return false; + SmallVector<OpaqueValueExpr, 2> OpaqueArgExprs; SmallVector<Expr *, 2> ArgExprs; ArgExprs.reserve(Args.size() - 1); @@ -3671,21 +3659,33 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, InitializationSequence Init(S, To, InitKind, ArgExprs); if (Init.Failed()) return false; - + ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs); if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; - // Under Objective-C ARC, if the destination has non-trivial Objective-C - // lifetime, this is a non-trivial construction. - if (S.getLangOpts().ObjCAutoRefCount && - hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType())) - return false; + if (Kind == clang::TT_IsConstructible) + return true; + + if (Kind == clang::TT_IsNothrowConstructible) + return S.canThrow(Result.get()) == CT_Cannot; - // The initialization succeeded; now make sure there are no non-trivial - // calls. - return !Result.get()->hasNonTrivialCall(S.Context); + if (Kind == clang::TT_IsTriviallyConstructible) { + // Under Objective-C ARC, if the destination has non-trivial Objective-C + // lifetime, this is a non-trivial construction. + if (S.getLangOpts().ObjCAutoRefCount && + hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType())) + return false; + + // The initialization succeeded; now make sure there are no non-trivial + // calls. + return !Result.get()->hasNonTrivialCall(S.Context); + } + + llvm_unreachable("unhandled type trait"); + return false; } + default: llvm_unreachable("not a TT"); } return false; @@ -3694,6 +3694,12 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc) { + QualType ResultType = Context.getLogicalOperationType(); + + if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness( + *this, Kind, KWLoc, Args[0]->getType())) + return ExprError(); + bool Dependent = false; for (unsigned I = 0, N = Args.size(); I != N; ++I) { if (Args[I]->getType()->isDependentType()) { @@ -3701,17 +3707,17 @@ ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, break; } } - - bool Value = false; + + bool Result = false; if (!Dependent) - Value = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc); - - return TypeTraitExpr::Create(Context, Context.BoolTy, KWLoc, Kind, - Args, RParenLoc, Value); + Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc); + + return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args, + RParenLoc, Result); } -ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, - ArrayRef<ParsedType> Args, +ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, + ArrayRef<ParsedType> Args, SourceLocation RParenLoc) { SmallVector<TypeSourceInfo *, 4> ConvertedArgs; ConvertedArgs.reserve(Args.size()); @@ -3724,13 +3730,12 @@ ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ConvertedArgs.push_back(TInfo); } - + return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc); } -static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, - QualType LhsT, QualType RhsT, - SourceLocation KeyLoc) { +static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, + QualType RhsT, SourceLocation KeyLoc) { assert(!LhsT->isDependentType() && !RhsT->isDependentType() && "Cannot evaluate traits of dependent types"); @@ -3833,7 +3838,8 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, ExprResult Result = Init.Perform(Self, To, Kind, FromPtr); return !Result.isInvalid() && !SFINAE.hasErrorOccurred(); } - + + case BTT_IsNothrowAssignable: case BTT_IsTriviallyAssignable: { // C++11 [meta.unary.prop]p3: // is_trivially_assignable is defined as: @@ -3875,56 +3881,30 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, EnterExpressionEvaluationContext Unevaluated(Self, Sema::Unevaluated); Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); - ExprResult Result = Self.BuildBinOp(/*S=*/0, KeyLoc, BO_Assign, &Lhs, &Rhs); + ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, + &Rhs); if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; - // Under Objective-C ARC, if the destination has non-trivial Objective-C - // lifetime, this is a non-trivial assignment. - if (Self.getLangOpts().ObjCAutoRefCount && - hasNontrivialObjCLifetime(LhsT.getNonReferenceType())) - return false; - - return !Result.get()->hasNonTrivialCall(Self.Context); - } - } - llvm_unreachable("Unknown type trait or not implemented"); -} + if (BTT == BTT_IsNothrowAssignable) + return Self.canThrow(Result.get()) == CT_Cannot; -ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT, - SourceLocation KWLoc, - TypeSourceInfo *LhsTSInfo, - TypeSourceInfo *RhsTSInfo, - SourceLocation RParen) { - QualType LhsT = LhsTSInfo->getType(); - QualType RhsT = RhsTSInfo->getType(); + if (BTT == BTT_IsTriviallyAssignable) { + // Under Objective-C ARC, if the destination has non-trivial Objective-C + // lifetime, this is a non-trivial assignment. + if (Self.getLangOpts().ObjCAutoRefCount && + hasNontrivialObjCLifetime(LhsT.getNonReferenceType())) + return false; - if (BTT == BTT_TypeCompatible) { - if (getLangOpts().CPlusPlus) { - Diag(KWLoc, diag::err_types_compatible_p_in_cplusplus) - << SourceRange(KWLoc, RParen); - return ExprError(); + return !Result.get()->hasNonTrivialCall(Self.Context); } - } - - bool Value = false; - if (!LhsT->isDependentType() && !RhsT->isDependentType()) - Value = EvaluateBinaryTypeTrait(*this, BTT, LhsT, RhsT, KWLoc); - // Select trait result type. - QualType ResultType; - switch (BTT) { - case BTT_IsBaseOf: ResultType = Context.BoolTy; break; - case BTT_IsConvertible: ResultType = Context.BoolTy; break; - case BTT_IsSame: ResultType = Context.BoolTy; break; - case BTT_TypeCompatible: ResultType = Context.IntTy; break; - case BTT_IsConvertibleTo: ResultType = Context.BoolTy; break; - case BTT_IsTriviallyAssignable: ResultType = Context.BoolTy; + llvm_unreachable("unhandled type trait"); + return false; } - - return Owned(new (Context) BinaryTypeTraitExpr(KWLoc, BTT, LhsTSInfo, - RhsTSInfo, Value, RParen, - ResultType)); + default: llvm_unreachable("not a BTT"); + } + llvm_unreachable("Unknown type trait or not implemented"); } ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, @@ -4012,9 +3992,8 @@ ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT, // returns 'size_t'. On Windows, the primary platform for the Embarcadero // compiler, there is no difference. On several other platforms this is an // important distinction. - return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, - DimExpr, RParen, - Context.getSizeType())); + return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr, + RParen, Context.getSizeType()); } ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, @@ -4047,13 +4026,13 @@ ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, } else if (Queried->getType()->isPlaceholderType()) { ExprResult PE = CheckPlaceholderExpr(Queried); if (PE.isInvalid()) return ExprError(); - return BuildExpressionTrait(ET, KWLoc, PE.take(), RParen); + return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen); } bool Value = EvaluateExpressionTrait(ET, Queried); - return Owned(new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value, - RParen, Context.BoolTy)); + return new (Context) + ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy); } QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, @@ -4066,12 +4045,12 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, // The LHS undergoes lvalue conversions if this is ->*. if (isIndirect) { - LHS = DefaultLvalueConversion(LHS.take()); + LHS = DefaultLvalueConversion(LHS.get()); if (LHS.isInvalid()) return QualType(); } // The RHS always undergoes lvalue conversions. - RHS = DefaultLvalueConversion(RHS.take()); + RHS = DefaultLvalueConversion(RHS.get()); if (RHS.isInvalid()) return QualType(); const char *OpSpelling = isIndirect ? "->*" : ".*"; @@ -4117,23 +4096,24 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, OpSpelling, (int)isIndirect)) { return QualType(); } - CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, - /*DetectVirtual=*/false); - // FIXME: Would it be useful to print full ambiguity paths, or is that - // overkill? - if (!IsDerivedFrom(LHSType, Class, Paths) || - Paths.isAmbiguous(Context.getCanonicalType(Class))) { + + if (!IsDerivedFrom(LHSType, Class)) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect << LHS.get()->getType(); return QualType(); } + + CXXCastPath BasePath; + if (CheckDerivedToBaseConversion(LHSType, Class, Loc, + SourceRange(LHS.get()->getLocStart(), + RHS.get()->getLocEnd()), + &BasePath)) + return QualType(); + // Cast LHS to type of use. QualType UseType = isIndirect ? Context.getPointerType(Class) : Class; ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind(); - - CXXCastPath BasePath; - BuildBasePathArray(Paths, BasePath); - LHS = ImpCastExprToType(LHS.take(), UseType, CK_DerivedToBase, VK, + LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK, &BasePath); } @@ -4296,7 +4276,8 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc) { Expr *Args[2] = { LHS.get(), RHS.get() }; - OverloadCandidateSet CandidateSet(QuestionLoc); + OverloadCandidateSet CandidateSet(QuestionLoc, + OverloadCandidateSet::CSK_Operator); Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, CandidateSet); @@ -4355,7 +4336,7 @@ static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) { InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(), SourceLocation()); - Expr *Arg = E.take(); + Expr *Arg = E.get(); InitializationSequence InitSeq(Self, Entity, Kind, Arg); ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg); if (Result.isInvalid()) @@ -4379,7 +4360,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // C++11 [expr.cond]p1 // The first expression is contextually converted to bool. if (!Cond.get()->isTypeDependent()) { - ExprResult CondRes = CheckCXXBooleanCondition(Cond.take()); + ExprResult CondRes = CheckCXXBooleanCondition(Cond.get()); if (CondRes.isInvalid()) return QualType(); Cond = CondRes; @@ -4400,42 +4381,21 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, bool LVoid = LTy->isVoidType(); bool RVoid = RTy->isVoidType(); if (LVoid || RVoid) { - // ... then the [l2r] conversions are performed on the second and third - // operands ... - LHS = DefaultFunctionArrayLvalueConversion(LHS.take()); - RHS = DefaultFunctionArrayLvalueConversion(RHS.take()); - if (LHS.isInvalid() || RHS.isInvalid()) - return QualType(); - - // Finish off the lvalue-to-rvalue conversion by copy-initializing a - // temporary if necessary. DefaultFunctionArrayLvalueConversion doesn't - // do this part for us. - 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); - if (NonVoid.isInvalid()) - return QualType(); + // ... one of the following shall hold: + // -- The second or the third operand (but not both) is a (possibly + // parenthesized) throw-expression; the result is of the type + // and value category of the other. + bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenImpCasts()); + bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenImpCasts()); + if (LThrow != RThrow) { + Expr *NonThrow = LThrow ? RHS.get() : LHS.get(); + VK = NonThrow->getValueKind(); + // DR (no number yet): the result is a bit-field if the + // non-throw-expression operand is a bit-field. + OK = NonThrow->getObjectKind(); + return NonThrow->getType(); } - LTy = LHS.get()->getType(); - RTy = RHS.get()->getType(); - - // ... and one of the following shall hold: - // -- The second or the third operand (but not both) is a throw- - // expression; the result is of the type of the other and is a prvalue. - bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenCasts()); - bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenCasts()); - if (LThrow && !RThrow) - return RTy; - if (RThrow && !LThrow) - return LTy; - // -- Both the second and third operands have type void; the result is of // type void and is a prvalue. if (LVoid && RVoid) @@ -4456,7 +4416,6 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // those operands to the type of the other. if (!Context.hasSameType(LTy, RTy) && (LTy->isRecordType() || RTy->isRecordType())) { - ImplicitConversionSequence ICSLeftToRight, ICSRightToLeft; // These return true if a single direction is already ambiguous. QualType L2RType, R2LType; bool HaveL2R, HaveR2L; @@ -4501,11 +4460,11 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, Qualifiers LCVR = Qualifiers::fromCVRMask(LTy.getCVRQualifiers()); Qualifiers RCVR = Qualifiers::fromCVRMask(RTy.getCVRQualifiers()); if (RCVR.isStrictSupersetOf(LCVR)) { - LHS = ImpCastExprToType(LHS.take(), RTy, CK_NoOp, LVK); + LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK); LTy = LHS.get()->getType(); } else if (LCVR.isStrictSupersetOf(RCVR)) { - RHS = ImpCastExprToType(RHS.take(), LTy, CK_NoOp, RVK); + RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK); RTy = RHS.get()->getType(); } } @@ -4542,8 +4501,8 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // C++11 [expr.cond]p6 // Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard // conversions are performed on the second and third operands. - LHS = DefaultFunctionArrayLvalueConversion(LHS.take()); - RHS = DefaultFunctionArrayLvalueConversion(RHS.take()); + LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); + RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); LTy = LHS.get()->getType(); @@ -4610,7 +4569,8 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // operand. The result is of the common type. bool NonStandardCompositeType = false; QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS, - isSFINAEContext()? 0 : &NonStandardCompositeType); + isSFINAEContext() ? nullptr + : &NonStandardCompositeType); if (!Composite.isNull()) { if (NonStandardCompositeType) Diag(QuestionLoc, @@ -4669,12 +4629,12 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, !T2->isAnyPointerType() && !T2->isMemberPointerType()) { if (T1->isNullPtrType() && E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take(); + E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get(); return T1; } if (T2->isNullPtrType() && E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take(); + E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get(); return T2; } return QualType(); @@ -4682,16 +4642,16 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { if (T2->isMemberPointerType()) - E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).take(); + E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).get(); else - E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take(); + E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get(); return T2; } if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { if (T1->isMemberPointerType()) - E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).take(); + E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).get(); else - E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take(); + E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get(); return T1; } @@ -4734,7 +4694,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, QualifierUnion.push_back( Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers()); - MemberOfClass.push_back(std::make_pair((const Type *)0, (const Type *)0)); + MemberOfClass.push_back(std::make_pair(nullptr, nullptr)); continue; } @@ -4829,14 +4789,14 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, = E1ToC1.Perform(*this, Entity1, Kind, E1); if (E1Result.isInvalid()) return QualType(); - E1 = E1Result.takeAs<Expr>(); + E1 = E1Result.getAs<Expr>(); // Convert E2 to Composite1 ExprResult E2Result = E2ToC1.Perform(*this, Entity1, Kind, E2); if (E2Result.isInvalid()) return QualType(); - E2 = E2Result.takeAs<Expr>(); + E2 = E2Result.getAs<Expr>(); return Composite1; } @@ -4854,14 +4814,14 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, = E1ToC2.Perform(*this, Entity2, Kind, E1); if (E1Result.isInvalid()) return QualType(); - E1 = E1Result.takeAs<Expr>(); + E1 = E1Result.getAs<Expr>(); // Convert E2 to Composite2 ExprResult E2Result = E2ToC2.Perform(*this, Entity2, Kind, E2); if (E2Result.isInvalid()) return QualType(); - E2 = E2Result.takeAs<Expr>(); + E2 = E2Result.getAs<Expr>(); return Composite2; } @@ -4874,7 +4834,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // If the result is a glvalue, we shouldn't bind it. if (!E->isRValue()) - return Owned(E); + return E; // In ARC, calls that return a retainable type can return retained, // in which case we have to insert a consuming cast. @@ -4917,13 +4877,13 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // we don't want any extra casts here. } else if (isa<CastExpr>(E) && isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) { - return Owned(E); + return E; // For message sends and property references, we try to find an // actual method. FIXME: we should infer retention by selector in // cases where we don't have an actual method. } else { - ObjCMethodDecl *D = 0; + ObjCMethodDecl *D = nullptr; if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) { D = Send->getMethodDecl(); } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) { @@ -4942,28 +4902,28 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // return an object. if (!ReturnsRetained && D && D->getMethodFamily() == OMF_performSelector) - return Owned(E); + return E; } // Don't reclaim an object of Class type. if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType()) - return Owned(E); + return E; ExprNeedsCleanups = true; CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject : CK_ARCReclaimReturnedObject); - return Owned(ImplicitCastExpr::Create(Context, E->getType(), ck, E, 0, - VK_RValue)); + return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr, + VK_RValue); } if (!getLangOpts().CPlusPlus) - return Owned(E); + return E; // Search for the base element type (cf. ASTContext::getBaseElementType) with // a fast path for the common case that the type is directly a RecordType. const Type *T = Context.getCanonicalType(E->getType().getTypePtr()); - const RecordType *RT = 0; + const RecordType *RT = nullptr; while (!RT) { switch (T->getTypeClass()) { case Type::Record: @@ -4976,7 +4936,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { T = cast<ArrayType>(T)->getElementType().getTypePtr(); break; default: - return Owned(E); + return E; } } @@ -4984,10 +4944,10 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // not processing a decltype expression. CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); if (RD->isInvalidDecl() || RD->isDependentContext()) - return Owned(E); + return E; bool IsDecltype = ExprEvalContexts.back().IsDecltype; - CXXDestructorDecl *Destructor = IsDecltype ? 0 : LookupDestructor(RD); + CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD); if (Destructor) { MarkFunctionReferenced(E->getExprLoc(), Destructor); @@ -4999,7 +4959,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // If destructor is trivial, we can avoid the extra copy. if (Destructor->isTrivial()) - return Owned(E); + return E; // We need a cleanup, but we don't need to remember the temporary. ExprNeedsCleanups = true; @@ -5011,7 +4971,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { if (IsDecltype) ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind); - return Owned(Bind); + return Bind; } ExprResult @@ -5019,11 +4979,11 @@ Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) { if (SubExpr.isInvalid()) return ExprError(); - return Owned(MaybeCreateExprWithCleanups(SubExpr.take())); + return MaybeCreateExprWithCleanups(SubExpr.get()); } Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) { - assert(SubExpr && "sub expression can't be null!"); + assert(SubExpr && "subexpression can't be null!"); CleanupVarDeclMarking(); @@ -5044,7 +5004,7 @@ Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) { } Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) { - assert(SubStmt && "sub statement can't be null!"); + assert(SubStmt && "sub-statement can't be null!"); CleanupVarDeclMarking(); @@ -5085,8 +5045,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { if (SubExpr.isInvalid()) return ExprError(); if (SubExpr.get() == PE->getSubExpr()) - return Owned(E); - return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.take()); + return E; + return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get()); } if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { if (BO->getOpcode() == BO_Comma) { @@ -5094,30 +5054,30 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { if (RHS.isInvalid()) return ExprError(); if (RHS.get() == BO->getRHS()) - return Owned(E); - return Owned(new (Context) BinaryOperator(BO->getLHS(), RHS.take(), - BO_Comma, BO->getType(), - BO->getValueKind(), - BO->getObjectKind(), - BO->getOperatorLoc(), - BO->isFPContractable())); + return E; + return new (Context) BinaryOperator( + BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(), + BO->getObjectKind(), BO->getOperatorLoc(), BO->isFPContractable()); } } CXXBindTemporaryExpr *TopBind = dyn_cast<CXXBindTemporaryExpr>(E); - if (TopBind) - E = TopBind->getSubExpr(); + CallExpr *TopCall = TopBind ? dyn_cast<CallExpr>(TopBind->getSubExpr()) + : nullptr; + if (TopCall) + E = TopCall; + else + TopBind = nullptr; // Disable the special decltype handling now. ExprEvalContexts.back().IsDecltype = false; // In MS mode, don't perform any extra checking of call return types within a // decltype expression. - if (getLangOpts().MicrosoftMode) - return Owned(E); + if (getLangOpts().MSVCCompat) + return E; // Perform the semantic checks we delayed until this point. - CallExpr *TopCall = dyn_cast<CallExpr>(E); for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size(); I != N; ++I) { CallExpr *Call = ExprEvalContexts.back().DelayedDecltypeCalls[I]; @@ -5158,12 +5118,12 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { } // Possibly strip off the top CXXBindTemporaryExpr. - return Owned(E); + return E; } /// Note a set of 'operator->' functions that were used for a member access. static void noteOperatorArrows(Sema &S, - llvm::ArrayRef<FunctionDecl *> OperatorArrows) { + ArrayRef<FunctionDecl *> OperatorArrows) { unsigned SkipStart = OperatorArrows.size(), SkipCount = 0; // FIXME: Make this configurable? unsigned Limit = 9; @@ -5198,7 +5158,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, Result = CheckPlaceholderExpr(Base); if (Result.isInvalid()) return ExprError(); - Base = Result.take(); + Base = Result.get(); QualType BaseType = Base->getType(); MayBePseudoDestructor = false; @@ -5212,7 +5172,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, ObjectType = ParsedType::make(BaseType); MayBePseudoDestructor = true; - return Owned(Base); + return Base; } // C++ [over.match.oper]p8: @@ -5245,7 +5205,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, // separate note) instead of having the error reported back to here // and giving a diagnostic with a fixit attached to the error itself. (FirstIteration && CurFD && CurFD->isFunctionTemplateSpecialization()) - ? 0 + ? nullptr : &NoArrowOperatorFound); if (Result.isInvalid()) { if (NoArrowOperatorFound) { @@ -5259,7 +5219,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, Diag(OpLoc, diag::err_typecheck_member_reference_arrow) << BaseType << Base->getSourceRange(); CallExpr *CE = dyn_cast<CallExpr>(Base); - if (Decl *CD = (CE ? CE->getCalleeDecl() : 0)) { + if (Decl *CD = (CE ? CE->getCalleeDecl() : nullptr)) { Diag(CD->getLocStart(), diag::note_member_reference_arrow_from_operator_arrow); } @@ -5302,7 +5262,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, } else if (!BaseType->isRecordType()) { ObjectType = ParsedType(); MayBePseudoDestructor = true; - return Owned(Base); + return Base; } // The object type must be complete (or dependent), or @@ -5331,7 +5291,7 @@ ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc, << isa<CXXPseudoDestructorExpr>(MemExpr) << FixItHint::CreateInsertion(ExpectedLParenLoc, "()"); - return ActOnCallExpr(/*Scope*/ 0, + return ActOnCallExpr(/*Scope*/ nullptr, MemExpr, /*LPLoc*/ ExpectedLParenLoc, None, @@ -5343,7 +5303,7 @@ static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base, if (Base->hasPlaceholderType()) { ExprResult result = S.CheckPlaceholderExpr(Base); if (result.isInvalid()) return true; - Base = result.take(); + Base = result.get(); } ObjectType = Base->getType(); @@ -5388,12 +5348,13 @@ ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, if (!ObjectType->isDependentType() && !ObjectType->isScalarType() && !ObjectType->isVectorType()) { - if (getLangOpts().MicrosoftMode && ObjectType->isVoidType()) + if (getLangOpts().MSVCCompat && ObjectType->isVoidType()) Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange(); - else + else { Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar) << ObjectType << Base->getSourceRange(); - return ExprError(); + return ExprError(); + } } // C++ [expr.pseudo]p2: @@ -5453,7 +5414,7 @@ ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, << ScopeTypeInfo->getTypeLoc().getLocalSourceRange(); ScopeType = QualType(); - ScopeTypeInfo = 0; + ScopeTypeInfo = nullptr; } } @@ -5467,7 +5428,7 @@ ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, Destructed); if (HasTrailingLParen) - return Owned(Result); + return Result; return DiagnoseDtorReference(Destructed.getLocation(), Result); } @@ -5505,7 +5466,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, // Convert the name of the type being destructed (following the ~) into a // type (with source-location information). QualType DestructedType; - TypeSourceInfo *DestructedTypeInfo = 0; + TypeSourceInfo *DestructedTypeInfo = nullptr; PseudoDestructorTypeStorage Destructed; if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) { ParsedType T = getTypeName(*SecondTypeName.Identifier, @@ -5560,7 +5521,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, } // Convert the name of the scope type (the type prior to '::') into a type. - TypeSourceInfo *ScopeTypeInfo = 0; + TypeSourceInfo *ScopeTypeInfo = nullptr; QualType ScopeType; if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || FirstTypeName.Identifier) { @@ -5629,7 +5590,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, PseudoDestructorTypeStorage Destructed(DestructedTypeInfo); return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(), - 0, SourceLocation(), TildeLoc, + nullptr, SourceLocation(), TildeLoc, Destructed, HasTrailingLParen); } @@ -5662,22 +5623,21 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, return Exp; } } - - ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/0, + ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr, FoundDecl, Method); if (Exp.isInvalid()) return true; MemberExpr *ME = - new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method, + new (Context) MemberExpr(Exp.get(), /*IsArrow=*/false, Method, SourceLocation(), Context.BoundMemberTy, VK_RValue, OK_Ordinary); if (HadMultipleCandidates) ME->setHadMultipleCandidates(true); MarkMemberReferenced(ME); - QualType ResultType = Method->getResultType(); + QualType ResultType = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); ResultType = ResultType.getNonLValueExprType(Context); @@ -5690,8 +5650,8 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen) { CanThrowResult CanThrow = canThrow(Operand); - return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand, - CanThrow, KeyLoc, RParen)); + return new (Context) + CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen); } ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation, @@ -5759,8 +5719,8 @@ static bool IsSpecialDiscardedValue(Expr *E) { ExprResult Sema::IgnoredValueConversions(Expr *E) { if (E->hasPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); - if (result.isInvalid()) return Owned(E); - E = result.take(); + if (result.isInvalid()) return E; + E = result.get(); } // C99 6.3.2.1: @@ -5775,7 +5735,7 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) { if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType()) return DefaultFunctionArrayConversion(E); - return Owned(E); + return E; } if (getLangOpts().CPlusPlus) { @@ -5788,30 +5748,30 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) { IsSpecialDiscardedValue(E)) { ExprResult Res = DefaultLvalueConversion(E); if (Res.isInvalid()) - return Owned(E); - E = Res.take(); + return E; + E = Res.get(); } - return Owned(E); + return E; } // GCC seems to also exclude expressions of incomplete enum type. if (const EnumType *T = E->getType()->getAs<EnumType>()) { if (!T->getDecl()->isComplete()) { // FIXME: stupid workaround for a codegen bug! - E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).take(); - return Owned(E); + E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get(); + return E; } } ExprResult Res = DefaultFunctionArrayLvalueConversion(E); if (Res.isInvalid()) - return Owned(E); - E = Res.take(); + return E; + E = Res.get(); if (!E->getType()->isVoidType()) RequireCompleteType(E->getExprLoc(), E->getType(), diag::err_incomplete_type); - return Owned(E); + return E; } // If we can unambiguously determine whether Var can never be used @@ -5829,7 +5789,7 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) { static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var, ASTContext &Context) { if (isa<ParmVarDecl>(Var)) return true; - const VarDecl *DefVD = 0; + const VarDecl *DefVD = nullptr; // If there is no initializer - this can not be a constant expression. if (!Var->getAnyInitializer(DefVD)) return true; @@ -5849,42 +5809,58 @@ static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var, return !IsVariableAConstantExpression(Var, Context); } -/// \brief Check if the current lambda scope has any potential captures, and -/// whether they can be captured by any of the enclosing lambdas that are -/// ready to capture. If there is a lambda that can capture a nested -/// potential-capture, go ahead and do so. Also, check to see if any -/// variables are uncaptureable or do not involve an odr-use so do not -/// need to be captured. +/// \brief Check if the current lambda has any potential captures +/// that must be captured by any of its enclosing lambdas that are ready to +/// capture. If there is a lambda that can capture a nested +/// potential-capture, go ahead and do so. Also, check to see if any +/// variables are uncaptureable or do not involve an odr-use so do not +/// need to be captured. + +static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures( + Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) { -static void CheckLambdaCaptures(Expr *const FE, - LambdaScopeInfo *const CurrentLSI, Sema &S) { - assert(!S.isUnevaluatedContext()); assert(S.CurContext->isDependentContext()); - const bool IsFullExprInstantiationDependent = - FE->isInstantiationDependent(); - // All the potentially captureable variables in the current nested + assert(CurrentLSI->CallOperator == S.CurContext && + "The current call operator must be synchronized with Sema's CurContext"); + + const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent(); + + ArrayRef<const FunctionScopeInfo *> FunctionScopesArrayRef( + S.FunctionScopes.data(), S.FunctionScopes.size()); + + // All the potentially captureable variables in the current nested // lambda (within a generic outer lambda), must be captured by an // outer lambda that is enclosed within a non-dependent context. - - for (size_t I = 0, N = CurrentLSI->getNumPotentialVariableCaptures(); - I != N; ++I) { - Expr *VarExpr = 0; - VarDecl *Var = 0; + const unsigned NumPotentialCaptures = + CurrentLSI->getNumPotentialVariableCaptures(); + for (unsigned I = 0; I != NumPotentialCaptures; ++I) { + Expr *VarExpr = nullptr; + VarDecl *Var = nullptr; CurrentLSI->getPotentialVariableCapture(I, Var, VarExpr); - // - if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) && + // If the variable is clearly identified as non-odr-used and the full + // expression is not instantiation dependent, only then do we not + // need to check enclosing lambda's for speculative captures. + // For e.g.: + // Even though 'x' is not odr-used, it should be captured. + // int test() { + // const int x = 10; + // auto L = [=](auto a) { + // (void) +x + a; + // }; + // } + if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) && !IsFullExprInstantiationDependent) - continue; - // Climb up until we find a lambda that can capture: - // - a generic-or-non-generic lambda call operator that is enclosed - // within a non-dependent context. - unsigned FunctionScopeIndexOfCapturableLambda = 0; - if (GetInnermostEnclosingCapturableLambda( - S.FunctionScopes, FunctionScopeIndexOfCapturableLambda, - S.CurContext, Var, S)) { - MarkVarDeclODRUsed(Var, VarExpr->getExprLoc(), - S, &FunctionScopeIndexOfCapturableLambda); + continue; + + // If we have a capture-capable lambda for the variable, go ahead and + // capture the variable in that lambda (and all its enclosing lambdas). + if (const Optional<unsigned> Index = + getStackIndexOfNearestEnclosingCaptureCapableLambda( + FunctionScopesArrayRef, Var, S)) { + const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue(); + MarkVarDeclODRUsed(Var, VarExpr->getExprLoc(), S, + &FunctionScopeIndexOfCapturableLambda); } const bool IsVarNeverAConstantExpression = VariableCanNeverBeAConstantExpression(Var, S.Context); @@ -5900,27 +5876,32 @@ static void CheckLambdaCaptures(Expr *const FE, if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/false, CaptureType, - DeclRefType, 0)) { + DeclRefType, nullptr)) { // We will never be able to capture this variable, and we need // to be able to in any and all instantiations, so diagnose it. S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/true, CaptureType, - DeclRefType, 0); + DeclRefType, nullptr); } } } + // Check if 'this' needs to be captured. if (CurrentLSI->hasPotentialThisCapture()) { - unsigned FunctionScopeIndexOfCapturableLambda = 0; - if (GetInnermostEnclosingCapturableLambda( - S.FunctionScopes, FunctionScopeIndexOfCapturableLambda, - S.CurContext, /*0 is 'this'*/ 0, S)) { - S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation, - /*Explicit*/false, /*BuildAndDiagnose*/true, - &FunctionScopeIndexOfCapturableLambda); + // If we have a capture-capable lambda for 'this', go ahead and capture + // 'this' in that lambda (and all its enclosing lambdas). + if (const Optional<unsigned> Index = + getStackIndexOfNearestEnclosingCaptureCapableLambda( + FunctionScopesArrayRef, /*0 is 'this'*/ nullptr, S)) { + const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue(); + S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation, + /*Explicit*/ false, /*BuildAndDiagnose*/ true, + &FunctionScopeIndexOfCapturableLambda); } } + + // Reset all the potential captures at the end of each full-expression. CurrentLSI->clearPotentialCaptures(); } @@ -5929,7 +5910,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, bool DiscardedValue, bool IsConstexpr, bool IsLambdaInitCaptureInitializer) { - ExprResult FullExpr = Owned(FE); + ExprResult FullExpr = FE; if (!FullExpr.get()) return ExprError(); @@ -5956,17 +5937,17 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, // Top-level expressions default to 'id' when we're in a debugger. if (DiscardedValue && getLangOpts().DebuggerCastResultToId && FullExpr.get()->getType() == Context.UnknownAnyTy) { - FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType()); + FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType()); if (FullExpr.isInvalid()) return ExprError(); } if (DiscardedValue) { - FullExpr = CheckPlaceholderExpr(FullExpr.take()); + FullExpr = CheckPlaceholderExpr(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); - FullExpr = IgnoredValueConversions(FullExpr.take()); + FullExpr = IgnoredValueConversions(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); } @@ -6017,11 +5998,12 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, // FunctionScopes.size() in InstantiatingTemplate's // constructor/destructor. // - Teach the handful of places that iterate over FunctionScopes to - // stop at the outermost enclosing lexical scope." - const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext); - if (IsInLambdaDeclContext && CurrentLSI && + // stop at the outermost enclosing lexical scope." + const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext); + if (IsInLambdaDeclContext && CurrentLSI && CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid()) - CheckLambdaCaptures(FE, CurrentLSI, *this); + CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI, + *this); return MaybeCreateExprWithCleanups(FullExpr); } |