123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899 |
- //===- ComputeDependence.cpp ----------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "clang/AST/ComputeDependence.h"
- #include "clang/AST/Attr.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/DeclarationName.h"
- #include "clang/AST/DependenceFlags.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/ExprConcepts.h"
- #include "clang/AST/ExprObjC.h"
- #include "clang/AST/ExprOpenMP.h"
- #include "clang/Basic/ExceptionSpecificationType.h"
- #include "llvm/ADT/ArrayRef.h"
- using namespace clang;
- ExprDependence clang::computeDependence(FullExpr *E) {
- return E->getSubExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(OpaqueValueExpr *E) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- if (auto *S = E->getSourceExpr())
- D |= S->getDependence();
- assert(!(D & ExprDependence::UnexpandedPack));
- return D;
- }
- ExprDependence clang::computeDependence(ParenExpr *E) {
- return E->getSubExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(UnaryOperator *E,
- const ASTContext &Ctx) {
- ExprDependence Dep =
- // FIXME: Do we need to look at the type?
- toExprDependenceForImpliedType(E->getType()->getDependence()) |
- E->getSubExpr()->getDependence();
- // C++ [temp.dep.constexpr]p5:
- // An expression of the form & qualified-id where the qualified-id names a
- // dependent member of the current instantiation is value-dependent. An
- // expression of the form & cast-expression is also value-dependent if
- // evaluating cast-expression as a core constant expression succeeds and
- // the result of the evaluation refers to a templated entity that is an
- // object with static or thread storage duration or a member function.
- //
- // What this amounts to is: constant-evaluate the operand and check whether it
- // refers to a templated entity other than a variable with local storage.
- if (Ctx.getLangOpts().CPlusPlus && E->getOpcode() == UO_AddrOf &&
- !(Dep & ExprDependence::Value)) {
- Expr::EvalResult Result;
- SmallVector<PartialDiagnosticAt, 8> Diag;
- Result.Diag = &Diag;
- // FIXME: This doesn't enforce the C++98 constant expression rules.
- if (E->getSubExpr()->EvaluateAsConstantExpr(Result, Ctx) && Diag.empty() &&
- Result.Val.isLValue()) {
- auto *VD = Result.Val.getLValueBase().dyn_cast<const ValueDecl *>();
- if (VD && VD->isTemplated()) {
- auto *VarD = dyn_cast<VarDecl>(VD);
- if (!VarD || !VarD->hasLocalStorage())
- Dep |= ExprDependence::Value;
- }
- }
- }
- return Dep;
- }
- ExprDependence clang::computeDependence(UnaryExprOrTypeTraitExpr *E) {
- // Never type-dependent (C++ [temp.dep.expr]p3).
- // Value-dependent if the argument is type-dependent.
- if (E->isArgumentType())
- return turnTypeToValueDependence(
- toExprDependenceAsWritten(E->getArgumentType()->getDependence()));
- auto ArgDeps = E->getArgumentExpr()->getDependence();
- auto Deps = ArgDeps & ~ExprDependence::TypeValue;
- // Value-dependent if the argument is type-dependent.
- if (ArgDeps & ExprDependence::Type)
- Deps |= ExprDependence::Value;
- // Check to see if we are in the situation where alignof(decl) should be
- // dependent because decl's alignment is dependent.
- auto ExprKind = E->getKind();
- if (ExprKind != UETT_AlignOf && ExprKind != UETT_PreferredAlignOf)
- return Deps;
- if ((Deps & ExprDependence::Value) && (Deps & ExprDependence::Instantiation))
- return Deps;
- auto *NoParens = E->getArgumentExpr()->IgnoreParens();
- const ValueDecl *D = nullptr;
- if (const auto *DRE = dyn_cast<DeclRefExpr>(NoParens))
- D = DRE->getDecl();
- else if (const auto *ME = dyn_cast<MemberExpr>(NoParens))
- D = ME->getMemberDecl();
- if (!D)
- return Deps;
- for (const auto *I : D->specific_attrs<AlignedAttr>()) {
- if (I->isAlignmentErrorDependent())
- Deps |= ExprDependence::Error;
- if (I->isAlignmentDependent())
- Deps |= ExprDependence::ValueInstantiation;
- }
- return Deps;
- }
- ExprDependence clang::computeDependence(ArraySubscriptExpr *E) {
- return E->getLHS()->getDependence() | E->getRHS()->getDependence();
- }
- ExprDependence clang::computeDependence(MatrixSubscriptExpr *E) {
- return E->getBase()->getDependence() | E->getRowIdx()->getDependence() |
- (E->getColumnIdx() ? E->getColumnIdx()->getDependence()
- : ExprDependence::None);
- }
- ExprDependence clang::computeDependence(CompoundLiteralExpr *E) {
- return toExprDependenceAsWritten(
- E->getTypeSourceInfo()->getType()->getDependence()) |
- toExprDependenceForImpliedType(E->getType()->getDependence()) |
- turnTypeToValueDependence(E->getInitializer()->getDependence());
- }
- ExprDependence clang::computeDependence(ImplicitCastExpr *E) {
- // We model implicit conversions as combining the dependence of their
- // subexpression, apart from its type, with the semantic portion of the
- // target type.
- ExprDependence D =
- toExprDependenceForImpliedType(E->getType()->getDependence());
- if (auto *S = E->getSubExpr())
- D |= S->getDependence() & ~ExprDependence::Type;
- return D;
- }
- ExprDependence clang::computeDependence(ExplicitCastExpr *E) {
- // Cast expressions are type-dependent if the type is
- // dependent (C++ [temp.dep.expr]p3).
- // Cast expressions are value-dependent if the type is
- // dependent or if the subexpression is value-dependent.
- //
- // Note that we also need to consider the dependence of the actual type here,
- // because when the type as written is a deduced type, that type is not
- // dependent, but it may be deduced as a dependent type.
- ExprDependence D =
- toExprDependenceAsWritten(
- cast<ExplicitCastExpr>(E)->getTypeAsWritten()->getDependence()) |
- toExprDependenceForImpliedType(E->getType()->getDependence());
- if (auto *S = E->getSubExpr())
- D |= S->getDependence() & ~ExprDependence::Type;
- return D;
- }
- ExprDependence clang::computeDependence(BinaryOperator *E) {
- return E->getLHS()->getDependence() | E->getRHS()->getDependence();
- }
- ExprDependence clang::computeDependence(ConditionalOperator *E) {
- // The type of the conditional operator depends on the type of the conditional
- // to support the GCC vector conditional extension. Additionally,
- // [temp.dep.expr] does specify state that this should be dependent on ALL sub
- // expressions.
- return E->getCond()->getDependence() | E->getLHS()->getDependence() |
- E->getRHS()->getDependence();
- }
- ExprDependence clang::computeDependence(BinaryConditionalOperator *E) {
- return E->getCommon()->getDependence() | E->getFalseExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(StmtExpr *E, unsigned TemplateDepth) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- // Propagate dependence of the result.
- if (const auto *CompoundExprResult =
- dyn_cast_or_null<ValueStmt>(E->getSubStmt()->getStmtExprResult()))
- if (const Expr *ResultExpr = CompoundExprResult->getExprStmt())
- D |= ResultExpr->getDependence();
- // Note: we treat a statement-expression in a dependent context as always
- // being value- and instantiation-dependent. This matches the behavior of
- // lambda-expressions and GCC.
- if (TemplateDepth)
- D |= ExprDependence::ValueInstantiation;
- // A param pack cannot be expanded over stmtexpr boundaries.
- return D & ~ExprDependence::UnexpandedPack;
- }
- ExprDependence clang::computeDependence(ConvertVectorExpr *E) {
- auto D = toExprDependenceAsWritten(
- E->getTypeSourceInfo()->getType()->getDependence()) |
- E->getSrcExpr()->getDependence();
- if (!E->getType()->isDependentType())
- D &= ~ExprDependence::Type;
- return D;
- }
- ExprDependence clang::computeDependence(ChooseExpr *E) {
- if (E->isConditionDependent())
- return ExprDependence::TypeValueInstantiation |
- E->getCond()->getDependence() | E->getLHS()->getDependence() |
- E->getRHS()->getDependence();
- auto Cond = E->getCond()->getDependence();
- auto Active = E->getLHS()->getDependence();
- auto Inactive = E->getRHS()->getDependence();
- if (!E->isConditionTrue())
- std::swap(Active, Inactive);
- // Take type- and value- dependency from the active branch. Propagate all
- // other flags from all branches.
- return (Active & ExprDependence::TypeValue) |
- ((Cond | Active | Inactive) & ~ExprDependence::TypeValue);
- }
- ExprDependence clang::computeDependence(ParenListExpr *P) {
- auto D = ExprDependence::None;
- for (auto *E : P->exprs())
- D |= E->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(VAArgExpr *E) {
- auto D = toExprDependenceAsWritten(
- E->getWrittenTypeInfo()->getType()->getDependence()) |
- (E->getSubExpr()->getDependence() & ~ExprDependence::Type);
- return D & ~ExprDependence::Value;
- }
- ExprDependence clang::computeDependence(NoInitExpr *E) {
- return toExprDependenceForImpliedType(E->getType()->getDependence()) &
- (ExprDependence::Instantiation | ExprDependence::Error);
- }
- ExprDependence clang::computeDependence(ArrayInitLoopExpr *E) {
- auto D = E->getCommonExpr()->getDependence() |
- E->getSubExpr()->getDependence() | ExprDependence::Instantiation;
- if (!E->getType()->isInstantiationDependentType())
- D &= ~ExprDependence::Instantiation;
- return turnTypeToValueDependence(D);
- }
- ExprDependence clang::computeDependence(ImplicitValueInitExpr *E) {
- return toExprDependenceForImpliedType(E->getType()->getDependence()) &
- ExprDependence::Instantiation;
- }
- ExprDependence clang::computeDependence(ExtVectorElementExpr *E) {
- return E->getBase()->getDependence();
- }
- ExprDependence clang::computeDependence(BlockExpr *E) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- if (E->getBlockDecl()->isDependentContext())
- D |= ExprDependence::Instantiation;
- return D;
- }
- ExprDependence clang::computeDependence(AsTypeExpr *E) {
- // FIXME: AsTypeExpr doesn't store the type as written. Assume the expression
- // type has identical sugar for now, so is a type-as-written.
- auto D = toExprDependenceAsWritten(E->getType()->getDependence()) |
- E->getSrcExpr()->getDependence();
- if (!E->getType()->isDependentType())
- D &= ~ExprDependence::Type;
- return D;
- }
- ExprDependence clang::computeDependence(CXXRewrittenBinaryOperator *E) {
- return E->getSemanticForm()->getDependence();
- }
- ExprDependence clang::computeDependence(CXXStdInitializerListExpr *E) {
- auto D = turnTypeToValueDependence(E->getSubExpr()->getDependence());
- D |= toExprDependenceForImpliedType(E->getType()->getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(CXXTypeidExpr *E) {
- auto D = ExprDependence::None;
- if (E->isTypeOperand())
- D = toExprDependenceAsWritten(
- E->getTypeOperandSourceInfo()->getType()->getDependence());
- else
- D = turnTypeToValueDependence(E->getExprOperand()->getDependence());
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- return D & ~ExprDependence::Type;
- }
- ExprDependence clang::computeDependence(MSPropertyRefExpr *E) {
- return E->getBaseExpr()->getDependence() & ~ExprDependence::Type;
- }
- ExprDependence clang::computeDependence(MSPropertySubscriptExpr *E) {
- return E->getIdx()->getDependence();
- }
- ExprDependence clang::computeDependence(CXXUuidofExpr *E) {
- if (E->isTypeOperand())
- return turnTypeToValueDependence(toExprDependenceAsWritten(
- E->getTypeOperandSourceInfo()->getType()->getDependence()));
- return turnTypeToValueDependence(E->getExprOperand()->getDependence());
- }
- ExprDependence clang::computeDependence(CXXThisExpr *E) {
- // 'this' is type-dependent if the class type of the enclosing
- // member function is dependent (C++ [temp.dep.expr]p2)
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- assert(!(D & ExprDependence::UnexpandedPack));
- return D;
- }
- ExprDependence clang::computeDependence(CXXThrowExpr *E) {
- auto *Op = E->getSubExpr();
- if (!Op)
- return ExprDependence::None;
- return Op->getDependence() & ~ExprDependence::TypeValue;
- }
- ExprDependence clang::computeDependence(CXXBindTemporaryExpr *E) {
- return E->getSubExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(CXXScalarValueInitExpr *E) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- if (auto *TSI = E->getTypeSourceInfo())
- D |= toExprDependenceAsWritten(TSI->getType()->getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(CXXDeleteExpr *E) {
- return turnTypeToValueDependence(E->getArgument()->getDependence());
- }
- ExprDependence clang::computeDependence(ArrayTypeTraitExpr *E) {
- auto D = toExprDependenceAsWritten(E->getQueriedType()->getDependence());
- if (auto *Dim = E->getDimensionExpression())
- D |= Dim->getDependence();
- return turnTypeToValueDependence(D);
- }
- ExprDependence clang::computeDependence(ExpressionTraitExpr *E) {
- // Never type-dependent.
- auto D = E->getQueriedExpression()->getDependence() & ~ExprDependence::Type;
- // Value-dependent if the argument is type-dependent.
- if (E->getQueriedExpression()->isTypeDependent())
- D |= ExprDependence::Value;
- return D;
- }
- ExprDependence clang::computeDependence(CXXNoexceptExpr *E, CanThrowResult CT) {
- auto D = E->getOperand()->getDependence() & ~ExprDependence::TypeValue;
- if (CT == CT_Dependent)
- D |= ExprDependence::ValueInstantiation;
- return D;
- }
- ExprDependence clang::computeDependence(PackExpansionExpr *E) {
- return (E->getPattern()->getDependence() & ~ExprDependence::UnexpandedPack) |
- ExprDependence::TypeValueInstantiation;
- }
- ExprDependence clang::computeDependence(SubstNonTypeTemplateParmExpr *E) {
- return E->getReplacement()->getDependence();
- }
- ExprDependence clang::computeDependence(CoroutineSuspendExpr *E) {
- if (auto *Resume = E->getResumeExpr())
- return (Resume->getDependence() &
- (ExprDependence::TypeValue | ExprDependence::Error)) |
- (E->getCommonExpr()->getDependence() & ~ExprDependence::TypeValue);
- return E->getCommonExpr()->getDependence() |
- ExprDependence::TypeValueInstantiation;
- }
- ExprDependence clang::computeDependence(DependentCoawaitExpr *E) {
- return E->getOperand()->getDependence() |
- ExprDependence::TypeValueInstantiation;
- }
- ExprDependence clang::computeDependence(ObjCBoxedExpr *E) {
- return E->getSubExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(ObjCEncodeExpr *E) {
- return toExprDependenceAsWritten(E->getEncodedType()->getDependence());
- }
- ExprDependence clang::computeDependence(ObjCIvarRefExpr *E) {
- return turnTypeToValueDependence(E->getBase()->getDependence());
- }
- ExprDependence clang::computeDependence(ObjCPropertyRefExpr *E) {
- if (E->isObjectReceiver())
- return E->getBase()->getDependence() & ~ExprDependence::Type;
- if (E->isSuperReceiver())
- return toExprDependenceForImpliedType(
- E->getSuperReceiverType()->getDependence()) &
- ~ExprDependence::TypeValue;
- assert(E->isClassReceiver());
- return ExprDependence::None;
- }
- ExprDependence clang::computeDependence(ObjCSubscriptRefExpr *E) {
- return E->getBaseExpr()->getDependence() | E->getKeyExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(ObjCIsaExpr *E) {
- return E->getBase()->getDependence() & ~ExprDependence::Type &
- ~ExprDependence::UnexpandedPack;
- }
- ExprDependence clang::computeDependence(ObjCIndirectCopyRestoreExpr *E) {
- return E->getSubExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(OMPArraySectionExpr *E) {
- auto D = E->getBase()->getDependence();
- if (auto *LB = E->getLowerBound())
- D |= LB->getDependence();
- if (auto *Len = E->getLength())
- D |= Len->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) {
- auto D = E->getBase()->getDependence();
- for (Expr *Dim: E->getDimensions())
- if (Dim)
- D |= turnValueToTypeDependence(Dim->getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(OMPIteratorExpr *E) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
- if (auto *DD = cast_or_null<DeclaratorDecl>(E->getIteratorDecl(I))) {
- // If the type is omitted, it's 'int', and is not dependent in any way.
- if (auto *TSI = DD->getTypeSourceInfo()) {
- D |= toExprDependenceAsWritten(TSI->getType()->getDependence());
- }
- }
- OMPIteratorExpr::IteratorRange IR = E->getIteratorRange(I);
- if (Expr *BE = IR.Begin)
- D |= BE->getDependence();
- if (Expr *EE = IR.End)
- D |= EE->getDependence();
- if (Expr *SE = IR.Step)
- D |= SE->getDependence();
- }
- return D;
- }
- /// Compute the type-, value-, and instantiation-dependence of a
- /// declaration reference
- /// based on the declaration being referenced.
- ExprDependence clang::computeDependence(DeclRefExpr *E, const ASTContext &Ctx) {
- auto Deps = ExprDependence::None;
- if (auto *NNS = E->getQualifier())
- Deps |= toExprDependence(NNS->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
- if (auto *FirstArg = E->getTemplateArgs()) {
- unsigned NumArgs = E->getNumTemplateArgs();
- for (auto *Arg = FirstArg, *End = FirstArg + NumArgs; Arg < End; ++Arg)
- Deps |= toExprDependence(Arg->getArgument().getDependence());
- }
- auto *Decl = E->getDecl();
- auto Type = E->getType();
- if (Decl->isParameterPack())
- Deps |= ExprDependence::UnexpandedPack;
- Deps |= toExprDependenceForImpliedType(Type->getDependence()) &
- ExprDependence::Error;
- // C++ [temp.dep.expr]p3:
- // An id-expression is type-dependent if it contains:
- // - an identifier associated by name lookup with one or more declarations
- // declared with a dependent type
- //
- // [The "or more" case is not modeled as a DeclRefExpr. There are a bunch
- // more bullets here that we handle by treating the declaration as having a
- // dependent type if they involve a placeholder type that can't be deduced.]
- if (Type->isDependentType())
- return Deps | ExprDependence::TypeValueInstantiation;
- else if (Type->isInstantiationDependentType())
- Deps |= ExprDependence::Instantiation;
- // - a conversion-function-id that specifies a dependent type
- if (Decl->getDeclName().getNameKind() ==
- DeclarationName::CXXConversionFunctionName) {
- QualType T = Decl->getDeclName().getCXXNameType();
- if (T->isDependentType())
- return Deps | ExprDependence::TypeValueInstantiation;
- if (T->isInstantiationDependentType())
- Deps |= ExprDependence::Instantiation;
- }
- // - a template-id that is dependent,
- // - a nested-name-specifier or a qualified-id that names a member of an
- // unknown specialization
- // [These are not modeled as DeclRefExprs.]
- // or if it names a dependent member of the current instantiation that is a
- // static data member of type "array of unknown bound of T" for some T
- // [handled below].
- // C++ [temp.dep.constexpr]p2:
- // An id-expression is value-dependent if:
- // - it is type-dependent [handled above]
- // - it is the name of a non-type template parameter,
- if (isa<NonTypeTemplateParmDecl>(Decl))
- return Deps | ExprDependence::ValueInstantiation;
- // - it names a potentially-constant variable that is initialized with an
- // expression that is value-dependent
- if (const auto *Var = dyn_cast<VarDecl>(Decl)) {
- if (Var->mightBeUsableInConstantExpressions(Ctx)) {
- if (const Expr *Init = Var->getAnyInitializer()) {
- if (Init->isValueDependent())
- Deps |= ExprDependence::ValueInstantiation;
- if (Init->containsErrors())
- Deps |= ExprDependence::Error;
- }
- }
- // - it names a static data member that is a dependent member of the
- // current instantiation and is not initialized in a member-declarator,
- if (Var->isStaticDataMember() &&
- Var->getDeclContext()->isDependentContext() &&
- !Var->getFirstDecl()->hasInit()) {
- const VarDecl *First = Var->getFirstDecl();
- TypeSourceInfo *TInfo = First->getTypeSourceInfo();
- if (TInfo->getType()->isIncompleteArrayType()) {
- Deps |= ExprDependence::TypeValueInstantiation;
- } else if (!First->hasInit()) {
- Deps |= ExprDependence::ValueInstantiation;
- }
- }
- return Deps;
- }
- // - it names a static member function that is a dependent member of the
- // current instantiation
- //
- // FIXME: It's unclear that the restriction to static members here has any
- // effect: any use of a non-static member function name requires either
- // forming a pointer-to-member or providing an object parameter, either of
- // which makes the overall expression value-dependent.
- if (auto *MD = dyn_cast<CXXMethodDecl>(Decl)) {
- if (MD->isStatic() && Decl->getDeclContext()->isDependentContext())
- Deps |= ExprDependence::ValueInstantiation;
- }
- return Deps;
- }
- ExprDependence clang::computeDependence(RecoveryExpr *E) {
- // RecoveryExpr is
- // - always value-dependent, and therefore instantiation dependent
- // - contains errors (ExprDependence::Error), by definition
- // - type-dependent if we don't know the type (fallback to an opaque
- // dependent type), or the type is known and dependent, or it has
- // type-dependent subexpressions.
- auto D = toExprDependenceAsWritten(E->getType()->getDependence()) |
- ExprDependence::ErrorDependent;
- // FIXME: remove the type-dependent bit from subexpressions, if the
- // RecoveryExpr has a non-dependent type.
- for (auto *S : E->subExpressions())
- D |= S->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(SYCLUniqueStableNameExpr *E) {
- return toExprDependenceAsWritten(
- E->getTypeSourceInfo()->getType()->getDependence());
- }
- ExprDependence clang::computeDependence(PredefinedExpr *E) {
- return toExprDependenceForImpliedType(E->getType()->getDependence());
- }
- ExprDependence clang::computeDependence(CallExpr *E,
- llvm::ArrayRef<Expr *> PreArgs) {
- auto D = E->getCallee()->getDependence();
- for (auto *A : llvm::ArrayRef(E->getArgs(), E->getNumArgs())) {
- if (A)
- D |= A->getDependence();
- }
- for (auto *A : PreArgs)
- D |= A->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(OffsetOfExpr *E) {
- auto D = turnTypeToValueDependence(toExprDependenceAsWritten(
- E->getTypeSourceInfo()->getType()->getDependence()));
- for (unsigned I = 0, N = E->getNumExpressions(); I < N; ++I)
- D |= turnTypeToValueDependence(E->getIndexExpr(I)->getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(MemberExpr *E) {
- auto *MemberDecl = E->getMemberDecl();
- auto D = E->getBase()->getDependence();
- if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
- DeclContext *DC = MemberDecl->getDeclContext();
- // dyn_cast_or_null is used to handle objC variables which do not
- // have a declaration context.
- CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC);
- if (RD && RD->isDependentContext() && RD->isCurrentInstantiation(DC)) {
- if (!E->getType()->isDependentType())
- D &= ~ExprDependence::Type;
- }
- // Bitfield with value-dependent width is type-dependent.
- if (FD && FD->isBitField() && FD->getBitWidth()->isValueDependent()) {
- D |= ExprDependence::Type;
- }
- }
- // FIXME: move remaining dependence computation from MemberExpr::Create()
- return D;
- }
- ExprDependence clang::computeDependence(InitListExpr *E) {
- auto D = ExprDependence::None;
- for (auto *A : E->inits())
- D |= A->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(ShuffleVectorExpr *E) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- for (auto *C : llvm::ArrayRef(E->getSubExprs(), E->getNumSubExprs()))
- D |= C->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(GenericSelectionExpr *E,
- bool ContainsUnexpandedPack) {
- auto D = ContainsUnexpandedPack ? ExprDependence::UnexpandedPack
- : ExprDependence::None;
- for (auto *AE : E->getAssocExprs())
- D |= AE->getDependence() & ExprDependence::Error;
- D |= E->getControllingExpr()->getDependence() & ExprDependence::Error;
- if (E->isResultDependent())
- return D | ExprDependence::TypeValueInstantiation;
- return D | (E->getResultExpr()->getDependence() &
- ~ExprDependence::UnexpandedPack);
- }
- ExprDependence clang::computeDependence(DesignatedInitExpr *E) {
- auto Deps = E->getInit()->getDependence();
- for (auto D : E->designators()) {
- auto DesignatorDeps = ExprDependence::None;
- if (D.isArrayDesignator())
- DesignatorDeps |= E->getArrayIndex(D)->getDependence();
- else if (D.isArrayRangeDesignator())
- DesignatorDeps |= E->getArrayRangeStart(D)->getDependence() |
- E->getArrayRangeEnd(D)->getDependence();
- Deps |= DesignatorDeps;
- if (DesignatorDeps & ExprDependence::TypeValue)
- Deps |= ExprDependence::TypeValueInstantiation;
- }
- return Deps;
- }
- ExprDependence clang::computeDependence(PseudoObjectExpr *O) {
- auto D = O->getSyntacticForm()->getDependence();
- for (auto *E : O->semantics())
- D |= E->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(AtomicExpr *A) {
- auto D = ExprDependence::None;
- for (auto *E : llvm::ArrayRef(A->getSubExprs(), A->getNumSubExprs()))
- D |= E->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(CXXNewExpr *E) {
- auto D = toExprDependenceAsWritten(
- E->getAllocatedTypeSourceInfo()->getType()->getDependence());
- D |= toExprDependenceForImpliedType(E->getAllocatedType()->getDependence());
- auto Size = E->getArraySize();
- if (Size && *Size)
- D |= turnTypeToValueDependence((*Size)->getDependence());
- if (auto *I = E->getInitializer())
- D |= turnTypeToValueDependence(I->getDependence());
- for (auto *A : E->placement_arguments())
- D |= turnTypeToValueDependence(A->getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(CXXPseudoDestructorExpr *E) {
- auto D = E->getBase()->getDependence();
- if (auto *TSI = E->getDestroyedTypeInfo())
- D |= toExprDependenceAsWritten(TSI->getType()->getDependence());
- if (auto *ST = E->getScopeTypeInfo())
- D |= turnTypeToValueDependence(
- toExprDependenceAsWritten(ST->getType()->getDependence()));
- if (auto *Q = E->getQualifier())
- D |= toExprDependence(Q->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
- return D;
- }
- static inline ExprDependence getDependenceInExpr(DeclarationNameInfo Name) {
- auto D = ExprDependence::None;
- if (Name.isInstantiationDependent())
- D |= ExprDependence::Instantiation;
- if (Name.containsUnexpandedParameterPack())
- D |= ExprDependence::UnexpandedPack;
- return D;
- }
- ExprDependence
- clang::computeDependence(OverloadExpr *E, bool KnownDependent,
- bool KnownInstantiationDependent,
- bool KnownContainsUnexpandedParameterPack) {
- auto Deps = ExprDependence::None;
- if (KnownDependent)
- Deps |= ExprDependence::TypeValue;
- if (KnownInstantiationDependent)
- Deps |= ExprDependence::Instantiation;
- if (KnownContainsUnexpandedParameterPack)
- Deps |= ExprDependence::UnexpandedPack;
- Deps |= getDependenceInExpr(E->getNameInfo());
- if (auto *Q = E->getQualifier())
- Deps |= toExprDependence(Q->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
- for (auto *D : E->decls()) {
- if (D->getDeclContext()->isDependentContext() ||
- isa<UnresolvedUsingValueDecl>(D))
- Deps |= ExprDependence::TypeValueInstantiation;
- }
- // If we have explicit template arguments, check for dependent
- // template arguments and whether they contain any unexpanded pack
- // expansions.
- for (auto A : E->template_arguments())
- Deps |= toExprDependence(A.getArgument().getDependence());
- return Deps;
- }
- ExprDependence clang::computeDependence(DependentScopeDeclRefExpr *E) {
- auto D = ExprDependence::TypeValue;
- D |= getDependenceInExpr(E->getNameInfo());
- if (auto *Q = E->getQualifier())
- D |= toExprDependence(Q->getDependence());
- for (auto A : E->template_arguments())
- D |= toExprDependence(A.getArgument().getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(CXXConstructExpr *E) {
- ExprDependence D =
- toExprDependenceForImpliedType(E->getType()->getDependence());
- for (auto *A : E->arguments())
- D |= A->getDependence() & ~ExprDependence::Type;
- return D;
- }
- ExprDependence clang::computeDependence(CXXTemporaryObjectExpr *E) {
- CXXConstructExpr *BaseE = E;
- return toExprDependenceAsWritten(
- E->getTypeSourceInfo()->getType()->getDependence()) |
- computeDependence(BaseE);
- }
- ExprDependence clang::computeDependence(CXXDefaultInitExpr *E) {
- return E->getExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(CXXDefaultArgExpr *E) {
- return E->getExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(LambdaExpr *E,
- bool ContainsUnexpandedParameterPack) {
- auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
- if (ContainsUnexpandedParameterPack)
- D |= ExprDependence::UnexpandedPack;
- return D;
- }
- ExprDependence clang::computeDependence(CXXUnresolvedConstructExpr *E) {
- auto D = ExprDependence::ValueInstantiation;
- D |= toExprDependenceAsWritten(E->getTypeAsWritten()->getDependence());
- D |= toExprDependenceForImpliedType(E->getType()->getDependence());
- for (auto *A : E->arguments())
- D |= A->getDependence() &
- (ExprDependence::UnexpandedPack | ExprDependence::Error);
- return D;
- }
- ExprDependence clang::computeDependence(CXXDependentScopeMemberExpr *E) {
- auto D = ExprDependence::TypeValueInstantiation;
- if (!E->isImplicitAccess())
- D |= E->getBase()->getDependence();
- if (auto *Q = E->getQualifier())
- D |= toExprDependence(Q->getDependence());
- D |= getDependenceInExpr(E->getMemberNameInfo());
- for (auto A : E->template_arguments())
- D |= toExprDependence(A.getArgument().getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(MaterializeTemporaryExpr *E) {
- return E->getSubExpr()->getDependence();
- }
- ExprDependence clang::computeDependence(CXXFoldExpr *E) {
- auto D = ExprDependence::TypeValueInstantiation;
- for (const auto *C : {E->getLHS(), E->getRHS()}) {
- if (C)
- D |= C->getDependence() & ~ExprDependence::UnexpandedPack;
- }
- return D;
- }
- ExprDependence clang::computeDependence(CXXParenListInitExpr *E) {
- auto D = ExprDependence::None;
- for (const auto *A : E->getInitExprs())
- D |= A->getDependence();
- return D;
- }
- ExprDependence clang::computeDependence(TypeTraitExpr *E) {
- auto D = ExprDependence::None;
- for (const auto *A : E->getArgs())
- D |= toExprDependenceAsWritten(A->getType()->getDependence()) &
- ~ExprDependence::Type;
- return D;
- }
- ExprDependence clang::computeDependence(ConceptSpecializationExpr *E,
- bool ValueDependent) {
- auto TA = TemplateArgumentDependence::None;
- const auto InterestingDeps = TemplateArgumentDependence::Instantiation |
- TemplateArgumentDependence::UnexpandedPack;
- for (const TemplateArgumentLoc &ArgLoc :
- E->getTemplateArgsAsWritten()->arguments()) {
- TA |= ArgLoc.getArgument().getDependence() & InterestingDeps;
- if (TA == InterestingDeps)
- break;
- }
- ExprDependence D =
- ValueDependent ? ExprDependence::Value : ExprDependence::None;
- auto Res = D | toExprDependence(TA);
- if(!ValueDependent && E->getSatisfaction().ContainsErrors)
- Res |= ExprDependence::Error;
- return Res;
- }
- ExprDependence clang::computeDependence(ObjCArrayLiteral *E) {
- auto D = ExprDependence::None;
- Expr **Elements = E->getElements();
- for (unsigned I = 0, N = E->getNumElements(); I != N; ++I)
- D |= turnTypeToValueDependence(Elements[I]->getDependence());
- return D;
- }
- ExprDependence clang::computeDependence(ObjCDictionaryLiteral *E) {
- auto Deps = ExprDependence::None;
- for (unsigned I = 0, N = E->getNumElements(); I < N; ++I) {
- auto KV = E->getKeyValueElement(I);
- auto KVDeps = turnTypeToValueDependence(KV.Key->getDependence() |
- KV.Value->getDependence());
- if (KV.EllipsisLoc.isValid())
- KVDeps &= ~ExprDependence::UnexpandedPack;
- Deps |= KVDeps;
- }
- return Deps;
- }
- ExprDependence clang::computeDependence(ObjCMessageExpr *E) {
- auto D = ExprDependence::None;
- if (auto *R = E->getInstanceReceiver())
- D |= R->getDependence();
- else
- D |= toExprDependenceForImpliedType(E->getType()->getDependence());
- for (auto *A : E->arguments())
- D |= A->getDependence();
- return D;
- }
|