Restore patch I reversed in r138040. Known buildbot
failures are resolved.

llvm-svn: 138234
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9023b34..2316590 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2319,6 +2319,7 @@
 ///
 void Parser::
 ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
+    
   if (Tok.is(tok::kw___extension__)) {
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 7c38857..f6a79e5 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -52,7 +52,10 @@
                              SourceLocation InlineLoc) {
   assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
   SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
-
+  Decl *DC = getObjCDeclContext();
+  if (DC)
+    Actions.ActOnObjCContainerFinishDefinition(DC);
+    
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteNamespaceDecl(getCurScope());
     ConsumeCodeCompletionToken();
@@ -89,8 +92,10 @@
     if (InlineLoc.isValid())
       Diag(InlineLoc, diag::err_inline_namespace_alias)
           << FixItHint::CreateRemoval(InlineLoc);
-
-    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
+    Decl *Res = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
+    if (DC)
+      Actions.ActOnObjCContainerStartDefinition(DC);
+    return Res;
   }
 
 
@@ -101,6 +106,8 @@
     }
     Diag(Tok, Ident ? diag::err_expected_lbrace :
          diag::err_expected_ident_lbrace);
+    if (DC)
+      Actions.ActOnObjCContainerStartDefinition(DC);
     return 0;
   }
 
@@ -115,6 +122,8 @@
     }
     Diag(LBrace, diag::err_namespace_nonnamespace_scope);
     SkipUntil(tok::r_brace, false);
+    if (DC)
+      Actions.ActOnObjCContainerStartDefinition(DC);
     return 0;
   }
 
@@ -173,6 +182,8 @@
   Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
 
   DeclEnd = RBraceLoc;
+  if (DC)
+    Actions.ActOnObjCContainerStartDefinition(DC);
   return NamespcDecl;
 }
 
@@ -317,7 +328,9 @@
                                              ParsedAttributesWithRange &attrs,
                                                Decl **OwnedType) {
   assert(Tok.is(tok::kw_using) && "Not using token");
-
+  Decl *DC = getObjCDeclContext();
+  if (DC)
+    Actions.ActOnObjCContainerFinishDefinition(DC);
   // Eat 'using'.
   SourceLocation UsingLoc = ConsumeToken();
 
@@ -335,7 +348,10 @@
         << R << FixItHint::CreateRemoval(R);
     }
 
-    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
+    Decl *Res = ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
+    if (DC)
+      Actions.ActOnObjCContainerStartDefinition(DC);
+    return Res;
   }
 
   // Otherwise, it must be a using-declaration or an alias-declaration.
@@ -343,8 +359,11 @@
   // Using declarations can't have attributes.
   ProhibitAttributes(attrs);
 
-  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
-                               AS_none, OwnedType);
+  Decl *Res = ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
+                                    AS_none, OwnedType);
+  if (DC)
+    Actions.ActOnObjCContainerStartDefinition(DC);
+  return Res;
 }
 
 /// ParseUsingDirective - Parse C++ using-directive, assumes
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index c8b2a09..f5471e5 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -33,7 +33,7 @@
   SourceLocation AtLoc = ConsumeToken(); // the "@"
 
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, false);
+    Actions.CodeCompleteObjCAtDirective(getCurScope());
     ConsumeCodeCompletionToken();
   }
 
@@ -195,11 +195,13 @@
                                         ProtocolRefs.size(),
                                         ProtocolLocs.data(),
                                         EndProtoLoc);
-    if (Tok.is(tok::l_brace))
-      ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
-                                      atLoc);
     
-    ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
+    if (Tok.is(tok::l_brace))
+      ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, atLoc);
+      
+    Actions.ActOnObjCContainerStartDefinition(CategoryType);
+    ParseObjCInterfaceDeclList(tok::objc_not_keyword);
+    Actions.ActOnObjCContainerFinishDefinition(CategoryType);
     return CategoryType;
   }
   // Parse a class interface.
@@ -241,7 +243,9 @@
   if (Tok.is(tok::l_brace))
     ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
 
-  ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
+  Actions.ActOnObjCContainerStartDefinition(ClsType);
+  ParseObjCInterfaceDeclList(tok::objc_interface);
+  Actions.ActOnObjCContainerFinishDefinition(ClsType);
   return ClsType;
 }
 
@@ -249,17 +253,16 @@
 /// it's used, but instead it's been lifted to here to support VS2005.
 struct Parser::ObjCPropertyCallback : FieldCallback {
   Parser &P;
-  Decl *IDecl;
   SmallVectorImpl<Decl *> &Props;
   ObjCDeclSpec &OCDS;
   SourceLocation AtLoc;
   tok::ObjCKeywordKind MethodImplKind;
         
-  ObjCPropertyCallback(Parser &P, Decl *IDecl,
+  ObjCPropertyCallback(Parser &P, 
                        SmallVectorImpl<Decl *> &Props,
                        ObjCDeclSpec &OCDS, SourceLocation AtLoc,
                        tok::ObjCKeywordKind MethodImplKind) :
-    P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
+    P(P), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
     MethodImplKind(MethodImplKind) {
   }
 
@@ -292,7 +295,7 @@
     bool isOverridingProperty = false;
     Decl *Property =
       P.Actions.ActOnProperty(P.getCurScope(), AtLoc, FD, OCDS,
-                              GetterSel, SetterSel, IDecl,
+                              GetterSel, SetterSel, 
                               &isOverridingProperty,
                               MethodImplKind);
     if (!isOverridingProperty)
@@ -314,8 +317,7 @@
 ///     @required
 ///     @optional
 ///
-void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
-                                        tok::ObjCKeywordKind contextKey) {
+void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) {
   SmallVector<Decl *, 32> allMethods;
   SmallVector<Decl *, 16> allProperties;
   SmallVector<DeclGroupPtrTy, 8> allTUVariables;
@@ -327,7 +329,7 @@
     // If this is a method prototype, parse it.
     if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
       Decl *methodPrototype =
-        ParseObjCMethodPrototype(interfaceDecl, MethodImplKind, false);
+        ParseObjCMethodPrototype(MethodImplKind, false);
       allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
       // method definitions.
@@ -339,7 +341,6 @@
       Diag(Tok, diag::err_expected_minus_or_plus);
       ParseObjCMethodDecl(Tok.getLocation(), 
                           tok::minus, 
-                          interfaceDecl,
                           MethodImplKind, false);
       continue;
     }
@@ -368,9 +369,6 @@
       // erroneous r_brace would cause an infinite loop if not handled here.
       if (Tok.is(tok::r_brace))
         break;
-
-      // FIXME: as the name implies, this rule allows function definitions.
-      // We could pass a flag or check for functions during semantic analysis.
       ParsedAttributes attrs(AttrFactory);
       allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
       continue;
@@ -379,7 +377,7 @@
     // Otherwise, we have an @ directive, eat the @.
     SourceLocation AtLoc = ConsumeToken(); // the "@"
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true);
+      Actions.CodeCompleteObjCAtDirective(getCurScope());
       ConsumeCodeCompletionToken();
       break;
     }
@@ -433,9 +431,9 @@
       ObjCDeclSpec OCDS;
       // Parse property attribute list, if any.
       if (Tok.is(tok::l_paren))
-        ParseObjCPropertyAttribute(OCDS, interfaceDecl);
+        ParseObjCPropertyAttribute(OCDS);
 
-      ObjCPropertyCallback Callback(*this, interfaceDecl, allProperties,
+      ObjCPropertyCallback Callback(*this, allProperties,
                                     OCDS, AtLoc, MethodImplKind);
 
       // Parse all the comma separated declarators.
@@ -450,7 +448,7 @@
   // We break out of the big loop in two cases: when we see @end or when we see
   // EOF.  In the former case, eat the @end.  In the later case, emit an error.
   if (Tok.is(tok::code_completion)) {
-    Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true);
+    Actions.CodeCompleteObjCAtDirective(getCurScope());
     ConsumeCodeCompletionToken();
   } else if (Tok.isObjCAtKeyword(tok::objc_end))
     ConsumeToken(); // the "end" identifier
@@ -459,7 +457,7 @@
 
   // Insert collected methods declarations into the @interface object.
   // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
-  Actions.ActOnAtEnd(getCurScope(), AtEnd, interfaceDecl,
+  Actions.ActOnAtEnd(getCurScope(), AtEnd,
                      allMethods.data(), allMethods.size(),
                      allProperties.data(), allProperties.size(),
                      allTUVariables.data(), allTUVariables.size());
@@ -485,7 +483,7 @@
 ///     weak
 ///     unsafe_unretained
 ///
-void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) {
+void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
   assert(Tok.getKind() == tok::l_paren);
   SourceLocation LHSLoc = ConsumeParen(); // consume '('
 
@@ -536,9 +534,9 @@
 
       if (Tok.is(tok::code_completion)) {
         if (IsSetter)
-          Actions.CodeCompleteObjCPropertySetter(getCurScope(), ClassDecl);
+          Actions.CodeCompleteObjCPropertySetter(getCurScope());
         else
-          Actions.CodeCompleteObjCPropertyGetter(getCurScope(), ClassDecl);
+          Actions.CodeCompleteObjCPropertyGetter(getCurScope());
         ConsumeCodeCompletionToken();
       }
 
@@ -590,14 +588,13 @@
 ///   objc-method-attributes:         [OBJC2]
 ///     __attribute__((deprecated))
 ///
-Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl,
-                                       tok::ObjCKeywordKind MethodImplKind,
+Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
                                        bool MethodDefinition) {
   assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
 
   tok::TokenKind methodType = Tok.getKind();
   SourceLocation mLoc = ConsumeToken();
-  Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind,
+  Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
                                     MethodDefinition);
   // Since this rule is used for both method declarations and definitions,
   // the caller is (optionally) responsible for consuming the ';'.
@@ -779,7 +776,9 @@
 
   SourceLocation LParenLoc = ConsumeParen();
   SourceLocation TypeStartLoc = Tok.getLocation();
-
+  Decl *DC = getObjCDeclContext();
+  if (DC)
+    Actions.ActOnObjCContainerFinishDefinition(DC);
   // Parse type qualifiers, in, inout, etc.
   ParseObjCTypeQualifierList(DS, Context);
 
@@ -802,6 +801,8 @@
     // place.  Emit an error then return what we have as the type.
     MatchRHSPunctuation(tok::r_paren, LParenLoc);
   }
+  if (DC)
+    Actions.ActOnObjCContainerStartDefinition(DC);
   return Ty;
 }
 
@@ -835,14 +836,13 @@
 ///
 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                   tok::TokenKind mType,
-                                  Decl *IDecl,
                                   tok::ObjCKeywordKind MethodImplKind,
                                   bool MethodDefinition) {
   ParsingDeclRAIIObject PD(*this);
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
-                                       /*ReturnType=*/ ParsedType(), IDecl);
+                                       /*ReturnType=*/ ParsedType());
     ConsumeCodeCompletionToken();
   }
 
@@ -859,7 +859,7 @@
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
-                                       ReturnType, IDecl);
+                                       ReturnType);
     ConsumeCodeCompletionToken();
   }
 
@@ -885,7 +885,7 @@
     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
     Decl *Result
          = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
-                                          mType, IDecl, DSRet, ReturnType, 
+                                          mType, DSRet, ReturnType, 
                                           selLoc, Sel, 0, 
                                           CParamInfo.data(), CParamInfo.size(),
                                           methodAttrs.getList(), MethodImplKind,
@@ -1001,23 +1001,18 @@
   if (getLang().ObjC2)
     MaybeParseGNUAttributes(methodAttrs);
   
-  if (KeyIdents.size() == 0) {
-    // Leave prototype scope.
-    PrototypeScope.Exit();
+  if (KeyIdents.size() == 0)
     return 0;
-  }
   
   Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
                                                    &KeyIdents[0]);
   Decl *Result
        = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
-                                        mType, IDecl, DSRet, ReturnType, 
+                                        mType, DSRet, ReturnType, 
                                         selLoc, Sel, &ArgInfos[0], 
                                         CParamInfo.data(), CParamInfo.size(),
                                         methodAttrs.getList(),
                                         MethodImplKind, isVariadic, MethodDefinition);
-  // Leave prototype scope.
-  PrototypeScope.Exit();
   
   PD.complete(Result);
   return Result;
@@ -1117,7 +1112,7 @@
                                              SourceLocation atLoc) {
   assert(Tok.is(tok::l_brace) && "expected {");
   SmallVector<Decl *, 32> AllIvarDecls;
-
+    
   ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
 
   SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
@@ -1175,11 +1170,13 @@
       }
 
       Decl *invoke(FieldDeclarator &FD) {
+        P.Actions.ActOnObjCContainerStartDefinition(IDecl);
         // Install the declarator into the interface decl.
         Decl *Field
           = P.Actions.ActOnIvar(P.getCurScope(),
                                 FD.D.getDeclSpec().getSourceRange().getBegin(),
-                                IDecl, FD.D, FD.BitfieldSize, visibility);
+                                FD.D, FD.BitfieldSize, visibility);
+        P.Actions.ActOnObjCContainerFinishDefinition(IDecl);
         if (Field)
           AllIvarDecls.push_back(Field);
         return Field;
@@ -1199,7 +1196,9 @@
     }
   }
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
-  Actions.ActOnLastBitfield(RBraceLoc, interfaceDecl, AllIvarDecls);
+  Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
+  Actions.ActOnLastBitfield(RBraceLoc, AllIvarDecls);
+  Actions.ActOnObjCContainerFinishDefinition(interfaceDecl);
   // Call ActOnFields() even if we don't have any decls. This is useful
   // for code rewriting tools that need to be aware of the empty list.
   Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
@@ -1295,7 +1294,11 @@
                                         ProtocolRefs.size(),
                                         ProtocolLocs.data(),
                                         EndProtoLoc, attrs.getList());
-  ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
+
+
+  Actions.ActOnObjCContainerStartDefinition(ProtoType);
+  ParseObjCInterfaceDeclList(tok::objc_protocol);
+  Actions.ActOnObjCContainerFinishDefinition(ProtoType);
   return ProtoType;
 }
 
@@ -1356,6 +1359,8 @@
     Decl *ImplCatType = Actions.ActOnStartCategoryImplementation(
                                     atLoc, nameId, nameLoc, categoryId,
                                     categoryLoc);
+
+    Actions.ActOnObjCContainerStartDefinition(ImplCatType);
     ObjCImpDecl = ImplCatType;
     PendingObjCImpDecl.push_back(ObjCImpDecl);
     return 0;
@@ -1378,11 +1383,11 @@
                                   superClassId, superClassLoc);
 
   if (Tok.is(tok::l_brace)) // we have ivars
-    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, 
-                                    tok::objc_private, atLoc);
+    ParseObjCClassInstanceVariables(ImplClsType, tok::objc_private, atLoc);
+
+  Actions.ActOnObjCContainerStartDefinition(ImplClsType);
   ObjCImpDecl = ImplClsType;
   PendingObjCImpDecl.push_back(ObjCImpDecl);
-  
   return 0;
 }
 
@@ -1392,7 +1397,8 @@
   Decl *Result = ObjCImpDecl;
   ConsumeToken(); // the "end" identifier
   if (ObjCImpDecl) {
-    Actions.ActOnAtEnd(getCurScope(), atEnd, ObjCImpDecl);
+    Actions.ActOnAtEnd(getCurScope(), atEnd);
+    Actions.ActOnObjCContainerFinishDefinition(ObjCImpDecl);
     ObjCImpDecl = 0;
     PendingObjCImpDecl.pop_back();
   }
@@ -1408,7 +1414,8 @@
   if (PendingObjCImpDecl.empty())
     return Actions.ConvertDeclToDeclGroup(0);
   Decl *ImpDecl = PendingObjCImpDecl.pop_back_val();
-  Actions.ActOnAtEnd(getCurScope(), SourceRange(), ImpDecl);
+  Actions.ActOnAtEnd(getCurScope(), SourceRange());
+  Actions.ActOnObjCContainerFinishDefinition(ImpDecl);
   return Actions.ConvertDeclToDeclGroup(ImpDecl);
 }
 
@@ -1455,7 +1462,7 @@
 
   while (true) {
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
+      Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
       ConsumeCodeCompletionToken();
     }
     
@@ -1474,8 +1481,7 @@
       ConsumeToken(); // consume '='
       
       if (Tok.is(tok::code_completion)) {
-        Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId,
-                                                       ObjCImpDecl);
+        Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
         ConsumeCodeCompletionToken();
       }
       
@@ -1486,7 +1492,7 @@
       propertyIvar = Tok.getIdentifierInfo();
       propertyIvarLoc = ConsumeToken(); // consume ivar-name
     }
-    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl,
+    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true,
                                   propertyId, propertyIvar, propertyIvarLoc);
     if (Tok.isNot(tok::comma))
       break;
@@ -1509,7 +1515,7 @@
   ConsumeToken(); // consume dynamic
   while (true) {
     if (Tok.is(tok::code_completion)) {
-      Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
+      Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
       ConsumeCodeCompletionToken();
     }
     
@@ -1521,7 +1527,7 @@
     
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
-    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl,
+    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false,
                                   propertyId, 0, SourceLocation());
 
     if (Tok.isNot(tok::comma))
@@ -1739,7 +1745,7 @@
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
 Decl *Parser::ParseObjCMethodDefinition() {
-  Decl *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
+  Decl *MDecl = ParseObjCMethodPrototype();
 
   PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
                                       "parsing Objective-C method");
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 05fabeb..d0e6349 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -27,11 +27,20 @@
 Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
                                              SourceLocation &DeclEnd,
                                              AccessSpecifier AS) {
-  if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less))
-    return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(),
-                                      DeclEnd);
-
-  return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
+  Decl *DC = getObjCDeclContext();
+  if (DC)
+    Actions.ActOnObjCContainerFinishDefinition(DC);
+  if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
+    Decl *Res = ParseExplicitInstantiation(SourceLocation(), ConsumeToken(),
+                                           DeclEnd);
+    if (DC)
+      Actions.ActOnObjCContainerStartDefinition(DC);
+    return Res;
+  }
+  Decl *Res = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
+  if (DC)
+    Actions.ActOnObjCContainerStartDefinition(DC);
+  return Res;
 }
 
 /// \brief RAII class that manages the template parameter depth.
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 5bb4165..d7e7d4b 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -811,7 +811,16 @@
                                              AccessSpecifier AS) {
   ParsingDeclSpec DS(*this);
   DS.takeAttributesFrom(attrs);
-  return ParseDeclarationOrFunctionDefinition(DS, AS);
+  Decl *DC = getObjCDeclContext();
+  if (DC)
+    // Must temporarily exit the objective-c container scope for
+    // parsing c constructs and re-enter objc container scope
+    // afterwards.
+    Actions.ActOnObjCContainerFinishDefinition(DC);
+  DeclGroupPtrTy resPtrTy =  ParseDeclarationOrFunctionDefinition(DS, AS);
+  if (DC)
+    Actions.ActOnObjCContainerStartDefinition(DC);
+  return resPtrTy;
 }
 
 /// ParseFunctionDefinition - We parsed and verified that the specified