add the location of the ')' in a do/while statement to DoStmt.
This fixes a source range problem reported by Olaf Krzikalla.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73266 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 3656333..a8688f6 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -709,14 +709,14 @@
   Stmt* SubExprs[END_EXPR];
   SourceLocation DoLoc;
   SourceLocation WhileLoc;
+  SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
 
 public:
-  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL) 
-    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL) {
+  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
+         SourceLocation RP)
+    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
     SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
     SubExprs[BODY] = body;
-    DoLoc = DL;
-    WhileLoc = WL;
   }  
 
   /// \brief Build an empty do-while statement.
@@ -734,8 +734,11 @@
   SourceLocation getWhileLoc() const { return WhileLoc; }
   void setWhileLoc(SourceLocation L) { WhileLoc = L; }
 
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
   virtual SourceRange getSourceRange() const { 
-    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 
+    return SourceRange(DoLoc, RParenLoc); 
   }
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == DoStmtClass; 
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 43406b9..f1207e4 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -517,7 +517,10 @@
     return StmtEmpty();
   }
   virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
-                                       SourceLocation WhileLoc, ExprArg Cond) {
+                                       SourceLocation WhileLoc, 
+                                       SourceLocation CondLParen,
+                                       ExprArg Cond,
+                                       SourceLocation CondRParen) {
     return StmtEmpty();
   }
   virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 8eb76a4..d613ae1 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -868,7 +868,9 @@
   OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false);
   OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
   bool ParseParenExprOrCondition(OwningExprResult &CondExp,
-                                 bool OnlyAllowCondition = false);
+                                 bool OnlyAllowCondition = false,
+                                 SourceLocation *LParenLoc = 0,
+                                 SourceLocation *RParenLoc = 0);
   OwningStmtResult ParseIfStatement();
   OwningStmtResult ParseSwitchStatement();
   OwningStmtResult ParseWhileStatement();
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 10059f6..e6871e3 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -210,6 +210,7 @@
   S->setBody(StmtStack.back());
   S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   return 2;
 }
 
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index b7caee5..73dea10 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -23,7 +23,6 @@
 
 namespace {
   class PCHStmtWriter : public StmtVisitor<PCHStmtWriter, void> {
-
     PCHWriter &Writer;
     PCHWriter::RecordData &Record;
 
@@ -197,6 +196,7 @@
   Writer.WriteSubStmt(S->getBody());
   Writer.AddSourceLocation(S->getDoLoc(), Record);
   Writer.AddSourceLocation(S->getWhileLoc(), Record);
+  Writer.AddSourceLocation(S->getRParenLoc(), Record);
   Code = pch::STMT_DO;
 }
 
diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp
index 026e605..170ab5e 100644
--- a/lib/Frontend/PrintParserCallbacks.cpp
+++ b/lib/Frontend/PrintParserCallbacks.cpp
@@ -327,7 +327,9 @@
       return StmtEmpty();
     }
     virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
-                                         SourceLocation WhileLoc, ExprArg Cond){
+                                         SourceLocation WhileLoc, 
+                                         SourceLocation LPLoc, ExprArg Cond,
+                                         SourceLocation RPLoc){
       Out << __FUNCTION__ << "\n";
       return StmtEmpty();
     }
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index f041d7d..7766bfa 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -487,8 +487,11 @@
 /// successfully parsed.  Note that a successful parse can still have semantic
 /// errors in the condition.
 bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp,
-                                       bool OnlyAllowCondition) {
+                                       bool OnlyAllowCondition,
+                                       SourceLocation *LParenLocPtr,
+                                       SourceLocation *RParenLocPtr) {
   SourceLocation LParenLoc = ConsumeParen();
+  if (LParenLocPtr) *LParenLocPtr = LParenLoc;
   
   if (getLang().CPlusPlus)
     CondExp = ParseCXXCondition();
@@ -507,7 +510,8 @@
   }
   
   // Otherwise the condition is valid or the rparen is present.
-  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  SourceLocation RPLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  if (RParenLocPtr) *RParenLocPtr = RPLoc;
   return false;
 }
 
@@ -837,14 +841,16 @@
 
   // Parse the parenthesized condition.
   OwningExprResult Cond(Actions);
-  ParseParenExprOrCondition(Cond, true);
+  SourceLocation LPLoc, RPLoc;
+  ParseParenExprOrCondition(Cond, true, &LPLoc, &RPLoc);
   
   DoScope.Exit();
 
   if (Cond.isInvalid() || Body.isInvalid())
     return StmtError();
 
-  return Actions.ActOnDoStmt(DoLoc, move(Body), WhileLoc, move(Cond));
+  return Actions.ActOnDoStmt(DoLoc, move(Body), WhileLoc, LPLoc,
+                             move(Cond), RPLoc);
 }
 
 /// ParseForStatement
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 09b3162..7e32c11 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1205,7 +1205,9 @@
   virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc, 
                                           FullExprArg Cond, StmtArg Body);
   virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
-                                       SourceLocation WhileLoc, ExprArg Cond);
+                                       SourceLocation WhileLoc,
+                                       SourceLocation CondLParen, ExprArg Cond,
+                                       SourceLocation CondRParen);
 
   virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
                                         SourceLocation LParenLoc,
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 15262e9..aa9b8db 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -568,7 +568,8 @@
 
 Action::OwningStmtResult
 Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
-                  SourceLocation WhileLoc, ExprArg Cond) {
+                  SourceLocation WhileLoc, SourceLocation CondLParen,
+                  ExprArg Cond, SourceLocation CondRParen) {
   Expr *condExpr = Cond.takeAs<Expr>();
   assert(condExpr && "ActOnDoStmt(): missing expression");
 
@@ -588,7 +589,7 @@
 
   Cond.release();
   return Owned(new (Context) DoStmt(Body.takeAs<Stmt>(), condExpr, DoLoc,
-                                    WhileLoc));
+                                    WhileLoc, CondRParen));
 }
 
 Action::OwningStmtResult
diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp
index fd349df..efdcec8 100644
--- a/lib/Sema/SemaTemplateInstantiateStmt.cpp
+++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp
@@ -260,7 +260,7 @@
     return SemaRef.StmtError();
 
   return SemaRef.ActOnDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
-                             move(Cond));
+                             SourceLocation(), move(Cond), S->getRParenLoc());
 }
 
 Sema::OwningStmtResult TemplateStmtInstantiator::VisitForStmt(ForStmt *S) {