Introduce the notion of instantiation dependence into Clang's AST. A

type/expression/template argument/etc. is instantiation-dependent if
it somehow involves a template parameter, even if it doesn't meet the
requirements for the more common kinds of dependence (dependent type,
type-dependent expression, value-dependent expression).

When we see an instantiation-dependent type, we know we always need to
perform substitution into that instantiation-dependent type. This
keeps us from short-circuiting evaluation in places where we
shouldn't, and lets us properly implement C++0x [temp.type]p2.

In theory, this would also allow us to properly mangle
instantiation-dependent-but-not-dependent decltype types per the
Itanium C++ ABI, but we aren't quite there because we still mangle
based on the canonical type in cases like, e.g.,

  template<unsigned> struct A { };
  template<typename T>
    void f(A<sizeof(sizeof(decltype(T() + T())))>) { }
  template void f<int>(A<sizeof(sizeof(int))>);

and therefore get the wrong answer.

llvm-svn: 134225
This commit is contained in:
Douglas Gregor 2011-07-01 01:22:09 +00:00
parent f2bcad972d
commit 678d76c026
25 changed files with 594 additions and 127 deletions

View File

@ -492,6 +492,9 @@ public:
LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding(); 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 /// \brief Determine whether this name contains an unexpanded
/// parameter pack. /// parameter pack.
bool containsUnexpandedParameterPack() const; bool containsUnexpandedParameterPack() const;

View File

@ -57,9 +57,12 @@ class Expr : public Stmt {
protected: protected:
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, 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.TypeDependent = TD;
ExprBits.ValueDependent = VD; ExprBits.ValueDependent = VD;
ExprBits.InstantiationDependent = ID;
ExprBits.ValueKind = VK; ExprBits.ValueKind = VK;
ExprBits.ObjectKind = OK; ExprBits.ObjectKind = OK;
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
@ -95,7 +98,11 @@ public:
bool isValueDependent() const { return ExprBits.ValueDependent; } bool isValueDependent() const { return ExprBits.ValueDependent; }
/// \brief Set whether this expression is value-dependent or not. /// \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 /// isTypeDependent - Determines whether this expression is
/// type-dependent (C++ [temp.dep.expr]), which means that its type /// type-dependent (C++ [temp.dep.expr]), which means that its type
@ -111,7 +118,37 @@ public:
bool isTypeDependent() const { return ExprBits.TypeDependent; } bool isTypeDependent() const { return ExprBits.TypeDependent; }
/// \brief Set whether this expression is type-dependent or not. /// \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<typename T>
/// 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 /// \brief Whether this expression contains an unexpanded parameter
/// pack (for C++0x variadic templates). /// pack (for C++0x variadic templates).
@ -595,7 +632,9 @@ public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK, OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
ExprObjectKind OK = OK_Ordinary) ExprObjectKind OK = OK_Ordinary)
: Expr(OpaqueValueExprClass, T, VK, OK, : Expr(OpaqueValueExprClass, T, VK, OK,
T->isDependentType(), T->isDependentType(), false), T->isDependentType(), T->isDependentType(),
T->isInstantiationDependentType(),
false),
SourceExpr(0), Loc(Loc) { SourceExpr(0), Loc(Loc) {
} }
@ -664,7 +703,8 @@ struct ExplicitTemplateArgumentList {
void initializeFrom(const TemplateArgumentListInfo &List); void initializeFrom(const TemplateArgumentListInfo &List);
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; void copyInto(TemplateArgumentListInfo &List) const;
static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(unsigned NumTemplateArgs);
static std::size_t sizeFor(const TemplateArgumentListInfo &List); static std::size_t sizeFor(const TemplateArgumentListInfo &List);
@ -747,7 +787,7 @@ class DeclRefExpr : public Expr {
public: public:
DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L) 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) { D(D), Loc(L) {
DeclRefExprBits.HasQualifier = 0; DeclRefExprBits.HasQualifier = 0;
DeclRefExprBits.HasExplicitTemplateArgs = 0; DeclRefExprBits.HasExplicitTemplateArgs = 0;
@ -936,6 +976,7 @@ public:
PredefinedExpr(SourceLocation l, QualType type, IdentType IT) PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
: Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary, : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary,
type->isDependentType(), type->isDependentType(), type->isDependentType(), type->isDependentType(),
type->isInstantiationDependentType(),
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
Loc(l), Type(IT) {} Loc(l), Type(IT) {}
@ -1023,7 +1064,7 @@ public:
IntegerLiteral(ASTContext &C, const llvm::APInt &V, IntegerLiteral(ASTContext &C, const llvm::APInt &V,
QualType type, SourceLocation l) QualType type, SourceLocation l)
: Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false, : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
false), false, false),
Loc(l) { Loc(l) {
assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
assert(V.getBitWidth() == C.getIntWidth(type) && assert(V.getBitWidth() == C.getIntWidth(type) &&
@ -1066,7 +1107,7 @@ public:
// type should be IntTy // type should be IntTy
CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l) CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l)
: Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
false), false, false),
Value(value), Loc(l), IsWide(iswide) { Value(value), Loc(l), IsWide(iswide) {
} }
@ -1101,7 +1142,7 @@ class FloatingLiteral : public Expr {
FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L) QualType Type, SourceLocation L)
: Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
false), false, false),
IsExact(isexact), Loc(L) { IsExact(isexact), Loc(L) {
setValue(C, V); setValue(C, V);
} }
@ -1152,7 +1193,7 @@ class ImaginaryLiteral : public Expr {
public: public:
ImaginaryLiteral(Expr *val, QualType Ty) ImaginaryLiteral(Expr *val, QualType Ty)
: Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
false), false, false),
Val(val) {} Val(val) {}
/// \brief Build an empty imaginary literal. /// \brief Build an empty imaginary literal.
@ -1200,7 +1241,8 @@ class StringLiteral : public Expr {
SourceLocation TokLocs[1]; SourceLocation TokLocs[1];
StringLiteral(QualType Ty) : 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: public:
/// This is the "fully general" constructor that allows representation of /// This is the "fully general" constructor that allows representation of
@ -1287,6 +1329,7 @@ public:
: Expr(ParenExprClass, val->getType(), : Expr(ParenExprClass, val->getType(),
val->getValueKind(), val->getObjectKind(), val->getValueKind(), val->getObjectKind(),
val->isTypeDependent(), val->isValueDependent(), val->isTypeDependent(), val->isValueDependent(),
val->isInstantiationDependent(),
val->containsUnexpandedParameterPack()), val->containsUnexpandedParameterPack()),
L(l), R(r), Val(val) {} L(l), R(r), Val(val) {}
@ -1343,6 +1386,8 @@ public:
: Expr(UnaryOperatorClass, type, VK, OK, : Expr(UnaryOperatorClass, type, VK, OK,
input->isTypeDependent() || type->isDependentType(), input->isTypeDependent() || type->isDependentType(),
input->isValueDependent(), input->isValueDependent(),
(input->isInstantiationDependent() ||
type->isInstantiationDependentType()),
input->containsUnexpandedParameterPack()), input->containsUnexpandedParameterPack()),
Opc(opc), Loc(l), Val(input) {} Opc(opc), Loc(l), Val(input) {}
@ -1638,6 +1683,7 @@ public:
false, // Never type-dependent (C++ [temp.dep.expr]p3). false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent. // Value-dependent if the argument is type-dependent.
TInfo->getType()->isDependentType(), TInfo->getType()->isDependentType(),
TInfo->getType()->isInstantiationDependentType(),
TInfo->getType()->containsUnexpandedParameterPack()), TInfo->getType()->containsUnexpandedParameterPack()),
Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) { Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) {
Argument.Ty = TInfo; Argument.Ty = TInfo;
@ -1650,6 +1696,7 @@ public:
false, // Never type-dependent (C++ [temp.dep.expr]p3). false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent. // Value-dependent if the argument is type-dependent.
E->isTypeDependent(), E->isTypeDependent(),
E->isInstantiationDependent(),
E->containsUnexpandedParameterPack()), E->containsUnexpandedParameterPack()),
Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) { Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) {
Argument.Ex = E; Argument.Ex = E;
@ -1727,6 +1774,8 @@ public:
: Expr(ArraySubscriptExprClass, t, VK, OK, : Expr(ArraySubscriptExprClass, t, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(), lhs->isValueDependent() || rhs->isValueDependent(),
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() || (lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())), rhs->containsUnexpandedParameterPack())),
RBracketLoc(rbracketloc) { RBracketLoc(rbracketloc) {
@ -1984,7 +2033,9 @@ public:
const DeclarationNameInfo &NameInfo, QualType ty, const DeclarationNameInfo &NameInfo, QualType ty,
ExprValueKind VK, ExprObjectKind OK) ExprValueKind VK, ExprObjectKind OK)
: Expr(MemberExprClass, ty, VK, OK, : Expr(MemberExprClass, ty, VK, OK,
base->isTypeDependent(), base->isValueDependent(), base->isTypeDependent(),
base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()), base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()),
MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow),
@ -2001,6 +2052,7 @@ public:
ExprValueKind VK, ExprObjectKind OK) ExprValueKind VK, ExprObjectKind OK)
: Expr(MemberExprClass, ty, VK, OK, : Expr(MemberExprClass, ty, VK, OK,
base->isTypeDependent(), base->isValueDependent(), base->isTypeDependent(), base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()), base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(),
IsArrow(isarrow), IsArrow(isarrow),
@ -2186,6 +2238,8 @@ public:
: Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
tinfo->getType()->isDependentType(), tinfo->getType()->isDependentType(),
init->isValueDependent(), init->isValueDependent(),
(init->isInstantiationDependent() ||
tinfo->getType()->isInstantiationDependentType()),
init->containsUnexpandedParameterPack()), init->containsUnexpandedParameterPack()),
LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {}
@ -2318,6 +2372,8 @@ protected:
// Cast expressions are value-dependent if the type is // Cast expressions are value-dependent if the type is
// dependent or if the subexpression is value-dependent. // dependent or if the subexpression is value-dependent.
ty->isDependentType() || (op && op->isValueDependent()), ty->isDependentType() || (op && op->isValueDependent()),
(ty->isInstantiationDependentType() ||
(op && op->isInstantiationDependent())),
(ty->containsUnexpandedParameterPack() || (ty->containsUnexpandedParameterPack() ||
op->containsUnexpandedParameterPack())), op->containsUnexpandedParameterPack())),
Op(op) { Op(op) {
@ -2551,6 +2607,8 @@ public:
: Expr(BinaryOperatorClass, ResTy, VK, OK, : Expr(BinaryOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(), lhs->isValueDependent() || rhs->isValueDependent(),
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() || (lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())), rhs->containsUnexpandedParameterPack())),
Opc(opc), OpLoc(opLoc) { Opc(opc), OpLoc(opLoc) {
@ -2653,6 +2711,8 @@ protected:
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK, : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isTypeDependent() || rhs->isTypeDependent(),
lhs->isValueDependent() || rhs->isValueDependent(), lhs->isValueDependent() || rhs->isValueDependent(),
(lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(lhs->containsUnexpandedParameterPack() || (lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())), rhs->containsUnexpandedParameterPack())),
Opc(opc), OpLoc(opLoc) { Opc(opc), OpLoc(opLoc) {
@ -2713,11 +2773,11 @@ class AbstractConditionalOperator : public Expr {
protected: protected:
AbstractConditionalOperator(StmtClass SC, QualType T, AbstractConditionalOperator(StmtClass SC, QualType T,
ExprValueKind VK, ExprObjectKind OK, ExprValueKind VK, ExprObjectKind OK,
bool TD, bool VD, bool TD, bool VD, bool ID,
bool ContainsUnexpandedParameterPack, bool ContainsUnexpandedParameterPack,
SourceLocation qloc, SourceLocation qloc,
SourceLocation cloc) SourceLocation cloc)
: Expr(SC, T, VK, OK, TD, VD, ContainsUnexpandedParameterPack), : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
QuestionLoc(qloc), ColonLoc(cloc) {} QuestionLoc(qloc), ColonLoc(cloc) {}
AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
@ -2765,6 +2825,9 @@ public:
(lhs->isTypeDependent() || rhs->isTypeDependent()), (lhs->isTypeDependent() || rhs->isTypeDependent()),
(cond->isValueDependent() || lhs->isValueDependent() || (cond->isValueDependent() || lhs->isValueDependent() ||
rhs->isValueDependent()), rhs->isValueDependent()),
(cond->isInstantiationDependent() ||
lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(cond->containsUnexpandedParameterPack() || (cond->containsUnexpandedParameterPack() ||
lhs->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack()), rhs->containsUnexpandedParameterPack()),
@ -2833,6 +2896,8 @@ public:
: AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
(common->isTypeDependent() || rhs->isTypeDependent()), (common->isTypeDependent() || rhs->isTypeDependent()),
(common->isValueDependent() || rhs->isValueDependent()), (common->isValueDependent() || rhs->isValueDependent()),
(common->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(common->containsUnexpandedParameterPack() || (common->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack()), rhs->containsUnexpandedParameterPack()),
qloc, cloc), qloc, cloc),
@ -2914,7 +2979,8 @@ class AddrLabelExpr : public Expr {
public: public:
AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
QualType t) 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) {} AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
/// \brief Build an empty address of a label expression. /// \brief Build an empty address of a label expression.
@ -2953,10 +3019,12 @@ class StmtExpr : public Expr {
SourceLocation LParenLoc, RParenLoc; SourceLocation LParenLoc, RParenLoc;
public: public:
// FIXME: Does type-dependence need to be computed differently? // 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, StmtExpr(CompoundStmt *substmt, QualType T,
SourceLocation lp, SourceLocation rp) : SourceLocation lp, SourceLocation rp) :
Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
T->isDependentType(), false, false), T->isDependentType(), false, false, false),
SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
/// \brief Build an empty statement expression. /// \brief Build an empty statement expression.
@ -3073,6 +3141,9 @@ public:
QualType t, ExprValueKind VK, ExprObjectKind OK, QualType t, ExprValueKind VK, ExprObjectKind OK,
SourceLocation RP, bool TypeDependent, bool ValueDependent) SourceLocation RP, bool TypeDependent, bool ValueDependent)
: Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
(cond->isInstantiationDependent() ||
lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(cond->containsUnexpandedParameterPack() || (cond->containsUnexpandedParameterPack() ||
lhs->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack())), rhs->containsUnexpandedParameterPack())),
@ -3134,7 +3205,8 @@ class GNUNullExpr : public Expr {
public: public:
GNUNullExpr(QualType Ty, SourceLocation Loc) 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) { } TokenLoc(Loc) { }
/// \brief Build an empty GNU __null expression. /// \brief Build an empty GNU __null expression.
@ -3166,6 +3238,8 @@ public:
SourceLocation RPLoc, QualType t) SourceLocation RPLoc, QualType t)
: Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary,
t->isDependentType(), false, t->isDependentType(), false,
(TInfo->getType()->isInstantiationDependentType() ||
e->isInstantiationDependent()),
(TInfo->getType()->containsUnexpandedParameterPack() || (TInfo->getType()->containsUnexpandedParameterPack() ||
e->containsUnexpandedParameterPack())), e->containsUnexpandedParameterPack())),
Val(e), TInfo(TInfo), Val(e), TInfo(TInfo),
@ -3723,7 +3797,7 @@ class ImplicitValueInitExpr : public Expr {
public: public:
explicit ImplicitValueInitExpr(QualType ty) explicit ImplicitValueInitExpr(QualType ty)
: Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
false, false, false) { } false, false, ty->isInstantiationDependentType(), false) { }
/// \brief Construct an empty implicit value initialization. /// \brief Construct an empty implicit value initialization.
explicit ImplicitValueInitExpr(EmptyShell Empty) explicit ImplicitValueInitExpr(EmptyShell Empty)
@ -3924,6 +3998,7 @@ public:
: Expr(ExtVectorElementExprClass, ty, VK, : Expr(ExtVectorElementExprClass, ty, VK,
(VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
base->isTypeDependent(), base->isValueDependent(), base->isTypeDependent(), base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()), base->containsUnexpandedParameterPack()),
Base(base), Accessor(&accessor), AccessorLoc(loc) {} Base(base), Accessor(&accessor), AccessorLoc(loc) {}
@ -3978,7 +4053,10 @@ protected:
public: public:
BlockExpr(BlockDecl *BD, QualType ty) BlockExpr(BlockDecl *BD, QualType ty)
: Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, : 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) {} TheBlock(BD) {}
/// \brief Build an empty block expression. /// \brief Build an empty block expression.
@ -4062,7 +4140,13 @@ public:
AsTypeExpr(Expr* SrcExpr, QualType DstType, AsTypeExpr(Expr* SrcExpr, QualType DstType,
ExprValueKind VK, ExprObjectKind OK, ExprValueKind VK, ExprObjectKind OK,
SourceLocation BuiltinLoc, SourceLocation RParenLoc) 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), SrcExpr(SrcExpr), DstType(DstType),
BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}

View File

@ -330,7 +330,7 @@ class CXXBoolLiteralExpr : public Expr {
public: public:
CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
false), false, false),
Value(val), Loc(l) {} Value(val), Loc(l) {}
explicit CXXBoolLiteralExpr(EmptyShell Empty) explicit CXXBoolLiteralExpr(EmptyShell Empty)
@ -359,7 +359,7 @@ class CXXNullPtrLiteralExpr : public Expr {
public: public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) : CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
false), false, false),
Loc(l) {} Loc(l) {}
explicit CXXNullPtrLiteralExpr(EmptyShell Empty) explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
@ -395,6 +395,7 @@ public:
false, false,
// typeid is value-dependent if the type or expression are dependent // typeid is value-dependent if the type or expression are dependent
Operand->getType()->isDependentType(), Operand->getType()->isDependentType(),
Operand->getType()->isInstantiationDependentType(),
Operand->getType()->containsUnexpandedParameterPack()), Operand->getType()->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { } Operand(Operand), Range(R) { }
@ -404,6 +405,7 @@ public:
false, false,
// typeid is value-dependent if the type or expression are dependent // typeid is value-dependent if the type or expression are dependent
Operand->isTypeDependent() || Operand->isValueDependent(), Operand->isTypeDependent() || Operand->isValueDependent(),
Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()), Operand->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { } Operand(Operand), Range(R) { }
@ -471,12 +473,14 @@ public:
CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
false, Operand->getType()->isDependentType(), false, Operand->getType()->isDependentType(),
Operand->getType()->isInstantiationDependentType(),
Operand->getType()->containsUnexpandedParameterPack()), Operand->getType()->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { } Operand(Operand), Range(R) { }
CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
false, Operand->isTypeDependent(), false, Operand->isTypeDependent(),
Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()), Operand->containsUnexpandedParameterPack()),
Operand(Operand), Range(R) { } Operand(Operand), Range(R) { }
@ -552,6 +556,7 @@ public:
// 'this' is type-dependent if the class type of the enclosing // 'this' is type-dependent if the class type of the enclosing
// member function is dependent (C++ [temp.dep.expr]p2) // member function is dependent (C++ [temp.dep.expr]p2)
Type->isDependentType(), Type->isDependentType(), Type->isDependentType(), Type->isDependentType(),
Type->isInstantiationDependentType(),
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
Loc(L), Implicit(isImplicit) { } Loc(L), Implicit(isImplicit) { }
@ -587,6 +592,7 @@ public:
// can by null, if the optional expression to throw isn't present. // can by null, if the optional expression to throw isn't present.
CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) : CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
expr && expr->isInstantiationDependent(),
expr && expr->containsUnexpandedParameterPack()), expr && expr->containsUnexpandedParameterPack()),
Op(expr), ThrowLoc(l) {} Op(expr), ThrowLoc(l) {}
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
@ -636,14 +642,14 @@ class CXXDefaultArgExpr : public Expr {
? param->getType().getNonReferenceType() ? param->getType().getNonReferenceType()
: param->getDefaultArg()->getType(), : param->getDefaultArg()->getType(),
param->getDefaultArg()->getValueKind(), param->getDefaultArg()->getValueKind(),
param->getDefaultArg()->getObjectKind(), false, false, false), param->getDefaultArg()->getObjectKind(), false, false, false, false),
Param(param, false), Loc(Loc) { } Param(param, false), Loc(Loc) { }
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
Expr *SubExpr) Expr *SubExpr)
: Expr(SC, SubExpr->getType(), : Expr(SC, SubExpr->getType(),
SubExpr->getValueKind(), SubExpr->getObjectKind(), SubExpr->getValueKind(), SubExpr->getObjectKind(),
false, false, false), false, false, false, false),
Param(param, true), Loc(Loc) { Param(param, true), Loc(Loc) {
*reinterpret_cast<Expr **>(this + 1) = SubExpr; *reinterpret_cast<Expr **>(this + 1) = SubExpr;
} }
@ -742,6 +748,7 @@ class CXXBindTemporaryExpr : public Expr {
: Expr(CXXBindTemporaryExprClass, SubExpr->getType(), : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
SubExpr->isValueDependent(), SubExpr->isValueDependent(),
SubExpr->isInstantiationDependent(),
SubExpr->containsUnexpandedParameterPack()), SubExpr->containsUnexpandedParameterPack()),
Temp(temp), SubExpr(SubExpr) { } Temp(temp), SubExpr(SubExpr) { }
@ -995,7 +1002,7 @@ public:
TypeSourceInfo *TypeInfo, TypeSourceInfo *TypeInfo,
SourceLocation rParenLoc ) : SourceLocation rParenLoc ) :
Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
false, false, false), false, false, Type->isInstantiationDependentType(), false),
RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
explicit CXXScalarValueInitExpr(EmptyShell Shell) explicit CXXScalarValueInitExpr(EmptyShell Shell)
@ -1241,6 +1248,7 @@ public:
bool arrayFormAsWritten, bool usualArrayDeleteWantsSize, bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
: Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
arg->isInstantiationDependent(),
arg->containsUnexpandedParameterPack()), arg->containsUnexpandedParameterPack()),
GlobalDelete(globalDelete), GlobalDelete(globalDelete),
ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
@ -1500,6 +1508,7 @@ public:
SourceLocation rparen, QualType ty) SourceLocation rparen, QualType ty)
: Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
false, queried->getType()->isDependentType(), false, queried->getType()->isDependentType(),
queried->getType()->isInstantiationDependentType(),
queried->getType()->containsUnexpandedParameterPack()), queried->getType()->containsUnexpandedParameterPack()),
UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { } UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
@ -1558,6 +1567,8 @@ public:
: Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
lhsType->getType()->isDependentType() || lhsType->getType()->isDependentType() ||
rhsType->getType()->isDependentType(), rhsType->getType()->isDependentType(),
(lhsType->getType()->isInstantiationDependentType() ||
rhsType->getType()->isInstantiationDependentType()),
(lhsType->getType()->containsUnexpandedParameterPack() || (lhsType->getType()->containsUnexpandedParameterPack() ||
rhsType->getType()->containsUnexpandedParameterPack())), rhsType->getType()->containsUnexpandedParameterPack())),
BTT(btt), Value(value), Loc(loc), RParen(rparen), BTT(btt), Value(value), Loc(loc), RParen(rparen),
@ -1625,6 +1636,8 @@ public:
Expr *dimension, SourceLocation rparen, QualType ty) Expr *dimension, SourceLocation rparen, QualType ty)
: Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
false, queried->getType()->isDependentType(), false, queried->getType()->isDependentType(),
(queried->getType()->isInstantiationDependentType() ||
(dimension && dimension->isInstantiationDependent())),
queried->getType()->containsUnexpandedParameterPack()), queried->getType()->containsUnexpandedParameterPack()),
ATT(att), Value(value), Dimension(dimension), ATT(att), Value(value), Dimension(dimension),
Loc(loc), RParen(rparen), QueriedType(queried) { } Loc(loc), RParen(rparen), QueriedType(queried) { }
@ -1684,6 +1697,7 @@ public:
false, // Not type-dependent false, // Not type-dependent
// Value-dependent if the argument is type-dependent. // Value-dependent if the argument is type-dependent.
queried->isTypeDependent(), queried->isTypeDependent(),
queried->isInstantiationDependent(),
queried->containsUnexpandedParameterPack()), queried->containsUnexpandedParameterPack()),
ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { } ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { }
@ -1736,8 +1750,9 @@ protected:
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End, UnresolvedSetIterator Begin, UnresolvedSetIterator End,
bool KnownDependent = false, bool KnownDependent,
bool KnownContainsUnexpandedParameterPack = false); bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack);
OverloadExpr(StmtClass K, EmptyShell Empty) OverloadExpr(StmtClass K, EmptyShell Empty)
: Expr(K, Empty), Results(0), NumResults(0), : Expr(K, Empty), Results(0), NumResults(0),
@ -1880,7 +1895,7 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedSetIterator Begin, UnresolvedSetIterator End, UnresolvedSetIterator Begin, UnresolvedSetIterator End,
bool StdIsAssociatedNamespace) bool StdIsAssociatedNamespace)
: OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo, : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo,
TemplateArgs, Begin, End), TemplateArgs, Begin, End, false, false, false),
RequiresADL(RequiresADL), RequiresADL(RequiresADL),
StdIsAssociatedNamespace(StdIsAssociatedNamespace), StdIsAssociatedNamespace(StdIsAssociatedNamespace),
Overloaded(Overloaded), NamingClass(NamingClass) Overloaded(Overloaded), NamingClass(NamingClass)
@ -2727,6 +2742,7 @@ public:
: Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
/*TypeDependent*/false, /*TypeDependent*/false,
/*ValueDependent*/Val == CT_Dependent, /*ValueDependent*/Val == CT_Dependent,
Val == CT_Dependent || Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()), Operand->containsUnexpandedParameterPack()),
Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
{ } { }
@ -2787,7 +2803,8 @@ public:
llvm::Optional<unsigned> NumExpansions) llvm::Optional<unsigned> NumExpansions)
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(), : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
Pattern->getObjectKind(), /*TypeDependent=*/true, Pattern->getObjectKind(), /*TypeDependent=*/true,
/*ValueDependent=*/true, /*ContainsUnexpandedParameterPack=*/false), /*ValueDependent=*/true, /*InstantiationDependent=*/true,
/*ContainsUnexpandedParameterPack=*/false),
EllipsisLoc(EllipsisLoc), EllipsisLoc(EllipsisLoc),
NumExpansions(NumExpansions? *NumExpansions + 1 : 0), NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
Pattern(Pattern) { } Pattern(Pattern) { }
@ -2874,6 +2891,7 @@ public:
SourceLocation PackLoc, SourceLocation RParenLoc) SourceLocation PackLoc, SourceLocation RParenLoc)
: Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
/*TypeDependent=*/false, /*ValueDependent=*/true, /*TypeDependent=*/false, /*ValueDependent=*/true,
/*InstantiationDependent=*/true,
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
Length(0), Pack(Pack) { } Length(0), Pack(Pack) { }
@ -2885,6 +2903,7 @@ public:
unsigned Length) unsigned Length)
: Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
/*TypeDependent=*/false, /*ValueDependent=*/false, /*TypeDependent=*/false, /*ValueDependent=*/false,
/*InstantiationDependent=*/false,
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
Length(Length), Pack(Pack) { } Length(Length), Pack(Pack) { }
@ -3018,6 +3037,7 @@ public:
: Expr(MaterializeTemporaryExprClass, T, : Expr(MaterializeTemporaryExprClass, T,
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
Temporary->isTypeDependent(), Temporary->isValueDependent(), Temporary->isTypeDependent(), Temporary->isValueDependent(),
Temporary->isInstantiationDependent(),
Temporary->containsUnexpandedParameterPack()), Temporary->containsUnexpandedParameterPack()),
Temporary(Temporary) { } Temporary(Temporary) { }

View File

@ -30,7 +30,7 @@ class ObjCStringLiteral : public Expr {
public: public:
ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
: Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
false), false, false),
String(SL), AtLoc(L) {} String(SL), AtLoc(L) {}
explicit ObjCStringLiteral(EmptyShell Empty) explicit ObjCStringLiteral(EmptyShell Empty)
: Expr(ObjCStringLiteralClass, Empty) {} : Expr(ObjCStringLiteralClass, Empty) {}
@ -67,6 +67,7 @@ public:
: Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
EncodedType->getType()->isDependentType(), EncodedType->getType()->isDependentType(),
EncodedType->getType()->isDependentType(), EncodedType->getType()->isDependentType(),
EncodedType->getType()->isInstantiationDependentType(),
EncodedType->getType()->containsUnexpandedParameterPack()), EncodedType->getType()->containsUnexpandedParameterPack()),
EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
@ -106,7 +107,7 @@ public:
ObjCSelectorExpr(QualType T, Selector selInfo, ObjCSelectorExpr(QualType T, Selector selInfo,
SourceLocation at, SourceLocation rp) SourceLocation at, SourceLocation rp)
: Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
false), false, false),
SelName(selInfo), AtLoc(at), RParenLoc(rp){} SelName(selInfo), AtLoc(at), RParenLoc(rp){}
explicit ObjCSelectorExpr(EmptyShell Empty) explicit ObjCSelectorExpr(EmptyShell Empty)
: Expr(ObjCSelectorExprClass, Empty) {} : Expr(ObjCSelectorExprClass, Empty) {}
@ -146,7 +147,7 @@ public:
ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
SourceLocation at, SourceLocation rp) SourceLocation at, SourceLocation rp)
: Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
false), false, false),
TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
explicit ObjCProtocolExpr(EmptyShell Empty) explicit ObjCProtocolExpr(EmptyShell Empty)
: Expr(ObjCProtocolExprClass, Empty) {} : Expr(ObjCProtocolExprClass, Empty) {}
@ -186,6 +187,7 @@ public:
bool arrow = false, bool freeIvar = false) : bool arrow = false, bool freeIvar = false) :
Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(), /*TypeDependent=*/false, base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()), base->containsUnexpandedParameterPack()),
D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {}
@ -248,6 +250,7 @@ public:
SourceLocation l, Expr *base) SourceLocation l, Expr *base)
: Expr(ObjCPropertyRefExprClass, t, VK, OK, : Expr(ObjCPropertyRefExprClass, t, VK, OK,
/*TypeDependent=*/false, base->isValueDependent(), /*TypeDependent=*/false, base->isValueDependent(),
base->isInstantiationDependent(),
base->containsUnexpandedParameterPack()), base->containsUnexpandedParameterPack()),
PropertyOrGetter(PD, false), Setter(0), PropertyOrGetter(PD, false), Setter(0),
IdLoc(l), ReceiverLoc(), Receiver(base) { IdLoc(l), ReceiverLoc(), Receiver(base) {
@ -257,7 +260,7 @@ public:
ExprValueKind VK, ExprObjectKind OK, ExprValueKind VK, ExprObjectKind OK,
SourceLocation l, SourceLocation sl, QualType st) SourceLocation l, SourceLocation sl, QualType st)
: Expr(ObjCPropertyRefExprClass, t, VK, OK, : Expr(ObjCPropertyRefExprClass, t, VK, OK,
/*TypeDependent=*/false, false, /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
st->containsUnexpandedParameterPack()), st->containsUnexpandedParameterPack()),
PropertyOrGetter(PD, false), Setter(0), PropertyOrGetter(PD, false), Setter(0),
IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
@ -267,7 +270,7 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK, QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc, Expr *Base) SourceLocation IdLoc, Expr *Base)
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false, : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
Base->isValueDependent(), Base->isValueDependent(), Base->isInstantiationDependent(),
Base->containsUnexpandedParameterPack()), Base->containsUnexpandedParameterPack()),
PropertyOrGetter(Getter, true), Setter(Setter), PropertyOrGetter(Getter, true), Setter(Setter),
IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
@ -277,7 +280,7 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK, QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc, SourceLocation IdLoc,
SourceLocation SuperLoc, QualType SuperTy) 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), PropertyOrGetter(Getter, true), Setter(Setter),
IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
} }
@ -286,7 +289,7 @@ public:
QualType T, ExprValueKind VK, ExprObjectKind OK, QualType T, ExprValueKind VK, ExprObjectKind OK,
SourceLocation IdLoc, SourceLocation IdLoc,
SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) 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), PropertyOrGetter(Getter, true), Setter(Setter),
IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
} }
@ -870,6 +873,7 @@ public:
ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
: Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
/*TypeDependent=*/false, base->isValueDependent(), /*TypeDependent=*/false, base->isValueDependent(),
base->isInstantiationDependent(),
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
@ -944,6 +948,7 @@ public:
ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
: Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
operand->isTypeDependent(), operand->isValueDependent(), operand->isTypeDependent(), operand->isValueDependent(),
operand->isInstantiationDependent(),
operand->containsUnexpandedParameterPack()), operand->containsUnexpandedParameterPack()),
Operand(operand) { Operand(operand) {
setShouldCopy(shouldCopy); setShouldCopy(shouldCopy);

View File

@ -186,6 +186,10 @@ public:
/// type or not. /// type or not.
bool isDependent() const; 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 /// \brief Whether this nested-name-specifier contains an unexpanded
/// parameter pack (for C++0x variadic templates). /// parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const; bool containsUnexpandedParameterPack() const;

View File

@ -154,9 +154,10 @@ protected:
unsigned ObjectKind : 2; unsigned ObjectKind : 2;
unsigned TypeDependent : 1; unsigned TypeDependent : 1;
unsigned ValueDependent : 1; unsigned ValueDependent : 1;
unsigned InstantiationDependent : 1;
unsigned ContainsUnexpandedParameterPack : 1; unsigned ContainsUnexpandedParameterPack : 1;
}; };
enum { NumExprBits = 15 }; enum { NumExprBits = 16 };
class DeclRefExprBitfields { class DeclRefExprBitfields {
friend class DeclRefExpr; friend class DeclRefExpr;

View File

@ -235,9 +235,14 @@ public:
bool isNull() const { return Kind == Null; } bool isNull() const { return Kind == Null; }
/// \brief Whether this template argument is dependent on a template /// \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; 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 /// \brief Whether this template argument contains an unexpanded
/// parameter pack. /// parameter pack.
bool containsUnexpandedParameterPack() const; bool containsUnexpandedParameterPack() const;

View File

@ -292,6 +292,10 @@ public:
/// \brief Determines whether this is a dependent template name. /// \brief Determines whether this is a dependent template name.
bool isDependent() const; 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 /// \brief Determines whether this template name contains an
/// unexpanded parameter pack (for C++0x variadic templates). /// unexpanded parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const; bool containsUnexpandedParameterPack() const;

View File

@ -1065,6 +1065,10 @@ private:
/// subclasses can pack their bitfields into the same word. /// subclasses can pack their bitfields into the same word.
unsigned Dependent : 1; 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). /// \brief Whether this type is a variably-modified type (C99 6.7.5).
unsigned VariablyModified : 1; unsigned VariablyModified : 1;
@ -1102,7 +1106,7 @@ private:
return CachedLocalOrUnnamed; return CachedLocalOrUnnamed;
} }
}; };
enum { NumTypeBits = 17 }; enum { NumTypeBits = 18 };
protected: protected:
// These classes allow subclasses to somewhat cleanly pack bitfields // These classes allow subclasses to somewhat cleanly pack bitfields
@ -1245,12 +1249,14 @@ private:
protected: protected:
// silence VC++ warning C4355: 'this' : used in base member initializer list // silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; } 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) bool ContainsUnexpandedParameterPack)
: ExtQualsTypeCommonBase(this, : ExtQualsTypeCommonBase(this,
canon.isNull() ? QualType(this_(), 0) : canon) { canon.isNull() ? QualType(this_(), 0) : canon) {
TypeBits.TC = tc; TypeBits.TC = tc;
TypeBits.Dependent = Dependent; TypeBits.Dependent = Dependent;
TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
TypeBits.VariablyModified = VariablyModified; TypeBits.VariablyModified = VariablyModified;
TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
TypeBits.CacheValidAndVisibility = 0; TypeBits.CacheValidAndVisibility = 0;
@ -1260,8 +1266,15 @@ protected:
} }
friend class ASTContext; friend class ASTContext;
void setDependent(bool D = true) { TypeBits.Dependent = D; } void setDependent(bool D = true) {
void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } 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) { void setContainsUnexpandedParameterPack(bool PP = true) {
TypeBits.ContainsUnexpandedParameterPack = PP; TypeBits.ContainsUnexpandedParameterPack = PP;
} }
@ -1453,6 +1466,14 @@ public:
/// (C++ [temp.dep.type]). /// (C++ [temp.dep.type]).
bool isDependentType() const { return TypeBits.Dependent; } 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). /// \brief Whether this type is a variably-modified type (C99 6.7.5).
bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
@ -1720,6 +1741,7 @@ public:
public: public:
BuiltinType(Kind K) BuiltinType(Kind K)
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
/*InstantiationDependent=*/(K == Dependent),
/*VariablyModified=*/false, /*VariablyModified=*/false,
/*Unexpanded paramter pack=*/false) { /*Unexpanded paramter pack=*/false) {
BuiltinTypeBits.Kind = K; BuiltinTypeBits.Kind = K;
@ -1765,6 +1787,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
QualType ElementType; QualType ElementType;
ComplexType(QualType Element, QualType CanonicalPtr) : ComplexType(QualType Element, QualType CanonicalPtr) :
Type(Complex, CanonicalPtr, Element->isDependentType(), Type(Complex, CanonicalPtr, Element->isDependentType(),
Element->isInstantiationDependentType(),
Element->isVariablyModifiedType(), Element->isVariablyModifiedType(),
Element->containsUnexpandedParameterPack()), Element->containsUnexpandedParameterPack()),
ElementType(Element) { ElementType(Element) {
@ -1795,6 +1818,7 @@ class ParenType : public Type, public llvm::FoldingSetNode {
ParenType(QualType InnerType, QualType CanonType) : ParenType(QualType InnerType, QualType CanonType) :
Type(Paren, CanonType, InnerType->isDependentType(), Type(Paren, CanonType, InnerType->isDependentType(),
InnerType->isInstantiationDependentType(),
InnerType->isVariablyModifiedType(), InnerType->isVariablyModifiedType(),
InnerType->containsUnexpandedParameterPack()), InnerType->containsUnexpandedParameterPack()),
Inner(InnerType) { Inner(InnerType) {
@ -1826,6 +1850,7 @@ class PointerType : public Type, public llvm::FoldingSetNode {
PointerType(QualType Pointee, QualType CanonicalPtr) : PointerType(QualType Pointee, QualType CanonicalPtr) :
Type(Pointer, CanonicalPtr, Pointee->isDependentType(), Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
Pointee->isInstantiationDependentType(),
Pointee->isVariablyModifiedType(), Pointee->isVariablyModifiedType(),
Pointee->containsUnexpandedParameterPack()), Pointee->containsUnexpandedParameterPack()),
PointeeType(Pointee) { PointeeType(Pointee) {
@ -1858,6 +1883,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType; // Block is some kind of pointer type QualType PointeeType; // Block is some kind of pointer type
BlockPointerType(QualType Pointee, QualType CanonicalCls) : BlockPointerType(QualType Pointee, QualType CanonicalCls) :
Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
Pointee->isInstantiationDependentType(),
Pointee->isVariablyModifiedType(), Pointee->isVariablyModifiedType(),
Pointee->containsUnexpandedParameterPack()), Pointee->containsUnexpandedParameterPack()),
PointeeType(Pointee) { PointeeType(Pointee) {
@ -1894,6 +1920,7 @@ protected:
ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
bool SpelledAsLValue) : bool SpelledAsLValue) :
Type(tc, CanonicalRef, Referencee->isDependentType(), Type(tc, CanonicalRef, Referencee->isDependentType(),
Referencee->isInstantiationDependentType(),
Referencee->isVariablyModifiedType(), Referencee->isVariablyModifiedType(),
Referencee->containsUnexpandedParameterPack()), Referencee->containsUnexpandedParameterPack()),
PointeeType(Referencee) PointeeType(Referencee)
@ -1978,6 +2005,8 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
Type(MemberPointer, CanonicalPtr, Type(MemberPointer, CanonicalPtr,
Cls->isDependentType() || Pointee->isDependentType(), Cls->isDependentType() || Pointee->isDependentType(),
(Cls->isInstantiationDependentType() ||
Pointee->isInstantiationDependentType()),
Pointee->isVariablyModifiedType(), Pointee->isVariablyModifiedType(),
(Cls->containsUnexpandedParameterPack() || (Cls->containsUnexpandedParameterPack() ||
Pointee->containsUnexpandedParameterPack())), Pointee->containsUnexpandedParameterPack())),
@ -2045,6 +2074,7 @@ protected:
ArraySizeModifier sm, unsigned tq, ArraySizeModifier sm, unsigned tq,
bool ContainsUnexpandedParameterPack) bool ContainsUnexpandedParameterPack)
: Type(tc, can, et->isDependentType() || tc == DependentSizedArray, : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
et->isInstantiationDependentType() || tc == DependentSizedArray,
(tc == VariableArray || et->isVariablyModifiedType()), (tc == VariableArray || et->isVariablyModifiedType()),
ContainsUnexpandedParameterPack), ContainsUnexpandedParameterPack),
ElementType(et) { ElementType(et) {
@ -2564,9 +2594,10 @@ protected:
FunctionType(TypeClass tc, QualType res, bool variadic, FunctionType(TypeClass tc, QualType res, bool variadic,
unsigned typeQuals, RefQualifierKind RefQualifier, unsigned typeQuals, RefQualifierKind RefQualifier,
QualType Canonical, bool Dependent, QualType Canonical, bool Dependent,
bool InstantiationDependent,
bool VariablyModified, bool ContainsUnexpandedParameterPack, bool VariablyModified, bool ContainsUnexpandedParameterPack,
ExtInfo Info) ExtInfo Info)
: Type(tc, Canonical, Dependent, VariablyModified, : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
ContainsUnexpandedParameterPack), ContainsUnexpandedParameterPack),
ResultType(res) { ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits; FunctionTypeBits.ExtInfo = Info.Bits;
@ -2611,7 +2642,8 @@ public:
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
: FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical, : FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical,
/*Dependent=*/false, Result->isVariablyModifiedType(), /*Dependent=*/false, /*InstantiationDependent=*/false,
Result->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false, Info) {} /*ContainsUnexpandedParameterPack=*/false, Info) {}
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
@ -2857,7 +2889,7 @@ class UnresolvedUsingType : public Type {
UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingTypenameDecl *Decl;
UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
: Type(UnresolvedUsing, QualType(), true, false, : Type(UnresolvedUsing, QualType(), true, true, false,
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {} Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
@ -2887,7 +2919,9 @@ class TypedefType : public Type {
TypedefNameDecl *Decl; TypedefNameDecl *Decl;
protected: protected:
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) 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), /*ContainsUnexpandedParameterPack=*/false),
Decl(const_cast<TypedefNameDecl*>(D)) { Decl(const_cast<TypedefNameDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type"); assert(!isa<TypedefType>(can) && "Invalid canonical type");
@ -2953,7 +2987,9 @@ public:
class TypeOfType : public Type { class TypeOfType : public Type {
QualType TOType; QualType TOType;
TypeOfType(QualType T, QualType can) TypeOfType(QualType T, QualType can)
: Type(TypeOf, can, T->isDependentType(), T->isVariablyModifiedType(), : Type(TypeOf, can, T->isDependentType(),
T->isInstantiationDependentType(),
T->isVariablyModifiedType(),
T->containsUnexpandedParameterPack()), T->containsUnexpandedParameterPack()),
TOType(T) { TOType(T) {
assert(!isa<TypedefType>(can) && "Invalid canonical type"); assert(!isa<TypedefType>(can) && "Invalid canonical type");
@ -3182,6 +3218,7 @@ private:
AttributedType(QualType canon, Kind attrKind, AttributedType(QualType canon, Kind attrKind,
QualType modified, QualType equivalent) QualType modified, QualType equivalent)
: Type(Attributed, canon, canon->isDependentType(), : Type(Attributed, canon, canon->isDependentType(),
canon->isInstantiationDependentType(),
canon->isVariablyModifiedType(), canon->isVariablyModifiedType(),
canon->containsUnexpandedParameterPack()), canon->containsUnexpandedParameterPack()),
ModifiedType(modified), EquivalentType(equivalent) { ModifiedType(modified), EquivalentType(equivalent) {
@ -3234,13 +3271,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
/// Build a non-canonical type. /// Build a non-canonical type.
TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
: Type(TemplateTypeParm, Canon, /*Dependent=*/true, : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
/*InstantiationDependent=*/true,
/*VariablyModified=*/false, /*VariablyModified=*/false,
Canon->containsUnexpandedParameterPack()), Canon->containsUnexpandedParameterPack()),
TTPDecl(TTPDecl) { } TTPDecl(TTPDecl) { }
/// Build the canonical type. /// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP) 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) { /*VariablyModified=*/false, PP) {
CanTTPTInfo.Depth = D; CanTTPTInfo.Depth = D;
CanTTPTInfo.Index = I; CanTTPTInfo.Index = I;
@ -3300,6 +3340,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
: Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
Canon->isInstantiationDependentType(),
Canon->isVariablyModifiedType(), Canon->isVariablyModifiedType(),
Canon->containsUnexpandedParameterPack()), Canon->containsUnexpandedParameterPack()),
Replaced(Param) { } Replaced(Param) { }
@ -3399,6 +3440,7 @@ class AutoType : public Type, public llvm::FoldingSetNode {
AutoType(QualType DeducedType) AutoType(QualType DeducedType)
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
/*Dependent=*/DeducedType.isNull(), /*Dependent=*/DeducedType.isNull(),
/*InstantiationDependent=*/DeducedType.isNull(),
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) { /*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
assert((DeducedType.isNull() || !DeducedType->isDependentType()) && assert((DeducedType.isNull() || !DeducedType->isDependentType()) &&
"deduced a dependent type for auto"); "deduced a dependent type for auto");
@ -3478,12 +3520,15 @@ public:
/// \brief Determine whether any of the given template arguments are /// \brief Determine whether any of the given template arguments are
/// dependent. /// dependent.
static bool anyDependentTemplateArguments(const TemplateArgument *Args, static bool anyDependentTemplateArguments(const TemplateArgument *Args,
unsigned NumArgs); unsigned NumArgs,
bool &InstantiationDependent);
static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, 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 '>' /// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments. /// enclosing the template arguments.
@ -3594,6 +3639,7 @@ class InjectedClassNameType : public Type {
// interdependencies. // interdependencies.
InjectedClassNameType(CXXRecordDecl *D, QualType TST) InjectedClassNameType(CXXRecordDecl *D, QualType TST)
: Type(InjectedClassName, QualType(), /*Dependent=*/true, : Type(InjectedClassName, QualType(), /*Dependent=*/true,
/*InstantiationDependent=*/true,
/*VariablyModified=*/false, /*VariablyModified=*/false,
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
Decl(D), InjectedType(TST) { Decl(D), InjectedType(TST) {
@ -3656,9 +3702,10 @@ enum ElaboratedTypeKeyword {
class TypeWithKeyword : public Type { class TypeWithKeyword : public Type {
protected: protected:
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
QualType Canonical, bool Dependent, bool VariablyModified, QualType Canonical, bool Dependent,
bool InstantiationDependent, bool VariablyModified,
bool ContainsUnexpandedParameterPack) bool ContainsUnexpandedParameterPack)
: Type(tc, Canonical, Dependent, VariablyModified, : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
ContainsUnexpandedParameterPack) { ContainsUnexpandedParameterPack) {
TypeWithKeywordBits.Keyword = Keyword; TypeWithKeywordBits.Keyword = Keyword;
} }
@ -3718,6 +3765,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
QualType NamedType, QualType CanonType) QualType NamedType, QualType CanonType)
: TypeWithKeyword(Keyword, Elaborated, CanonType, : TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->isDependentType(), NamedType->isDependentType(),
NamedType->isInstantiationDependentType(),
NamedType->isVariablyModifiedType(), NamedType->isVariablyModifiedType(),
NamedType->containsUnexpandedParameterPack()), NamedType->containsUnexpandedParameterPack()),
NNS(NNS), NamedType(NamedType) { NNS(NNS), NamedType(NamedType) {
@ -3780,6 +3828,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType) const IdentifierInfo *Name, QualType CanonType)
: TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
/*InstantiationDependent=*/true,
/*VariablyModified=*/false, /*VariablyModified=*/false,
NNS->containsUnexpandedParameterPack()), NNS->containsUnexpandedParameterPack()),
NNS(NNS), Name(Name) { NNS(NNS), Name(Name) {
@ -3933,6 +3982,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
PackExpansionType(QualType Pattern, QualType Canon, PackExpansionType(QualType Pattern, QualType Canon,
llvm::Optional<unsigned> NumExpansions) llvm::Optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon, /*Dependent=*/true, : Type(PackExpansion, Canon, /*Dependent=*/true,
/*InstantiationDependent=*/true,
/*VariableModified=*/Pattern->isVariablyModifiedType(), /*VariableModified=*/Pattern->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
Pattern(Pattern), Pattern(Pattern),
@ -4024,7 +4074,7 @@ protected:
enum Nonce_ObjCInterface { Nonce_ObjCInterface }; enum Nonce_ObjCInterface { Nonce_ObjCInterface };
ObjCObjectType(enum Nonce_ObjCInterface) ObjCObjectType(enum Nonce_ObjCInterface)
: Type(ObjCInterface, QualType(), false, false, false), : Type(ObjCInterface, QualType(), false, false, false, false),
BaseType(QualType(this_(), 0)) { BaseType(QualType(this_(), 0)) {
ObjCObjectTypeBits.NumProtocols = 0; ObjCObjectTypeBits.NumProtocols = 0;
} }
@ -4181,7 +4231,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType; QualType PointeeType;
ObjCObjectPointerType(QualType Canonical, QualType Pointee) ObjCObjectPointerType(QualType Canonical, QualType Pointee)
: Type(ObjCObjectPointer, Canonical, false, false, false), : Type(ObjCObjectPointer, Canonical, false, false, false, false),
PointeeType(Pointee) {} PointeeType(Pointee) {}
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.

View File

@ -37,6 +37,7 @@ class LocInfoType : public Type {
LocInfoType(QualType ty, TypeSourceInfo *TInfo) LocInfoType(QualType ty, TypeSourceInfo *TInfo)
: Type((TypeClass)LocInfo, ty, ty->isDependentType(), : Type((TypeClass)LocInfo, ty, ty->isDependentType(),
ty->isInstantiationDependentType(),
ty->isVariablyModifiedType(), ty->isVariablyModifiedType(),
ty->containsUnexpandedParameterPack()), ty->containsUnexpandedParameterPack()),
DeclInfo(TInfo) { DeclInfo(TInfo) {

View File

@ -2802,7 +2802,12 @@ static QualType getDecltypeForExpr(const Expr *e, const ASTContext &Context) {
/// on canonical type's (which are always unique). /// on canonical type's (which are always unique).
QualType ASTContext::getDecltypeType(Expr *e) const { QualType ASTContext::getDecltypeType(Expr *e) const {
DecltypeType *dt; 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; llvm::FoldingSetNodeID ID;
DependentDecltypeType::Profile(ID, *this, e); DependentDecltypeType::Profile(ID, *this, e);

View File

@ -533,6 +533,28 @@ bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
llvm_unreachable("All name kinds handled."); 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 DeclarationNameInfo::getAsString() const {
std::string Result; std::string Result;
llvm::raw_string_ostream OS(Result); llvm::raw_string_ostream OS(Result);

View File

@ -142,9 +142,10 @@ void ExplicitTemplateArgumentList::initializeFrom(
} }
void ExplicitTemplateArgumentList::initializeFrom( void ExplicitTemplateArgumentList::initializeFrom(
const TemplateArgumentListInfo &Info, const TemplateArgumentListInfo &Info,
bool &Dependent, bool &Dependent,
bool &ContainsUnexpandedParameterPack) { bool &InstantiationDependent,
bool &ContainsUnexpandedParameterPack) {
LAngleLoc = Info.getLAngleLoc(); LAngleLoc = Info.getLAngleLoc();
RAngleLoc = Info.getRAngleLoc(); RAngleLoc = Info.getRAngleLoc();
NumTemplateArgs = Info.size(); NumTemplateArgs = Info.size();
@ -152,6 +153,8 @@ void ExplicitTemplateArgumentList::initializeFrom(
TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
for (unsigned i = 0; i != NumTemplateArgs; ++i) { for (unsigned i = 0; i != NumTemplateArgs; ++i) {
Dependent = Dependent || Info[i].getArgument().isDependent(); Dependent = Dependent || Info[i].getArgument().isDependent();
InstantiationDependent = InstantiationDependent ||
Info[i].getArgument().isInstantiationDependent();
ContainsUnexpandedParameterPack ContainsUnexpandedParameterPack
= ContainsUnexpandedParameterPack || = ContainsUnexpandedParameterPack ||
Info[i].getArgument().containsUnexpandedParameterPack(); Info[i].getArgument().containsUnexpandedParameterPack();
@ -178,14 +181,16 @@ std::size_t ExplicitTemplateArgumentList::sizeFor(
return sizeFor(Info.size()); 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. /// based on the declaration being referenced.
static void computeDeclRefDependence(NamedDecl *D, QualType T, static void computeDeclRefDependence(NamedDecl *D, QualType T,
bool &TypeDependent, bool &TypeDependent,
bool &ValueDependent) { bool &ValueDependent,
bool &InstantiationDependent) {
TypeDependent = false; TypeDependent = false;
ValueDependent = false; ValueDependent = false;
InstantiationDependent = false;
// (TD) C++ [temp.dep.expr]p3: // (TD) C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains: // An id-expression is type-dependent if it contains:
@ -200,20 +205,31 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T,
if (T->isDependentType()) { if (T->isDependentType()) {
TypeDependent = true; TypeDependent = true;
ValueDependent = true; ValueDependent = true;
InstantiationDependent = true;
return; return;
} else if (T->isInstantiationDependentType()) {
InstantiationDependent = true;
} }
// (TD) - a conversion-function-id that specifies a dependent type // (TD) - a conversion-function-id that specifies a dependent type
if (D->getDeclName().getNameKind() if (D->getDeclName().getNameKind()
== DeclarationName::CXXConversionFunctionName && == DeclarationName::CXXConversionFunctionName) {
D->getDeclName().getCXXNameType()->isDependentType()) { QualType T = D->getDeclName().getCXXNameType();
TypeDependent = true; if (T->isDependentType()) {
ValueDependent = true; TypeDependent = true;
return; ValueDependent = true;
InstantiationDependent = true;
return;
}
if (T->isInstantiationDependentType())
InstantiationDependent = true;
} }
// (VD) - the name of a non-type template parameter, // (VD) - the name of a non-type template parameter,
if (isa<NonTypeTemplateParmDecl>(D)) { if (isa<NonTypeTemplateParmDecl>(D)) {
ValueDependent = true; ValueDependent = true;
InstantiationDependent = true;
return; return;
} }
@ -223,16 +239,20 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T,
if (Var->getType()->isIntegralOrEnumerationType() && if (Var->getType()->isIntegralOrEnumerationType() &&
Var->getType().getCVRQualifiers() == Qualifiers::Const) { Var->getType().getCVRQualifiers() == Qualifiers::Const) {
if (const Expr *Init = Var->getAnyInitializer()) if (const Expr *Init = Var->getAnyInitializer())
if (Init->isValueDependent()) if (Init->isValueDependent()) {
ValueDependent = true; ValueDependent = true;
InstantiationDependent = true;
}
} }
// (VD) - FIXME: Missing from the standard: // (VD) - FIXME: Missing from the standard:
// - a member function or a static data member of the current // - a member function or a static data member of the current
// instantiation // instantiation
else if (Var->isStaticDataMember() && else if (Var->isStaticDataMember() &&
Var->getDeclContext()->isDependentContext()) Var->getDeclContext()->isDependentContext()) {
ValueDependent = true; ValueDependent = true;
InstantiationDependent = true;
}
return; return;
} }
@ -242,6 +262,7 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T,
// instantiation // instantiation
if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) { if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) {
ValueDependent = true; ValueDependent = true;
InstantiationDependent = true;
return; return;
} }
} }
@ -249,7 +270,9 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T,
void DeclRefExpr::computeDependence() { void DeclRefExpr::computeDependence() {
bool TypeDependent = false; bool TypeDependent = false;
bool ValueDependent = false; bool ValueDependent = false;
computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent); bool InstantiationDependent = false;
computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent,
InstantiationDependent);
// (TD) C++ [temp.dep.expr]p3: // (TD) C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains: // An id-expression is type-dependent if it contains:
@ -262,13 +285,16 @@ void DeclRefExpr::computeDependence() {
hasExplicitTemplateArgs() && hasExplicitTemplateArgs() &&
TemplateSpecializationType::anyDependentTemplateArguments( TemplateSpecializationType::anyDependentTemplateArguments(
getTemplateArgs(), getTemplateArgs(),
getNumTemplateArgs())) { getNumTemplateArgs(),
InstantiationDependent)) {
TypeDependent = true; TypeDependent = true;
ValueDependent = true; ValueDependent = true;
InstantiationDependent = true;
} }
ExprBits.TypeDependent = TypeDependent; ExprBits.TypeDependent = TypeDependent;
ExprBits.ValueDependent = ValueDependent; ExprBits.ValueDependent = ValueDependent;
ExprBits.InstantiationDependent = InstantiationDependent;
// Is the declaration a parameter pack? // Is the declaration a parameter pack?
if (getDecl()->isParameterPack()) if (getDecl()->isParameterPack())
@ -280,7 +306,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FoundD, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK) 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()) { D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc) if (QualifierLoc)
@ -289,9 +315,17 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
if (FoundD) if (FoundD)
getInternalFoundDecl() = FoundD; getInternalFoundDecl() = FoundD;
DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0; DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0;
if (TemplateArgs) if (TemplateArgs) {
getExplicitTemplateArgs().initializeFrom(*TemplateArgs); bool Dependent = false;
bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false;
getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
InstantiationDependent,
ContainsUnexpandedParameterPack);
if (InstantiationDependent)
setInstantiationDependent(true);
}
computeDependence(); computeDependence();
} }
@ -670,6 +704,7 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
: Expr(SC, t, VK, OK_Ordinary, : Expr(SC, t, VK, OK_Ordinary,
fn->isTypeDependent(), fn->isTypeDependent(),
fn->isValueDependent(), fn->isValueDependent(),
fn->isInstantiationDependent(),
fn->containsUnexpandedParameterPack()), fn->containsUnexpandedParameterPack()),
NumArgs(numargs) { NumArgs(numargs) {
@ -680,6 +715,8 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (args[i]->isValueDependent()) if (args[i]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (args[i]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (args[i]->containsUnexpandedParameterPack()) if (args[i]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -695,6 +732,7 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
: Expr(CallExprClass, t, VK, OK_Ordinary, : Expr(CallExprClass, t, VK, OK_Ordinary,
fn->isTypeDependent(), fn->isTypeDependent(),
fn->isValueDependent(), fn->isValueDependent(),
fn->isInstantiationDependent(),
fn->containsUnexpandedParameterPack()), fn->containsUnexpandedParameterPack()),
NumArgs(numargs) { NumArgs(numargs) {
@ -705,6 +743,8 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (args[i]->isValueDependent()) if (args[i]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (args[i]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (args[i]->containsUnexpandedParameterPack()) if (args[i]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -862,6 +902,7 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type,
: Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary, : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary,
/*TypeDependent=*/false, /*TypeDependent=*/false,
/*ValueDependent=*/tsi->getType()->isDependentType(), /*ValueDependent=*/tsi->getType()->isDependentType(),
tsi->getType()->isInstantiationDependentType(),
tsi->getType()->containsUnexpandedParameterPack()), tsi->getType()->containsUnexpandedParameterPack()),
OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi),
NumComps(numComps), NumExprs(numExprs) NumComps(numComps), NumExprs(numExprs)
@ -917,7 +958,12 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) { if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) {
E->setValueDependent(true); E->setValueDependent(true);
E->setTypeDependent(true); E->setTypeDependent(true);
} E->setInstantiationDependent(true);
}
else if (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
E->setInstantiationDependent(true);
E->HasQualifierOrFoundDecl = true; E->HasQualifierOrFoundDecl = true;
MemberNameQualifier *NQ = E->getMemberQualifier(); MemberNameQualifier *NQ = E->getMemberQualifier();
@ -926,8 +972,15 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
} }
if (targs) { if (targs) {
bool Dependent = false;
bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false;
E->HasExplicitTemplateArgumentList = true; E->HasExplicitTemplateArgumentList = true;
E->getExplicitTemplateArgs().initializeFrom(*targs); E->getExplicitTemplateArgs().initializeFrom(*targs, Dependent,
InstantiationDependent,
ContainsUnexpandedParameterPack);
if (InstantiationDependent)
E->setInstantiationDependent(true);
} }
return E; return E;
@ -1251,7 +1304,7 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
Expr **initExprs, unsigned numInits, Expr **initExprs, unsigned numInits,
SourceLocation rbraceloc) SourceLocation rbraceloc)
: Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false, : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
false), false, false),
InitExprs(C, numInits), InitExprs(C, numInits),
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
HadArrayRangeDesignator(false) HadArrayRangeDesignator(false)
@ -1261,6 +1314,8 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (initExprs[I]->isValueDependent()) if (initExprs[I]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (initExprs[I]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (initExprs[I]->containsUnexpandedParameterPack()) if (initExprs[I]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
} }
@ -2575,6 +2630,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
SourceLocation RBracLoc) SourceLocation RBracLoc)
: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
/*TypeDependent=*/false, /*ValueDependent=*/false, /*TypeDependent=*/false, /*ValueDependent=*/false,
/*InstantiationDependent=*/false,
/*ContainsUnexpandedParameterPack=*/false), /*ContainsUnexpandedParameterPack=*/false),
NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass), NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass),
HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc), HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc),
@ -2597,7 +2653,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
SourceLocation RBracLoc) SourceLocation RBracLoc)
: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
T->isDependentType(), T->containsUnexpandedParameterPack()), T->isDependentType(), T->isInstantiationDependentType(),
T->containsUnexpandedParameterPack()),
NumArgs(NumArgs), Kind(Class), NumArgs(NumArgs), Kind(Class),
HasMethod(Method != 0), IsDelegateInitCall(false), HasMethod(Method != 0), IsDelegateInitCall(false),
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
@ -2611,6 +2668,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (Args[I]->isValueDependent()) if (Args[I]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (Args[I]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (Args[I]->containsUnexpandedParameterPack()) if (Args[I]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -2629,6 +2688,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
SourceLocation RBracLoc) SourceLocation RBracLoc)
: Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(),
Receiver->isTypeDependent(), Receiver->isTypeDependent(),
Receiver->isInstantiationDependent(),
Receiver->containsUnexpandedParameterPack()), Receiver->containsUnexpandedParameterPack()),
NumArgs(NumArgs), Kind(Instance), NumArgs(NumArgs), Kind(Instance),
HasMethod(Method != 0), IsDelegateInitCall(false), HasMethod(Method != 0), IsDelegateInitCall(false),
@ -2643,6 +2703,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (Args[I]->isValueDependent()) if (Args[I]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (Args[I]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (Args[I]->containsUnexpandedParameterPack()) if (Args[I]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -2784,6 +2846,7 @@ ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr,
SourceLocation RP) SourceLocation RP)
: Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary, : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
Type->isDependentType(), Type->isDependentType(), Type->isDependentType(), Type->isDependentType(),
Type->isInstantiationDependentType(),
Type->containsUnexpandedParameterPack()), Type->containsUnexpandedParameterPack()),
BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr)
{ {
@ -2793,6 +2856,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (args[i]->isValueDependent()) if (args[i]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (args[i]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (args[i]->containsUnexpandedParameterPack()) if (args[i]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -2822,6 +2887,7 @@ GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context,
AssocExprs[ResultIndex]->getObjectKind(), AssocExprs[ResultIndex]->getObjectKind(),
AssocExprs[ResultIndex]->isTypeDependent(), AssocExprs[ResultIndex]->isTypeDependent(),
AssocExprs[ResultIndex]->isValueDependent(), AssocExprs[ResultIndex]->isValueDependent(),
AssocExprs[ResultIndex]->isInstantiationDependent(),
ContainsUnexpandedParameterPack), ContainsUnexpandedParameterPack),
AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]),
SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs),
@ -2842,8 +2908,9 @@ GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context,
Context.DependentTy, Context.DependentTy,
VK_RValue, VK_RValue,
OK_Ordinary, OK_Ordinary,
/*isTypeDependent=*/ true, /*isTypeDependent=*/true,
/*isValueDependent=*/ true, /*isValueDependent=*/true,
/*isInstantiationDependent=*/true,
ContainsUnexpandedParameterPack), ContainsUnexpandedParameterPack),
AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]),
SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs),
@ -2877,6 +2944,7 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty,
: Expr(DesignatedInitExprClass, Ty, : Expr(DesignatedInitExprClass, Ty,
Init->getValueKind(), Init->getObjectKind(), Init->getValueKind(), Init->getObjectKind(),
Init->isTypeDependent(), Init->isValueDependent(), Init->isTypeDependent(), Init->isValueDependent(),
Init->isInstantiationDependent(),
Init->containsUnexpandedParameterPack()), Init->containsUnexpandedParameterPack()),
EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) {
@ -2897,7 +2965,8 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty,
Expr *Index = IndexExprs[IndexIdx]; Expr *Index = IndexExprs[IndexIdx];
if (Index->isTypeDependent() || Index->isValueDependent()) if (Index->isTypeDependent() || Index->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (Index->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
// Propagate unexpanded parameter packs. // Propagate unexpanded parameter packs.
if (Index->containsUnexpandedParameterPack()) if (Index->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -2909,9 +2978,14 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty,
Expr *Start = IndexExprs[IndexIdx]; Expr *Start = IndexExprs[IndexIdx];
Expr *End = IndexExprs[IndexIdx + 1]; Expr *End = IndexExprs[IndexIdx + 1];
if (Start->isTypeDependent() || Start->isValueDependent() || if (Start->isTypeDependent() || Start->isValueDependent() ||
End->isTypeDependent() || End->isValueDependent()) End->isTypeDependent() || End->isValueDependent()) {
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
ExprBits.InstantiationDependent = true;
} else if (Start->isInstantiationDependent() ||
End->isInstantiationDependent()) {
ExprBits.InstantiationDependent = true;
}
// Propagate unexpanded parameter packs. // Propagate unexpanded parameter packs.
if (Start->containsUnexpandedParameterPack() || if (Start->containsUnexpandedParameterPack() ||
End->containsUnexpandedParameterPack()) End->containsUnexpandedParameterPack())
@ -3035,7 +3109,7 @@ ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
Expr **exprs, unsigned nexprs, Expr **exprs, unsigned nexprs,
SourceLocation rparenloc, QualType T) SourceLocation rparenloc, QualType T)
: Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary, : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
false, false, false), false, false, false, false),
NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
assert(!T.isNull() && "ParenListExpr must have a valid type"); assert(!T.isNull() && "ParenListExpr must have a valid type");
Exprs = new (C) Stmt*[nexprs]; Exprs = new (C) Stmt*[nexprs];
@ -3044,6 +3118,8 @@ ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
if (exprs[i]->isValueDependent()) if (exprs[i]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (exprs[i]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (exprs[i]->containsUnexpandedParameterPack()) if (exprs[i]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -3108,13 +3184,16 @@ Stmt::child_range ObjCMessageExpr::children() {
BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK,
SourceLocation l, bool ByRef, SourceLocation l, bool ByRef,
bool constAdded) bool constAdded)
: Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, false,
d->isParameterPack()), d->isParameterPack()),
D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded) D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded)
{ {
bool TypeDependent = false; bool TypeDependent = false;
bool ValueDependent = false; bool ValueDependent = false;
computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent); bool InstantiationDependent = false;
computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent,
InstantiationDependent);
ExprBits.TypeDependent = TypeDependent; ExprBits.TypeDependent = TypeDependent;
ExprBits.ValueDependent = ValueDependent; ExprBits.ValueDependent = ValueDependent;
ExprBits.InstantiationDependent = InstantiationDependent;
} }

View File

@ -57,6 +57,7 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
SourceLocation constructorRParen) SourceLocation constructorRParen)
: Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
ty->isDependentType(), ty->isDependentType(), ty->isDependentType(), ty->isDependentType(),
ty->isInstantiationDependentType(),
ty->containsUnexpandedParameterPack()), ty->containsUnexpandedParameterPack()),
GlobalNew(globalNew), Initializer(initializer), GlobalNew(globalNew), Initializer(initializer),
UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
@ -68,6 +69,9 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs); AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
unsigned i = 0; unsigned i = 0;
if (Array) { if (Array) {
if (arraySize->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (arraySize->containsUnexpandedParameterPack()) if (arraySize->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -75,6 +79,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
} }
for (unsigned j = 0; j < NumPlacementArgs; ++j) { for (unsigned j = 0; j < NumPlacementArgs; ++j) {
if (placementArgs[j]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (placementArgs[j]->containsUnexpandedParameterPack()) if (placementArgs[j]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -82,6 +88,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
} }
for (unsigned j = 0; j < NumConstructorArgs; ++j) { for (unsigned j = 0; j < NumConstructorArgs; ++j) {
if (constructorArgs[j]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (constructorArgs[j]->containsUnexpandedParameterPack()) if (constructorArgs[j]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -144,6 +152,14 @@ CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context,
(DestroyedType.getTypeSourceInfo() && (DestroyedType.getTypeSourceInfo() &&
DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
/*isValueDependent=*/Base->isValueDependent(), /*isValueDependent=*/Base->isValueDependent(),
(Base->isInstantiationDependent() ||
(QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) ||
(ScopeType &&
ScopeType->getType()->isInstantiationDependentType()) ||
(DestroyedType.getTypeSourceInfo() &&
DestroyedType.getTypeSourceInfo()->getType()
->isInstantiationDependentType())),
// ContainsUnexpandedParameterPack // ContainsUnexpandedParameterPack
(Base->containsUnexpandedParameterPack() || (Base->containsUnexpandedParameterPack() ||
(QualifierLoc && (QualifierLoc &&
@ -212,9 +228,14 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C,
UnresolvedSetIterator Begin, UnresolvedSetIterator Begin,
UnresolvedSetIterator End, UnresolvedSetIterator End,
bool KnownDependent, bool KnownDependent,
bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack) bool KnownContainsUnexpandedParameterPack)
: Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
KnownDependent, KnownDependent,
(KnownInstantiationDependent ||
NameInfo.isInstantiationDependent() ||
(QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
(KnownContainsUnexpandedParameterPack || (KnownContainsUnexpandedParameterPack ||
NameInfo.containsUnexpandedParameterPack() || NameInfo.containsUnexpandedParameterPack() ||
(QualifierLoc && (QualifierLoc &&
@ -246,14 +267,18 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C,
// expansions. // expansions.
if (TemplateArgs) { if (TemplateArgs) {
bool Dependent = false; bool Dependent = false;
bool InstantiationDependent = false;
bool ContainsUnexpandedParameterPack = false; bool ContainsUnexpandedParameterPack = false;
getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
InstantiationDependent,
ContainsUnexpandedParameterPack); ContainsUnexpandedParameterPack);
if (Dependent) { if (Dependent) {
ExprBits.TypeDependent = true; ExprBits.TypeDependent = true;
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
} }
if (InstantiationDependent)
ExprBits.InstantiationDependent = true;
if (ContainsUnexpandedParameterPack) if (ContainsUnexpandedParameterPack)
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
} }
@ -291,6 +316,9 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
const TemplateArgumentListInfo *Args) const TemplateArgumentListInfo *Args)
: Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary,
true, true, true, true,
(NameInfo.isInstantiationDependent() ||
(QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
(NameInfo.containsUnexpandedParameterPack() || (NameInfo.containsUnexpandedParameterPack() ||
(QualifierLoc && (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier() QualifierLoc.getNestedNameSpecifier()
@ -300,11 +328,14 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
{ {
if (Args) { if (Args) {
bool Dependent = true; bool Dependent = true;
bool InstantiationDependent = true;
bool ContainsUnexpandedParameterPack bool ContainsUnexpandedParameterPack
= ExprBits.ContainsUnexpandedParameterPack; = ExprBits.ContainsUnexpandedParameterPack;
reinterpret_cast<ExplicitTemplateArgumentList*>(this+1) reinterpret_cast<ExplicitTemplateArgumentList*>(this+1)
->initializeFrom(*Args, Dependent, ContainsUnexpandedParameterPack); ->initializeFrom(*Args, Dependent, InstantiationDependent,
ContainsUnexpandedParameterPack);
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
} }
} }
@ -632,6 +663,7 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
SourceRange ParenRange) SourceRange ParenRange)
: Expr(SC, T, VK_RValue, OK_Ordinary, : Expr(SC, T, VK_RValue, OK_Ordinary,
T->isDependentType(), T->isDependentType(), T->isDependentType(), T->isDependentType(),
T->isInstantiationDependentType(),
T->containsUnexpandedParameterPack()), T->containsUnexpandedParameterPack()),
Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable), Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable),
ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
@ -645,6 +677,8 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
if (args[i]->isValueDependent()) if (args[i]->isValueDependent())
ExprBits.ValueDependent = true; ExprBits.ValueDependent = true;
if (args[i]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
if (args[i]->containsUnexpandedParameterPack()) if (args[i]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -660,6 +694,7 @@ ExprWithCleanups::ExprWithCleanups(ASTContext &C,
: Expr(ExprWithCleanupsClass, subexpr->getType(), : Expr(ExprWithCleanupsClass, subexpr->getType(),
subexpr->getValueKind(), subexpr->getObjectKind(), subexpr->getValueKind(), subexpr->getObjectKind(),
subexpr->isTypeDependent(), subexpr->isValueDependent(), subexpr->isTypeDependent(), subexpr->isValueDependent(),
subexpr->isInstantiationDependent(),
subexpr->containsUnexpandedParameterPack()), subexpr->containsUnexpandedParameterPack()),
SubExpr(subexpr), Temps(0), NumTemps(0) { SubExpr(subexpr), Temps(0), NumTemps(0) {
if (numtemps) { if (numtemps) {
@ -691,7 +726,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
: Expr(CXXUnresolvedConstructExprClass, : Expr(CXXUnresolvedConstructExprClass,
Type->getType().getNonReferenceType(), Type->getType().getNonReferenceType(),
VK_LValue, OK_Ordinary, VK_LValue, OK_Ordinary,
Type->getType()->isDependentType(), true, Type->getType()->isDependentType(), true, true,
Type->getType()->containsUnexpandedParameterPack()), Type->getType()->containsUnexpandedParameterPack()),
Type(Type), Type(Type),
LParenLoc(LParenLoc), LParenLoc(LParenLoc),
@ -740,7 +775,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
DeclarationNameInfo MemberNameInfo, DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs) const TemplateArgumentListInfo *TemplateArgs)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
VK_LValue, OK_Ordinary, true, true, VK_LValue, OK_Ordinary, true, true, true,
((Base && Base->containsUnexpandedParameterPack()) || ((Base && Base->containsUnexpandedParameterPack()) ||
(QualifierLoc && (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier() QualifierLoc.getNestedNameSpecifier()
@ -753,8 +788,10 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
MemberNameInfo(MemberNameInfo) { MemberNameInfo(MemberNameInfo) {
if (TemplateArgs) { if (TemplateArgs) {
bool Dependent = true; bool Dependent = true;
bool InstantiationDependent = true;
bool ContainsUnexpandedParameterPack = false; bool ContainsUnexpandedParameterPack = false;
getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
InstantiationDependent,
ContainsUnexpandedParameterPack); ContainsUnexpandedParameterPack);
if (ContainsUnexpandedParameterPack) if (ContainsUnexpandedParameterPack)
ExprBits.ContainsUnexpandedParameterPack = true; ExprBits.ContainsUnexpandedParameterPack = true;
@ -769,7 +806,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
NamedDecl *FirstQualifierFoundInScope, NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo) DeclarationNameInfo MemberNameInfo)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
VK_LValue, OK_Ordinary, true, true, VK_LValue, OK_Ordinary, true, true, true,
((Base && Base->containsUnexpandedParameterPack()) || ((Base && Base->containsUnexpandedParameterPack()) ||
(QualifierLoc && (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()-> QualifierLoc.getNestedNameSpecifier()->
@ -874,6 +911,8 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C,
// Dependent // Dependent
((Base && Base->isTypeDependent()) || ((Base && Base->isTypeDependent()) ||
BaseType->isDependentType()), BaseType->isDependentType()),
((Base && Base->isInstantiationDependent()) ||
BaseType->isInstantiationDependentType()),
// Contains unexpanded parameter pack // Contains unexpanded parameter pack
((Base && Base->containsUnexpandedParameterPack()) || ((Base && Base->containsUnexpandedParameterPack()) ||
BaseType->containsUnexpandedParameterPack())), BaseType->containsUnexpandedParameterPack())),
@ -962,7 +1001,7 @@ SubstNonTypeTemplateParmPackExpr(QualType T,
SourceLocation NameLoc, SourceLocation NameLoc,
const TemplateArgument &ArgPack) const TemplateArgument &ArgPack)
: Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary,
true, false, true), true, true, true, true),
Param(Param), Arguments(ArgPack.pack_begin()), Param(Param), Arguments(ArgPack.pack_begin()),
NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { } NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { }

View File

@ -174,6 +174,28 @@ bool NestedNameSpecifier::isDependent() const {
return false; 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 { bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
switch (getKind()) { switch (getKind()) {
case Identifier: case Identifier:

View File

@ -104,6 +104,45 @@ bool TemplateArgument::isDependent() const {
return false; 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<DeclContext>(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 { bool TemplateArgument::isPackExpansion() const {
switch (getKind()) { switch (getKind()) {
case Null: case Null:

View File

@ -99,6 +99,15 @@ bool TemplateName::isDependent() const {
return true; return true;
} }
bool TemplateName::isInstantiationDependent() const {
if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
if (QTN->getQualifier()->isInstantiationDependent())
return true;
}
return isDependent();
}
bool TemplateName::containsUnexpandedParameterPack() const { bool TemplateName::containsUnexpandedParameterPack() const {
if (TemplateDecl *Template = getAsTemplateDecl()) { if (TemplateDecl *Template = getAsTemplateDecl()) {
if (TemplateTemplateParmDecl *TTP if (TemplateTemplateParmDecl *TTP

View File

@ -110,6 +110,7 @@ DependentSizedExtVectorType::DependentSizedExtVectorType(const
Expr *SizeExpr, Expr *SizeExpr,
SourceLocation loc) SourceLocation loc)
: Type(DependentSizedExtVector, can, /*Dependent=*/true, : Type(DependentSizedExtVector, can, /*Dependent=*/true,
/*InstantiationDependent=*/true,
ElementType->isVariablyModifiedType(), ElementType->isVariablyModifiedType(),
(ElementType->containsUnexpandedParameterPack() || (ElementType->containsUnexpandedParameterPack() ||
(SizeExpr && SizeExpr->containsUnexpandedParameterPack()))), (SizeExpr && SizeExpr->containsUnexpandedParameterPack()))),
@ -129,6 +130,7 @@ DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType,
VectorKind vecKind) VectorKind vecKind)
: Type(Vector, canonType, vecType->isDependentType(), : Type(Vector, canonType, vecType->isDependentType(),
vecType->isInstantiationDependentType(),
vecType->isVariablyModifiedType(), vecType->isVariablyModifiedType(),
vecType->containsUnexpandedParameterPack()), vecType->containsUnexpandedParameterPack()),
ElementType(vecType) ElementType(vecType)
@ -140,6 +142,7 @@ VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType,
VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements, VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
QualType canonType, VectorKind vecKind) QualType canonType, VectorKind vecKind)
: Type(tc, canonType, vecType->isDependentType(), : Type(tc, canonType, vecType->isDependentType(),
vecType->isInstantiationDependentType(),
vecType->isVariablyModifiedType(), vecType->isVariablyModifiedType(),
vecType->containsUnexpandedParameterPack()), vecType->containsUnexpandedParameterPack()),
ElementType(vecType) ElementType(vecType)
@ -387,7 +390,7 @@ const RecordType *Type::getAsUnionType() const {
ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
ObjCProtocolDecl * const *Protocols, ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) unsigned NumProtocols)
: Type(ObjCObject, Canonical, false, false, false), : Type(ObjCObject, Canonical, false, false, false, false),
BaseType(Base) BaseType(Base)
{ {
ObjCObjectTypeBits.NumProtocols = NumProtocols; ObjCObjectTypeBits.NumProtocols = NumProtocols;
@ -1350,7 +1353,7 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType(
NestedNameSpecifier *NNS, const IdentifierInfo *Name, NestedNameSpecifier *NNS, const IdentifierInfo *Name,
unsigned NumArgs, const TemplateArgument *Args, unsigned NumArgs, const TemplateArgument *Args,
QualType Canon) QualType Canon)
: TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true,
/*VariablyModified=*/false, /*VariablyModified=*/false,
NNS && NNS->containsUnexpandedParameterPack()), NNS && NNS->containsUnexpandedParameterPack()),
NNS(NNS), Name(Name), NumArgs(NumArgs) { NNS(NNS), Name(Name), NumArgs(NumArgs) {
@ -1485,6 +1488,7 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
: FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals,
epi.RefQualifier, canonical, epi.RefQualifier, canonical,
result->isDependentType(), result->isDependentType(),
result->isInstantiationDependentType(),
result->isVariablyModifiedType(), result->isVariablyModifiedType(),
result->containsUnexpandedParameterPack(), result->containsUnexpandedParameterPack(),
epi.ExtInfo), epi.ExtInfo),
@ -1497,7 +1501,9 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
for (unsigned i = 0; i != numArgs; ++i) { for (unsigned i = 0; i != numArgs; ++i) {
if (args[i]->isDependentType()) if (args[i]->isDependentType())
setDependent(); setDependent();
else if (args[i]->isInstantiationDependentType())
setInstantiationDependent();
if (args[i]->containsUnexpandedParameterPack()) if (args[i]->containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack(); setContainsUnexpandedParameterPack();
@ -1510,7 +1516,9 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) { for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) {
if (epi.Exceptions[i]->isDependentType()) if (epi.Exceptions[i]->isDependentType())
setDependent(); setDependent();
else if (epi.Exceptions[i]->isInstantiationDependentType())
setInstantiationDependent();
if (epi.Exceptions[i]->containsUnexpandedParameterPack()) if (epi.Exceptions[i]->containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack(); setContainsUnexpandedParameterPack();
@ -1520,6 +1528,14 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
// Store the noexcept expression and context. // Store the noexcept expression and context.
Expr **noexSlot = reinterpret_cast<Expr**>(argSlot + numArgs); Expr **noexSlot = reinterpret_cast<Expr**>(argSlot + numArgs);
*noexSlot = epi.NoexceptExpr; *noexSlot = epi.NoexceptExpr;
if (epi.NoexceptExpr) {
if (epi.NoexceptExpr->isValueDependent()
|| epi.NoexceptExpr->isTypeDependent())
setDependent();
else if (epi.NoexceptExpr->isInstantiationDependent())
setInstantiationDependent();
}
} }
if (epi.ConsumedArguments) { if (epi.ConsumedArguments) {
@ -1623,6 +1639,7 @@ QualType TypedefType::desugar() const {
TypeOfExprType::TypeOfExprType(Expr *E, QualType can) TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
: Type(TypeOfExpr, can, E->isTypeDependent(), : Type(TypeOfExpr, can, E->isTypeDependent(),
E->isInstantiationDependent(),
E->getType()->isVariablyModifiedType(), E->getType()->isVariablyModifiedType(),
E->containsUnexpandedParameterPack()), E->containsUnexpandedParameterPack()),
TOExpr(E) { TOExpr(E) {
@ -1639,6 +1656,7 @@ void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
: Type(Decltype, can, E->isTypeDependent(), : Type(Decltype, can, E->isTypeDependent(),
E->isInstantiationDependent(),
E->getType()->isVariablyModifiedType(), E->getType()->isVariablyModifiedType(),
E->containsUnexpandedParameterPack()), E->containsUnexpandedParameterPack()),
E(E), E(E),
@ -1654,7 +1672,9 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
} }
TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) 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), /*ContainsUnexpandedParameterPack=*/false),
decl(const_cast<TagDecl*>(D)) {} decl(const_cast<TagDecl*>(D)) {}
@ -1674,6 +1694,7 @@ UnaryTransformType::UnaryTransformType(QualType BaseType,
UTTKind UKind, UTTKind UKind,
QualType CanonicalType) QualType CanonicalType)
: Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(), : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(),
UnderlyingType->isInstantiationDependentType(),
UnderlyingType->isVariablyModifiedType(), UnderlyingType->isVariablyModifiedType(),
BaseType->containsUnexpandedParameterPack()) BaseType->containsUnexpandedParameterPack())
, BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind)
@ -1707,7 +1728,8 @@ SubstTemplateTypeParmPackType::
SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
QualType Canon, QualType Canon,
const TemplateArgument &ArgPack) 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()) Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size())
{ {
} }
@ -1732,23 +1754,39 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
} }
bool TemplateSpecializationType:: bool TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) { anyDependentTemplateArguments(const TemplateArgumentListInfo &Args,
return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size()); bool &InstantiationDependent) {
return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size(),
InstantiationDependent);
} }
bool TemplateSpecializationType:: bool TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N,
for (unsigned i = 0; i != N; ++i) bool &InstantiationDependent) {
if (Args[i].getArgument().isDependent()) for (unsigned i = 0; i != N; ++i) {
if (Args[i].getArgument().isDependent()) {
InstantiationDependent = true;
return true; return true;
}
if (Args[i].getArgument().isInstantiationDependent())
InstantiationDependent = true;
}
return false; return false;
} }
bool TemplateSpecializationType:: bool TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) { anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N,
for (unsigned i = 0; i != N; ++i) bool &InstantiationDependent) {
if (Args[i].isDependent()) for (unsigned i = 0; i != N; ++i) {
if (Args[i].isDependent()) {
InstantiationDependent = true;
return true; return true;
}
if (Args[i].isInstantiationDependent())
InstantiationDependent = true;
}
return false; return false;
} }
@ -1759,6 +1797,8 @@ TemplateSpecializationType(TemplateName T,
: Type(TemplateSpecialization, : Type(TemplateSpecialization,
Canon.isNull()? QualType(this, 0) : Canon, Canon.isNull()? QualType(this, 0) : Canon,
Canon.isNull()? T.isDependent() : Canon->isDependentType(), Canon.isNull()? T.isDependent() : Canon->isDependentType(),
Canon.isNull()? T.isDependent()
: Canon->isInstantiationDependentType(),
false, T.containsUnexpandedParameterPack()), false, T.containsUnexpandedParameterPack()),
Template(T), NumArgs(NumArgs) { Template(T), NumArgs(NumArgs) {
assert(!T.getAsDependentTemplateName() && assert(!T.getAsDependentTemplateName() &&
@ -1767,8 +1807,12 @@ TemplateSpecializationType(TemplateName T,
T.getKind() == TemplateName::SubstTemplateTemplateParm || T.getKind() == TemplateName::SubstTemplateTemplateParm ||
T.getKind() == TemplateName::SubstTemplateTemplateParmPack) && T.getKind() == TemplateName::SubstTemplateTemplateParmPack) &&
"Unexpected template name for TemplateSpecializationType"); "Unexpected template name for TemplateSpecializationType");
bool InstantiationDependent;
(void)InstantiationDependent;
assert((!Canon.isNull() || assert((!Canon.isNull() ||
T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) && T.isDependent() ||
anyDependentTemplateArguments(Args, NumArgs,
InstantiationDependent)) &&
"No canonical type for non-dependent class template specialization"); "No canonical type for non-dependent class template specialization");
TemplateArgument *TemplateArgs TemplateArgument *TemplateArgs
@ -1782,6 +1826,9 @@ TemplateSpecializationType(TemplateName T,
// U<T> is always non-dependent, irrespective of the type T. // U<T> is always non-dependent, irrespective of the type T.
if (Canon.isNull() && Args[Arg].isDependent()) if (Canon.isNull() && Args[Arg].isDependent())
setDependent(); setDependent();
else if (Args[Arg].isInstantiationDependent())
setInstantiationDependent();
if (Args[Arg].getKind() == TemplateArgument::Type && if (Args[Arg].getKind() == TemplateArgument::Type &&
Args[Arg].getAsType()->isVariablyModifiedType()) Args[Arg].getAsType()->isVariablyModifiedType())
setVariablyModified(); setVariablyModified();

View File

@ -1898,6 +1898,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
QualType CanonType; QualType CanonType;
bool InstantiationDependent = false;
if (TypeAliasTemplateDecl *AliasTemplate if (TypeAliasTemplateDecl *AliasTemplate
= dyn_cast<TypeAliasTemplateDecl>(Template)) { = dyn_cast<TypeAliasTemplateDecl>(Template)) {
// Find the canonical type for this type alias template specialization. // Find the canonical type for this type alias template specialization.
@ -1923,7 +1924,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
return QualType(); return QualType();
} else if (Name.isDependent() || } else if (Name.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments( TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs)) { TemplateArgs, InstantiationDependent)) {
// This class template specialization is a dependent // This class template specialization is a dependent
// type. Therefore, its canonical type is another class template // type. Therefore, its canonical type is another class template
// specialization type that contains all of the converted // specialization type that contains all of the converted
@ -4833,10 +4834,12 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
Converted)) Converted))
return true; return true;
bool InstantiationDependent;
if (!Name.isDependent() && if (!Name.isDependent() &&
!TemplateSpecializationType::anyDependentTemplateArguments( !TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs.getArgumentArray(), TemplateArgs.getArgumentArray(),
TemplateArgs.size())) { TemplateArgs.size(),
InstantiationDependent)) {
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
<< ClassTemplate->getDeclName(); << ClassTemplate->getDeclName();
isPartialSpecialization = false; isPartialSpecialization = false;

View File

@ -807,7 +807,7 @@ bool TemplateInstantiator::AlreadyTransformed(QualType T) {
if (T.isNull()) if (T.isNull())
return true; return true;
if (T->isDependentType() || T->isVariablyModifiedType()) if (T->isInstantiationDependentType() || T->isVariablyModifiedType())
return false; return false;
getSema().MarkDeclarationsReferencedInType(Loc, T); getSema().MarkDeclarationsReferencedInType(Loc, T);
@ -1340,7 +1340,7 @@ TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
"Cannot perform an instantiation without some context on the " "Cannot perform an instantiation without some context on the "
"instantiation stack"); "instantiation stack");
if (!T->getType()->isDependentType() && if (!T->getType()->isInstantiationDependentType() &&
!T->getType()->isVariablyModifiedType()) !T->getType()->isVariablyModifiedType())
return T; return T;
@ -1359,7 +1359,7 @@ TypeSourceInfo *Sema::SubstType(TypeLoc TL,
if (TL.getType().isNull()) if (TL.getType().isNull())
return 0; return 0;
if (!TL.getType()->isDependentType() && if (!TL.getType()->isInstantiationDependentType() &&
!TL.getType()->isVariablyModifiedType()) { !TL.getType()->isVariablyModifiedType()) {
// FIXME: Make a copy of the TypeLoc data here, so that we can // FIXME: Make a copy of the TypeLoc data here, so that we can
// return a new TypeSourceInfo. Inefficient! // 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 // If T is not a dependent type or a variably-modified type, there
// is nothing to do. // is nothing to do.
if (!T->isDependentType() && !T->isVariablyModifiedType()) if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType())
return T; return T;
TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity); TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
@ -1396,7 +1396,8 @@ QualType Sema::SubstType(QualType T,
} }
static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
if (T->getType()->isDependentType() || T->getType()->isVariablyModifiedType()) if (T->getType()->isInstantiationDependentType() ||
T->getType()->isVariablyModifiedType())
return true; return true;
TypeLoc TL = T->getTypeLoc().IgnoreParens(); 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 // The parameter's type as written might be dependent even if the
// decayed type was not dependent. // decayed type was not dependent.
if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo()) if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo())
if (TSInfo->getType()->isDependentType()) if (TSInfo->getType()->isInstantiationDependentType())
return true; return true;
// TODO: currently we always rebuild expressions. When we // TODO: currently we always rebuild expressions. When we

View File

@ -132,7 +132,7 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
bool IsTypeAlias) { bool IsTypeAlias) {
bool Invalid = false; bool Invalid = false;
TypeSourceInfo *DI = D->getTypeSourceInfo(); TypeSourceInfo *DI = D->getTypeSourceInfo();
if (DI->getType()->isDependentType() || if (DI->getType()->isInstantiationDependentType() ||
DI->getType()->isVariablyModifiedType()) { DI->getType()->isVariablyModifiedType()) {
DI = SemaRef.SubstType(DI, TemplateArgs, DI = SemaRef.SubstType(DI, TemplateArgs,
D->getLocation(), D->getDeclName()); D->getLocation(), D->getDeclName());
@ -435,7 +435,7 @@ Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) {
Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
bool Invalid = false; bool Invalid = false;
TypeSourceInfo *DI = D->getTypeSourceInfo(); TypeSourceInfo *DI = D->getTypeSourceInfo();
if (DI->getType()->isDependentType() || if (DI->getType()->isInstantiationDependentType() ||
DI->getType()->isVariablyModifiedType()) { DI->getType()->isVariablyModifiedType()) {
DI = SemaRef.SubstType(DI, TemplateArgs, DI = SemaRef.SubstType(DI, TemplateArgs,
D->getLocation(), D->getDeclName()); D->getLocation(), D->getDeclName());

View File

@ -60,7 +60,7 @@ namespace clang {
/// \brief The number of record fields required for the Expr class /// \brief The number of record fields required for the Expr class
/// itself. /// itself.
static const unsigned NumExprFields = NumStmtFields + 6; static const unsigned NumExprFields = NumStmtFields + 7;
/// \brief Read and initialize a ExplicitTemplateArgumentList structure. /// \brief Read and initialize a ExplicitTemplateArgumentList structure.
void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList, void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList,
@ -414,6 +414,7 @@ void ASTStmtReader::VisitExpr(Expr *E) {
E->setType(Reader.GetType(Record[Idx++])); E->setType(Reader.GetType(Record[Idx++]));
E->setTypeDependent(Record[Idx++]); E->setTypeDependent(Record[Idx++]);
E->setValueDependent(Record[Idx++]); E->setValueDependent(Record[Idx++]);
E->setInstantiationDependent(Record[Idx++]);
E->ExprBits.ContainsUnexpandedParameterPack = Record[Idx++]; E->ExprBits.ContainsUnexpandedParameterPack = Record[Idx++];
E->setValueKind(static_cast<ExprValueKind>(Record[Idx++])); E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++])); E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++]));

View File

@ -1517,8 +1517,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
//Stmt //Stmt
//Expr //Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent 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, 1)); //UnexpandedParamPack
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
@ -1536,8 +1537,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
//Stmt //Stmt
//Expr //Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent 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, 1)); //UnexpandedParamPack
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
@ -1553,8 +1555,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
//Stmt //Stmt
//Expr //Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsTypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //IsValueDependent 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, 1)); //UnexpandedParamPack
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind

View File

@ -375,6 +375,7 @@ void ASTStmtWriter::VisitExpr(Expr *E) {
Writer.AddTypeRef(E->getType(), Record); Writer.AddTypeRef(E->getType(), Record);
Record.push_back(E->isTypeDependent()); Record.push_back(E->isTypeDependent());
Record.push_back(E->isValueDependent()); Record.push_back(E->isValueDependent());
Record.push_back(E->isInstantiationDependent());
Record.push_back(E->containsUnexpandedParameterPack()); Record.push_back(E->containsUnexpandedParameterPack());
Record.push_back(E->getValueKind()); Record.push_back(E->getValueKind());
Record.push_back(E->getObjectKind()); Record.push_back(E->getObjectKind());

View File

@ -751,3 +751,22 @@ namespace test30 {
// CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE( // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
} }
} }
namespace test31 { // instantiation-dependent mangling of decltype
int x;
template<class T> auto f1(T p)->decltype(x) { return 0; }
// The return type in the mangling of the template signature
// is encoded as "i".
template<class T> 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<class T> 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);
}