Fix <rdar://problem/6451399> problems with labels and blocks.

- Move the 'LabelMap' from Sema to Scope. To avoid layering problems, the second element is now a 'StmtTy *', which makes the LabelMap a bit more verbose to deal with.
- Add 'ActiveScope' to Sema. Managed by ActOnStartOfFunctionDef(), ObjCActOnStartOfMethodDef(), ActOnBlockStmtExpr().
- Changed ActOnLabelStmt(), ActOnGotoStmt(), ActOnAddrLabel(), and ActOnFinishFunctionBody() to use the new ActiveScope.
- Added FIXME to workaround in ActOnFinishFunctionBody() (for dealing with C++ nested functions).  


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65694 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 990e951..dfcb65a 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -165,12 +165,19 @@
 Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
                      SourceLocation ColonLoc, StmtArg subStmt) {
   Stmt *SubStmt = static_cast<Stmt*>(subStmt.release());
-  // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = LabelMap[II];
 
+  // Look up the record for this label identifier.
+  Scope::LabelMapTy::iterator I = ActiveScope->LabelMap.find(II);
+
+  LabelStmt *LabelDecl;
+  
   // If not forward referenced or defined already, just create a new LabelStmt.
-  if (LabelDecl == 0)
-    return Owned(LabelDecl = new (Context) LabelStmt(IdentLoc, II, SubStmt));
+  if (I == ActiveScope->LabelMap.end()) {
+    LabelDecl = new (Context) LabelStmt(IdentLoc, II, SubStmt);
+    ActiveScope->LabelMap.insert(std::make_pair(II, LabelDecl));
+    return Owned(LabelDecl);
+  } else
+    LabelDecl = static_cast<LabelStmt *>(I->second);
 
   assert(LabelDecl->getID() == II && "Label mismatch!");
 
@@ -672,11 +679,16 @@
     return StmtError(Diag(GotoLoc, diag::err_goto_in_block));
 
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = LabelMap[LabelII];
+  Scope::LabelMapTy::iterator I = ActiveScope->LabelMap.find(LabelII);
 
-  // If we haven't seen this label yet, create a forward reference.
-  if (LabelDecl == 0)
+  LabelStmt *LabelDecl;
+  
+  // If not forward referenced or defined already, just create a new LabelStmt.
+  if (I == ActiveScope->LabelMap.end()) {
     LabelDecl = new (Context) LabelStmt(LabelLoc, LabelII, 0);
+    ActiveScope->LabelMap.insert(std::make_pair(LabelII, LabelDecl));
+  } else
+    LabelDecl = static_cast<LabelStmt *>(I->second);
 
   return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
 }