Template instantiation for WhileStmt and CXXConditionDeclExpr.

llvm-svn: 71896
This commit is contained in:
Douglas Gregor 2009-05-15 21:45:53 +00:00
parent 8d2ad873e7
commit 8a930c3b73
5 changed files with 59 additions and 12 deletions

View File

@ -564,7 +564,10 @@ public:
CXXConditionDeclExpr(SourceLocation startLoc, CXXConditionDeclExpr(SourceLocation startLoc,
SourceLocation eqLoc, VarDecl *var) SourceLocation eqLoc, VarDecl *var)
: DeclRefExpr(CXXConditionDeclExprClass, var, : DeclRefExpr(CXXConditionDeclExprClass, var,
var->getType().getNonReferenceType(), startLoc) {} var->getType().getNonReferenceType(), startLoc,
var->getType()->isDependentType(),
/*FIXME:integral constant?*/
var->getType()->isDependentType()) {}
virtual void Destroy(ASTContext& Ctx); virtual void Destroy(ASTContext& Ctx);

View File

@ -520,17 +520,19 @@ Sema::ActOnWhileStmt(SourceLocation WhileLoc, ExprArg Cond, StmtArg Body) {
Expr *condExpr = Cond.takeAs<Expr>(); Expr *condExpr = Cond.takeAs<Expr>();
assert(condExpr && "ActOnWhileStmt(): missing expression"); assert(condExpr && "ActOnWhileStmt(): missing expression");
DefaultFunctionArrayConversion(condExpr); if (!condExpr->isTypeDependent()) {
Cond = condExpr; DefaultFunctionArrayConversion(condExpr);
QualType condType = condExpr->getType(); Cond = condExpr;
QualType condType = condExpr->getType();
if (getLangOptions().CPlusPlus) {
if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4 if (getLangOptions().CPlusPlus) {
return StmtError(); if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4
} else if (!condType->isScalarType()) // C99 6.8.5p2 return StmtError();
return StmtError(Diag(WhileLoc, } else if (!condType->isScalarType()) // C99 6.8.5p2
diag::err_typecheck_statement_requires_scalar) return StmtError(Diag(WhileLoc,
<< condType << condExpr->getSourceRange()); diag::err_typecheck_statement_requires_scalar)
<< condType << condExpr->getSourceRange());
}
Cond.release(); Cond.release();
return Owned(new (Context) WhileStmt(condExpr, Body.takeAs<Stmt>(), return Owned(new (Context) WhileStmt(condExpr, Body.takeAs<Stmt>(),

View File

@ -42,6 +42,7 @@ namespace {
OwningExprResult VisitUnaryOperator(UnaryOperator *E); OwningExprResult VisitUnaryOperator(UnaryOperator *E);
OwningExprResult VisitBinaryOperator(BinaryOperator *E); OwningExprResult VisitBinaryOperator(BinaryOperator *E);
OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
OwningExprResult VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E);
OwningExprResult VisitConditionalOperator(ConditionalOperator *E); OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E); OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
@ -262,6 +263,21 @@ TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
return move(Result); return move(Result);
} }
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
VarDecl *Var
= cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
SemaRef.CurContext,
TemplateArgs));
if (!Var)
return SemaRef.ExprError();
return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
E->getStartLoc(),
SourceLocation(),
Var));
}
Sema::OwningExprResult Sema::OwningExprResult
TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) { TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
Sema::OwningExprResult Cond = Visit(E->getCond()); Sema::OwningExprResult Cond = Visit(E->getCond());

View File

@ -40,6 +40,7 @@ namespace {
OwningStmtResult VisitNullStmt(NullStmt *S); OwningStmtResult VisitNullStmt(NullStmt *S);
OwningStmtResult VisitCompoundStmt(CompoundStmt *S); OwningStmtResult VisitCompoundStmt(CompoundStmt *S);
OwningStmtResult VisitIfStmt(IfStmt *S); OwningStmtResult VisitIfStmt(IfStmt *S);
OwningStmtResult VisitWhileStmt(WhileStmt *S);
OwningStmtResult VisitExpr(Expr *E); OwningStmtResult VisitExpr(Expr *E);
OwningStmtResult VisitLabelStmt(LabelStmt *S); OwningStmtResult VisitLabelStmt(LabelStmt *S);
OwningStmtResult VisitGotoStmt(GotoStmt *S); OwningStmtResult VisitGotoStmt(GotoStmt *S);
@ -156,6 +157,20 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitIfStmt(IfStmt *S) {
S->getElseLoc(), move(Else)); S->getElseLoc(), move(Else));
} }
Sema::OwningStmtResult TemplateStmtInstantiator::VisitWhileStmt(WhileStmt *S) {
// Instantiate the condition
OwningExprResult Cond = SemaRef.InstantiateExpr(S->getCond(), TemplateArgs);
if (Cond.isInvalid())
return SemaRef.StmtError();
// Instantiate the body
OwningStmtResult Body = SemaRef.InstantiateStmt(S->getBody(), TemplateArgs);
if (Body.isInvalid())
return SemaRef.StmtError();
return SemaRef.ActOnWhileStmt(S->getWhileLoc(), move(Cond), move(Body));
}
Sema::OwningStmtResult TemplateStmtInstantiator::VisitExpr(Expr *E) { Sema::OwningStmtResult TemplateStmtInstantiator::VisitExpr(Expr *E) {
Sema::OwningExprResult Result = SemaRef.InstantiateExpr(E, TemplateArgs); Sema::OwningExprResult Result = SemaRef.InstantiateExpr(E, TemplateArgs);
if (Result.isInvalid()) if (Result.isInvalid())

View File

@ -87,3 +87,14 @@ template <typename T> struct X7 {
}; };
template struct X7<int>; template struct X7<int>;
template<typename T> struct While0 {
void f(T t) {
while (t) {
}
while (T t2 = T()) ;
}
};
template struct While0<float>;