diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-16 00:20:29 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-16 00:20:29 +0000 |
commit | 30776d419f5481fc8729e9137849d9d1d55614ce (patch) | |
tree | 1197ec88479de299c683c831ef88bc613f06a1df /clang | |
parent | 2a2d00f041a2eca6453443fb4853816b63c12dcd (diff) | |
download | bcm5719-llvm-30776d419f5481fc8729e9137849d9d1d55614ce.tar.gz bcm5719-llvm-30776d419f5481fc8729e9137849d9d1d55614ce.zip |
Template instantiation for IndirectGotoStmt. Now my life is complete.
llvm-svn: 71917
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/Stmt.h | 9 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReaderStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriterStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateStmt.cpp | 12 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-function-1.cpp | 10 |
6 files changed, 40 insertions, 9 deletions
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 698da72abda..57b420870ff 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/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/clang/lib/Frontend/PCHReaderStmt.cpp b/clang/lib/Frontend/PCHReaderStmt.cpp index a729003a997..d4ff6adda02 100644 --- a/clang/lib/Frontend/PCHReaderStmt.cpp +++ b/clang/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<Expr>(StmtStack.back())); return 1; } diff --git a/clang/lib/Frontend/PCHWriterStmt.cpp b/clang/lib/Frontend/PCHWriterStmt.cpp index 575e8430ce1..b7caee5e551 100644 --- a/clang/lib/Frontend/PCHWriterStmt.cpp +++ b/clang/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/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index b877da2a0ca..647deb1e488 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -706,13 +706,15 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, ExprArg DestExp) { // Convert operand to void* Expr* E = DestExp.takeAs<Expr>(); - 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/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp b/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp index 9252677025a..527b33d710c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp +++ b/clang/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/clang/test/SemaTemplate/instantiate-function-1.cpp b/clang/test/SemaTemplate/instantiate-function-1.cpp index abd0d1c0fbd..5a348e7dd26 100644 --- a/clang/test/SemaTemplate/instantiate-function-1.cpp +++ b/clang/test/SemaTemplate/instantiate-function-1.cpp @@ -170,3 +170,13 @@ template<typename T, int I1, int I2> struct Switch1 { template struct Switch1<int, 1, 2>; template struct Switch1<int, 2, 2>; // expected-note{{instantiation}} + +template<typename T> struct IndirectGoto0 { + void f(T x) { + // FIXME: crummy error message below + goto *x; // expected-error{{incompatible}} + } +}; + +template struct IndirectGoto0<void*>; +template struct IndirectGoto0<int>; // expected-note{{instantiation}} |