Lines Matching +full:fine +full:- +full:tune

1 //===- ExprClassification.cpp - Expression AST Node Implementation --------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
38 assert(!TR->isReferenceType() && "Expressions can't have reference type.");
45 if (TR->isFunctionType() || TR == Ctx.OverloadTy)
50 else if (TR->isVoidType() && !TR.hasQualifiers())
84 if (T->isRecordType())
86 if (T->isArrayType())
99 return Lang.CPlusPlus ? ClassifyTemporary(E->getType()) : Cl::CL_PRValue;
112 switch (E->getStmtClass()) {
154 // In C++, they're prvalue temporaries, except for file-scope arrays.
156 return !E->isLValue() ? ClassifyTemporary(E->getType()) : Cl::CL_LValue;
212 // Make HLSL this reference-like
217 return ClassifyInternal(Ctx, cast<ConstantExpr>(E)->getSubExpr());
222 cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
225 // A pack-index-expression always expands to an id-expression.
227 if (cast<PackIndexingExpr>(E)->isInstantiationDependent())
229 return ClassifyInternal(Ctx, cast<PackIndexingExpr>(E)->getSelectedExpr());
237 if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType())
238 return ClassifyInternal(Ctx, cast<ArraySubscriptExpr>(E)->getBase());
240 // Step over the array-to-pointer decay if present, but not over the
242 auto *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreImpCasts();
243 if (Base->getType()->isArrayType())
250 return ClassifyInternal(Ctx, cast<MatrixSubscriptExpr>(E)->getBase());
255 if (E->getType() == Ctx.UnknownAnyTy)
256 return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
258 return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
265 switch (cast<UnaryOperator>(E)->getOpcode()) {
274 return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr());
277 // expressions: l-value only if the operand is a true l-value.
280 const Expr *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
302 return ClassifyExprValueKind(Lang, E, E->getValueKind());
304 // Pseudo-object expressions can produce l-values with reference magic.
307 cast<PseudoObjectExpr>(E)->getValueKind());
312 return ClassifyExprValueKind(Lang, E, E->getValueKind());
317 return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr());
323 if (cast<GenericSelectionExpr>(E)->isResultDependent())
325 return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());
339 return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType(Ctx));
343 Ctx, cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm());
347 return ClassifyInternal(Ctx, cast<ChooseExpr>(E)->getChosenSubExpr());
352 if (cast<ExtVectorElementExpr>(E)->containsDuplicateElements())
354 if (cast<ExtVectorElementExpr>(E)->isArrow())
356 return ClassifyInternal(Ctx, cast<ExtVectorElementExpr>(E)->getBase());
360 return ClassifyInternal(Ctx, cast<CXXDefaultArgExpr>(E)->getExpr());
364 return ClassifyInternal(Ctx, cast<CXXDefaultInitExpr>(E)->getExpr());
368 return ClassifyInternal(Ctx, cast<CXXBindTemporaryExpr>(E)->getSubExpr());
372 return ClassifyInternal(Ctx, cast<ExprWithCleanups>(E)->getSubExpr());
386 return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
390 cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
395 return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
402 return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
409 cast<ObjCMessageExpr>(E)->getMethodDecl()) {
410 Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getReturnType());
424 return ClassifyUnnamed(Ctx, E->getType());
427 return ClassifyInternal(Ctx, cast<DesignatedInitExpr>(E)->getInit());
430 const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt();
431 if (const auto *LastExpr = dyn_cast_or_null<Expr>(S->body_back()))
432 return ClassifyUnnamed(Ctx, LastExpr->getType());
437 return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern());
440 return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
448 // value kind for us, so we only need to fine-tune.
449 if (E->isPRValue())
450 return ClassifyExprValueKind(Lang, E, E->getValueKind());
451 assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
452 "Only 1-element init lists can be glvalues.");
453 return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0));
457 return ClassifyInternal(Ctx, cast<CoroutineSuspendExpr>(E)->getResumeExpr());
463 if (isa<ArrayType>(E->getType()))
471 /// ClassifyDecl - Return the classification of an expression referencing the
479 // special-case this.
482 if (M->isImplicitObjectMemberFunction())
484 if (M->isStatic())
491 islvalue = NTTParm->getType()->isReferenceType() ||
492 NTTParm->getType()->isRecordType();
503 /// ClassifyUnnamed - Return the classification of an expression yielding an
514 if (T->isLValueReferenceType())
516 const auto *RV = T->getAs<RValueReferenceType>();
520 return RV->getPointeeType()->isFunctionType() ? Cl::CL_LValue : Cl::CL_XValue;
524 if (E->getType() == Ctx.UnknownAnyTy)
525 return (isa<FunctionDecl>(E->getMemberDecl())
533 if (E->isArrow())
536 Expr *Base = E->getBase()->IgnoreParens();
542 NamedDecl *Member = E->getMemberDecl();
543 // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2.
547 if (Value->getType()->isReferenceType())
551 // -- If E2 is a static member [...] then E1.E2 is an lvalue.
552 if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord())
555 // -- If E2 is a non-static data member [...]. If E1 is an lvalue, then
560 if (E->isArrow())
562 Expr *Base = E->getBase()->IgnoreParenImpCasts();
565 return ClassifyInternal(Ctx, E->getBase());
568 // -- If E2 is a [...] member function, [...]
569 // -- If it refers to a static member function [...], then E1.E2 is an
571 // -- Otherwise [...] E1.E2 is a prvalue.
573 if (Method->isStatic())
575 if (Method->isImplicitObjectMemberFunction())
580 // -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue.
590 if (E->isAssignmentOp())
591 return (E->getLHS()->getObjectKind() == OK_ObjCProperty
596 if (E->getOpcode() == BO_Comma)
597 return ClassifyInternal(Ctx, E->getRHS());
602 if (E->getOpcode() == BO_PtrMemD)
603 return (E->getType()->isFunctionType() ||
604 E->hasPlaceholderType(BuiltinType::BoundMember))
606 : ClassifyInternal(Ctx, E->getLHS());
608 // C++ [expr.mptr.oper]p6: The result of an ->* expression is an lvalue if its
610 if (E->getOpcode() == BO_PtrMemI)
611 return (E->getType()->isFunctionType() ||
612 E->hasPlaceholderType(BuiltinType::BoundMember))
628 if (True->getType()->isVoidType() || False->getType()->isVoidType()) {
630 // parenthesized) throw-expression; the result is of the [...] value
632 bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts());
633 bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts());
658 // use of the GCC cast-as-lvalue extension.
659 if (const auto *CE = dyn_cast<ExplicitCastExpr>(E->IgnoreParens())) {
660 if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
661 Loc = CE->getExprLoc();
671 if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType())
677 if (Expr->isImplicitProperty() &&
678 Expr->getImplicitPropertySetter() == nullptr)
682 CanQualType CT = Ctx.getCanonicalType(E->getType());
691 if (CT->isArrayType())
694 if (CT->isIncompleteType())
698 if (const RecordType *R = CT->getAs<RecordType>())
699 if (R->hasConstFields())