Index: include/clang/Parse/Action.h
===================================================================
--- include/clang/Parse/Action.h	(revision 67470)
+++ include/clang/Parse/Action.h	(working copy)
@@ -242,7 +242,9 @@
 
   /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
   /// gives the actions implementation a chance to process the group as a whole.
-  virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
+  virtual DeclTy *FinalizeDeclaratorGroup(Scope *S,
+                                          SourceLocation EndTokenLoc,
+                                          DeclTy *Group) {
     return Group;
   }
 
@@ -374,11 +376,15 @@
   /// ActOnTagStartDefinition - Invoked when we have entered the
   /// scope of a tag's definition (e.g., for an enumeration, class,
   /// struct, or union).
-  virtual void ActOnTagStartDefinition(Scope *S, DeclTy *TagDecl) { }
+  virtual void ActOnTagStartDefinition(Scope *S,
+                                       SourceLocation StartLoc,
+                                       DeclTy *TagDecl) { }
 
   /// ActOnTagFinishDefinition - Invoked once we have finished parsing
   /// the definition of a tag (enumeration, class, struct, or union).
-  virtual void ActOnTagFinishDefinition(Scope *S, DeclTy *TagDecl) { }
+  virtual void ActOnTagFinishDefinition(Scope *S,
+                                        SourceLocation EndLoc,
+                                        DeclTy *TagDecl) { }
 
   virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
                                     DeclTy *LastEnumConstant,
Index: Driver/PrintParserCallbacks.cpp
===================================================================
--- Driver/PrintParserCallbacks.cpp	(revision 67470)
+++ Driver/PrintParserCallbacks.cpp	(working copy)
@@ -7,8 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This code simply runs the preprocessor on the input file and prints out the
-// result.  This is the traditional behavior of the -E option.
+// This code provides stubs for methods defined in the clang::Action interface.
 //
 //===----------------------------------------------------------------------===//
 
@@ -114,7 +113,9 @@
 
     /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
     /// gives the actions implementation a chance to process the group as a whole.
-    virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
+    virtual DeclTy *FinalizeDeclaratorGroup(Scope *S,
+                                            SourceLocation EndToken,
+                                            DeclTy *Group) {
       llvm::cout << __FUNCTION__ << "\n";
       return 0;
     }
@@ -195,6 +196,18 @@
       llvm::cout << __FUNCTION__ << "\n";
       return 0;
     }
+
+    virtual void ActOnTagStartDefinition(Scope *S, SourceLocation StartLoc,
+                                         DeclTy *TagDecl) {
+      llvm::cout << __FUNCTION__ << "\n";
+      return;
+    }
+
+    virtual void ActOnTagFinishDefinition(Scope *S, SourceLocation EndLoc,
+                                          DeclTy *TagDecl) {
+      llvm::cout << __FUNCTION__ << "\n";
+      return;
+    }
   
     /// Act on @defs() element found when parsing a structure.  ClassName is the
     /// name of the referenced class.   
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 67470)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -2452,7 +2452,9 @@
 }
 
 /// The declarators are chained together backwards, reverse the list.
-Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
+Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S,
+                                            SourceLocation EndTokenLoc,
+                                            DeclTy *group) {
   // Often we have single declarators, handle them quickly.
   Decl *Group = static_cast<Decl*>(group);
   if (Group == 0)
@@ -3338,7 +3340,8 @@
   return New;
 }
 
-void Sema::ActOnTagStartDefinition(Scope *S, DeclTy *TagD) {
+void Sema::ActOnTagStartDefinition(Scope *S, SourceLocation TagStart,
+                                   DeclTy *TagD) {
   AdjustDeclIfTemplate(TagD);
   TagDecl *Tag = cast<TagDecl>((Decl *)TagD);
 
@@ -3364,7 +3367,8 @@
   }
 }
 
-void Sema::ActOnTagFinishDefinition(Scope *S, DeclTy *TagD) {
+void Sema::ActOnTagFinishDefinition(Scope *S, SourceLocation TagStart,
+                                    DeclTy *TagD) {
   AdjustDeclIfTemplate(TagD);
   TagDecl *Tag = cast<TagDecl>((Decl *)TagD);
 
Index: lib/Sema/Sema.h
===================================================================
--- lib/Sema/Sema.h	(revision 67470)
+++ lib/Sema/Sema.h	(working copy)
@@ -352,7 +352,9 @@
   virtual void AddInitializerToDecl(DeclTy *dcl, ExprArg init);
   void AddInitializerToDecl(DeclTy *dcl, ExprArg init, bool DirectInit);
   void ActOnUninitializedDecl(DeclTy *dcl);
-  virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
+  virtual DeclTy *FinalizeDeclaratorGroup(Scope *S,
+                                          SourceLocation EndTokenLoc,
+                                          DeclTy *Group);
 
   virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D);
   virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
@@ -410,11 +412,13 @@
   /// ActOnTagStartDefinition - Invoked when we have entered the
   /// scope of a tag's definition (e.g., for an enumeration, class,
   /// struct, or union).
-  virtual void ActOnTagStartDefinition(Scope *S, DeclTy *TagDecl);
+  virtual void ActOnTagStartDefinition(Scope *S, SourceLocation StartLoc,
+                                       DeclTy *TagDecl);
 
   /// ActOnTagFinishDefinition - Invoked once we have finished parsing
   /// the definition of a tag (enumeration, class, struct, or union).
-  virtual void ActOnTagFinishDefinition(Scope *S, DeclTy *TagDecl);
+  virtual void ActOnTagFinishDefinition(Scope *S, SourceLocation EndLoc,
+                                        DeclTy *TagDecl);
 
   EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
                                       EnumConstantDecl *LastEnumConst,
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp	(revision 67470)
+++ lib/Parse/ParseDecl.cpp	(working copy)
@@ -387,13 +387,20 @@
       Diag(Tok, diag::err_parse_error);
       return 0;
     }
-    return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
+
+    // Return the semicolon's location such that
+    // action consumers know where it was
+    return Actions.FinalizeDeclaratorGroup(CurScope, PrevTokLocation,
+                                           LastDeclInGroup);
   }
   // If this is an ObjC2 for-each loop, this is a successful declarator
   // parse.  The syntax for these looks like:
   // 'for' '(' declaration 'in' expr ')' statement
   if (D.getContext()  == Declarator::ForContext && isTokIdentifier_in()) {
-    return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
+
+    // Return current 'in' token's location to action consumers
+    return Actions.FinalizeDeclaratorGroup(CurScope, Tok.getLocation(),
+                                           LastDeclInGroup);
   }
   Diag(Tok, diag::err_parse_error);
   // Skip to end of block or statement
@@ -1107,7 +1114,7 @@
   SourceLocation LBraceLoc = ConsumeBrace();
   
   ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
-  Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+  Actions.ActOnTagStartDefinition(CurScope, RecordLoc, TagDecl);
 
   // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
   // C++.
@@ -1190,7 +1197,7 @@
                       LBraceLoc, RBraceLoc,
                       AttrList);
   StructScope.Exit();
-  Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
+  Actions.ActOnTagFinishDefinition(CurScope, Tok.getLocation(), TagDecl);
 }
 
 
@@ -1287,7 +1294,7 @@
 void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
   // Enter the scope of the enum body and start the definition.
   ParseScope EnumScope(this, Scope::DeclScope);
-  Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
+  Actions.ActOnTagStartDefinition(CurScope, StartLoc, EnumDecl);
 
   SourceLocation LBraceLoc = ConsumeBrace();
   
@@ -1342,7 +1349,7 @@
     AttrList = ParseAttributes(); // FIXME: where do they do?
 
   EnumScope.Exit();
-  Actions.ActOnTagFinishDefinition(CurScope, EnumDecl);
+  Actions.ActOnTagFinishDefinition(CurScope, Tok.getLocation(), EnumDecl);
 }
 
 /// isTypeSpecifierQualifier - Return true if the current token could be the
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp	(revision 67470)
+++ lib/Parse/ParseDeclCXX.cpp	(working copy)
@@ -817,7 +817,8 @@
   if (Tok.is(tok::semi)) {
     ConsumeToken();
     // Reverse the chain list.
-    return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
+    return Actions.FinalizeDeclaratorGroup(CurScope, PrevTokLocation,
+                                           LastDeclInGroup);
   }
 
   Diag(Tok, diag::err_expected_semi_decl_list);
@@ -857,7 +858,7 @@
   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
 
   if (TagDecl)
-    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+    Actions.ActOnTagStartDefinition(CurScope, RecordLoc, TagDecl);
   else {
     SkipUntil(tok::r_brace, false, false);
     return;
@@ -933,7 +934,7 @@
   // Leave the class scope.
   ClassScope.Exit();
 
-  Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
+  Actions.ActOnTagFinishDefinition(CurScope, Tok.getLocation(), TagDecl);
 }
 
 /// ParseConstructorInitializer - Parse a C++ constructor initializer,
