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,
SourceLocation eqLoc, VarDecl *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);

View File

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

View File

@ -42,6 +42,7 @@ namespace {
OwningExprResult VisitUnaryOperator(UnaryOperator *E);
OwningExprResult VisitBinaryOperator(BinaryOperator *E);
OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
OwningExprResult VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E);
OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
@ -262,6 +263,21 @@ TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
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
TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
Sema::OwningExprResult Cond = Visit(E->getCond());

View File

@ -40,6 +40,7 @@ namespace {
OwningStmtResult VisitNullStmt(NullStmt *S);
OwningStmtResult VisitCompoundStmt(CompoundStmt *S);
OwningStmtResult VisitIfStmt(IfStmt *S);
OwningStmtResult VisitWhileStmt(WhileStmt *S);
OwningStmtResult VisitExpr(Expr *E);
OwningStmtResult VisitLabelStmt(LabelStmt *S);
OwningStmtResult VisitGotoStmt(GotoStmt *S);
@ -156,6 +157,20 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitIfStmt(IfStmt *S) {
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::OwningExprResult Result = SemaRef.InstantiateExpr(E, TemplateArgs);
if (Result.isInvalid())

View File

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