diff options
-rw-r--r-- | include/clang/AST/DeclarationName.h | 4 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 114 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 134 | ||||
-rw-r--r-- | include/clang/AST/ExprObjC.h | 36 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 13 | ||||
-rw-r--r-- | include/clang/AST/TemplateBase.h | 4 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 21 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 168 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 267 | ||||
-rw-r--r-- | lib/AST/TemplateBase.cpp | 36 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 45 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 5 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 5 |
17 files changed, 572 insertions, 308 deletions
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 9adc15980c..309535be50 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -492,6 +492,10 @@ public: LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding(); } + /// \brief Determine whether this name contains an unexpanded + /// parameter pack. + bool containsUnexpandedParameterPack() const; + /// getAsString - Retrieve the human-readable string for this name. std::string getAsString() const; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 5039baa03a..d46ef43ee6 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -57,13 +57,12 @@ class Expr : public Stmt { protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD) : Stmt(SC) { + bool TD, bool VD, bool ContainsUnexpandedParameterPack) : Stmt(SC) { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; - // FIXME: Variadic templates. - ExprBits.ContainsUnexpandedParameterPack = false; + ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; setType(T); } @@ -132,6 +131,12 @@ public: return ExprBits.ContainsUnexpandedParameterPack; } + /// \brief Set the bit that describes whether this expression + /// contains an unexpanded parameter pack. + void setContainsUnexpandedParameterPack(bool PP = true) { + ExprBits.ContainsUnexpandedParameterPack = PP; + } + /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. @@ -568,6 +573,8 @@ struct ExplicitTemplateArgumentList { } void initializeFrom(const TemplateArgumentListInfo &List); + void initializeFrom(const TemplateArgumentListInfo &List, + bool &Dependent, bool &ContainsUnexpandedParameterPack); void copyInto(TemplateArgumentListInfo &List) const; static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(const TemplateArgumentListInfo &List); @@ -631,7 +638,7 @@ class DeclRefExpr : public Expr { public: DeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l) : - Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false), + Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false, false), DecoratedD(d, 0), Loc(l) { computeDependence(); } @@ -795,7 +802,8 @@ private: public: PredefinedExpr(SourceLocation l, QualType type, IdentType IT) : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary, - type->isDependentType(), type->isDependentType()), + type->isDependentType(), type->isDependentType(), + /*ContainsUnexpandedParameterPack=*/false), Loc(l), Type(IT) {} /// \brief Construct an empty predefined expression. @@ -882,7 +890,8 @@ public: // or UnsignedLongLongTy IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l) - : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false), + : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false, + false), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); setValue(C, V); @@ -920,7 +929,8 @@ class CharacterLiteral : public Expr { public: // type should be IntTy 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), Value(value), Loc(l), IsWide(iswide) { } @@ -955,7 +965,8 @@ class FloatingLiteral : public Expr { FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) - : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false), + : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, + false), IsExact(isexact), Loc(L) { setValue(C, V); } @@ -1006,7 +1017,8 @@ class ImaginaryLiteral : public Expr { Stmt *Val; public: ImaginaryLiteral(Expr *val, QualType Ty) - : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false), + : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, + false), Val(val) {} /// \brief Build an empty imaginary literal. @@ -1052,7 +1064,7 @@ class StringLiteral : public Expr { SourceLocation TokLocs[1]; StringLiteral(QualType Ty) : - Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false) {} + Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false) {} public: /// This is the "fully general" constructor that allows representation of @@ -1140,7 +1152,8 @@ public: ParenExpr(SourceLocation l, SourceLocation r, Expr *val) : Expr(ParenExprClass, val->getType(), val->getValueKind(), val->getObjectKind(), - val->isTypeDependent(), val->isValueDependent()), + val->isTypeDependent(), val->isValueDependent(), + val->containsUnexpandedParameterPack()), L(l), R(r), Val(val) {} /// \brief Construct an empty parenthesized expression. @@ -1196,7 +1209,8 @@ public: ExprValueKind VK, ExprObjectKind OK, SourceLocation l) : Expr(UnaryOperatorClass, type, VK, OK, input->isTypeDependent() || type->isDependentType(), - input->isValueDependent()), + input->isValueDependent(), + input->containsUnexpandedParameterPack()), Opc(opc), Loc(l), Val(input) {} /// \brief Build an empty unary operator. @@ -1483,7 +1497,8 @@ public: Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. - TInfo->getType()->isDependentType()), + TInfo->getType()->isDependentType(), + TInfo->getType()->containsUnexpandedParameterPack()), isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) { Argument.Ty = TInfo; } @@ -1494,7 +1509,8 @@ public: Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. - E->isTypeDependent()), + E->isTypeDependent(), + E->containsUnexpandedParameterPack()), isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) { Argument.Ex = E; } @@ -1569,7 +1585,9 @@ public: SourceLocation rbracketloc) : Expr(ArraySubscriptExprClass, t, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent()), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), RBracketLoc(rbracketloc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -1790,7 +1808,8 @@ public: const DeclarationNameInfo &NameInfo, QualType ty, ExprValueKind VK, ExprObjectKind OK) : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), base->isValueDependent()), + base->isTypeDependent(), base->isValueDependent(), + base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) { @@ -1805,7 +1824,8 @@ public: SourceLocation l, QualType ty, ExprValueKind VK, ExprObjectKind OK) : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), base->isValueDependent()), + base->isTypeDependent(), base->isValueDependent(), + base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {} @@ -1991,11 +2011,12 @@ class CompoundLiteralExpr : public Expr { Stmt *Init; bool FileScope; public: - // FIXME: Can compound literals be value-dependent? CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, QualType T, ExprValueKind VK, Expr *init, bool fileScope) : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, - tinfo->getType()->isDependentType(), false), + tinfo->getType()->isDependentType(), + init->isValueDependent(), + init->containsUnexpandedParameterPack()), LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} /// \brief Construct an empty compound literal. @@ -2119,7 +2140,9 @@ protected: ty->isDependentType(), // Cast expressions are value-dependent if the type is // dependent or if the subexpression is value-dependent. - ty->isDependentType() || (op && op->isValueDependent())), + ty->isDependentType() || (op && op->isValueDependent()), + (ty->containsUnexpandedParameterPack() || + op->containsUnexpandedParameterPack())), Op(op) { assert(kind != CK_Invalid && "creating cast with invalid cast kind"); CastExprBits.Kind = kind; @@ -2351,7 +2374,9 @@ public: SourceLocation opLoc) : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent()), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -2450,7 +2475,9 @@ protected: SourceLocation opLoc, bool dead) : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent()), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -2519,7 +2546,10 @@ public: ((lhs && lhs->isTypeDependent()) || (rhs && rhs->isTypeDependent())), (cond->isValueDependent() || (lhs && lhs->isValueDependent()) || - (rhs && rhs->isValueDependent()))), + (rhs && rhs->isValueDependent())), + (cond->containsUnexpandedParameterPack() || + (lhs && lhs->containsUnexpandedParameterPack()) || + (rhs && rhs->containsUnexpandedParameterPack()))), QuestionLoc(QLoc), ColonLoc(CLoc) { SubExprs[COND] = cond; @@ -2589,7 +2619,7 @@ class AddrLabelExpr : public Expr { public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L, QualType t) - : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false), + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} /// \brief Build an empty address of a label expression. @@ -2632,7 +2662,7 @@ public: StmtExpr(CompoundStmt *substmt, QualType T, SourceLocation lp, SourceLocation rp) : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, - T->isDependentType(), false), + T->isDependentType(), false, false), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } /// \brief Build an empty statement expression. @@ -2679,19 +2709,9 @@ class ShuffleVectorExpr : public Expr { unsigned NumExprs; public: - // FIXME: Can a shufflevector be value-dependent? Does type-dependence need - // to be computed differently? ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, QualType Type, SourceLocation BLoc, - SourceLocation RP) : - Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary, - Type->isDependentType(), false), - BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) { - - SubExprs = new (C) Stmt*[nexpr]; - for (unsigned i = 0; i < nexpr; i++) - SubExprs[i] = args[i]; - } + SourceLocation RP); /// \brief Build an empty vector-shuffle expression. explicit ShuffleVectorExpr(EmptyShell Empty) @@ -2755,7 +2775,10 @@ public: ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool TypeDependent, bool ValueDependent) - : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent), + : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, + (cond->containsUnexpandedParameterPack() || + lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), BuiltinLoc(BLoc), RParenLoc(RP) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; @@ -2813,7 +2836,7 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false), TokenLoc(Loc) { } /// \brief Build an empty GNU __null expression. @@ -2845,7 +2868,9 @@ public: VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo, SourceLocation RPLoc, QualType t) : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, - t->isDependentType(), false), + t->isDependentType(), false, + (TInfo->getType()->containsUnexpandedParameterPack() || + e->containsUnexpandedParameterPack())), Val(e), TInfo(TInfo), BuiltinLoc(BLoc), RParenLoc(RPLoc) { } @@ -3346,7 +3371,7 @@ class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false) { } + false, false, false) { } /// \brief Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -3434,7 +3459,8 @@ public: IdentifierInfo &accessor, SourceLocation loc) : Expr(ExtVectorElementExprClass, ty, VK, (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), - base->isTypeDependent(), base->isValueDependent()), + base->isTypeDependent(), base->isValueDependent(), + base->containsUnexpandedParameterPack()), Base(base), Accessor(&accessor), AccessorLoc(loc) {} /// \brief Build an empty vector element expression. @@ -3490,7 +3516,7 @@ protected: public: BlockExpr(BlockDecl *BD, QualType ty, bool hasBlockDeclRefExprs) : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, - ty->isDependentType(), false), + ty->isDependentType(), false, false), TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {} /// \brief Build an empty block expression. @@ -3541,7 +3567,7 @@ public: SourceLocation l, bool ByRef, bool constAdded = false, Stmt *copyConstructorVal = 0) : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, - (!t.isNull() && t->isDependentType()), false), + (!t.isNull() && t->isDependentType()), false, false), D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded), CopyConstructorVal(copyConstructorVal) {} @@ -3591,7 +3617,7 @@ class OpaqueValueExpr : public Expr { public: OpaqueValueExpr(QualType T, ExprValueKind VK, ExprObjectKind OK = OK_Ordinary) : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType(), T->isDependentType()) { + T->isDependentType(), T->isDependentType(), false) { } explicit OpaqueValueExpr(EmptyShell Empty) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 6b18561424..403ee04321 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -283,7 +283,8 @@ class CXXBoolLiteralExpr : public Expr { SourceLocation Loc; public: 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), Value(val), Loc(l) {} explicit CXXBoolLiteralExpr(EmptyShell Empty) @@ -312,7 +313,8 @@ class CXXNullPtrLiteralExpr : public Expr { SourceLocation Loc; public: CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) : - Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + false), Loc(l) {} explicit CXXNullPtrLiteralExpr(EmptyShell Empty) @@ -348,15 +350,17 @@ public: // typeid is never type-dependent (C++ [temp.dep.expr]p4) false, // typeid is value-dependent if the type or expression are dependent - Operand->getType()->isDependentType()), + Operand->getType()->isDependentType(), + Operand->getType()->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, + false, // typeid is value-dependent if the type or expression are dependent - Operand->isTypeDependent() || Operand->isValueDependent()), + Operand->isTypeDependent() || Operand->isValueDependent(), + Operand->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } CXXTypeidExpr(EmptyShell Empty, bool isExpr) @@ -419,12 +423,14 @@ private: public: CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) : Expr(CXXUuidofExprClass, Ty, VK_RValue, OK_Ordinary, - false, Operand->getType()->isDependentType()), + false, Operand->getType()->isDependentType(), + Operand->getType()->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) : Expr(CXXUuidofExprClass, Ty, VK_RValue, OK_Ordinary, - false, Operand->isTypeDependent()), + false, Operand->isTypeDependent(), + Operand->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } CXXUuidofExpr(EmptyShell Empty, bool isExpr) @@ -495,7 +501,8 @@ public: : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary, // 'this' is type-dependent if the class type of the enclosing // member function is dependent (C++ [temp.dep.expr]p2) - Type->isDependentType(), Type->isDependentType()), + Type->isDependentType(), Type->isDependentType(), + /*ContainsUnexpandedParameterPack=*/false), Loc(L), Implicit(isImplicit) { } CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} @@ -530,7 +537,8 @@ public: // exepression. The l is the location of the throw keyword. expr // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) : - Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false), + Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + expr && expr->containsUnexpandedParameterPack()), Op(expr), ThrowLoc(l) {} CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} @@ -578,14 +586,15 @@ class CXXDefaultArgExpr : public Expr { ? param->getType().getNonReferenceType() : param->getDefaultArg()->getType(), param->getDefaultArg()->getValueKind(), - param->getDefaultArg()->getObjectKind(), false, false), + param->getDefaultArg()->getObjectKind(), false, false, false), Param(param, false), Loc(Loc) { } CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, Expr *SubExpr) : Expr(SC, SubExpr->getType(), SubExpr->getValueKind(), SubExpr->getObjectKind(), - false, false), Param(param, true), Loc(Loc) { + false, false, false), + Param(param, true), Loc(Loc) { *reinterpret_cast<Expr **>(this + 1) = SubExpr; } @@ -680,11 +689,12 @@ class CXXBindTemporaryExpr : public Expr { Stmt *SubExpr; - CXXBindTemporaryExpr(CXXTemporary *temp, Expr* subexpr, - bool TD=false, bool VD=false) - : Expr(CXXBindTemporaryExprClass, subexpr->getType(), - VK_RValue, OK_Ordinary, TD, VD), - Temp(temp), SubExpr(subexpr) { } + CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr) + : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), + VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), + SubExpr->isValueDependent(), + SubExpr->containsUnexpandedParameterPack()), + Temp(temp), SubExpr(SubExpr) { } public: CXXBindTemporaryExpr(EmptyShell Empty) @@ -935,7 +945,7 @@ public: TypeSourceInfo *TypeInfo, SourceLocation rParenLoc ) : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, - false, false), + false, false, false), RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} explicit CXXScalarValueInitExpr(EmptyShell Shell) @@ -1147,7 +1157,8 @@ public: CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, bool arrayFormAsWritten, 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->containsUnexpandedParameterPack()), GlobalDelete(globalDelete), ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), OperatorDelete(operatorDelete), Argument(arg), Loc(loc) { } @@ -1408,7 +1419,8 @@ public: TypeSourceInfo *queried, bool value, SourceLocation rparen, QualType ty) : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, - false, queried->getType()->isDependentType()), + false, queried->getType()->isDependentType(), + queried->getType()->containsUnexpandedParameterPack()), UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { } explicit UnaryTypeTraitExpr(EmptyShell Empty) @@ -1466,7 +1478,9 @@ public: bool value, SourceLocation rparen, QualType ty) : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, lhsType->getType()->isDependentType() || - rhsType->getType()->isDependentType()), + rhsType->getType()->isDependentType(), + (lhsType->getType()->containsUnexpandedParameterPack() || + rhsType->getType()->containsUnexpandedParameterPack())), BTT(btt), Value(value), Loc(loc), RParen(rparen), LhsType(lhsType), RhsType(rhsType) { } @@ -1522,27 +1536,29 @@ class OverloadExpr : public Expr { /// The source range of the scope specifier. SourceRange QualifierRange; + friend class ASTStmtReader; + protected: /// True if the name was a template-id. bool HasExplicitTemplateArgs; - OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent, + OverloadExpr(StmtClass K, ASTContext &C, NestedNameSpecifier *Qualifier, SourceRange QRange, const DeclarationNameInfo &NameInfo, - bool HasTemplateArgs, - UnresolvedSetIterator Begin, UnresolvedSetIterator End); + const TemplateArgumentListInfo *TemplateArgs, + UnresolvedSetIterator Begin, UnresolvedSetIterator End, + bool KnownDependent = false, + bool KnownContainsUnexpandedParameterPack = false); OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty), Results(0), NumResults(0), Qualifier(0), HasExplicitTemplateArgs(false) { } -public: - /// Computes whether an unresolved lookup on the given declarations - /// and optional template arguments is type- and value-dependent. - static bool ComputeDependence(UnresolvedSetIterator Begin, - UnresolvedSetIterator End, - const TemplateArgumentListInfo *Args); + void initializeResults(ASTContext &C, + UnresolvedSetIterator Begin, + UnresolvedSetIterator End); +public: struct FindResult { OverloadExpr *Expression; bool IsAddressOfOperand; @@ -1586,9 +1602,6 @@ public: return UnresolvedSetIterator(Results + NumResults); } - void initializeResults(ASTContext &C, - UnresolvedSetIterator Begin,UnresolvedSetIterator End); - /// Gets the number of declarations in the unresolved set. unsigned getNumDecls() const { return NumResults; } @@ -1667,15 +1680,15 @@ class UnresolvedLookupExpr : public OverloadExpr { /// against the qualified-lookup bits. CXXRecordDecl *NamingClass; - UnresolvedLookupExpr(ASTContext &C, QualType T, bool Dependent, + UnresolvedLookupExpr(ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifier *Qualifier, SourceRange QRange, const DeclarationNameInfo &NameInfo, - bool RequiresADL, bool Overloaded, bool HasTemplateArgs, + bool RequiresADL, bool Overloaded, + const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedLookupExprClass, C, T, - Dependent, Qualifier, QRange, NameInfo, HasTemplateArgs, - Begin, End), + : OverloadExpr(UnresolvedLookupExprClass, C, Qualifier, QRange, NameInfo, + TemplateArgs, Begin, End), RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass) {} @@ -1686,7 +1699,6 @@ class UnresolvedLookupExpr : public OverloadExpr { public: static UnresolvedLookupExpr *Create(ASTContext &C, - bool Dependent, CXXRecordDecl *NamingClass, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1694,16 +1706,12 @@ public: bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - return new(C) UnresolvedLookupExpr(C, - Dependent ? C.DependentTy : C.OverloadTy, - Dependent, NamingClass, - Qualifier, QualifierRange, NameInfo, - ADL, Overloaded, false, - Begin, End); + return new(C) UnresolvedLookupExpr(C, NamingClass, Qualifier, + QualifierRange, NameInfo, ADL, + Overloaded, 0, Begin, End); } static UnresolvedLookupExpr *Create(ASTContext &C, - bool Dependent, CXXRecordDecl *NamingClass, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -1825,12 +1833,7 @@ class DependentScopeDeclRefExpr : public Expr { NestedNameSpecifier *Qualifier, SourceRange QualifierRange, const DeclarationNameInfo &NameInfo, - bool HasExplicitTemplateArgs) - : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, - true, true), - NameInfo(NameInfo), QualifierRange(QualifierRange), Qualifier(Qualifier), - HasExplicitTemplateArgs(HasExplicitTemplateArgs) - {} + const TemplateArgumentListInfo *Args); public: static DependentScopeDeclRefExpr *Create(ASTContext &C, @@ -2161,20 +2164,13 @@ class CXXDependentScopeMemberExpr : public Expr { public: CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, QualType BaseType, - bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - NamedDecl *FirstQualifierFoundInScope, - DeclarationNameInfo MemberNameInfo) - : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true), - Base(Base), BaseType(BaseType), IsArrow(IsArrow), - HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), - Qualifier(Qualifier), QualifierRange(QualifierRange), - FirstQualifierFoundInScope(FirstQualifierFoundInScope), - MemberNameInfo(MemberNameInfo) { } + Expr *Base, QualType BaseType, + bool IsArrow, + SourceLocation OperatorLoc, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + NamedDecl *FirstQualifierFoundInScope, + DeclarationNameInfo MemberNameInfo); static CXXDependentScopeMemberExpr * Create(ASTContext &C, @@ -2384,8 +2380,7 @@ class UnresolvedMemberExpr : public OverloadExpr { /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; - UnresolvedMemberExpr(ASTContext &C, QualType T, bool Dependent, - bool HasUnresolvedUsing, + UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, @@ -2400,7 +2395,7 @@ class UnresolvedMemberExpr : public OverloadExpr { public: static UnresolvedMemberExpr * - Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing, + Create(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifier *Qualifier, @@ -2553,7 +2548,8 @@ public: SourceLocation Keyword, SourceLocation RParen) : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, /*TypeDependent*/false, - /*ValueDependent*/Val == CT_Dependent), + /*ValueDependent*/Val == CT_Dependent, + Operand->containsUnexpandedParameterPack()), Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) { } diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 263ba17a02..0eba6ba9f2 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -29,7 +29,8 @@ class ObjCStringLiteral : public Expr { SourceLocation AtLoc; public: 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), String(SL), AtLoc(L) {} explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} @@ -66,7 +67,8 @@ public: SourceLocation at, SourceLocation rp) : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, EncodedType->getType()->isDependentType(), - EncodedType->getType()->isDependentType()), + EncodedType->getType()->isDependentType(), + EncodedType->getType()->containsUnexpandedParameterPack()), EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} @@ -105,7 +107,8 @@ class ObjCSelectorExpr : public Expr { public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) - : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false), + : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, + false), SelName(selInfo), AtLoc(at), RParenLoc(rp){} explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} @@ -145,8 +148,9 @@ class ObjCProtocolExpr : public Expr { public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false), - TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} + : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, + false), + TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} @@ -185,9 +189,9 @@ public: SourceLocation l, Expr *base, bool arrow = false, bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent()), D(d), - Loc(l), Base(base), IsArrow(arrow), - IsFreeIvar(freeIvar) {} + /*TypeDependent=*/false, base->isValueDependent(), + base->containsUnexpandedParameterPack()), + D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} explicit ObjCIvarRefExpr(EmptyShell Empty) : Expr(ObjCIvarRefExprClass, Empty) {} @@ -248,7 +252,8 @@ public: ExprValueKind VK, ExprObjectKind OK, SourceLocation l, Expr *base) : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, base->isValueDependent()), + /*TypeDependent=*/false, base->isValueDependent(), + base->containsUnexpandedParameterPack()), PropertyOrGetter(PD, false), Setter(0), IdLoc(l), ReceiverLoc(), Receiver(base) { } @@ -257,7 +262,8 @@ public: ExprValueKind VK, ExprObjectKind OK, SourceLocation l, SourceLocation sl, QualType st) : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false), + /*TypeDependent=*/false, false, + st->containsUnexpandedParameterPack()), PropertyOrGetter(PD, false), Setter(0), IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { } @@ -266,7 +272,8 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, Expr *Base) : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, - Base->isValueDependent()), + Base->isValueDependent(), + Base->containsUnexpandedParameterPack()), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { } @@ -275,7 +282,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation SuperLoc, QualType SuperTy) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false), + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { } @@ -284,7 +291,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false), + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { } @@ -808,7 +815,8 @@ class ObjCIsaExpr : public Expr { public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent()), + /*TypeDependent=*/false, base->isValueDependent(), + /*ContainsUnexpandedParameterPack=*/false), Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} /// \brief Build an empty expression. diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 124977d97f..01e0ae56c9 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -143,7 +143,18 @@ protected: friend class DeclRefExpr; // computeDependence friend class InitListExpr; // ctor friend class DesignatedInitExpr; // ctor - friend class ASTStmtReader; + friend class ASTStmtReader; // deserialization + friend class CXXNewExpr; // ctor + friend class DependentScopeDeclRefExpr; // ctor + friend class CXXConstructExpr; // ctor + friend class CallExpr; // ctor + friend class OffsetOfExpr; // ctor + friend class ObjCMessageExpr; // ctor + friend class ShuffleVectorExpr; // ctor + friend class ParenListExpr; // ctor + friend class CXXUnresolvedConstructExpr; // ctor + friend class CXXDependentScopeMemberExpr; // ctor + friend class OverloadExpr; // ctor unsigned : NumStmtBits; unsigned ValueKind : 2; diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index e5057e547e..df1bbe98e0 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -182,6 +182,10 @@ public: /// \brief Determine whether this template argument has no value. bool isNull() const { return Kind == Null; } + /// \brief Whether this template argument is dependent on a template + /// parameter. + bool isDependent() const; + /// \brief Whether this template argument contains an unexpanded /// parameter pack. bool containsUnexpandedParameterPack() const; diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 860a0b276a..596ecc593e 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -512,6 +512,27 @@ DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { } } +bool DeclarationNameInfo::containsUnexpandedParameterPack() 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()->containsUnexpandedParameterPack(); + + return Name.getCXXNameType()->containsUnexpandedParameterPack(); + } +} + std::string DeclarationNameInfo::getAsString() const { std::string Result; llvm::raw_string_ostream OS(Result); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index bb91934669..5d0e0e3093 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -108,6 +108,25 @@ void ExplicitTemplateArgumentList::initializeFrom( new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); } +void ExplicitTemplateArgumentList::initializeFrom( + const TemplateArgumentListInfo &Info, + bool &Dependent, + bool &ContainsUnexpandedParameterPack) { + LAngleLoc = Info.getLAngleLoc(); + RAngleLoc = Info.getRAngleLoc(); + NumTemplateArgs = Info.size(); + + TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); + for (unsigned i = 0; i != NumTemplateArgs; ++i) { + Dependent = Dependent || Info[i].getArgument().isDependent(); + ContainsUnexpandedParameterPack + = ContainsUnexpandedParameterPack || + Info[i].getArgument().containsUnexpandedParameterPack(); + + new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); + } +} + void ExplicitTemplateArgumentList::copyInto( TemplateArgumentListInfo &Info) const { Info.setLAngleLoc(LAngleLoc); @@ -188,6 +207,9 @@ void DeclRefExpr::computeDependence() { // (TD) - a nested-name-specifier or a qualified-id that names a // member of an unknown specialization. // (handled by DependentScopeDeclRefExpr) + + // FIXME: Variadic templates require that we compute whether this + // declaration reference contains an unexpanded parameter pack. } DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, @@ -195,7 +217,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false), + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -217,7 +239,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false), + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -597,14 +619,23 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs, QualType t, ExprValueKind VK, SourceLocation rparenloc) : Expr(SC, t, VK, OK_Ordinary, - fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs), - fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)), + fn->isTypeDependent(), + fn->isValueDependent(), + fn->containsUnexpandedParameterPack()), NumArgs(numargs) { SubExprs = new (C) Stmt*[numargs+1]; SubExprs[FN] = fn; - for (unsigned i = 0; i != numargs; ++i) + for (unsigned i = 0; i != numargs; ++i) { + if (args[i]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (args[i]->isValueDependent()) + ExprBits.ValueDependent = true; + if (args[i]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + SubExprs[i+ARGS_START] = args[i]; + } RParenLoc = rparenloc; } @@ -612,20 +643,30 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, ExprValueKind VK, SourceLocation rparenloc) : Expr(CallExprClass, t, VK, OK_Ordinary, - fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs), - fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)), + fn->isTypeDependent(), + fn->isValueDependent(), + fn->containsUnexpandedParameterPack()), NumArgs(numargs) { SubExprs = new (C) Stmt*[numargs+1]; SubExprs[FN] = fn; - for (unsigned i = 0; i != numargs; ++i) + for (unsigned i = 0; i != numargs; ++i) { + if (args[i]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (args[i]->isValueDependent()) + ExprBits.ValueDependent = true; + if (args[i]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + SubExprs[i+ARGS_START] = args[i]; + } RParenLoc = rparenloc; } CallExpr::CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty) : Expr(SC, Empty), SubExprs(0), NumArgs(0) { + // FIXME: Why do we allocate this? SubExprs = new (C) Stmt*[1]; } @@ -745,9 +786,8 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, SourceLocation RParenLoc) : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, - /*ValueDependent=*/tsi->getType()->isDependentType() || - hasAnyTypeDependentArguments(exprsPtr, numExprs) || - hasAnyValueDependentArguments(exprsPtr, numExprs)), + /*ValueDependent=*/tsi->getType()->isDependentType(), + tsi->getType()->containsUnexpandedParameterPack()), OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), NumComps(numComps), NumExprs(numExprs) { @@ -756,6 +796,11 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, } for(unsigned i = 0; i < numExprs; ++i) { + if (exprsPtr[i]->isTypeDependent() || exprsPtr[i]->isValueDependent()) + ExprBits.ValueDependent = true; + if (exprsPtr[i]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + setIndexExpr(i, exprsPtr[i]); } } @@ -1100,7 +1145,8 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) { InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, Expr **initExprs, unsigned numInits, SourceLocation rbraceloc) - : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false), + : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false, + false), InitExprs(C, numInits), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), UnionFieldInit(0), HadArrayRangeDesignator(false) @@ -1110,6 +1156,8 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, ExprBits.TypeDependent = true; if (initExprs[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (initExprs[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; } InitExprs.insert(C, InitExprs.end(), initExprs, initExprs+numInits); @@ -2216,7 +2264,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/false), + /*TypeDependent=*/false, /*ValueDependent=*/false, + /*ContainsUnexpandedParameterPack=*/false), NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass), HasMethod(Method != 0), SuperLoc(SuperLoc), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method @@ -2238,16 +2287,24 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), - (T->isDependentType() || - hasAnyValueDependentArguments(Args, NumArgs))), + T->isDependentType(), T->containsUnexpandedParameterPack()), NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method : Sel.getAsOpaquePtr())), SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { setReceiverPointer(Receiver); - if (NumArgs) - memcpy(getArgs(), Args, NumArgs * sizeof(Expr *)); + Stmt **MyArgs = getArgs(); + for (unsigned I = 0; I != NumArgs; ++I) { + if (Args[I]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (Args[I]->isValueDependent()) + ExprBits.ValueDependent = true; + if (Args[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + MyArgs[I] = Args[I]; + } } ObjCMessageExpr::ObjCMessageExpr(QualType T, @@ -2260,16 +2317,25 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), - (Receiver->isTypeDependent() || - hasAnyValueDependentArguments(Args, NumArgs))), + Receiver->isTypeDependent(), + Receiver->containsUnexpandedParameterPack()), NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method : Sel.getAsOpaquePtr())), SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { setReceiverPointer(Receiver); - if (NumArgs) - memcpy(getArgs(), Args, NumArgs * sizeof(Expr *)); + Stmt **MyArgs = getArgs(); + for (unsigned I = 0; I != NumArgs; ++I) { + if (Args[I]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (Args[I]->isValueDependent()) + ExprBits.ValueDependent = true; + if (Args[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + MyArgs[I] = Args[I]; + } } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, @@ -2388,6 +2454,27 @@ bool ChooseExpr::isConditionTrue(ASTContext &C) const { return getCond()->EvaluateAsInt(C) != 0; } +ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, + QualType Type, SourceLocation BLoc, + SourceLocation RP) + : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary, + Type->isDependentType(), Type->isDependentType(), + Type->containsUnexpandedParameterPack()), + BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) +{ + SubExprs = new (C) Stmt*[nexpr]; + for (unsigned i = 0; i < nexpr; i++) { + if (args[i]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (args[i]->isValueDependent()) + ExprBits.ValueDependent = true; + if (args[i]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + SubExprs[i] = args[i]; + } +} + void ShuffleVectorExpr::setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs) { if (SubExprs) C.Deallocate(SubExprs); @@ -2419,7 +2506,8 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, Expr *Init) : Expr(DesignatedInitExprClass, Ty, Init->getValueKind(), Init->getObjectKind(), - Init->isTypeDependent(), Init->isValueDependent()), + Init->isTypeDependent(), Init->isValueDependent(), + Init->containsUnexpandedParameterPack()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { this->Designators = new (C) Designator[NumDesignators]; @@ -2437,8 +2525,12 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, if (this->Designators[I].isArrayDesignator()) { // Compute type- and value-dependence. Expr *Index = IndexExprs[IndexIdx]; - ExprBits.ValueDependent = ExprBits.ValueDependent || - Index->isTypeDependent() || Index->isValueDependent(); + if (Index->isTypeDependent() || Index->isValueDependent()) + ExprBits.ValueDependent = true; + + // Propagate unexpanded parameter packs. + if (Index->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; // Copy the index expressions into permanent storage. *Child++ = IndexExprs[IndexIdx++]; @@ -2446,9 +2538,14 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, // Compute type- and value-dependence. Expr *Start = IndexExprs[IndexIdx]; Expr *End = IndexExprs[IndexIdx + 1]; - ExprBits.ValueDependent = ExprBits.ValueDependent || - Start->isTypeDependent() || Start->isValueDependent() || - End->isTypeDependent() || End->isValueDependent(); + if (Start->isTypeDependent() || Start->isValueDependent() || + End->isTypeDependent() || End->isValueDependent()) + ExprBits.ValueDependent = true; + + // Propagate unexpanded parameter packs. + if (Start->containsUnexpandedParameterPack() || + End->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; // Copy the start/end expressions into permanent storage. *Child++ = IndexExprs[IndexIdx++]; @@ -2559,14 +2656,21 @@ void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx, ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, SourceLocation rparenloc) -: Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, - hasAnyTypeDependentArguments(exprs, nexprs), - hasAnyValueDependentArguments(exprs, nexprs)), - NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { + : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, + false, false, false), + NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { Exprs = new (C) Stmt*[nexprs]; - for (unsigned i = 0; i != nexprs; ++i) + for (unsigned i = 0; i != nexprs; ++i) { + if (exprs[i]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (exprs[i]->isValueDependent()) + ExprBits.ValueDependent = true; + if (exprs[i]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + Exprs[i] = exprs[i]; + } } //===----------------------------------------------------------------------===// diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 1c134608a5..cbd33f2dc4 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -117,7 +117,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, SourceLocation constructorLParen, SourceLocation constructorRParen) : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, - ty->isDependentType(), ty->isDependentType()), + ty->isDependentType(), ty->isDependentType(), + ty->containsUnexpandedParameterPack()), GlobalNew(globalNew), Initializer(initializer), SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete), Constructor(constructor), @@ -126,12 +127,26 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, ConstructorRParen(constructorRParen) { AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs); unsigned i = 0; - if (Array) + if (Array) { + if (arraySize->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + SubExprs[i++] = arraySize; - for (unsigned j = 0; j < NumPlacementArgs; ++j) + } + + for (unsigned j = 0; j < NumPlacementArgs; ++j) { + if (placementArgs[j]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + SubExprs[i++] = placementArgs[j]; - for (unsigned j = 0; j < NumConstructorArgs; ++j) + } + + for (unsigned j = 0; j < NumConstructorArgs; ++j) { + if (constructorArgs[j]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + SubExprs[i++] = constructorArgs[j]; + } } void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray, @@ -197,7 +212,15 @@ CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context, /*isTypeDependent=*/(Base->isTypeDependent() || (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), - /*isValueDependent=*/Base->isValueDependent()), + /*isValueDependent=*/Base->isValueDependent(), + // ContainsUnexpandedParameterPack + (Base->containsUnexpandedParameterPack() || + (Qualifier && Qualifier->containsUnexpandedParameterPack()) || + (ScopeType && + ScopeType->getType()->containsUnexpandedParameterPack()) || + (DestroyedType.getTypeSourceInfo() && + DestroyedType.getTypeSourceInfo()->getType() + ->containsUnexpandedParameterPack()))), Base(static_cast<Stmt *>(Base)), IsArrow(isArrow), OperatorLoc(OperatorLoc), Qualifier(Qualifier), QualifierRange(QualifierRange), @@ -221,7 +244,7 @@ SourceRange CXXPseudoDestructorExpr::getSourceRange() const { // UnresolvedLookupExpr UnresolvedLookupExpr * -UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent, +UnresolvedLookupExpr::Create(ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -233,19 +256,10 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent, { void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + ExplicitTemplateArgumentList::sizeFor(Args)); - UnresolvedLookupExpr *ULE - = new (Mem) UnresolvedLookupExpr(C, - Dependent ? C.DependentTy : C.OverloadTy, - Dependent, NamingClass, - Qualifier, QualifierRange, NameInfo, - ADL, - /*Overload*/ true, - /*ExplicitTemplateArgs*/ true, - Begin, End); - - reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args); - - return ULE; + return new (Mem) UnresolvedLookupExpr(C, NamingClass, + Qualifier, QualifierRange, NameInfo, + ADL, /*Overload*/ true, &Args, + Begin, End); } UnresolvedLookupExpr * @@ -260,46 +274,75 @@ UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) { return E; } -OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, - bool Dependent, NestedNameSpecifier *Qualifier, - SourceRange QRange, +OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, + NestedNameSpecifier *Qualifier, SourceRange QRange, const DeclarationNameInfo &NameInfo, - bool HasTemplateArgs, + const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, - UnresolvedSetIterator End) - : Expr(K, T, VK_LValue, OK_Ordinary, Dependent, Dependent), - Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier), - QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs) + UnresolvedSetIterator End, + bool KnownDependent, + bool KnownContainsUnexpandedParameterPack) + : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, + KnownDependent, + (KnownContainsUnexpandedParameterPack || + NameInfo.containsUnexpandedParameterPack() || + (Qualifier && Qualifier->containsUnexpandedParameterPack()))), + Results(0), NumResults(End - Begin), NameInfo(NameInfo), + Qualifier(Qualifier), QualifierRange(QRange), + HasExplicitTemplateArgs(TemplateArgs != 0) { - initializeResults(C, Begin, End); -} - -void OverloadExpr::initializeResults(ASTContext &C, - UnresolvedSetIterator Begin, - UnresolvedSetIterator End) { - assert(Results == 0 && "Results already initialized!"); NumResults = End - Begin; if (NumResults) { + // Determine whether this expression is type-dependent. + for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) { + if ((*I)->getDeclContext()->isDependentContext() || + isa<UnresolvedUsingValueDecl>(*I)) { + ExprBits.TypeDependent = true; + ExprBits.ValueDependent = true; + } + } + Results = static_cast<DeclAccessPair *>( C.Allocate(sizeof(DeclAccessPair) * NumResults, llvm::alignOf<DeclAccessPair>())); memcpy(Results, &*Begin.getIterator(), NumResults * sizeof(DeclAccessPair)); } -} - -bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin, - UnresolvedSetIterator End, - const TemplateArgumentListInfo *Args) { - for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) - if ((*I)->getDeclContext()->isDependentContext()) - return true; + // If we have explicit template arguments, check for dependent + // template arguments and whether they contain any unexpanded pack + // expansions. + if (TemplateArgs) { + bool Dependent = false; + bool ContainsUnexpandedParameterPack = false; + getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + ContainsUnexpandedParameterPack); + + if (Dependent) { + ExprBits.TypeDependent = true; + ExprBits.ValueDependent = true; + } + if (ContainsUnexpandedParameterPack) + ExprBits.ContainsUnexpandedParameterPack = true; + } - if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args)) - return true; + if (isTypeDependent()) + setType(C.DependentTy); +} - return false; +void OverloadExpr::initializeResults(ASTContext &C, + UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { + assert(Results == 0 && "Results already initialized!"); + NumResults = End - Begin; + if (NumResults) { + Results = static_cast<DeclAccessPair *>( + C.Allocate(sizeof(DeclAccessPair) * NumResults, + + llvm::alignOf<DeclAccessPair>())); + memcpy(Results, &*Begin.getIterator(), + NumResults * sizeof(DeclAccessPair)); + } } CXXRecordDecl *OverloadExpr::getNamingClass() const { @@ -332,6 +375,29 @@ Stmt::child_iterator BinaryTypeTraitExpr::child_end() { } // DependentScopeDeclRefExpr +DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + const DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *Args) + : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, + true, true, + (NameInfo.containsUnexpandedParameterPack() || + (Qualifier && Qualifier->containsUnexpandedParameterPack()))), + NameInfo(NameInfo), QualifierRange(QualifierRange), Qualifier(Qualifier), + HasExplicitTemplateArgs(Args != 0) +{ + if (Args) { + bool Dependent = true; + bool ContainsUnexpandedParameterPack + = ExprBits.ContainsUnexpandedParameterPack; + + reinterpret_cast<ExplicitTemplateArgumentList*>(this+1) + ->initializeFrom(*Args, Dependent, ContainsUnexpandedParameterPack); + ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + } +} + DependentScopeDeclRefExpr * DependentScopeDeclRefExpr::Create(ASTContext &C, NestedNameSpecifier *Qualifier, @@ -339,19 +405,12 @@ DependentScopeDeclRefExpr::Create(ASTContext &C, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) { std::size_t size = sizeof(DependentScopeDeclRefExpr); - if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args); - void *Mem = C.Allocate(size); - - DependentScopeDeclRefExpr *DRE - = new (Mem) DependentScopeDeclRefExpr(C.DependentTy, - Qualifier, QualifierRange, - NameInfo, Args != 0); - if (Args) - reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1) - ->initializeFrom(*Args); - - return DRE; + size += ExplicitTemplateArgumentList::sizeFor(*Args); + void *Mem = C.Allocate(size); + return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, + Qualifier, QualifierRange, + NameInfo, Args); } DependentScopeDeclRefExpr * @@ -361,10 +420,8 @@ DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C, if (NumTemplateArgs) size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size); - return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(), - DeclarationNameInfo(), - NumTemplateArgs != 0); + DeclarationNameInfo(), 0); } StmtIterator DependentScopeDeclRefExpr::child_begin() { @@ -580,9 +637,7 @@ CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, assert(SubExpr->getType()->isRecordType() && "Expression bound to a temporary must have record type!"); - return new (C) CXXBindTemporaryExpr(Temp, SubExpr, - SubExpr->isTypeDependent(), - SubExpr->isValueDependent()); + return new (C) CXXBindTemporaryExpr(Temp, SubExpr); } CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, @@ -624,19 +679,24 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, bool ZeroInitialization, ConstructionKind ConstructKind, SourceRange ParenRange) -: Expr(SC, T, VK_RValue, OK_Ordinary, - T->isDependentType(), - (T->isDependentType() || - CallExpr::hasAnyValueDependentArguments(args, numargs))), - Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable), - ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), - Args(0), NumArgs(numargs) + : Expr(SC, T, VK_RValue, OK_Ordinary, + T->isDependentType(), T->isDependentType(), + T->containsUnexpandedParameterPack()), + Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable), + ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), + Args(0), NumArgs(numargs) { if (NumArgs) { Args = new (C) Stmt*[NumArgs]; for (unsigned i = 0; i != NumArgs; ++i) { assert(args[i] && "NULL argument in CXXConstructExpr"); + + if (args[i]->isValueDependent()) + ExprBits.ValueDependent = true; + if (args[i]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + Args[i] = args[i]; } } @@ -648,7 +708,8 @@ ExprWithCleanups::ExprWithCleanups(ASTContext &C, unsigned numtemps) : Expr(ExprWithCleanupsClass, subexpr->getType(), subexpr->getValueKind(), subexpr->getObjectKind(), - subexpr->isTypeDependent(), subexpr->isValueDependent()), + subexpr->isTypeDependent(), subexpr->isValueDependent(), + subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr), Temps(0), NumTemps(0) { if (numtemps) { setNumTemporaries(C, numtemps); @@ -705,13 +766,19 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, : Expr(CXXUnresolvedConstructExprClass, Type->getType().getNonReferenceType(), VK_LValue, OK_Ordinary, - Type->getType()->isDependentType(), true), + Type->getType()->isDependentType(), true, + Type->getType()->containsUnexpandedParameterPack()), Type(Type), LParenLoc(LParenLoc), RParenLoc(RParenLoc), NumArgs(NumArgs) { Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1); - memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs); + for (unsigned I = 0; I != NumArgs; ++I) { + if (Args[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + StoredArgs[I] = Args[I]; + } } CXXUnresolvedConstructExpr * @@ -757,17 +824,45 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true), + VK_LValue, OK_Ordinary, true, true, + ((Base && Base->containsUnexpandedParameterPack()) || + (Qualifier && Qualifier->containsUnexpandedParameterPack()) || + MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(TemplateArgs != 0), OperatorLoc(OperatorLoc), Qualifier(Qualifier), QualifierRange(QualifierRange), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { - if (TemplateArgs) - getExplicitTemplateArgs().initializeFrom(*TemplateArgs); + if (TemplateArgs) { + bool Dependent = true; + bool ContainsUnexpandedParameterPack = false; + getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + ContainsUnexpandedParameterPack); + if (ContainsUnexpandedParameterPack) + ExprBits.ContainsUnexpandedParameterPack = true; + } } +CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, + Expr *Base, QualType BaseType, + bool IsArrow, + SourceLocation OperatorLoc, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + NamedDecl *FirstQualifierFoundInScope, + DeclarationNameInfo MemberNameInfo) + : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, + VK_LValue, OK_Ordinary, true, true, + ((Base && Base->containsUnexpandedParameterPack()) || + (Qualifier && Qualifier->containsUnexpandedParameterPack()) || + MemberNameInfo.containsUnexpandedParameterPack())), + Base(Base), BaseType(BaseType), IsArrow(IsArrow), + HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), + Qualifier(Qualifier), QualifierRange(QualifierRange), + FirstQualifierFoundInScope(FirstQualifierFoundInScope), + MemberNameInfo(MemberNameInfo) { } + CXXDependentScopeMemberExpr * CXXDependentScopeMemberExpr::Create(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, @@ -827,8 +922,7 @@ Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() { return child_iterator(&Base + 1); } -UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T, - bool Dependent, +UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, @@ -839,17 +933,21 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent, + : OverloadExpr(UnresolvedMemberExprClass, C, Qualifier, QualifierRange, MemberNameInfo, - TemplateArgs != 0, Begin, End), + TemplateArgs, Begin, End, + // Dependent + ((Base && Base->isTypeDependent()) || + BaseType->isDependentType()), + // Contains unexpanded parameter pack + ((Base && Base->containsUnexpandedParameterPack()) || + BaseType->containsUnexpandedParameterPack())), IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) { - if (TemplateArgs) - getExplicitTemplateArgs().initializeFrom(*TemplateArgs); } UnresolvedMemberExpr * -UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent, +UnresolvedMemberExpr::Create(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, @@ -865,8 +963,7 @@ UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent, void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>()); return new (Mem) UnresolvedMemberExpr(C, - Dependent ? C.DependentTy : C.OverloadTy, - Dependent, HasUnresolvedUsing, Base, BaseType, + HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, Qualifier, QualifierRange, MemberNameInfo, TemplateArgs, Begin, End); } diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index ef2deea8c8..ead7885077 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -26,6 +26,42 @@ using namespace clang; // TemplateArgument Implementation //===----------------------------------------------------------------------===// +bool TemplateArgument::isDependent() const { + switch (getKind()) { + case Null: + assert(false && "Should not have a NULL template argument"); + return false; + + case Type: + return getAsType()->isDependentType(); + + case Template: + return getAsTemplate().isDependent(); + + 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()->isTypeDependent() || getAsExpr()->isValueDependent()); + + case Pack: + for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { + if (P->isDependent()) + return true; + } + + return false; + } + + return false; +} + bool TemplateArgument::containsUnexpandedParameterPack() const { switch (getKind()) { case Null: diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 25aa5e0ea1..0991e5a709 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1220,45 +1220,6 @@ bool EnumType::classof(const TagType *TT) { return isa<EnumDecl>(TT->getDecl()); } -static bool isDependent(const TemplateArgument &Arg) { - switch (Arg.getKind()) { - case TemplateArgument::Null: - assert(false && "Should not have a NULL template argument"); - return false; - - case TemplateArgument::Type: - return Arg.getAsType()->isDependentType(); - - case TemplateArgument::Template: - return Arg.getAsTemplate().isDependent(); - - case TemplateArgument::Declaration: - if (DeclContext *DC = dyn_cast<DeclContext>(Arg.getAsDecl())) - return DC->isDependentContext(); - return Arg.getAsDecl()->getDeclContext()->isDependentContext(); - - case TemplateArgument::Integral: - // Never dependent - return false; - - case TemplateArgument::Expression: - return (Arg.getAsExpr()->isTypeDependent() || - Arg.getAsExpr()->isValueDependent()); - - case TemplateArgument::Pack: - for (TemplateArgument::pack_iterator P = Arg.pack_begin(), - PEnd = Arg.pack_end(); - P != PEnd; ++P) { - if (isDependent(*P)) - return true; - } - - return false; - } - - return false; -} - bool TemplateSpecializationType:: anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) { return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size()); @@ -1267,7 +1228,7 @@ anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) { bool TemplateSpecializationType:: anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { for (unsigned i = 0; i != N; ++i) - if (isDependent(Args[i].getArgument())) + if (Args[i].getArgument().isDependent()) return true; return false; } @@ -1275,7 +1236,7 @@ anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { bool TemplateSpecializationType:: anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) { for (unsigned i = 0; i != N; ++i) - if (isDependent(Args[i])) + if (Args[i].isDependent()) return true; return false; } @@ -1298,7 +1259,7 @@ TemplateSpecializationType(TemplateName T, = reinterpret_cast<TemplateArgument *>(this + 1); for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { // Update dependent and variably-modified bits. - if (isDependent(Args[Arg])) + if (Args[Arg].isDependent()) setDependent(); if (Args[Arg].getKind() == TemplateArgument::Type && Args[Arg].getAsType()->isVariablyModifiedType()) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 218a0b313d..baa7bf8670 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2149,10 +2149,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // we've picked a target. R.suppressDiagnostics(); - bool Dependent - = UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(), 0); UnresolvedLookupExpr *ULE - = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(), + = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), (NestedNameSpecifier*) SS.getScopeRep(), SS.getRange(), R.getLookupNameInfo(), NeedsADL, R.isOverloadedResult(), @@ -3324,18 +3322,12 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, // Construct an unresolved result if we in fact got an unresolved // result. if (R.isOverloadedResult() || R.isUnresolvableResult()) { - bool Dependent = - BaseExprType->isDependentType() || - R.isUnresolvableResult() || - OverloadExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs); - // Suppress any lookup-related diagnostics; we'll do these when we // pick a member. R.suppressDiagnostics(); UnresolvedMemberExpr *MemExpr - = UnresolvedMemberExpr::Create(Context, Dependent, - R.isUnresolvableResult(), + = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(), BaseExpr, BaseExprType, IsArrow, OpLoc, Qualifier, SS.getRange(), diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 76fcaeae58..9dcf9003dc 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3633,7 +3633,8 @@ void Sema::IgnoredValueConversions(Expr *&E) { } ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) { - if (!FullExpr) return ExprError(); + if (!FullExpr) + return ExprError(); if (DiagnoseUnexpandedParameterPack(FullExpr)) return ExprError(); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 569be26677..5a2150664c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7275,7 +7275,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators UnresolvedLookupExpr *Fn - = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass, + = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); @@ -7452,9 +7452,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // TODO: provide better source location info in DNLoc component. DeclarationNameInfo OpNameInfo(OpName, OpLoc); UnresolvedLookupExpr *Fn - = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass, - 0, SourceRange(), OpNameInfo, - /*ADL*/ true, IsOverloaded(Fns), + = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(), + OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, 2, @@ -7679,7 +7678,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, DeclarationNameInfo OpNameInfo(OpName, LLoc); OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); UnresolvedLookupExpr *Fn - = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass, + = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(), OpNameInfo, /*ADL*/ true, /*Overloaded*/ false, UnresolvedSetIterator(), diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 6c212a7eb8..2c7ff5bd47 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -32,7 +32,9 @@ using namespace sema; StmtResult Sema::ActOnExprStmt(FullExprArg expr) { Expr *E = expr.get(); - assert(E && "ActOnExprStmt(): missing expression"); + if (!E) // FIXME: FullExprArg has no error state? + return StmtError(); + // C99 6.8.3p2: The expression in an expression statement is evaluated as a // void expression for its side effects. Conversion to void allows any // operand, even incomplete types. diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 141c41618d..d38bffd9e3 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1709,11 +1709,8 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, // We don't want lookup warnings at this point. R.suppressDiagnostics(); - bool Dependent - = UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(), - &TemplateArgs); UnresolvedLookupExpr *ULE - = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(), + = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), Qualifier, QualifierRange, R.getLookupNameInfo(), RequiresADL, TemplateArgs, diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index 20a02e380c..5575e46c5f 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -9,3 +9,8 @@ struct TestPPName { typedef Types *types_pointer; // expected-error{{declaration type contains unexpanded parameter pack}} }; + +template<typename ... Types> +void TestPPNameFunc(int i) { + f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack}} +} |