Implement codegen support for labels and gotos.  We now compile:

void test1() {
  foo:
    goto foo;
    goto foo;
    goto foo;
}

void test() {
  goto l;

l:
  ;
}
into:

define void @test1() {
entry:
        br label %foo

foo:            ; preds = %0, %foo, %entry
        br label %foo
                ; No predecessors!
        br label %foo
                ; No predecessors!
}

define void @test() {
entry:
        br label %l

l:              ; preds = %entry
}

llvm-svn: 39524
diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp
index ff31a83..4061b41 100644
--- a/clang/CodeGen/CodeGenFunction.cpp
+++ b/clang/CodeGen/CodeGenFunction.cpp
@@ -25,6 +25,15 @@
   : CGM(cgm), Target(CGM.getContext().Target) {}
 
 
+llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
+  BasicBlock *&BB = LabelMap[S];
+  if (BB) return BB;
+  
+  // Create, but don't insert, the new block.
+  return BB = new BasicBlock(S->getName());
+}
+
+
 /// ConvertType - Convert the specified type to its LLVM form.
 const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) {
   // FIXME: Cache these, move the CodeGenModule, expand, etc.
@@ -104,11 +113,11 @@
 void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
   const llvm::Type *Ty = ConvertType(FD->getType(), FD->getLocation());
   
-  llvm::Function *F = new Function(cast<llvm::FunctionType>(Ty),
-                                   Function::ExternalLinkage,
-                                   FD->getName(), &CGM.getModule());
+  CurFn = new Function(cast<llvm::FunctionType>(Ty),
+                       Function::ExternalLinkage,
+                       FD->getName(), &CGM.getModule());
   
-  BasicBlock *EntryBB = new BasicBlock("entry", F);
+  BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
   
   // TODO: Walk the decls, creating allocas etc.
   
@@ -132,6 +141,8 @@
     break;
   case Stmt::NullStmtClass: break;
   case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
+  case Stmt::LabelStmtClass:    EmitLabelStmt(cast<LabelStmt>(*S));       break;
+  case Stmt::GotoStmtClass:     EmitGotoStmt(cast<GotoStmt>(*S));         break;
   }
 }
 
@@ -143,3 +154,29 @@
     EmitStmt(*I);
 }
 
+void CodeGenFunction::EmitBlock(BasicBlock *BB) {
+  // Emit a branch from this block to the next one if this was a real block.  If
+  // this was just a fall-through block after a terminator, don't emit it.
+  if (!Builder.GetInsertBlock()->empty() ||
+      Builder.GetInsertBlock()->getValueName()) {
+    Builder.CreateBr(BB);
+  } else {
+    // TODO: cache and reuse these.
+    Builder.GetInsertBlock()->eraseFromParent();
+  }
+  CurFn->getBasicBlockList().push_back(BB);
+  Builder.SetInsertPoint(BB);
+}
+
+void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
+  llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
+  
+  EmitBlock(NextBB);
+}
+
+void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
+  Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
+  
+  Builder.SetInsertPoint(new BasicBlock("", CurFn));
+}
+