From: Douglas Gregor Date: Sat, 16 May 2009 00:20:29 +0000 (+0000) Subject: Template instantiation for IndirectGotoStmt. Now my life is complete. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f1b9e689fa5c101512aef99225f2afea1673449;p=clang Template instantiation for IndirectGotoStmt. Now my life is complete. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71917 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 698da72abd..57b420870f 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -840,10 +840,13 @@ public: /// class IndirectGotoStmt : public Stmt { SourceLocation GotoLoc; + SourceLocation StarLoc; Stmt *Target; public: - IndirectGotoStmt(SourceLocation gotoLoc, Expr *target) - : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), Target((Stmt*)target) {} + IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, + Expr *target) + : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc), + Target((Stmt*)target) {} /// \brief Build an empty indirect goto statement. explicit IndirectGotoStmt(EmptyShell Empty) @@ -851,6 +854,8 @@ public: void setGotoLoc(SourceLocation L) { GotoLoc = L; } SourceLocation getGotoLoc() const { return GotoLoc; } + void setStarLoc(SourceLocation L) { StarLoc = L; } + SourceLocation getStarLoc() const { return StarLoc; } Expr *getTarget(); const Expr *getTarget() const; diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index a729003a99..d4ff6adda0 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -236,6 +236,7 @@ unsigned PCHStmtReader::VisitGotoStmt(GotoStmt *S) { unsigned PCHStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) { VisitStmt(S); S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setTarget(cast_or_null(StmtStack.back())); return 1; } diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index 575e8430ce..b7caee5e55 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -223,6 +223,7 @@ void PCHStmtWriter::VisitGotoStmt(GotoStmt *S) { void PCHStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) { VisitStmt(S); Writer.AddSourceLocation(S->getGotoLoc(), Record); + Writer.AddSourceLocation(S->getStarLoc(), Record); Writer.WriteSubStmt(S->getTarget()); Code = pch::STMT_INDIRECT_GOTO; } diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index b877da2a0c..647deb1e48 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -706,13 +706,15 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, ExprArg DestExp) { // Convert operand to void* Expr* E = DestExp.takeAs(); - QualType ETy = E->getType(); - AssignConvertType ConvTy = - CheckSingleAssignmentConstraints(Context.VoidPtrTy, E); - if (DiagnoseAssignmentResult(ConvTy, StarLoc, Context.VoidPtrTy, ETy, - E, "passing")) - return StmtError(); - return Owned(new (Context) IndirectGotoStmt(GotoLoc, E)); + if (!E->isTypeDependent()) { + QualType ETy = E->getType(); + AssignConvertType ConvTy = + CheckSingleAssignmentConstraints(Context.VoidPtrTy, E); + if (DiagnoseAssignmentResult(ConvTy, StarLoc, Context.VoidPtrTy, ETy, + E, "passing")) + return StmtError(); + } + return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E)); } Action::OwningStmtResult diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp index 9252677025..527b33d710 100644 --- a/lib/Sema/SemaTemplateInstantiateStmt.cpp +++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp @@ -49,6 +49,7 @@ namespace { OwningStmtResult VisitExpr(Expr *E); OwningStmtResult VisitLabelStmt(LabelStmt *S); OwningStmtResult VisitGotoStmt(GotoStmt *S); + OwningStmtResult VisitIndirectGotoStmt(IndirectGotoStmt *S); OwningStmtResult VisitBreakStmt(BreakStmt *S); OwningStmtResult VisitContinueStmt(ContinueStmt *S); OwningStmtResult VisitReturnStmt(ReturnStmt *S); @@ -104,6 +105,17 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitGotoStmt(GotoStmt *S) { S->getLabel()->getID()); } +Sema::OwningStmtResult +TemplateStmtInstantiator::VisitIndirectGotoStmt(IndirectGotoStmt *S) { + OwningExprResult Target = SemaRef.InstantiateExpr(S->getTarget(), + TemplateArgs); + if (Target.isInvalid()) + return SemaRef.StmtError(); + + return SemaRef.ActOnIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(), + move(Target)); +} + Sema::OwningStmtResult TemplateStmtInstantiator::VisitBreakStmt(BreakStmt *S) { return SemaRef.Owned(S->Clone(SemaRef.Context)); } diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index abd0d1c0fb..5a348e7dd2 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -170,3 +170,13 @@ template struct Switch1 { template struct Switch1; template struct Switch1; // expected-note{{instantiation}} + +template struct IndirectGoto0 { + void f(T x) { + // FIXME: crummy error message below + goto *x; // expected-error{{incompatible}} + } +}; + +template struct IndirectGoto0; +template struct IndirectGoto0; // expected-note{{instantiation}}