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];
|
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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue