forked from OSchip/llvm-project
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:
parent
9fd76cc19c
commit
815b70efcd
|
@ -709,14 +709,14 @@ class DoStmt : public Stmt {
|
|||
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 @@ public:
|
|||
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;
|
||||
|
|
|
@ -517,7 +517,10 @@ public:
|
|||
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,
|
||||
|
|
|
@ -868,7 +868,9 @@ private:
|
|||
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();
|
||||
|
|
|
@ -210,6 +210,7 @@ unsigned PCHStmtReader::VisitDoStmt(DoStmt *S) {
|
|||
S->setBody(StmtStack.back());
|
||||
S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ using namespace clang;
|
|||
|
||||
namespace {
|
||||
class PCHStmtWriter : public StmtVisitor<PCHStmtWriter, void> {
|
||||
|
||||
PCHWriter &Writer;
|
||||
PCHWriter::RecordData &Record;
|
||||
|
||||
|
@ -197,6 +196,7 @@ void PCHStmtWriter::VisitDoStmt(DoStmt *S) {
|
|||
Writer.WriteSubStmt(S->getBody());
|
||||
Writer.AddSourceLocation(S->getDoLoc(), Record);
|
||||
Writer.AddSourceLocation(S->getWhileLoc(), Record);
|
||||
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
||||
Code = pch::STMT_DO;
|
||||
}
|
||||
|
||||
|
|
|
@ -327,7 +327,9 @@ namespace {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -487,8 +487,11 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
|||
/// 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 @@ bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp,
|
|||
}
|
||||
|
||||
// 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 @@ Parser::OwningStmtResult Parser::ParseDoStatement() {
|
|||
|
||||
// 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
|
||||
|
|
|
@ -1205,7 +1205,9 @@ public:
|
|||
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,
|
||||
|
|
|
@ -568,7 +568,8 @@ Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, StmtArg Body) {
|
|||
|
||||
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 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
|
|||
|
||||
Cond.release();
|
||||
return Owned(new (Context) DoStmt(Body.takeAs<Stmt>(), condExpr, DoLoc,
|
||||
WhileLoc));
|
||||
WhileLoc, CondRParen));
|
||||
}
|
||||
|
||||
Action::OwningStmtResult
|
||||
|
|
|
@ -260,7 +260,7 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitDoStmt(DoStmt *S) {
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue