diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index e54719b33d..bb098313ea 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -492,6 +492,9 @@ public: LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding(); } + /// \brief Determine whether this name involves a template parameter. + bool isInstantiationDependent() const; + /// \brief Determine whether this name contains an unexpanded /// parameter pack. bool containsUnexpandedParameterPack() const; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 09ffc1a4bf..66caa4af57 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -57,9 +57,12 @@ class Expr : public Stmt { protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, bool ContainsUnexpandedParameterPack) : Stmt(SC) { + bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) + : Stmt(SC) + { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; + ExprBits.InstantiationDependent = ID; ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; @@ -95,7 +98,11 @@ public: bool isValueDependent() const { return ExprBits.ValueDependent; } /// \brief Set whether this expression is value-dependent or not. - void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; } + void setValueDependent(bool VD) { + ExprBits.ValueDependent = VD; + if (VD) + ExprBits.InstantiationDependent = true; + } /// isTypeDependent - Determines whether this expression is /// type-dependent (C++ [temp.dep.expr]), which means that its type @@ -111,7 +118,37 @@ public: bool isTypeDependent() const { return ExprBits.TypeDependent; } /// \brief Set whether this expression is type-dependent or not. - void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; } + void setTypeDependent(bool TD) { + ExprBits.TypeDependent = TD; + if (TD) + ExprBits.InstantiationDependent = true; + } + + /// \brief Whether this expression is instantiation-dependent, meaning that + /// it depends in some way on a template parameter, even if neither its type + /// nor (constant) value can change due to the template instantiation. + /// + /// In the following example, the expression \c sizeof(sizeof(T() + T())) is + /// instantiation-dependent (since it involves a template parameter \c T), but + /// is neither type- nor value-dependent, since the type of the inner + /// \c sizeof is known (\c std::size_t) and therefore the size of the outer + /// \c sizeof is known. + /// + /// \code + /// template + /// void f(T x, T y) { + /// sizeof(sizeof(T() + T()); + /// } + /// \endcode + /// + bool isInstantiationDependent() const { + return ExprBits.InstantiationDependent; + } + + /// \brief Set whether this expression is instantiation-dependent or not. + void setInstantiationDependent(bool ID) { + ExprBits.InstantiationDependent = ID; + } /// \brief Whether this expression contains an unexpanded parameter /// pack (for C++0x variadic templates). @@ -595,7 +632,9 @@ public: OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK, ExprObjectKind OK = OK_Ordinary) : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType(), T->isDependentType(), false), + T->isDependentType(), T->isDependentType(), + T->isInstantiationDependentType(), + false), SourceExpr(0), Loc(Loc) { } @@ -664,7 +703,8 @@ struct ExplicitTemplateArgumentList { void initializeFrom(const TemplateArgumentListInfo &List); void initializeFrom(const TemplateArgumentListInfo &List, - bool &Dependent, bool &ContainsUnexpandedParameterPack); + bool &Dependent, bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack); void copyInto(TemplateArgumentListInfo &List) const; static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(const TemplateArgumentListInfo &List); @@ -747,7 +787,7 @@ class DeclRefExpr : public Expr { public: DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), Loc(L) { DeclRefExprBits.HasQualifier = 0; DeclRefExprBits.HasExplicitTemplateArgs = 0; @@ -936,6 +976,7 @@ public: PredefinedExpr(SourceLocation l, QualType type, IdentType IT) : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary, type->isDependentType(), type->isDependentType(), + type->isInstantiationDependentType(), /*ContainsUnexpandedParameterPack=*/false), Loc(l), Type(IT) {} @@ -1023,7 +1064,7 @@ public: IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l) : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); assert(V.getBitWidth() == C.getIntWidth(type) && @@ -1066,7 +1107,7 @@ public: // type should be IntTy CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l) : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Value(value), Loc(l), IsWide(iswide) { } @@ -1101,7 +1142,7 @@ class FloatingLiteral : public Expr { FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, - false), + false, false), IsExact(isexact), Loc(L) { setValue(C, V); } @@ -1152,7 +1193,7 @@ class ImaginaryLiteral : public Expr { public: ImaginaryLiteral(Expr *val, QualType Ty) : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Val(val) {} /// \brief Build an empty imaginary literal. @@ -1200,7 +1241,8 @@ class StringLiteral : public Expr { SourceLocation TokLocs[1]; StringLiteral(QualType Ty) : - Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false) {} + Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false, + false) {} public: /// This is the "fully general" constructor that allows representation of @@ -1287,6 +1329,7 @@ public: : Expr(ParenExprClass, val->getType(), val->getValueKind(), val->getObjectKind(), val->isTypeDependent(), val->isValueDependent(), + val->isInstantiationDependent(), val->containsUnexpandedParameterPack()), L(l), R(r), Val(val) {} @@ -1343,6 +1386,8 @@ public: : Expr(UnaryOperatorClass, type, VK, OK, input->isTypeDependent() || type->isDependentType(), input->isValueDependent(), + (input->isInstantiationDependent() || + type->isInstantiationDependentType()), input->containsUnexpandedParameterPack()), Opc(opc), Loc(l), Val(input) {} @@ -1638,6 +1683,7 @@ public: false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. TInfo->getType()->isDependentType(), + TInfo->getType()->isInstantiationDependentType(), TInfo->getType()->containsUnexpandedParameterPack()), Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) { Argument.Ty = TInfo; @@ -1650,6 +1696,7 @@ public: false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. E->isTypeDependent(), + E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) { Argument.Ex = E; @@ -1727,6 +1774,8 @@ public: : Expr(ArraySubscriptExprClass, t, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), RBracketLoc(rbracketloc) { @@ -1984,7 +2033,9 @@ public: const DeclarationNameInfo &NameInfo, QualType ty, ExprValueKind VK, ExprObjectKind OK) : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), base->isValueDependent(), + base->isTypeDependent(), + base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), @@ -2001,6 +2052,7 @@ public: ExprValueKind VK, ExprObjectKind OK) : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), @@ -2186,6 +2238,8 @@ public: : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, tinfo->getType()->isDependentType(), init->isValueDependent(), + (init->isInstantiationDependent() || + tinfo->getType()->isInstantiationDependentType()), init->containsUnexpandedParameterPack()), LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} @@ -2318,6 +2372,8 @@ protected: // Cast expressions are value-dependent if the type is // dependent or if the subexpression is value-dependent. ty->isDependentType() || (op && op->isValueDependent()), + (ty->isInstantiationDependentType() || + (op && op->isInstantiationDependent())), (ty->containsUnexpandedParameterPack() || op->containsUnexpandedParameterPack())), Op(op) { @@ -2551,6 +2607,8 @@ public: : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { @@ -2653,6 +2711,8 @@ protected: : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { @@ -2713,11 +2773,11 @@ class AbstractConditionalOperator : public Expr { protected: AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, + bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack, SourceLocation qloc, SourceLocation cloc) - : Expr(SC, T, VK, OK, TD, VD, ContainsUnexpandedParameterPack), + : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack), QuestionLoc(qloc), ColonLoc(cloc) {} AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) @@ -2765,6 +2825,9 @@ public: (lhs->isTypeDependent() || rhs->isTypeDependent()), (cond->isValueDependent() || lhs->isValueDependent() || rhs->isValueDependent()), + (cond->isInstantiationDependent() || + lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (cond->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack()), @@ -2833,6 +2896,8 @@ public: : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, (common->isTypeDependent() || rhs->isTypeDependent()), (common->isValueDependent() || rhs->isValueDependent()), + (common->isInstantiationDependent() || + rhs->isInstantiationDependent()), (common->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack()), qloc, cloc), @@ -2914,7 +2979,8 @@ class AddrLabelExpr : public Expr { public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, QualType t) - : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false), + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false, + false), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} /// \brief Build an empty address of a label expression. @@ -2953,10 +3019,12 @@ class StmtExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: // FIXME: Does type-dependence need to be computed differently? + // FIXME: Do we need to compute instantiation instantiation-dependence for + // statements? (ugh!) StmtExpr(CompoundStmt *substmt, QualType T, SourceLocation lp, SourceLocation rp) : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, - T->isDependentType(), false, false), + T->isDependentType(), false, false, false), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } /// \brief Build an empty statement expression. @@ -3073,6 +3141,9 @@ public: QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool TypeDependent, bool ValueDependent) : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, + (cond->isInstantiationDependent() || + lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (cond->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), @@ -3134,7 +3205,8 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false), + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false, + false), TokenLoc(Loc) { } /// \brief Build an empty GNU __null expression. @@ -3166,6 +3238,8 @@ public: SourceLocation RPLoc, QualType t) : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(), false, + (TInfo->getType()->isInstantiationDependentType() || + e->isInstantiationDependent()), (TInfo->getType()->containsUnexpandedParameterPack() || e->containsUnexpandedParameterPack())), Val(e), TInfo(TInfo), @@ -3723,7 +3797,7 @@ class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, false) { } + false, false, ty->isInstantiationDependentType(), false) { } /// \brief Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -3924,6 +3998,7 @@ public: : Expr(ExtVectorElementExprClass, ty, VK, (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), base->isTypeDependent(), base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), Accessor(&accessor), AccessorLoc(loc) {} @@ -3978,7 +4053,10 @@ protected: public: BlockExpr(BlockDecl *BD, QualType ty) : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, - ty->isDependentType(), false, false), + ty->isDependentType(), false, + // FIXME: Check for instantiate-dependence in the statement? + ty->isInstantiationDependentType(), + false), TheBlock(BD) {} /// \brief Build an empty block expression. @@ -4062,7 +4140,13 @@ public: AsTypeExpr(Expr* SrcExpr, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc) - : Expr(AsTypeExprClass, DstType, VK, OK, false, false, false), + : Expr(AsTypeExprClass, DstType, VK, OK, + DstType->isDependentType(), + DstType->isDependentType() || SrcExpr->isValueDependent(), + (DstType->isInstantiationDependentType() || + SrcExpr->isInstantiationDependent()), + (DstType->containsUnexpandedParameterPack() || + SrcExpr->containsUnexpandedParameterPack())), SrcExpr(SrcExpr), DstType(DstType), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 5cc5ee11a4..8f650f07be 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -330,7 +330,7 @@ class CXXBoolLiteralExpr : public Expr { public: CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Value(val), Loc(l) {} explicit CXXBoolLiteralExpr(EmptyShell Empty) @@ -359,7 +359,7 @@ class CXXNullPtrLiteralExpr : public Expr { public: CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Loc(l) {} explicit CXXNullPtrLiteralExpr(EmptyShell Empty) @@ -395,6 +395,7 @@ public: false, // typeid is value-dependent if the type or expression are dependent Operand->getType()->isDependentType(), + Operand->getType()->isInstantiationDependentType(), Operand->getType()->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } @@ -404,6 +405,7 @@ public: false, // typeid is value-dependent if the type or expression are dependent Operand->isTypeDependent() || Operand->isValueDependent(), + Operand->isInstantiationDependent(), Operand->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } @@ -471,12 +473,14 @@ public: CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, Operand->getType()->isDependentType(), + Operand->getType()->isInstantiationDependentType(), Operand->getType()->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, Operand->isTypeDependent(), + Operand->isInstantiationDependent(), Operand->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } @@ -552,6 +556,7 @@ public: // 'this' is type-dependent if the class type of the enclosing // member function is dependent (C++ [temp.dep.expr]p2) Type->isDependentType(), Type->isDependentType(), + Type->isInstantiationDependentType(), /*ContainsUnexpandedParameterPack=*/false), Loc(L), Implicit(isImplicit) { } @@ -587,6 +592,7 @@ public: // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + expr && expr->isInstantiationDependent(), expr && expr->containsUnexpandedParameterPack()), Op(expr), ThrowLoc(l) {} CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} @@ -636,14 +642,14 @@ class CXXDefaultArgExpr : public Expr { ? param->getType().getNonReferenceType() : param->getDefaultArg()->getType(), param->getDefaultArg()->getValueKind(), - param->getDefaultArg()->getObjectKind(), false, false, false), + param->getDefaultArg()->getObjectKind(), false, false, false, false), Param(param, false), Loc(Loc) { } CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, Expr *SubExpr) : Expr(SC, SubExpr->getType(), SubExpr->getValueKind(), SubExpr->getObjectKind(), - false, false, false), + false, false, false, false), Param(param, true), Loc(Loc) { *reinterpret_cast(this + 1) = SubExpr; } @@ -742,6 +748,7 @@ class CXXBindTemporaryExpr : public Expr { : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), SubExpr->isValueDependent(), + SubExpr->isInstantiationDependent(), SubExpr->containsUnexpandedParameterPack()), Temp(temp), SubExpr(SubExpr) { } @@ -995,7 +1002,7 @@ public: TypeSourceInfo *TypeInfo, SourceLocation rParenLoc ) : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, - false, false, false), + false, false, Type->isInstantiationDependentType(), false), RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} explicit CXXScalarValueInitExpr(EmptyShell Shell) @@ -1241,6 +1248,7 @@ public: bool arrayFormAsWritten, bool usualArrayDeleteWantsSize, FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, + arg->isInstantiationDependent(), arg->containsUnexpandedParameterPack()), GlobalDelete(globalDelete), ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), @@ -1500,6 +1508,7 @@ public: SourceLocation rparen, QualType ty) : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, queried->getType()->isDependentType(), + queried->getType()->isInstantiationDependentType(), queried->getType()->containsUnexpandedParameterPack()), UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { } @@ -1558,6 +1567,8 @@ public: : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, lhsType->getType()->isDependentType() || rhsType->getType()->isDependentType(), + (lhsType->getType()->isInstantiationDependentType() || + rhsType->getType()->isInstantiationDependentType()), (lhsType->getType()->containsUnexpandedParameterPack() || rhsType->getType()->containsUnexpandedParameterPack())), BTT(btt), Value(value), Loc(loc), RParen(rparen), @@ -1625,6 +1636,8 @@ public: Expr *dimension, SourceLocation rparen, QualType ty) : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, queried->getType()->isDependentType(), + (queried->getType()->isInstantiationDependentType() || + (dimension && dimension->isInstantiationDependent())), queried->getType()->containsUnexpandedParameterPack()), ATT(att), Value(value), Dimension(dimension), Loc(loc), RParen(rparen), QueriedType(queried) { } @@ -1684,6 +1697,7 @@ public: false, // Not type-dependent // Value-dependent if the argument is type-dependent. queried->isTypeDependent(), + queried->isInstantiationDependent(), queried->containsUnexpandedParameterPack()), ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { } @@ -1736,8 +1750,9 @@ protected: const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, - bool KnownDependent = false, - bool KnownContainsUnexpandedParameterPack = false); + bool KnownDependent, + bool KnownInstantiationDependent, + bool KnownContainsUnexpandedParameterPack); OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty), Results(0), NumResults(0), @@ -1880,7 +1895,7 @@ class UnresolvedLookupExpr : public OverloadExpr { UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool StdIsAssociatedNamespace) : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo, - TemplateArgs, Begin, End), + TemplateArgs, Begin, End, false, false, false), RequiresADL(RequiresADL), StdIsAssociatedNamespace(StdIsAssociatedNamespace), Overloaded(Overloaded), NamingClass(NamingClass) @@ -2727,6 +2742,7 @@ public: : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, /*TypeDependent*/false, /*ValueDependent*/Val == CT_Dependent, + Val == CT_Dependent || Operand->isInstantiationDependent(), Operand->containsUnexpandedParameterPack()), Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) { } @@ -2787,7 +2803,8 @@ public: llvm::Optional NumExpansions) : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), Pattern->getObjectKind(), /*TypeDependent=*/true, - /*ValueDependent=*/true, /*ContainsUnexpandedParameterPack=*/false), + /*ValueDependent=*/true, /*InstantiationDependent=*/true, + /*ContainsUnexpandedParameterPack=*/false), EllipsisLoc(EllipsisLoc), NumExpansions(NumExpansions? *NumExpansions + 1 : 0), Pattern(Pattern) { } @@ -2874,6 +2891,7 @@ public: SourceLocation PackLoc, SourceLocation RParenLoc) : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/true, + /*InstantiationDependent=*/true, /*ContainsUnexpandedParameterPack=*/false), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(0), Pack(Pack) { } @@ -2885,6 +2903,7 @@ public: unsigned Length) : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/false, + /*InstantiationDependent=*/false, /*ContainsUnexpandedParameterPack=*/false), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(Length), Pack(Pack) { } @@ -3018,6 +3037,7 @@ public: : Expr(MaterializeTemporaryExprClass, T, BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, Temporary->isTypeDependent(), Temporary->isValueDependent(), + Temporary->isInstantiationDependent(), Temporary->containsUnexpandedParameterPack()), Temporary(Temporary) { } diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 472a7efcda..49d4cfe676 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -30,7 +30,7 @@ class ObjCStringLiteral : public Expr { public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, - false), + false, false), String(SL), AtLoc(L) {} explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} @@ -67,6 +67,7 @@ public: : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, EncodedType->getType()->isDependentType(), EncodedType->getType()->isDependentType(), + EncodedType->getType()->isInstantiationDependentType(), EncodedType->getType()->containsUnexpandedParameterPack()), EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} @@ -106,7 +107,7 @@ public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, - false), + false, false), SelName(selInfo), AtLoc(at), RParenLoc(rp){} explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} @@ -146,7 +147,7 @@ public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, - false), + false, false), TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} @@ -186,6 +187,7 @@ public: bool arrow = false, bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} @@ -248,6 +250,7 @@ public: SourceLocation l, Expr *base) : Expr(ObjCPropertyRefExprClass, t, VK, OK, /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), PropertyOrGetter(PD, false), Setter(0), IdLoc(l), ReceiverLoc(), Receiver(base) { @@ -257,7 +260,7 @@ public: ExprValueKind VK, ExprObjectKind OK, SourceLocation l, SourceLocation sl, QualType st) : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false, + /*TypeDependent=*/false, false, st->isInstantiationDependentType(), st->containsUnexpandedParameterPack()), PropertyOrGetter(PD, false), Setter(0), IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { @@ -267,7 +270,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, Expr *Base) : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, - Base->isValueDependent(), + Base->isValueDependent(), Base->isInstantiationDependent(), Base->containsUnexpandedParameterPack()), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { @@ -277,7 +280,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation SuperLoc, QualType SuperTy) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { } @@ -286,7 +289,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { } @@ -870,6 +873,7 @@ public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), /*ContainsUnexpandedParameterPack=*/false), Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} @@ -944,6 +948,7 @@ public: ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, operand->isTypeDependent(), operand->isValueDependent(), + operand->isInstantiationDependent(), operand->containsUnexpandedParameterPack()), Operand(operand) { setShouldCopy(shouldCopy); diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index c21c76b006..5deefe9d97 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -186,6 +186,10 @@ public: /// type or not. bool isDependent() const; + /// \brief Whether this nested name specifier involves a template + /// parameter. + bool isInstantiationDependent() const; + /// \brief Whether this nested-name-specifier contains an unexpanded /// parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 8a4c0d11ac..73a878ce7f 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -154,9 +154,10 @@ protected: unsigned ObjectKind : 2; unsigned TypeDependent : 1; unsigned ValueDependent : 1; + unsigned InstantiationDependent : 1; unsigned ContainsUnexpandedParameterPack : 1; }; - enum { NumExprBits = 15 }; + enum { NumExprBits = 16 }; class DeclRefExprBitfields { friend class DeclRefExpr; diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 821b4fcbb1..1c693e00c8 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -235,9 +235,14 @@ public: bool isNull() const { return Kind == Null; } /// \brief Whether this template argument is dependent on a template - /// parameter. + /// parameter such that its result can change from one instantiation to + /// another. bool isDependent() const; + /// \brief Whether this template argument is dependent on a template + /// parameter. + bool isInstantiationDependent() const; + /// \brief Whether this template argument contains an unexpanded /// parameter pack. bool containsUnexpandedParameterPack() const; diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index db4612990f..a180f587ed 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -292,6 +292,10 @@ public: /// \brief Determines whether this is a dependent template name. bool isDependent() const; + /// \brief Determines whether this is a template name that somehow + /// depends on a template parameter. + bool isInstantiationDependent() const; + /// \brief Determines whether this template name contains an /// unexpanded parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 06a9787d92..f1710f0e97 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1065,6 +1065,10 @@ private: /// subclasses can pack their bitfields into the same word. unsigned Dependent : 1; + /// \brief Whether this type somehow involves a template parameter, even + /// if the resolution of the type does not depend on a template parameter. + unsigned InstantiationDependent : 1; + /// \brief Whether this type is a variably-modified type (C99 6.7.5). unsigned VariablyModified : 1; @@ -1102,7 +1106,7 @@ private: return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 17 }; + enum { NumTypeBits = 18 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields @@ -1245,12 +1249,14 @@ private: protected: // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } - Type(TypeClass tc, QualType canon, bool Dependent, bool VariablyModified, + Type(TypeClass tc, QualType canon, bool Dependent, + bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack) : ExtQualsTypeCommonBase(this, canon.isNull() ? QualType(this_(), 0) : canon) { TypeBits.TC = tc; TypeBits.Dependent = Dependent; + TypeBits.InstantiationDependent = Dependent || InstantiationDependent; TypeBits.VariablyModified = VariablyModified; TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; TypeBits.CacheValidAndVisibility = 0; @@ -1260,8 +1266,15 @@ protected: } friend class ASTContext; - void setDependent(bool D = true) { TypeBits.Dependent = D; } - void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } + void setDependent(bool D = true) { + TypeBits.Dependent = D; + if (D) + TypeBits.InstantiationDependent = true; + } + void setInstantiationDependent(bool D = true) { + TypeBits.InstantiationDependent = D; } + void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; + } void setContainsUnexpandedParameterPack(bool PP = true) { TypeBits.ContainsUnexpandedParameterPack = PP; } @@ -1453,6 +1466,14 @@ public: /// (C++ [temp.dep.type]). bool isDependentType() const { return TypeBits.Dependent; } + /// \brief Determine whether this type is an instantiation-dependent type, + /// meaning that the type involves a template parameter (even if the + /// definition does not actually depend on the type substituted for that + /// template parameter). + bool isInstantiationDependentType() const { + return TypeBits.InstantiationDependent; + } + /// \brief Whether this type is a variably-modified type (C99 6.7.5). bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } @@ -1720,6 +1741,7 @@ public: public: BuiltinType(Kind K) : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), + /*InstantiationDependent=*/(K == Dependent), /*VariablyModified=*/false, /*Unexpanded paramter pack=*/false) { BuiltinTypeBits.Kind = K; @@ -1765,6 +1787,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode { QualType ElementType; ComplexType(QualType Element, QualType CanonicalPtr) : Type(Complex, CanonicalPtr, Element->isDependentType(), + Element->isInstantiationDependentType(), Element->isVariablyModifiedType(), Element->containsUnexpandedParameterPack()), ElementType(Element) { @@ -1795,6 +1818,7 @@ class ParenType : public Type, public llvm::FoldingSetNode { ParenType(QualType InnerType, QualType CanonType) : Type(Paren, CanonType, InnerType->isDependentType(), + InnerType->isInstantiationDependentType(), InnerType->isVariablyModifiedType(), InnerType->containsUnexpandedParameterPack()), Inner(InnerType) { @@ -1826,6 +1850,7 @@ class PointerType : public Type, public llvm::FoldingSetNode { PointerType(QualType Pointee, QualType CanonicalPtr) : Type(Pointer, CanonicalPtr, Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), Pointee->isVariablyModifiedType(), Pointee->containsUnexpandedParameterPack()), PointeeType(Pointee) { @@ -1858,6 +1883,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; // Block is some kind of pointer type BlockPointerType(QualType Pointee, QualType CanonicalCls) : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), Pointee->isVariablyModifiedType(), Pointee->containsUnexpandedParameterPack()), PointeeType(Pointee) { @@ -1894,6 +1920,7 @@ protected: ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, bool SpelledAsLValue) : Type(tc, CanonicalRef, Referencee->isDependentType(), + Referencee->isInstantiationDependentType(), Referencee->isVariablyModifiedType(), Referencee->containsUnexpandedParameterPack()), PointeeType(Referencee) @@ -1978,6 +2005,8 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode { MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : Type(MemberPointer, CanonicalPtr, Cls->isDependentType() || Pointee->isDependentType(), + (Cls->isInstantiationDependentType() || + Pointee->isInstantiationDependentType()), Pointee->isVariablyModifiedType(), (Cls->containsUnexpandedParameterPack() || Pointee->containsUnexpandedParameterPack())), @@ -2045,6 +2074,7 @@ protected: ArraySizeModifier sm, unsigned tq, bool ContainsUnexpandedParameterPack) : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, + et->isInstantiationDependentType() || tc == DependentSizedArray, (tc == VariableArray || et->isVariablyModifiedType()), ContainsUnexpandedParameterPack), ElementType(et) { @@ -2564,9 +2594,10 @@ protected: FunctionType(TypeClass tc, QualType res, bool variadic, unsigned typeQuals, RefQualifierKind RefQualifier, QualType Canonical, bool Dependent, + bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack, ExtInfo Info) - : Type(tc, Canonical, Dependent, VariablyModified, + : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, ContainsUnexpandedParameterPack), ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; @@ -2611,7 +2642,8 @@ public: class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) : FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical, - /*Dependent=*/false, Result->isVariablyModifiedType(), + /*Dependent=*/false, /*InstantiationDependent=*/false, + Result->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false, Info) {} friend class ASTContext; // ASTContext creates these. @@ -2857,7 +2889,7 @@ class UnresolvedUsingType : public Type { UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) - : Type(UnresolvedUsing, QualType(), true, false, + : Type(UnresolvedUsing, QualType(), true, true, false, /*ContainsUnexpandedParameterPack=*/false), Decl(const_cast(D)) {} friend class ASTContext; // ASTContext creates these. @@ -2887,7 +2919,9 @@ class TypedefType : public Type { TypedefNameDecl *Decl; protected: TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) - : Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(), + : Type(tc, can, can->isDependentType(), + can->isInstantiationDependentType(), + can->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false), Decl(const_cast(D)) { assert(!isa(can) && "Invalid canonical type"); @@ -2953,7 +2987,9 @@ public: class TypeOfType : public Type { QualType TOType; TypeOfType(QualType T, QualType can) - : Type(TypeOf, can, T->isDependentType(), T->isVariablyModifiedType(), + : Type(TypeOf, can, T->isDependentType(), + T->isInstantiationDependentType(), + T->isVariablyModifiedType(), T->containsUnexpandedParameterPack()), TOType(T) { assert(!isa(can) && "Invalid canonical type"); @@ -3182,6 +3218,7 @@ private: AttributedType(QualType canon, Kind attrKind, QualType modified, QualType equivalent) : Type(Attributed, canon, canon->isDependentType(), + canon->isInstantiationDependentType(), canon->isVariablyModifiedType(), canon->containsUnexpandedParameterPack()), ModifiedType(modified), EquivalentType(equivalent) { @@ -3234,13 +3271,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { /// Build a non-canonical type. TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) : Type(TemplateTypeParm, Canon, /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, Canon->containsUnexpandedParameterPack()), TTPDecl(TTPDecl) { } /// Build the canonical type. TemplateTypeParmType(unsigned D, unsigned I, bool PP) - : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true, + : Type(TemplateTypeParm, QualType(this, 0), + /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, PP) { CanTTPTInfo.Depth = D; CanTTPTInfo.Index = I; @@ -3300,6 +3340,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), + Canon->isInstantiationDependentType(), Canon->isVariablyModifiedType(), Canon->containsUnexpandedParameterPack()), Replaced(Param) { } @@ -3399,6 +3440,7 @@ class AutoType : public Type, public llvm::FoldingSetNode { AutoType(QualType DeducedType) : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, /*Dependent=*/DeducedType.isNull(), + /*InstantiationDependent=*/DeducedType.isNull(), /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { assert((DeducedType.isNull() || !DeducedType->isDependentType()) && "deduced a dependent type for auto"); @@ -3478,12 +3520,15 @@ public: /// \brief Determine whether any of the given template arguments are /// dependent. static bool anyDependentTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs); + unsigned NumArgs, + bool &InstantiationDependent); static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, - unsigned NumArgs); + unsigned NumArgs, + bool &InstantiationDependent); - static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &); + static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, + bool &InstantiationDependent); /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. @@ -3594,6 +3639,7 @@ class InjectedClassNameType : public Type { // interdependencies. InjectedClassNameType(CXXRecordDecl *D, QualType TST) : Type(InjectedClassName, QualType(), /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, /*ContainsUnexpandedParameterPack=*/false), Decl(D), InjectedType(TST) { @@ -3656,9 +3702,10 @@ enum ElaboratedTypeKeyword { class TypeWithKeyword : public Type { protected: TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, - QualType Canonical, bool Dependent, bool VariablyModified, + QualType Canonical, bool Dependent, + bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack) - : Type(tc, Canonical, Dependent, VariablyModified, + : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, ContainsUnexpandedParameterPack) { TypeWithKeywordBits.Keyword = Keyword; } @@ -3718,6 +3765,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { QualType NamedType, QualType CanonType) : TypeWithKeyword(Keyword, Elaborated, CanonType, NamedType->isDependentType(), + NamedType->isInstantiationDependentType(), NamedType->isVariablyModifiedType(), NamedType->containsUnexpandedParameterPack()), NNS(NNS), NamedType(NamedType) { @@ -3780,6 +3828,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, NNS->containsUnexpandedParameterPack()), NNS(NNS), Name(Name) { @@ -3933,6 +3982,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { PackExpansionType(QualType Pattern, QualType Canon, llvm::Optional NumExpansions) : Type(PackExpansion, Canon, /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariableModified=*/Pattern->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false), Pattern(Pattern), @@ -4024,7 +4074,7 @@ protected: enum Nonce_ObjCInterface { Nonce_ObjCInterface }; ObjCObjectType(enum Nonce_ObjCInterface) - : Type(ObjCInterface, QualType(), false, false, false), + : Type(ObjCInterface, QualType(), false, false, false, false), BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; } @@ -4181,7 +4231,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, false, false, false), + : Type(ObjCObjectPointer, Canonical, false, false, false, false), PointeeType(Pointee) {} friend class ASTContext; // ASTContext creates these. diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/Sema/LocInfoType.h index 566591d150..e1d3ae9051 100644 --- a/include/clang/Sema/LocInfoType.h +++ b/include/clang/Sema/LocInfoType.h @@ -37,6 +37,7 @@ class LocInfoType : public Type { LocInfoType(QualType ty, TypeSourceInfo *TInfo) : Type((TypeClass)LocInfo, ty, ty->isDependentType(), + ty->isInstantiationDependentType(), ty->isVariablyModifiedType(), ty->containsUnexpandedParameterPack()), DeclInfo(TInfo) { diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index ec064fc2f4..4c42393365 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2802,7 +2802,12 @@ static QualType getDecltypeForExpr(const Expr *e, const ASTContext &Context) { /// on canonical type's (which are always unique). QualType ASTContext::getDecltypeType(Expr *e) const { DecltypeType *dt; - if (e->isTypeDependent()) { + + // C++0x [temp.type]p2: + // If an expression e involves a template parameter, decltype(e) denotes a + // unique dependent type. Two such decltype-specifiers refer to the same + // type only if their expressions are equivalent (14.5.6.1). + if (e->isInstantiationDependent()) { llvm::FoldingSetNodeID ID; DependentDecltypeType::Profile(ID, *this, e); diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index cef54e97c9..72c0e9da7f 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -533,6 +533,28 @@ bool DeclarationNameInfo::containsUnexpandedParameterPack() const { llvm_unreachable("All name kinds handled."); } +bool DeclarationNameInfo::isInstantiationDependent() const { + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::CXXOperatorName: + case DeclarationName::CXXLiteralOperatorName: + case DeclarationName::CXXUsingDirective: + return false; + + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) + return TInfo->getType()->isInstantiationDependentType(); + + return Name.getCXXNameType()->isInstantiationDependentType(); + } + llvm_unreachable("All name kinds handled."); +} + std::string DeclarationNameInfo::getAsString() const { std::string Result; llvm::raw_string_ostream OS(Result); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 1d0319f601..3002e305ac 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -142,9 +142,10 @@ void ExplicitTemplateArgumentList::initializeFrom( } void ExplicitTemplateArgumentList::initializeFrom( - const TemplateArgumentListInfo &Info, - bool &Dependent, - bool &ContainsUnexpandedParameterPack) { + const TemplateArgumentListInfo &Info, + bool &Dependent, + bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack) { LAngleLoc = Info.getLAngleLoc(); RAngleLoc = Info.getRAngleLoc(); NumTemplateArgs = Info.size(); @@ -152,6 +153,8 @@ void ExplicitTemplateArgumentList::initializeFrom( TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); for (unsigned i = 0; i != NumTemplateArgs; ++i) { Dependent = Dependent || Info[i].getArgument().isDependent(); + InstantiationDependent = InstantiationDependent || + Info[i].getArgument().isInstantiationDependent(); ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack || Info[i].getArgument().containsUnexpandedParameterPack(); @@ -178,14 +181,16 @@ std::size_t ExplicitTemplateArgumentList::sizeFor( return sizeFor(Info.size()); } -/// \brief Compute the type- and value-dependence of a declaration reference +/// \brief Compute the type-, value-, and instantiation-dependence of a +/// declaration reference /// based on the declaration being referenced. static void computeDeclRefDependence(NamedDecl *D, QualType T, bool &TypeDependent, - bool &ValueDependent) { + bool &ValueDependent, + bool &InstantiationDependent) { TypeDependent = false; ValueDependent = false; - + InstantiationDependent = false; // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -200,20 +205,31 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, if (T->isDependentType()) { TypeDependent = true; ValueDependent = true; + InstantiationDependent = true; return; + } else if (T->isInstantiationDependentType()) { + InstantiationDependent = true; } // (TD) - a conversion-function-id that specifies a dependent type if (D->getDeclName().getNameKind() - == DeclarationName::CXXConversionFunctionName && - D->getDeclName().getCXXNameType()->isDependentType()) { - TypeDependent = true; - ValueDependent = true; - return; + == DeclarationName::CXXConversionFunctionName) { + QualType T = D->getDeclName().getCXXNameType(); + if (T->isDependentType()) { + TypeDependent = true; + ValueDependent = true; + InstantiationDependent = true; + return; + } + + if (T->isInstantiationDependentType()) + InstantiationDependent = true; } + // (VD) - the name of a non-type template parameter, if (isa(D)) { ValueDependent = true; + InstantiationDependent = true; return; } @@ -223,16 +239,20 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, if (Var->getType()->isIntegralOrEnumerationType() && Var->getType().getCVRQualifiers() == Qualifiers::Const) { if (const Expr *Init = Var->getAnyInitializer()) - if (Init->isValueDependent()) + if (Init->isValueDependent()) { ValueDependent = true; + InstantiationDependent = 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()) + Var->getDeclContext()->isDependentContext()) { ValueDependent = true; + InstantiationDependent = true; + } return; } @@ -242,6 +262,7 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, // instantiation if (isa(D) && D->getDeclContext()->isDependentContext()) { ValueDependent = true; + InstantiationDependent = true; return; } } @@ -249,7 +270,9 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, void DeclRefExpr::computeDependence() { bool TypeDependent = false; bool ValueDependent = false; - computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent); + bool InstantiationDependent = false; + computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent, + InstantiationDependent); // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -262,13 +285,16 @@ void DeclRefExpr::computeDependence() { hasExplicitTemplateArgs() && TemplateSpecializationType::anyDependentTemplateArguments( getTemplateArgs(), - getNumTemplateArgs())) { + getNumTemplateArgs(), + InstantiationDependent)) { TypeDependent = true; ValueDependent = true; + InstantiationDependent = true; } ExprBits.TypeDependent = TypeDependent; ExprBits.ValueDependent = ValueDependent; + ExprBits.InstantiationDependent = InstantiationDependent; // Is the declaration a parameter pack? if (getDecl()->isParameterPack()) @@ -280,7 +306,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; if (QualifierLoc) @@ -289,9 +315,17 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, if (FoundD) getInternalFoundDecl() = FoundD; DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0; - if (TemplateArgs) - getExplicitTemplateArgs().initializeFrom(*TemplateArgs); - + if (TemplateArgs) { + bool Dependent = false; + bool InstantiationDependent = false; + bool ContainsUnexpandedParameterPack = false; + getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); + if (InstantiationDependent) + setInstantiationDependent(true); + } + computeDependence(); } @@ -670,6 +704,7 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(), fn->isValueDependent(), + fn->isInstantiationDependent(), fn->containsUnexpandedParameterPack()), NumArgs(numargs) { @@ -680,6 +715,8 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, ExprBits.TypeDependent = true; if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -695,6 +732,7 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, : Expr(CallExprClass, t, VK, OK_Ordinary, fn->isTypeDependent(), fn->isValueDependent(), + fn->isInstantiationDependent(), fn->containsUnexpandedParameterPack()), NumArgs(numargs) { @@ -705,6 +743,8 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, ExprBits.TypeDependent = true; if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -862,6 +902,7 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/tsi->getType()->isDependentType(), + tsi->getType()->isInstantiationDependentType(), tsi->getType()->containsUnexpandedParameterPack()), OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), NumComps(numComps), NumExprs(numExprs) @@ -917,7 +958,12 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) { E->setValueDependent(true); E->setTypeDependent(true); - } + E->setInstantiationDependent(true); + } + else if (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) + E->setInstantiationDependent(true); + E->HasQualifierOrFoundDecl = true; MemberNameQualifier *NQ = E->getMemberQualifier(); @@ -926,8 +972,15 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, } if (targs) { + bool Dependent = false; + bool InstantiationDependent = false; + bool ContainsUnexpandedParameterPack = false; E->HasExplicitTemplateArgumentList = true; - E->getExplicitTemplateArgs().initializeFrom(*targs); + E->getExplicitTemplateArgs().initializeFrom(*targs, Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); + if (InstantiationDependent) + E->setInstantiationDependent(true); } return E; @@ -1251,7 +1304,7 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, Expr **initExprs, unsigned numInits, SourceLocation rbraceloc) : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false, - false), + false, false), InitExprs(C, numInits), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), HadArrayRangeDesignator(false) @@ -1261,6 +1314,8 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, ExprBits.TypeDependent = true; if (initExprs[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (initExprs[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (initExprs[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; } @@ -2575,6 +2630,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/false, + /*InstantiationDependent=*/false, /*ContainsUnexpandedParameterPack=*/false), NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass), HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc), @@ -2597,7 +2653,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), - T->isDependentType(), T->containsUnexpandedParameterPack()), + T->isDependentType(), T->isInstantiationDependentType(), + T->containsUnexpandedParameterPack()), NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0), IsDelegateInitCall(false), SelectorOrMethod(reinterpret_cast(Method? Method @@ -2611,6 +2668,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprBits.TypeDependent = true; if (Args[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (Args[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (Args[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2629,6 +2688,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), Receiver->isTypeDependent(), + Receiver->isInstantiationDependent(), Receiver->containsUnexpandedParameterPack()), NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0), IsDelegateInitCall(false), @@ -2643,6 +2703,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprBits.TypeDependent = true; if (Args[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (Args[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (Args[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2784,6 +2846,7 @@ ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, SourceLocation RP) : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary, Type->isDependentType(), Type->isDependentType(), + Type->isInstantiationDependentType(), Type->containsUnexpandedParameterPack()), BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) { @@ -2793,6 +2856,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, ExprBits.TypeDependent = true; if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2822,6 +2887,7 @@ GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context, AssocExprs[ResultIndex]->getObjectKind(), AssocExprs[ResultIndex]->isTypeDependent(), AssocExprs[ResultIndex]->isValueDependent(), + AssocExprs[ResultIndex]->isInstantiationDependent(), ContainsUnexpandedParameterPack), AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), @@ -2842,8 +2908,9 @@ GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context, Context.DependentTy, VK_RValue, OK_Ordinary, - /*isTypeDependent=*/ true, - /*isValueDependent=*/ true, + /*isTypeDependent=*/true, + /*isValueDependent=*/true, + /*isInstantiationDependent=*/true, ContainsUnexpandedParameterPack), AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), @@ -2877,6 +2944,7 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, : Expr(DesignatedInitExprClass, Ty, Init->getValueKind(), Init->getObjectKind(), Init->isTypeDependent(), Init->isValueDependent(), + Init->isInstantiationDependent(), Init->containsUnexpandedParameterPack()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { @@ -2897,7 +2965,8 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, Expr *Index = IndexExprs[IndexIdx]; if (Index->isTypeDependent() || Index->isValueDependent()) ExprBits.ValueDependent = true; - + if (Index->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; // Propagate unexpanded parameter packs. if (Index->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2909,9 +2978,14 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, Expr *Start = IndexExprs[IndexIdx]; Expr *End = IndexExprs[IndexIdx + 1]; if (Start->isTypeDependent() || Start->isValueDependent() || - End->isTypeDependent() || End->isValueDependent()) + End->isTypeDependent() || End->isValueDependent()) { ExprBits.ValueDependent = true; - + ExprBits.InstantiationDependent = true; + } else if (Start->isInstantiationDependent() || + End->isInstantiationDependent()) { + ExprBits.InstantiationDependent = true; + } + // Propagate unexpanded parameter packs. if (Start->containsUnexpandedParameterPack() || End->containsUnexpandedParameterPack()) @@ -3035,7 +3109,7 @@ ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, SourceLocation rparenloc, QualType T) : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary, - false, false, false), + false, false, false, false), NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { assert(!T.isNull() && "ParenListExpr must have a valid type"); Exprs = new (C) Stmt*[nexprs]; @@ -3044,6 +3118,8 @@ ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, ExprBits.TypeDependent = true; if (exprs[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (exprs[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (exprs[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -3108,13 +3184,16 @@ Stmt::child_range ObjCMessageExpr::children() { BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, SourceLocation l, bool ByRef, bool constAdded) - : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, + : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, false, d->isParameterPack()), D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded) { bool TypeDependent = false; bool ValueDependent = false; - computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent); + bool InstantiationDependent = false; + computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent, + InstantiationDependent); ExprBits.TypeDependent = TypeDependent; ExprBits.ValueDependent = ValueDependent; + ExprBits.InstantiationDependent = InstantiationDependent; } diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 1a1a0a36a6..32209f6be6 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -57,6 +57,7 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, SourceLocation constructorRParen) : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, ty->isDependentType(), ty->isDependentType(), + ty->isInstantiationDependentType(), ty->containsUnexpandedParameterPack()), GlobalNew(globalNew), Initializer(initializer), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize), @@ -68,6 +69,9 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs); unsigned i = 0; if (Array) { + if (arraySize->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (arraySize->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -75,6 +79,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, } for (unsigned j = 0; j < NumPlacementArgs; ++j) { + if (placementArgs[j]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (placementArgs[j]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -82,6 +88,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, } for (unsigned j = 0; j < NumConstructorArgs; ++j) { + if (constructorArgs[j]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (constructorArgs[j]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -144,6 +152,14 @@ CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context, (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), /*isValueDependent=*/Base->isValueDependent(), + (Base->isInstantiationDependent() || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) || + (ScopeType && + ScopeType->getType()->isInstantiationDependentType()) || + (DestroyedType.getTypeSourceInfo() && + DestroyedType.getTypeSourceInfo()->getType() + ->isInstantiationDependentType())), // ContainsUnexpandedParameterPack (Base->containsUnexpandedParameterPack() || (QualifierLoc && @@ -212,9 +228,14 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, + bool KnownInstantiationDependent, bool KnownContainsUnexpandedParameterPack) : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, KnownDependent, + (KnownInstantiationDependent || + NameInfo.isInstantiationDependent() || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (KnownContainsUnexpandedParameterPack || NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && @@ -246,14 +267,18 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, // expansions. if (TemplateArgs) { bool Dependent = false; + bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + InstantiationDependent, ContainsUnexpandedParameterPack); if (Dependent) { - ExprBits.TypeDependent = true; - ExprBits.ValueDependent = true; - } + ExprBits.TypeDependent = true; + ExprBits.ValueDependent = true; + } + if (InstantiationDependent) + ExprBits.InstantiationDependent = true; if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } @@ -291,6 +316,9 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, const TemplateArgumentListInfo *Args) : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, true, true, + (NameInfo.isInstantiationDependent() || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() @@ -300,11 +328,14 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, { if (Args) { bool Dependent = true; + bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = ExprBits.ContainsUnexpandedParameterPack; reinterpret_cast(this+1) - ->initializeFrom(*Args, Dependent, ContainsUnexpandedParameterPack); + ->initializeFrom(*Args, Dependent, InstantiationDependent, + ContainsUnexpandedParameterPack); + ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; } } @@ -632,6 +663,7 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, SourceRange ParenRange) : Expr(SC, T, VK_RValue, OK_Ordinary, T->isDependentType(), T->isDependentType(), + T->isInstantiationDependentType(), T->containsUnexpandedParameterPack()), Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable), ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), @@ -645,6 +677,8 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -660,6 +694,7 @@ ExprWithCleanups::ExprWithCleanups(ASTContext &C, : Expr(ExprWithCleanupsClass, subexpr->getType(), subexpr->getValueKind(), subexpr->getObjectKind(), subexpr->isTypeDependent(), subexpr->isValueDependent(), + subexpr->isInstantiationDependent(), subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr), Temps(0), NumTemps(0) { if (numtemps) { @@ -691,7 +726,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, : Expr(CXXUnresolvedConstructExprClass, Type->getType().getNonReferenceType(), VK_LValue, OK_Ordinary, - Type->getType()->isDependentType(), true, + Type->getType()->isDependentType(), true, true, Type->getType()->containsUnexpandedParameterPack()), Type(Type), LParenLoc(LParenLoc), @@ -740,7 +775,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true, + VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() @@ -753,8 +788,10 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, MemberNameInfo(MemberNameInfo) { if (TemplateArgs) { bool Dependent = true; + bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + InstantiationDependent, ContainsUnexpandedParameterPack); if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; @@ -769,7 +806,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true, + VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()-> @@ -874,6 +911,8 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, // Dependent ((Base && Base->isTypeDependent()) || BaseType->isDependentType()), + ((Base && Base->isInstantiationDependent()) || + BaseType->isInstantiationDependentType()), // Contains unexpanded parameter pack ((Base && Base->containsUnexpandedParameterPack()) || BaseType->containsUnexpandedParameterPack())), @@ -962,7 +1001,7 @@ SubstNonTypeTemplateParmPackExpr(QualType T, SourceLocation NameLoc, const TemplateArgument &ArgPack) : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, - true, false, true), + true, true, true, true), Param(Param), Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { } diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index 2878dff3ed..f6d4f2513c 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -174,6 +174,28 @@ bool NestedNameSpecifier::isDependent() const { return false; } +/// \brief Whether this nested name specifier refers to a dependent +/// type or not. +bool NestedNameSpecifier::isInstantiationDependent() const { + switch (getKind()) { + case Identifier: + // Identifier specifiers always represent dependent types + return true; + + case Namespace: + case NamespaceAlias: + case Global: + return false; + + case TypeSpec: + case TypeSpecWithTemplate: + return getAsType()->isInstantiationDependentType(); + } + + // Necessary to suppress a GCC warning. + return false; +} + bool NestedNameSpecifier::containsUnexpandedParameterPack() const { switch (getKind()) { case Identifier: diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 103da1d8a4..56c6e7bc47 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -104,6 +104,45 @@ bool TemplateArgument::isDependent() const { return false; } +bool TemplateArgument::isInstantiationDependent() const { + switch (getKind()) { + case Null: + assert(false && "Should not have a NULL template argument"); + return false; + + case Type: + return getAsType()->isInstantiationDependentType(); + + case Template: + return getAsTemplate().isInstantiationDependent(); + + case TemplateExpansion: + return true; + + case Declaration: + if (DeclContext *DC = dyn_cast(getAsDecl())) + return DC->isDependentContext(); + return getAsDecl()->getDeclContext()->isDependentContext(); + + case Integral: + // Never dependent + return false; + + case Expression: + return getAsExpr()->isInstantiationDependent(); + + case Pack: + for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { + if (P->isInstantiationDependent()) + return true; + } + + return false; + } + + return false; +} + bool TemplateArgument::isPackExpansion() const { switch (getKind()) { case Null: diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp index b22e4b4c0d..1f7b19aae4 100644 --- a/lib/AST/TemplateName.cpp +++ b/lib/AST/TemplateName.cpp @@ -99,6 +99,15 @@ bool TemplateName::isDependent() const { return true; } +bool TemplateName::isInstantiationDependent() const { + if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { + if (QTN->getQualifier()->isInstantiationDependent()) + return true; + } + + return isDependent(); +} + bool TemplateName::containsUnexpandedParameterPack() const { if (TemplateDecl *Template = getAsTemplateDecl()) { if (TemplateTemplateParmDecl *TTP diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 1569173df7..ca63ec87b1 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -110,6 +110,7 @@ DependentSizedExtVectorType::DependentSizedExtVectorType(const Expr *SizeExpr, SourceLocation loc) : Type(DependentSizedExtVector, can, /*Dependent=*/true, + /*InstantiationDependent=*/true, ElementType->isVariablyModifiedType(), (ElementType->containsUnexpandedParameterPack() || (SizeExpr && SizeExpr->containsUnexpandedParameterPack()))), @@ -129,6 +130,7 @@ DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind) : Type(Vector, canonType, vecType->isDependentType(), + vecType->isInstantiationDependentType(), vecType->isVariablyModifiedType(), vecType->containsUnexpandedParameterPack()), ElementType(vecType) @@ -140,6 +142,7 @@ VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind) : Type(tc, canonType, vecType->isDependentType(), + vecType->isInstantiationDependentType(), vecType->isVariablyModifiedType(), vecType->containsUnexpandedParameterPack()), ElementType(vecType) @@ -387,7 +390,7 @@ const RecordType *Type::getAsUnionType() const { ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) - : Type(ObjCObject, Canonical, false, false, false), + : Type(ObjCObject, Canonical, false, false, false, false), BaseType(Base) { ObjCObjectTypeBits.NumProtocols = NumProtocols; @@ -1350,7 +1353,7 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType( NestedNameSpecifier *NNS, const IdentifierInfo *Name, unsigned NumArgs, const TemplateArgument *Args, QualType Canon) - : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, + : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true, /*VariablyModified=*/false, NNS && NNS->containsUnexpandedParameterPack()), NNS(NNS), Name(Name), NumArgs(NumArgs) { @@ -1485,6 +1488,7 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, epi.RefQualifier, canonical, result->isDependentType(), + result->isInstantiationDependentType(), result->isVariablyModifiedType(), result->containsUnexpandedParameterPack(), epi.ExtInfo), @@ -1497,7 +1501,9 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, for (unsigned i = 0; i != numArgs; ++i) { if (args[i]->isDependentType()) setDependent(); - + else if (args[i]->isInstantiationDependentType()) + setInstantiationDependent(); + if (args[i]->containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); @@ -1510,7 +1516,9 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) { if (epi.Exceptions[i]->isDependentType()) setDependent(); - + else if (epi.Exceptions[i]->isInstantiationDependentType()) + setInstantiationDependent(); + if (epi.Exceptions[i]->containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); @@ -1520,6 +1528,14 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, // Store the noexcept expression and context. Expr **noexSlot = reinterpret_cast(argSlot + numArgs); *noexSlot = epi.NoexceptExpr; + + if (epi.NoexceptExpr) { + if (epi.NoexceptExpr->isValueDependent() + || epi.NoexceptExpr->isTypeDependent()) + setDependent(); + else if (epi.NoexceptExpr->isInstantiationDependent()) + setInstantiationDependent(); + } } if (epi.ConsumedArguments) { @@ -1623,6 +1639,7 @@ QualType TypedefType::desugar() const { TypeOfExprType::TypeOfExprType(Expr *E, QualType can) : Type(TypeOfExpr, can, E->isTypeDependent(), + E->isInstantiationDependent(), E->getType()->isVariablyModifiedType(), E->containsUnexpandedParameterPack()), TOExpr(E) { @@ -1639,6 +1656,7 @@ void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) : Type(Decltype, can, E->isTypeDependent(), + E->isInstantiationDependent(), E->getType()->isVariablyModifiedType(), E->containsUnexpandedParameterPack()), E(E), @@ -1654,7 +1672,9 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, } TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) - : Type(TC, can, D->isDependentType(), /*VariablyModified=*/false, + : Type(TC, can, D->isDependentType(), + /*InstantiationDependent=*/D->isDependentType(), + /*VariablyModified=*/false, /*ContainsUnexpandedParameterPack=*/false), decl(const_cast(D)) {} @@ -1674,6 +1694,7 @@ UnaryTransformType::UnaryTransformType(QualType BaseType, UTTKind UKind, QualType CanonicalType) : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(), + UnderlyingType->isInstantiationDependentType(), UnderlyingType->isVariablyModifiedType(), BaseType->containsUnexpandedParameterPack()) , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) @@ -1707,7 +1728,8 @@ SubstTemplateTypeParmPackType:: SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, QualType Canon, const TemplateArgument &ArgPack) - : Type(SubstTemplateTypeParmPack, Canon, true, false, true), Replaced(Param), + : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), + Replaced(Param), Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) { } @@ -1732,23 +1754,39 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID, } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) { - return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size()); +anyDependentTemplateArguments(const TemplateArgumentListInfo &Args, + bool &InstantiationDependent) { + return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size(), + InstantiationDependent); } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { - for (unsigned i = 0; i != N; ++i) - if (Args[i].getArgument().isDependent()) +anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N, + bool &InstantiationDependent) { + for (unsigned i = 0; i != N; ++i) { + if (Args[i].getArgument().isDependent()) { + InstantiationDependent = true; return true; + } + + if (Args[i].getArgument().isInstantiationDependent()) + InstantiationDependent = true; + } return false; } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) { - for (unsigned i = 0; i != N; ++i) - if (Args[i].isDependent()) +anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N, + bool &InstantiationDependent) { + for (unsigned i = 0; i != N; ++i) { + if (Args[i].isDependent()) { + InstantiationDependent = true; return true; + } + + if (Args[i].isInstantiationDependent()) + InstantiationDependent = true; + } return false; } @@ -1759,6 +1797,8 @@ TemplateSpecializationType(TemplateName T, : Type(TemplateSpecialization, Canon.isNull()? QualType(this, 0) : Canon, Canon.isNull()? T.isDependent() : Canon->isDependentType(), + Canon.isNull()? T.isDependent() + : Canon->isInstantiationDependentType(), false, T.containsUnexpandedParameterPack()), Template(T), NumArgs(NumArgs) { assert(!T.getAsDependentTemplateName() && @@ -1767,8 +1807,12 @@ TemplateSpecializationType(TemplateName T, T.getKind() == TemplateName::SubstTemplateTemplateParm || T.getKind() == TemplateName::SubstTemplateTemplateParmPack) && "Unexpected template name for TemplateSpecializationType"); + bool InstantiationDependent; + (void)InstantiationDependent; assert((!Canon.isNull() || - T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) && + T.isDependent() || + anyDependentTemplateArguments(Args, NumArgs, + InstantiationDependent)) && "No canonical type for non-dependent class template specialization"); TemplateArgument *TemplateArgs @@ -1782,6 +1826,9 @@ TemplateSpecializationType(TemplateName T, // U is always non-dependent, irrespective of the type T. if (Canon.isNull() && Args[Arg].isDependent()) setDependent(); + else if (Args[Arg].isInstantiationDependent()) + setInstantiationDependent(); + if (Args[Arg].getKind() == TemplateArgument::Type && Args[Arg].getAsType()->isVariablyModifiedType()) setVariablyModified(); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index d88b785762..a7034aa771 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1898,6 +1898,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, QualType CanonType; + bool InstantiationDependent = false; if (TypeAliasTemplateDecl *AliasTemplate = dyn_cast(Template)) { // Find the canonical type for this type alias template specialization. @@ -1923,7 +1924,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, return QualType(); } else if (Name.isDependent() || TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs)) { + TemplateArgs, InstantiationDependent)) { // This class template specialization is a dependent // type. Therefore, its canonical type is another class template // specialization type that contains all of the converted @@ -4833,10 +4834,12 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, Converted)) return true; + bool InstantiationDependent; if (!Name.isDependent() && !TemplateSpecializationType::anyDependentTemplateArguments( TemplateArgs.getArgumentArray(), - TemplateArgs.size())) { + TemplateArgs.size(), + InstantiationDependent)) { Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) << ClassTemplate->getDeclName(); isPartialSpecialization = false; diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index c452e26a40..675cef7986 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -807,7 +807,7 @@ bool TemplateInstantiator::AlreadyTransformed(QualType T) { if (T.isNull()) return true; - if (T->isDependentType() || T->isVariablyModifiedType()) + if (T->isInstantiationDependentType() || T->isVariablyModifiedType()) return false; getSema().MarkDeclarationsReferencedInType(Loc, T); @@ -1340,7 +1340,7 @@ TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T, "Cannot perform an instantiation without some context on the " "instantiation stack"); - if (!T->getType()->isDependentType() && + if (!T->getType()->isInstantiationDependentType() && !T->getType()->isVariablyModifiedType()) return T; @@ -1359,7 +1359,7 @@ TypeSourceInfo *Sema::SubstType(TypeLoc TL, if (TL.getType().isNull()) return 0; - if (!TL.getType()->isDependentType() && + if (!TL.getType()->isInstantiationDependentType() && !TL.getType()->isVariablyModifiedType()) { // FIXME: Make a copy of the TypeLoc data here, so that we can // return a new TypeSourceInfo. Inefficient! @@ -1388,7 +1388,7 @@ QualType Sema::SubstType(QualType T, // If T is not a dependent type or a variably-modified type, there // is nothing to do. - if (!T->isDependentType() && !T->isVariablyModifiedType()) + if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType()) return T; TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity); @@ -1396,7 +1396,8 @@ QualType Sema::SubstType(QualType T, } static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { - if (T->getType()->isDependentType() || T->getType()->isVariablyModifiedType()) + if (T->getType()->isInstantiationDependentType() || + T->getType()->isVariablyModifiedType()) return true; TypeLoc TL = T->getTypeLoc().IgnoreParens(); @@ -1410,7 +1411,7 @@ static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { // The parameter's type as written might be dependent even if the // decayed type was not dependent. if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo()) - if (TSInfo->getType()->isDependentType()) + if (TSInfo->getType()->isInstantiationDependentType()) return true; // TODO: currently we always rebuild expressions. When we diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 196e847728..b6d5abfcc8 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -132,7 +132,7 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias) { bool Invalid = false; TypeSourceInfo *DI = D->getTypeSourceInfo(); - if (DI->getType()->isDependentType() || + if (DI->getType()->isInstantiationDependentType() || DI->getType()->isVariablyModifiedType()) { DI = SemaRef.SubstType(DI, TemplateArgs, D->getLocation(), D->getDeclName()); @@ -435,7 +435,7 @@ Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) { Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { bool Invalid = false; TypeSourceInfo *DI = D->getTypeSourceInfo(); - if (DI->getType()->isDependentType() || + if (DI->getType()->isInstantiationDependentType() || DI->getType()->isVariablyModifiedType()) { DI = SemaRef.SubstType(DI, TemplateArgs, D->getLocation(), D->getDeclName()); diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index f6c27d4106..1697b3bda8 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -60,7 +60,7 @@ namespace clang { /// \brief The number of record fields required for the Expr class /// itself. - static const unsigned NumExprFields = NumStmtFields + 6; + static const unsigned NumExprFields = NumStmtFields + 7; /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList, @@ -414,6 +414,7 @@ void ASTStmtReader::VisitExpr(Expr *E) { E->setType(Reader.GetType(Record[Idx++])); E->setTypeDependent(Record[Idx++]); E->setValueDependent(Record[Idx++]); + E->setInstantiationDependent(Record[Idx++]); E->ExprBits.ContainsUnexpandedParameterPack = Record[Idx++]; E->setValueKind(static_cast(Record[Idx++])); E->setObjectKind(static_cast(Record[Idx++])); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 651e2078cf..2b83494957 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -1517,8 +1517,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { //Stmt //Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind @@ -1536,8 +1537,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { //Stmt //Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind @@ -1553,8 +1555,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { //Stmt //Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index b66fdfa558..91c0b3d914 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -375,6 +375,7 @@ void ASTStmtWriter::VisitExpr(Expr *E) { Writer.AddTypeRef(E->getType(), Record); Record.push_back(E->isTypeDependent()); Record.push_back(E->isValueDependent()); + Record.push_back(E->isInstantiationDependent()); Record.push_back(E->containsUnexpandedParameterPack()); Record.push_back(E->getValueKind()); Record.push_back(E->getObjectKind()); diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index e76dfb1c96..8363528570 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -751,3 +751,22 @@ namespace test30 { // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE( } } + +namespace test31 { // instantiation-dependent mangling of decltype + int x; + template auto f1(T p)->decltype(x) { return 0; } + // The return type in the mangling of the template signature + // is encoded as "i". + template auto f2(T p)->decltype(p) { return 0; } + // The return type in the mangling of the template signature + // is encoded as "Dtfp_E". + void g(int); + template auto f3(T p)->decltype(g(p)) {} + + // CHECK: define weak_odr i32 @_ZN6test312f1IiEEiT_( + template int f1(int); + // CHECK: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_ + template int f2(int); + // CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_ + template void f3(int); +}