add the location of the ')' in a do/while statement to DoStmt.

This fixes a source range problem reported by Olaf Krzikalla.

llvm-svn: 73266
This commit is contained in:
Chris Lattner 2009-06-12 23:04:47 +00:00
parent 9fd76cc19c
commit 815b70efcd
10 changed files with 37 additions and 17 deletions

View File

@ -709,14 +709,14 @@ class DoStmt : public Stmt {
Stmt* SubExprs[END_EXPR]; Stmt* SubExprs[END_EXPR];
SourceLocation DoLoc; SourceLocation DoLoc;
SourceLocation WhileLoc; SourceLocation WhileLoc;
SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
public: public:
DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL) DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
: Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL) { SourceLocation RP)
: Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
SubExprs[COND] = reinterpret_cast<Stmt*>(cond); SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
SubExprs[BODY] = body; SubExprs[BODY] = body;
DoLoc = DL;
WhileLoc = WL;
} }
/// \brief Build an empty do-while statement. /// \brief Build an empty do-while statement.
@ -734,8 +734,11 @@ public:
SourceLocation getWhileLoc() const { return WhileLoc; } SourceLocation getWhileLoc() const { return WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileLoc = L; } void setWhileLoc(SourceLocation L) { WhileLoc = L; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
virtual SourceRange getSourceRange() const { virtual SourceRange getSourceRange() const {
return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); return SourceRange(DoLoc, RParenLoc);
} }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == DoStmtClass; return T->getStmtClass() == DoStmtClass;

View File

@ -517,7 +517,10 @@ public:
return StmtEmpty(); return StmtEmpty();
} }
virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body, virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
SourceLocation WhileLoc, ExprArg Cond) { SourceLocation WhileLoc,
SourceLocation CondLParen,
ExprArg Cond,
SourceLocation CondRParen) {
return StmtEmpty(); return StmtEmpty();
} }
virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc, virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,

View File

@ -868,7 +868,9 @@ private:
OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false); OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false);
OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false); OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
bool ParseParenExprOrCondition(OwningExprResult &CondExp, bool ParseParenExprOrCondition(OwningExprResult &CondExp,
bool OnlyAllowCondition = false); bool OnlyAllowCondition = false,
SourceLocation *LParenLoc = 0,
SourceLocation *RParenLoc = 0);
OwningStmtResult ParseIfStatement(); OwningStmtResult ParseIfStatement();
OwningStmtResult ParseSwitchStatement(); OwningStmtResult ParseSwitchStatement();
OwningStmtResult ParseWhileStatement(); OwningStmtResult ParseWhileStatement();

View File

@ -210,6 +210,7 @@ unsigned PCHStmtReader::VisitDoStmt(DoStmt *S) {
S->setBody(StmtStack.back()); S->setBody(StmtStack.back());
S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
return 2; return 2;
} }

View File

@ -23,7 +23,6 @@ using namespace clang;
namespace { namespace {
class PCHStmtWriter : public StmtVisitor<PCHStmtWriter, void> { class PCHStmtWriter : public StmtVisitor<PCHStmtWriter, void> {
PCHWriter &Writer; PCHWriter &Writer;
PCHWriter::RecordData &Record; PCHWriter::RecordData &Record;
@ -197,6 +196,7 @@ void PCHStmtWriter::VisitDoStmt(DoStmt *S) {
Writer.WriteSubStmt(S->getBody()); Writer.WriteSubStmt(S->getBody());
Writer.AddSourceLocation(S->getDoLoc(), Record); Writer.AddSourceLocation(S->getDoLoc(), Record);
Writer.AddSourceLocation(S->getWhileLoc(), Record); Writer.AddSourceLocation(S->getWhileLoc(), Record);
Writer.AddSourceLocation(S->getRParenLoc(), Record);
Code = pch::STMT_DO; Code = pch::STMT_DO;
} }

View File

@ -327,7 +327,9 @@ namespace {
return StmtEmpty(); return StmtEmpty();
} }
virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body, virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
SourceLocation WhileLoc, ExprArg Cond){ SourceLocation WhileLoc,
SourceLocation LPLoc, ExprArg Cond,
SourceLocation RPLoc){
Out << __FUNCTION__ << "\n"; Out << __FUNCTION__ << "\n";
return StmtEmpty(); return StmtEmpty();
} }

View File

@ -487,8 +487,11 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
/// successfully parsed. Note that a successful parse can still have semantic /// successfully parsed. Note that a successful parse can still have semantic
/// errors in the condition. /// errors in the condition.
bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp, bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp,
bool OnlyAllowCondition) { bool OnlyAllowCondition,
SourceLocation *LParenLocPtr,
SourceLocation *RParenLocPtr) {
SourceLocation LParenLoc = ConsumeParen(); SourceLocation LParenLoc = ConsumeParen();
if (LParenLocPtr) *LParenLocPtr = LParenLoc;
if (getLang().CPlusPlus) if (getLang().CPlusPlus)
CondExp = ParseCXXCondition(); CondExp = ParseCXXCondition();
@ -507,7 +510,8 @@ bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp,
} }
// Otherwise the condition is valid or the rparen is present. // 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; return false;
} }
@ -837,14 +841,16 @@ Parser::OwningStmtResult Parser::ParseDoStatement() {
// Parse the parenthesized condition. // Parse the parenthesized condition.
OwningExprResult Cond(Actions); OwningExprResult Cond(Actions);
ParseParenExprOrCondition(Cond, true); SourceLocation LPLoc, RPLoc;
ParseParenExprOrCondition(Cond, true, &LPLoc, &RPLoc);
DoScope.Exit(); DoScope.Exit();
if (Cond.isInvalid() || Body.isInvalid()) if (Cond.isInvalid() || Body.isInvalid())
return StmtError(); return StmtError();
return Actions.ActOnDoStmt(DoLoc, move(Body), WhileLoc, move(Cond)); return Actions.ActOnDoStmt(DoLoc, move(Body), WhileLoc, LPLoc,
move(Cond), RPLoc);
} }
/// ParseForStatement /// ParseForStatement

View File

@ -1205,7 +1205,9 @@ public:
virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc, virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
FullExprArg Cond, StmtArg Body); FullExprArg Cond, StmtArg Body);
virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, 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, virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
SourceLocation LParenLoc, SourceLocation LParenLoc,

View File

@ -568,7 +568,8 @@ Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, StmtArg Body) {
Action::OwningStmtResult Action::OwningStmtResult
Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body, Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
SourceLocation WhileLoc, ExprArg Cond) { SourceLocation WhileLoc, SourceLocation CondLParen,
ExprArg Cond, SourceLocation CondRParen) {
Expr *condExpr = Cond.takeAs<Expr>(); Expr *condExpr = Cond.takeAs<Expr>();
assert(condExpr && "ActOnDoStmt(): missing expression"); assert(condExpr && "ActOnDoStmt(): missing expression");
@ -588,7 +589,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
Cond.release(); Cond.release();
return Owned(new (Context) DoStmt(Body.takeAs<Stmt>(), condExpr, DoLoc, return Owned(new (Context) DoStmt(Body.takeAs<Stmt>(), condExpr, DoLoc,
WhileLoc)); WhileLoc, CondRParen));
} }
Action::OwningStmtResult Action::OwningStmtResult

View File

@ -260,7 +260,7 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitDoStmt(DoStmt *S) {
return SemaRef.StmtError(); return SemaRef.StmtError();
return SemaRef.ActOnDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(), return SemaRef.ActOnDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
move(Cond)); SourceLocation(), move(Cond), S->getRParenLoc());
} }
Sema::OwningStmtResult TemplateStmtInstantiator::VisitForStmt(ForStmt *S) { Sema::OwningStmtResult TemplateStmtInstantiator::VisitForStmt(ForStmt *S) {