From: Douglas Gregor Date: Mon, 23 Nov 2009 11:41:28 +0000 (+0000) Subject: Centralize and complete the computation of value- and type-dependence for DeclRefExprs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0da76df9218d7c27b471b0a4d83a5b29fe24e5b4;p=clang Centralize and complete the computation of value- and type-dependence for DeclRefExprs git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89649 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 47404fa7bf..4b13c556cb 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -429,26 +429,23 @@ class DeclRefExpr : public Expr { DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, NamedDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, - QualType T, bool TD, bool VD); + QualType T); protected: - // FIXME: Eventually, this constructor will go away and all subclasses - // will have to provide the type- and value-dependent flags. - DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) : - Expr(SC, t), DecoratedD(d, 0), Loc(l) {} + /// \brief Computes the type- and value-dependence flags for this + /// declaration reference expression. + void computeDependence(); - DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD, - bool VD) : - Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {} + DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) : + Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) { + computeDependence(); + } public: - // FIXME: Eventually, this constructor will go away and all clients - // will have to provide the type- and value-dependent flags. DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) : - Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {} - - DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) : - Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {} + Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) { + computeDependence(); + } /// \brief Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) @@ -459,15 +456,8 @@ public: SourceRange QualifierRange, NamedDecl *D, SourceLocation NameLoc, - QualType T, bool TD, bool VD); - - static DeclRefExpr *Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - NamedDecl *D, - SourceLocation NameLoc, - const TemplateArgumentListInfo *TemplateArgs, - QualType T, bool TD, bool VD); + QualType T, + const TemplateArgumentListInfo *TemplateArgs = 0); NamedDecl *getDecl() { return DecoratedD.getPointer(); } const NamedDecl *getDecl() const { return DecoratedD.getPointer(); } diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 055926f03d..4823c0bca4 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -681,10 +681,7 @@ public: CXXConditionDeclExpr(SourceLocation startLoc, SourceLocation eqLoc, VarDecl *var) : DeclRefExpr(CXXConditionDeclExprClass, var, - var->getType().getNonReferenceType(), startLoc, - var->getType()->isDependentType(), - /*FIXME:integral constant?*/ - var->getType()->isDependentType()) {} + var->getType().getNonReferenceType(), startLoc) {} SourceLocation getStartLoc() const { return getLocation(); } diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 2d2851036c..902339e1ef 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -214,9 +214,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*Param)) { Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), - NTTP->getLocation(), - NTTP->getType()->isDependentType(), - /*Value-dependent=*/true); + NTTP->getLocation()); TemplateArgs.push_back(TemplateArgument(E)); } else { TemplateTemplateParmDecl *TTP = cast(*Param); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 61492694fc..7c80f04be2 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -56,12 +56,64 @@ std::size_t ExplicitTemplateArgumentList::sizeFor( sizeof(TemplateArgumentLoc) * Info.size(); } +void DeclRefExpr::computeDependence() { + TypeDependent = false; + ValueDependent = false; + + NamedDecl *D = getDecl(); + + // (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: + + // (TD) - an identifier that was declared with dependent type + // (VD) - a name declared with a dependent type, + if (getType()->isDependentType()) { + TypeDependent = true; + ValueDependent = true; + } + // (TD) - a conversion-function-id that specifies a dependent type + else if (D->getDeclName().getNameKind() + == DeclarationName::CXXConversionFunctionName && + D->getDeclName().getCXXNameType()->isDependentType()) { + TypeDependent = true; + ValueDependent = true; + } + // (TD) - a template-id that is dependent, + else if (hasExplicitTemplateArgumentList() && + TemplateSpecializationType::anyDependentTemplateArguments( + getTemplateArgs(), + getNumTemplateArgs())) { + TypeDependent = true; + ValueDependent = true; + } + // (VD) - the name of a non-type template parameter, + else if (isa(D)) + ValueDependent = true; + // (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 (Var->getType()->isIntegralType() && + Var->getType().getCVRQualifiers() == Qualifiers::Const && + Var->getInit() && + Var->getInit()->isValueDependent()) + ValueDependent = true; + } + // (TD) - a nested-name-specifier or a qualified-id that names a + // member of an unknown specialization. + // (handled by DependentScopeDeclRefExpr) +} + DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, NamedDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, - QualType T, bool TD, bool VD) - : Expr(DeclRefExprClass, T, TD, VD), + QualType T) + : Expr(DeclRefExprClass, T, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -75,16 +127,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, if (TemplateArgs) getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs); -} -DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - NamedDecl *D, - SourceLocation NameLoc, - QualType T, bool TD, bool VD) { - return Create(Context, Qualifier, QualifierRange, D, NameLoc, - /*TemplateArgs*/ 0, T, TD, VD); + computeDependence(); } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, @@ -92,8 +136,8 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, SourceRange QualifierRange, NamedDecl *D, SourceLocation NameLoc, - const TemplateArgumentListInfo *TemplateArgs, - QualType T, bool TD, bool VD) { + QualType T, + const TemplateArgumentListInfo *TemplateArgs) { std::size_t Size = sizeof(DeclRefExpr); if (Qualifier != 0) Size += sizeof(NameQualifier); @@ -103,7 +147,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, void *Mem = Context.Allocate(Size, llvm::alignof()); return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc, - TemplateArgs, T, TD, VD); + TemplateArgs, T); } SourceRange DeclRefExpr::getSourceRange() const { diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index bc9eb67674..e989e4a9b7 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -297,8 +297,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { continue; } else E = new (getContext()) DeclRefExpr (cast(VD), - VD->getType(), SourceLocation(), - false, false); + VD->getType(), + SourceLocation()); } if (BDRE->isByRef()) { NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF | @@ -836,7 +836,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { 0, QualType(PadTy), 0, VarDecl::None); Expr *E; E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(), - SourceLocation(), false, false); + SourceLocation()); BlockDeclRefDecls.push_back(E); } BlockDeclRefDecls.push_back(BDRE); diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 06955e5c30..710fa55b69 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -2627,7 +2627,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); IdentifierInfo *ID = &Context->Idents.get(Name); VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - ID, QualType()/*UNUSED*/, 0, VarDecl::Extern); + ID, getProtocolType(), 0, VarDecl::Extern); DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation()); Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf, Context->getPointerType(DRE->getType()), diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 472efc48cb..cff346b9df 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1391,8 +1391,7 @@ public: bool IsAddressOfOperand); OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty, - SourceLocation Loc, bool TypeDependent, - bool ValueDependent, + SourceLocation Loc, const CXXScopeSpec *SS = 0); VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field, llvm::SmallVectorImpl &Path); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 42b49c5d0b..1506fbaf60 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -415,7 +415,6 @@ static bool ShouldSnapshotBlockValueReference(BlockSemaInfo *CurBlock, /// BuildDeclRefExpr - Build a DeclRefExpr. Sema::OwningExprResult Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc, - bool TypeDependent, bool ValueDependent, const CXXScopeSpec *SS) { assert(!isa(D)); @@ -445,8 +444,7 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc, return Owned(DeclRefExpr::Create(Context, SS? (NestedNameSpecifier *)SS->getScopeRep() : 0, SS? SS->getRange() : SourceRange(), - D, Loc, - Ty, TypeDependent, ValueDependent)); + D, Loc, Ty)); } /// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or @@ -842,7 +840,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, QualType NoProtoType = T; if (const FunctionProtoType *Proto = T->getAs()) NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType()); - return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS); + return BuildDeclRefExpr(Func, NoProtoType, Loc, SS); } } @@ -1139,56 +1137,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS, // If this reference is not in a block or if the referenced variable is // within the block, create a normal DeclRefExpr. - bool TypeDependent = false; - bool ValueDependent = false; - if (getLangOptions().CPlusPlus) { - // C++ [temp.dep.expr]p3: - // An id-expression is type-dependent if it contains: - // - an identifier that was declared with a dependent type, - if (VD->getType()->isDependentType()) - TypeDependent = true; - // - FIXME: a template-id that is dependent, - // - a conversion-function-id that specifies a dependent type, - else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName && - Name.getCXXNameType()->isDependentType()) - TypeDependent = true; - // - a nested-name-specifier that contains a class-name that - // names a dependent type. - else { - for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) { - // FIXME: could stop early at namespace scope. - if (DC->isRecord()) { - CXXRecordDecl *Record = cast(DC); - if (Context.getTypeDeclType(Record)->isDependentType()) { - TypeDependent = true; - break; - } - } - } - } - - // C++ [temp.dep.constexpr]p2: - // - // An identifier is value-dependent if it is: - // - a name declared with a dependent type, - if (TypeDependent) - ValueDependent = true; - // - the name of a non-type template parameter, - else if (isa(VD)) - ValueDependent = true; - // - a constant with integral or enumeration type and is - // initialized with an expression that is value-dependent - else if (const VarDecl *Dcl = dyn_cast(VD)) { - if (Context.getCanonicalType(Dcl->getType()).getCVRQualifiers() - == Qualifiers::Const && - Dcl->getInit()) { - ValueDependent = Dcl->getInit()->isValueDependent(); - } - } - } - - return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, - TypeDependent, ValueDependent, SS); + return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, SS); } Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 591144d81d..8a009e57f6 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5647,11 +5647,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { DRE->getQualifierRange(), Fn, DRE->getLocation(), - (DRE->hasExplicitTemplateArgumentList() - ? &TemplateArgs : 0), Fn->getType(), - DRE->isTypeDependent(), - DRE->isValueDependent()); + (DRE->hasExplicitTemplateArgumentList() + ? &TemplateArgs : 0)); } if (UnresolvedLookupExpr *ULE = dyn_cast(E)) { @@ -5660,9 +5658,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { ULE->getQualifierRange(), Fn, ULE->getNameLoc(), - Fn->getType(), - Fn->getType()->isDependentType(), - false); + Fn->getType()); } @@ -5699,9 +5695,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { return DeclRefExpr::Create(Context, TID->getQualifier(), TID->getQualifierRange(), Fn, TID->getTemplateNameLoc(), - &TemplateArgs, - Fn->getType(), - /*FIXME?*/false, /*FIXME?*/false); + Fn->getType(), + &TemplateArgs); } assert(false && "Invalid reference to overloaded function"); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 3c5c239739..502c151f4e 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -790,7 +790,6 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, = SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), E->getLocation(), - /*FIXME:*/false, /*FIXME:*/false, &SS); if (RefExpr.isInvalid()) return SemaRef.ExprError(); @@ -802,8 +801,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, } return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), - E->getLocation(), - /*FIXME:*/false, /*FIXME:*/false); + E->getLocation()); } assert(Arg.getKind() == TemplateArgument::Integral); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index dcc0d184a1..ecac31a3e7 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1643,7 +1643,7 @@ public: FunctionDecl *Builtin = cast(*Lookup.first); Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(), - BuiltinLoc, false, false); + BuiltinLoc); SemaRef.UsualUnaryConversions(Callee); // Build the CallExpr