From: Douglas Gregor Date: Wed, 19 Jan 2011 21:52:31 +0000 (+0000) Subject: Refactor the dependence computation for DeclRefExpr so that we can X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d967e31ee796efff24b84b704a063634f6b55627;p=clang Refactor the dependence computation for DeclRefExpr so that we can reuse it for BlockDeclRefExpr. Do so, fixing the dependence calculate for BlockDeclRefExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123851 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 48871f5325..f68f78bd44 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -143,6 +143,7 @@ protected: friend class DeclRefExpr; // computeDependence friend class InitListExpr; // ctor friend class DesignatedInitExpr; // ctor + friend class BlockDeclRefExpr; // ctor friend class ASTStmtReader; // deserialization friend class CXXNewExpr; // ctor friend class DependentScopeDeclRefExpr; // ctor diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 9dc790256e..c45fe3497d 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -145,11 +145,14 @@ std::size_t ExplicitTemplateArgumentList::sizeFor( return sizeFor(Info.size()); } -void DeclRefExpr::computeDependence() { - ExprBits.TypeDependent = false; - ExprBits.ValueDependent = false; +/// \brief Compute the type- and value-dependence of a declaration reference +/// based on the declaration being referenced. +static void computeDeclRefDependence(NamedDecl *D, QualType T, + bool &TypeDependent, + bool &ValueDependent) { + TypeDependent = false; + ValueDependent = false; - NamedDecl *D = getDecl(); // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -158,60 +161,84 @@ void DeclRefExpr::computeDependence() { // // (VD) C++ [temp.dep.constexpr]p2: // An identifier is value-dependent if it is: - + // (TD) - an identifier that was declared with dependent type // (VD) - a name declared with a dependent type, - if (getType()->isDependentType()) { - ExprBits.TypeDependent = true; - ExprBits.ValueDependent = true; + if (T->isDependentType()) { + TypeDependent = true; + ValueDependent = true; + return; } + // (TD) - a conversion-function-id that specifies a dependent type - else if (D->getDeclName().getNameKind() - == DeclarationName::CXXConversionFunctionName && + if (D->getDeclName().getNameKind() + == DeclarationName::CXXConversionFunctionName && D->getDeclName().getCXXNameType()->isDependentType()) { - ExprBits.TypeDependent = true; - ExprBits.ValueDependent = true; - } - // (TD) - a template-id that is dependent, - else if (hasExplicitTemplateArgs() && - TemplateSpecializationType::anyDependentTemplateArguments( - getTemplateArgs(), - getNumTemplateArgs())) { - ExprBits.TypeDependent = true; - ExprBits.ValueDependent = true; + TypeDependent = true; + ValueDependent = true; + return; } // (VD) - the name of a non-type template parameter, - else if (isa(D)) - ExprBits.ValueDependent = true; + if (isa(D)) { + ValueDependent = true; + return; + } + // (VD) - a constant with integral or enumeration type and is // initialized with an expression that is value-dependent. - else if (VarDecl *Var = dyn_cast(D)) { + if (VarDecl *Var = dyn_cast(D)) { if (Var->getType()->isIntegralOrEnumerationType() && Var->getType().getCVRQualifiers() == Qualifiers::Const) { if (const Expr *Init = Var->getAnyInitializer()) if (Init->isValueDependent()) - ExprBits.ValueDependent = true; + ValueDependent = true; } + // (VD) - FIXME: Missing from the standard: // - a member function or a static data member of the current // instantiation else if (Var->isStaticDataMember() && Var->getDeclContext()->isDependentContext()) - ExprBits.ValueDependent = true; - } + ValueDependent = true; + + return; + } + // (VD) - FIXME: Missing from the standard: // - a member function or a static data member of the current // instantiation - else if (isa(D) && D->getDeclContext()->isDependentContext()) - ExprBits.ValueDependent = true; - // (TD) - a nested-name-specifier or a qualified-id that names a - // member of an unknown specialization. - // (handled by DependentScopeDeclRefExpr) - - // Determine whether this expression contains any unexpanded parameter - // packs. + if (isa(D) && D->getDeclContext()->isDependentContext()) { + ValueDependent = true; + return; + } +} + +void DeclRefExpr::computeDependence() { + bool TypeDependent = false; + bool ValueDependent = false; + computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent); + + // (TD) C++ [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains: + // + // and + // + // (VD) C++ [temp.dep.constexpr]p2: + // An identifier is value-dependent if it is: + if (!TypeDependent && !ValueDependent && + hasExplicitTemplateArgs() && + TemplateSpecializationType::anyDependentTemplateArguments( + getTemplateArgs(), + getNumTemplateArgs())) { + TypeDependent = true; + ValueDependent = true; + } + + ExprBits.TypeDependent = TypeDependent; + ExprBits.ValueDependent = ValueDependent; + // Is the declaration a parameter pack? - if (D->isParameterPack()) + if (getDecl()->isParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; } @@ -2935,13 +2962,16 @@ Stmt::child_iterator ObjCMessageExpr::child_end() { BlockDeclRefExpr::BlockDeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l, bool ByRef, bool constAdded, Stmt *copyConstructorVal) - : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, - (!t.isNull() && t->isDependentType()), false, + : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, d->isParameterPack()), D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded), CopyConstructorVal(copyConstructorVal) { - // FIXME: Compute type/value dependence. + bool TypeDependent = false; + bool ValueDependent = false; + computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent); + ExprBits.TypeDependent = TypeDependent; + ExprBits.ValueDependent = ValueDependent; } Stmt::child_iterator BlockExpr::child_begin() { return child_iterator(); } diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm index d3f4d9823c..0108ed4f90 100644 --- a/test/SemaObjCXX/blocks.mm +++ b/test/SemaObjCXX/blocks.mm @@ -94,3 +94,13 @@ namespace N2 { } template void test2<2>(); } + +// Handle value-dependent block declaration references. +namespace N3 { + template struct X { }; + + template + void f() { + X xN = ^() { return X(); }(); + } +}