]> granicus.if.org Git - clang/commitdiff
Template instantiation for IndirectGotoStmt. Now my life is complete.
authorDouglas Gregor <dgregor@apple.com>
Sat, 16 May 2009 00:20:29 +0000 (00:20 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 16 May 2009 00:20:29 +0000 (00:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71917 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriterStmt.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/SemaTemplateInstantiateStmt.cpp
test/SemaTemplate/instantiate-function-1.cpp

index 698da72abdac5b3d49c2ba5571d09aceaa5a6186..57b420870fff52437025eafb62a64b92953a1eb0 100644 (file)
@@ -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;
index a729003a9979aaac5188cecc80587013c6347b35..d4ff6adda02b3173f2073b5154e55cbbf0ce11f8 100644 (file)
@@ -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;
 }
index 575e8430ce17bfbad4b9c93234ebf71bad89f6b3..b7caee5e55109ccc53ae912a8270f34d86e0523f 100644 (file)
@@ -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;
 }
index b877da2a0ca6da65b6ccf0a28f839319178e1b74..647deb1e4888391529af98a8b198f4ac64252fcd 100644 (file)
@@ -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
index 9252677025acd46e220ab024be7feab122c67639..527b33d710cb114c6b14e95318bc3b642f5b9c2a 100644 (file)
@@ -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));
 }
index abd0d1c0fbdb3080bb533e4f4efdbd597a93afca..5a348e7dd261cf18980a729e8010fed0194015cd 100644 (file)
@@ -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}}