Add CodeGen support for indirect goto.
 - Follows emission scheme used by llvm-gcc, i.e. invent an id for
   each label whose address is taken and replace each indirect goto by
   a switch to each possible target.
 - Currently we emit a switch for each indirect goto instead of
   merging them as llvm-gcc does.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54318 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 9743c7c..a5cf946 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -62,6 +62,8 @@
   case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
   case Stmt::LabelStmtClass:    EmitLabelStmt(cast<LabelStmt>(*S));       break;
   case Stmt::GotoStmtClass:     EmitGotoStmt(cast<GotoStmt>(*S));         break;
+  case Stmt::IndirectGotoStmtClass:  
+    EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break;
 
   case Stmt::IfStmtClass:       EmitIfStmt(cast<IfStmt>(*S));             break;
   case Stmt::WhileStmtClass:    EmitWhileStmt(cast<WhileStmt>(*S));       break;
@@ -157,7 +159,25 @@
   Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn));
 }
 
+void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
+  // Emit initial switch which will be patched up later by
+  // EmitIndirectSwitches(). We need a default dest, so we use the
+  // current BB, but this is overwritten.
+  llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()),
+                                          llvm::Type::Int32Ty, 
+                                          "addr");
+  llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock());
+  IndirectSwitches.push_back(I);
+
+  // Emit a block after the branch so that dead code after a goto has some place
+  // to go.
+  Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn));
+}
+
 void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
+  // FIXME: It would probably be nice for us to skip emission of if
+  // (0) code here.
+
   // C99 6.8.4.1: The first substatement is executed if the expression compares
   // unequal to 0.  The condition must be a scalar type.
   llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());