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/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index e99be90..98b8dbc 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2444,6 +2444,8 @@
   Decl *decl = static_cast<Decl*>(D);
   FunctionDecl *FD = cast<FunctionDecl>(decl);
 
+  ActiveScope = FnBodyScope;
+    
   // See if this is a redefinition.
   const FunctionDecl *Definition;
   if (FD->getBody(Definition)) {
@@ -2586,17 +2588,29 @@
     return 0;
   }
   PopDeclContext();
+
+  // FIXME: Temporary hack to workaround nested C++ functions. For example:
+  // class C2 {
+  //   void f() {
+  //     class LC1 {
+  //       int m() { return 1; }
+  //     };
+  //   }
+  // };
+  if (ActiveScope == 0)
+    return D;
+    
   // Verify and clean out per-function state.
 
-  bool HaveLabels = !LabelMap.empty();
+  bool HaveLabels = !ActiveScope->LabelMap.empty();
   // Check goto/label use.
-  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
-       I = LabelMap.begin(), E = LabelMap.end(); I != E; ++I) {
+  for (Scope::LabelMapTy::iterator I = ActiveScope->LabelMap.begin(), 
+       E = ActiveScope->LabelMap.end(); I != E; ++I) {
     // Verify that we have no forward references left.  If so, there was a goto
     // or address of a label taken, but no definition of it.  Label fwd
     // definitions are indicated with a null substmt.
-    if (I->second->getSubStmt() == 0) {
-      LabelStmt *L = I->second;
+    LabelStmt *L = static_cast<LabelStmt*>(I->second);
+    if (L->getSubStmt() == 0) {
       // Emit error.
       Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
       
@@ -2618,7 +2632,8 @@
       }
     }
   }
-  LabelMap.clear();
+  // This reset is for both functions and methods.
+  ActiveScope = 0;
 
   if (!Body) return D;