diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/clang14/lib/AST/ComputeDependence.cpp | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/clang14/lib/AST/ComputeDependence.cpp')
-rw-r--r-- | contrib/libs/clang14/lib/AST/ComputeDependence.cpp | 852 |
1 files changed, 852 insertions, 0 deletions
diff --git a/contrib/libs/clang14/lib/AST/ComputeDependence.cpp b/contrib/libs/clang14/lib/AST/ComputeDependence.cpp new file mode 100644 index 0000000000..5648cf2103 --- /dev/null +++ b/contrib/libs/clang14/lib/AST/ComputeDependence.cpp @@ -0,0 +1,852 @@ +//===- 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 = toExprDependence(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 = toExprDependence(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( + toExprDependence(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 toExprDependence(E->getTypeSourceInfo()->getType()->getDependence()) | + turnTypeToValueDependence(E->getInitializer()->getDependence()); +} + +ExprDependence clang::computeDependence(CastExpr *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. + auto D = toExprDependence(E->getType()->getDependence()); + if (E->getStmtClass() == Stmt::ImplicitCastExprClass) { + // An implicit cast expression doesn't (lexically) contain an + // unexpanded pack, even if its target type does. + D &= ~ExprDependence::UnexpandedPack; + } + 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 = toExprDependence(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 = toExprDependence(E->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 = + toExprDependence(E->getWrittenTypeInfo()->getType()->getDependence()) | + (E->getSubExpr()->getDependence() & ~ExprDependence::Type); + return D & ~ExprDependence::Value; +} + +ExprDependence clang::computeDependence(NoInitExpr *E) { + return toExprDependence(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 toExprDependence(E->getType()->getDependence()) & + ExprDependence::Instantiation; +} + +ExprDependence clang::computeDependence(ExtVectorElementExpr *E) { + return E->getBase()->getDependence(); +} + +ExprDependence clang::computeDependence(BlockExpr *E) { + auto D = toExprDependence(E->getType()->getDependence()); + if (E->getBlockDecl()->isDependentContext()) + D |= ExprDependence::Instantiation; + return D & ~ExprDependence::UnexpandedPack; +} + +ExprDependence clang::computeDependence(AsTypeExpr *E) { + auto D = toExprDependence(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 |= toExprDependence(E->getType()->getDependence()) & + (ExprDependence::Type | ExprDependence::Error); + return D; +} + +ExprDependence clang::computeDependence(CXXTypeidExpr *E) { + auto D = ExprDependence::None; + if (E->isTypeOperand()) + D = toExprDependence( + 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(toExprDependence( + 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 = toExprDependence(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) { + return toExprDependence(E->getType()->getDependence()) & + ~ExprDependence::TypeValue; +} + +ExprDependence clang::computeDependence(CXXDeleteExpr *E) { + return turnTypeToValueDependence(E->getArgument()->getDependence()); +} + +ExprDependence clang::computeDependence(ArrayTypeTraitExpr *E) { + auto D = toExprDependence(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 toExprDependence(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 toExprDependence(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() | + toExprDependence(E->getType()->getDependence()); + for (Expr *Dim: E->getDimensions()) + if (Dim) + D |= Dim->getDependence(); + return D; +} + +ExprDependence clang::computeDependence(OMPIteratorExpr *E) { + auto D = toExprDependence(E->getType()->getDependence()); + for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { + if (auto *VD = cast_or_null<ValueDecl>(E->getIteratorDecl(I))) + D |= toExprDependence(VD->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 |= toExprDependence(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 = toExprDependence(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 toExprDependence(E->getTypeSourceInfo()->getType()->getDependence()); +} + +ExprDependence clang::computeDependence(PredefinedExpr *E) { + return toExprDependence(E->getType()->getDependence()) & + ~ExprDependence::UnexpandedPack; +} + +ExprDependence clang::computeDependence(CallExpr *E, + llvm::ArrayRef<Expr *> PreArgs) { + auto D = E->getCallee()->getDependence(); + for (auto *A : llvm::makeArrayRef(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( + toExprDependence(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 = toExprDependence(E->getType()->getDependence()); + for (auto *C : llvm::makeArrayRef(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::makeArrayRef(A->getSubExprs(), A->getNumSubExprs())) + D |= E->getDependence(); + return D; +} + +ExprDependence clang::computeDependence(CXXNewExpr *E) { + auto D = toExprDependence(E->getType()->getDependence()); + auto Size = E->getArraySize(); + if (Size.hasValue() && *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 (!E->getDestroyedType().isNull()) + D |= toExprDependence(E->getDestroyedType()->getDependence()); + if (auto *ST = E->getScopeTypeInfo()) + D |= turnTypeToValueDependence( + toExprDependence(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) { + auto D = toExprDependence(E->getType()->getDependence()); + for (auto *A : E->arguments()) + D |= A->getDependence() & ~ExprDependence::Type; + return D; +} + +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 = toExprDependence(E->getType()->getDependence()); + if (ContainsUnexpandedParameterPack) + D |= ExprDependence::UnexpandedPack; + return D; +} + +ExprDependence clang::computeDependence(CXXUnresolvedConstructExpr *E) { + auto D = ExprDependence::ValueInstantiation; + D |= toExprDependence(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(TypeTraitExpr *E) { + auto D = ExprDependence::None; + for (const auto *A : E->getArgs()) + D |= + toExprDependence(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; + return D | toExprDependence(TA); +} + +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 |= toExprDependence(E->getType()->getDependence()); + for (auto *A : E->arguments()) + D |= A->getDependence(); + return D; +} |