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) {