forked from OSchip/llvm-project
Use a scoped object to manage entry/exit from a parser scope rather than explicitly calling EnterScope/ExitScope
llvm-svn: 60830
This commit is contained in:
parent
4637c3c698
commit
7307d6ca96
|
@ -305,6 +305,44 @@ private:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Scope manipulation
|
// Scope manipulation
|
||||||
|
|
||||||
|
/// ParseScope - Introduces a new scope for parsing. The kind of
|
||||||
|
/// scope is determined by ScopeFlags. Objects of this type should
|
||||||
|
/// be created on the stack to coincide with the position where the
|
||||||
|
/// parser enters the new scope, and this object's constructor will
|
||||||
|
/// create that new scope. Similarly, once the object is destroyed
|
||||||
|
/// the parser will exit the scope.
|
||||||
|
class ParseScope {
|
||||||
|
Parser *Self;
|
||||||
|
ParseScope(const ParseScope&); // do not implement
|
||||||
|
ParseScope& operator=(const ParseScope&); // do not implement
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ParseScope - Construct a new object to manage a scope in the
|
||||||
|
// parser Self where the new Scope is created with the flags
|
||||||
|
// ScopeFlags, but only when ManageScope is true (the default). If
|
||||||
|
// ManageScope is false, this object does nothing.
|
||||||
|
ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true)
|
||||||
|
: Self(Self) {
|
||||||
|
if (ManageScope)
|
||||||
|
Self->EnterScope(ScopeFlags);
|
||||||
|
else
|
||||||
|
this->Self = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit - Exit the scope associated with this object now, rather
|
||||||
|
// than waiting until the object is destroyed.
|
||||||
|
void Exit() {
|
||||||
|
if (Self) {
|
||||||
|
Self->ExitScope();
|
||||||
|
Self = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ParseScope() {
|
||||||
|
Exit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// EnterScope - Start a new scope.
|
/// EnterScope - Start a new scope.
|
||||||
void EnterScope(unsigned ScopeFlags);
|
void EnterScope(unsigned ScopeFlags);
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
|
||||||
/// (non-nested) C++ class. Now go over the stack of lexed methods that were
|
/// (non-nested) C++ class. Now go over the stack of lexed methods that were
|
||||||
/// collected during its parsing and parse them all.
|
/// collected during its parsing and parse them all.
|
||||||
void Parser::ParseLexedMethodDefs() {
|
void Parser::ParseLexedMethodDefs() {
|
||||||
while (!getCurTopClassStack().empty()) {
|
for (; !getCurTopClassStack().empty(); getCurTopClassStack().pop()) {
|
||||||
LexedMethod &LM = getCurTopClassStack().top();
|
LexedMethod &LM = getCurTopClassStack().top();
|
||||||
|
|
||||||
assert(!LM.Toks.empty() && "Empty body!");
|
assert(!LM.Toks.empty() && "Empty body!");
|
||||||
|
@ -81,15 +81,13 @@ void Parser::ParseLexedMethodDefs() {
|
||||||
|
|
||||||
// Parse the method body. Function body parsing code is similar enough
|
// Parse the method body. Function body parsing code is similar enough
|
||||||
// to be re-used for method bodies as well.
|
// to be re-used for method bodies as well.
|
||||||
EnterScope(Scope::FnScope|Scope::DeclScope);
|
ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
|
||||||
Actions.ActOnStartOfFunctionDef(CurScope, LM.D);
|
Actions.ActOnStartOfFunctionDef(CurScope, LM.D);
|
||||||
|
|
||||||
if (Tok.is(tok::colon))
|
if (Tok.is(tok::colon))
|
||||||
ParseConstructorInitializer(LM.D);
|
ParseConstructorInitializer(LM.D);
|
||||||
|
|
||||||
ParseFunctionStatementBody(LM.D, Tok.getLocation(), Tok.getLocation());
|
ParseFunctionStatementBody(LM.D, Tok.getLocation(), Tok.getLocation());
|
||||||
|
|
||||||
getCurTopClassStack().pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1728,7 +1728,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
|
|
||||||
// Enter function-declaration scope, limiting any declarators to the
|
// Enter function-declaration scope, limiting any declarators to the
|
||||||
// function prototype scope, including parameter declarators.
|
// function prototype scope, including parameter declarators.
|
||||||
EnterScope(Scope::FnScope|Scope::DeclScope);
|
ParseScope PrototypeScope(this, Scope::FnScope|Scope::DeclScope);
|
||||||
|
|
||||||
bool IsVariadic = false;
|
bool IsVariadic = false;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -1818,7 +1818,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave prototype scope.
|
// Leave prototype scope.
|
||||||
ExitScope();
|
PrototypeScope.Exit();
|
||||||
|
|
||||||
// If we have the closing ')', eat it.
|
// If we have the closing ')', eat it.
|
||||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
|
|
|
@ -67,7 +67,7 @@ Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
|
||||||
SourceLocation LBrace = ConsumeBrace();
|
SourceLocation LBrace = ConsumeBrace();
|
||||||
|
|
||||||
// Enter a scope for the namespace.
|
// Enter a scope for the namespace.
|
||||||
EnterScope(Scope::DeclScope);
|
ParseScope NamespaceScope(this, Scope::DeclScope);
|
||||||
|
|
||||||
DeclTy *NamespcDecl =
|
DeclTy *NamespcDecl =
|
||||||
Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
|
Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
|
||||||
|
@ -76,7 +76,7 @@ Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
|
||||||
ParseExternalDeclaration();
|
ParseExternalDeclaration();
|
||||||
|
|
||||||
// Leave the namespace scope.
|
// Leave the namespace scope.
|
||||||
ExitScope();
|
NamespaceScope.Exit();
|
||||||
|
|
||||||
SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
|
SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
|
||||||
Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
|
Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
|
||||||
|
@ -590,7 +590,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter a scope for the class.
|
// Enter a scope for the class.
|
||||||
EnterScope(Scope::CXXClassScope|Scope::DeclScope);
|
ParseScope ClassScope(this, Scope::CXXClassScope|Scope::DeclScope);
|
||||||
|
|
||||||
Actions.ActOnStartCXXClassDef(CurScope, TagDecl, LBraceLoc);
|
Actions.ActOnStartCXXClassDef(CurScope, TagDecl, LBraceLoc);
|
||||||
|
|
||||||
|
@ -659,7 +659,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave the class scope.
|
// Leave the class scope.
|
||||||
ExitScope();
|
ClassScope.Exit();
|
||||||
|
|
||||||
Actions.ActOnFinishCXXClassDef(TagDecl);
|
Actions.ActOnFinishCXXClassDef(TagDecl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1159,8 +1159,8 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// argument decls, decls within the compound expression, etc. This also
|
// argument decls, decls within the compound expression, etc. This also
|
||||||
// allows determining whether a variable reference inside the block is
|
// allows determining whether a variable reference inside the block is
|
||||||
// within or outside of the block.
|
// within or outside of the block.
|
||||||
EnterScope(Scope::BlockScope|Scope::FnScope|Scope::BreakScope|
|
ParseScope BlockScope(this, Scope::BlockScope|Scope::FnScope|Scope::BreakScope|
|
||||||
Scope::ContinueScope|Scope::DeclScope);
|
Scope::ContinueScope|Scope::DeclScope);
|
||||||
|
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockStart(CaretLoc, CurScope);
|
Actions.ActOnBlockStart(CaretLoc, CurScope);
|
||||||
|
@ -1179,7 +1179,6 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// If there was an error parsing the arguments, they may have tried to use
|
// If there was an error parsing the arguments, they may have tried to use
|
||||||
// ^(x+y) which requires an argument list. Just skip the whole block
|
// ^(x+y) which requires an argument list. Just skip the whole block
|
||||||
// literal.
|
// literal.
|
||||||
ExitScope();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1200,7 +1199,6 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
Actions.ActOnBlockError(CaretLoc, CurScope);
|
Actions.ActOnBlockError(CaretLoc, CurScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExitScope();
|
|
||||||
return Result.result();
|
return Result.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1214,11 +1214,11 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
|
||||||
}
|
}
|
||||||
// Enter a scope to hold everything within the compound stmt. Compound
|
// Enter a scope to hold everything within the compound stmt. Compound
|
||||||
// statements can always hold declarations.
|
// statements can always hold declarations.
|
||||||
EnterScope(Scope::DeclScope);
|
ParseScope BodyScope(this, Scope::DeclScope);
|
||||||
|
|
||||||
OwningStmtResult SynchBody(Actions, ParseCompoundStatementBody());
|
OwningStmtResult SynchBody(Actions, ParseCompoundStatementBody());
|
||||||
|
|
||||||
ExitScope();
|
BodyScope.Exit();
|
||||||
if (SynchBody.isInvalid())
|
if (SynchBody.isInvalid())
|
||||||
SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
|
SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.release(),
|
return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.release(),
|
||||||
|
@ -1246,9 +1246,9 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
}
|
}
|
||||||
OwningStmtResult CatchStmts(Actions);
|
OwningStmtResult CatchStmts(Actions);
|
||||||
OwningStmtResult FinallyStmt(Actions);
|
OwningStmtResult FinallyStmt(Actions);
|
||||||
EnterScope(Scope::DeclScope);
|
ParseScope TryScope(this, Scope::DeclScope);
|
||||||
OwningStmtResult TryBody(Actions, ParseCompoundStatementBody());
|
OwningStmtResult TryBody(Actions, ParseCompoundStatementBody());
|
||||||
ExitScope();
|
TryScope.Exit();
|
||||||
if (TryBody.isInvalid())
|
if (TryBody.isInvalid())
|
||||||
TryBody = Actions.ActOnNullStmt(Tok.getLocation());
|
TryBody = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
|
|
||||||
|
@ -1267,7 +1267,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
ConsumeToken(); // consume catch
|
ConsumeToken(); // consume catch
|
||||||
if (Tok.is(tok::l_paren)) {
|
if (Tok.is(tok::l_paren)) {
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
EnterScope(Scope::DeclScope);
|
ParseScope CatchScope(this, Scope::DeclScope);
|
||||||
if (Tok.isNot(tok::ellipsis)) {
|
if (Tok.isNot(tok::ellipsis)) {
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
ParseDeclarationSpecifiers(DS);
|
ParseDeclarationSpecifiers(DS);
|
||||||
|
@ -1297,7 +1297,6 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
|
CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
|
||||||
RParenLoc, FirstPart.release(), CatchBody.release(),
|
RParenLoc, FirstPart.release(), CatchBody.release(),
|
||||||
CatchStmts.release());
|
CatchStmts.release());
|
||||||
ExitScope();
|
|
||||||
} else {
|
} else {
|
||||||
Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
|
Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
|
||||||
<< "@catch clause";
|
<< "@catch clause";
|
||||||
|
@ -1307,8 +1306,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
} else {
|
} else {
|
||||||
assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
|
assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
|
||||||
ConsumeToken(); // consume finally
|
ConsumeToken(); // consume finally
|
||||||
EnterScope(Scope::DeclScope);
|
ParseScope FinallyScope(this, Scope::DeclScope);
|
||||||
|
|
||||||
|
|
||||||
OwningStmtResult FinallyBody(Actions, true);
|
OwningStmtResult FinallyBody(Actions, true);
|
||||||
if (Tok.is(tok::l_brace))
|
if (Tok.is(tok::l_brace))
|
||||||
|
@ -1320,7 +1318,6 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
||||||
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
|
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
|
||||||
FinallyBody.release());
|
FinallyBody.release());
|
||||||
catch_or_finally_seen = true;
|
catch_or_finally_seen = true;
|
||||||
ExitScope();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1355,7 +1352,7 @@ Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
|
||||||
SourceLocation BraceLoc = Tok.getLocation();
|
SourceLocation BraceLoc = Tok.getLocation();
|
||||||
|
|
||||||
// Enter a scope for the method body.
|
// Enter a scope for the method body.
|
||||||
EnterScope(Scope::FnScope|Scope::DeclScope);
|
ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
|
||||||
|
|
||||||
// Tell the actions module that we have entered a method definition with the
|
// Tell the actions module that we have entered a method definition with the
|
||||||
// specified Declarator for the method.
|
// specified Declarator for the method.
|
||||||
|
@ -1368,7 +1365,7 @@ Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
|
||||||
FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
|
FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
|
||||||
|
|
||||||
// Leave the function body scope.
|
// Leave the function body scope.
|
||||||
ExitScope();
|
BodyScope.Exit();
|
||||||
|
|
||||||
// TODO: Pass argument information.
|
// TODO: Pass argument information.
|
||||||
Actions.ActOnFinishFunctionBody(MDecl, FnBody.release());
|
Actions.ActOnFinishFunctionBody(MDecl, FnBody.release());
|
||||||
|
|
|
@ -333,12 +333,10 @@ Parser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
|
||||||
|
|
||||||
// Enter a scope to hold everything within the compound stmt. Compound
|
// Enter a scope to hold everything within the compound stmt. Compound
|
||||||
// statements can always hold declarations.
|
// statements can always hold declarations.
|
||||||
EnterScope(Scope::DeclScope);
|
ParseScope CompoundScope(this, Scope::DeclScope);
|
||||||
|
|
||||||
// Parse the statements in the body.
|
// Parse the statements in the body.
|
||||||
OwningStmtResult Body(Actions, ParseCompoundStatementBody(isStmtExpr));
|
OwningStmtResult Body(Actions, ParseCompoundStatementBody(isStmtExpr));
|
||||||
|
|
||||||
ExitScope();
|
|
||||||
return Body.result();
|
return Body.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,8 +444,7 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
// while, for, and switch statements are local to the if, while, for, or
|
// while, for, and switch statements are local to the if, while, for, or
|
||||||
// switch statement (including the controlled statement).
|
// switch statement (including the controlled statement).
|
||||||
//
|
//
|
||||||
if (C99orCXX)
|
ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
|
||||||
EnterScope(Scope::DeclScope | Scope::ControlScope);
|
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
OwningExprResult CondExp(Actions);
|
OwningExprResult CondExp(Actions);
|
||||||
|
@ -461,8 +458,6 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
|
|
||||||
if (CondExp.isInvalid()) {
|
if (CondExp.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
if (C99orCXX)
|
|
||||||
ExitScope();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,15 +479,15 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
// would have to notify ParseStatement not to create a new scope. It's
|
// would have to notify ParseStatement not to create a new scope. It's
|
||||||
// simpler to let it create a new scope.
|
// simpler to let it create a new scope.
|
||||||
//
|
//
|
||||||
bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
ParseScope InnerScope(this, Scope::DeclScope,
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
C99orCXX && Tok.isNot(tok::l_brace));
|
||||||
|
|
||||||
// Read the 'then' stmt.
|
// Read the 'then' stmt.
|
||||||
SourceLocation ThenStmtLoc = Tok.getLocation();
|
SourceLocation ThenStmtLoc = Tok.getLocation();
|
||||||
OwningStmtResult ThenStmt(Actions, ParseStatement());
|
OwningStmtResult ThenStmt(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the 'if' scope if needed.
|
// Pop the 'if' scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
InnerScope.Exit();
|
||||||
|
|
||||||
// If it has an else, parse it.
|
// If it has an else, parse it.
|
||||||
SourceLocation ElseLoc;
|
SourceLocation ElseLoc;
|
||||||
|
@ -511,18 +506,17 @@ Parser::StmtResult Parser::ParseIfStatement() {
|
||||||
// The substatement in a selection-statement (each substatement, in the else
|
// The substatement in a selection-statement (each substatement, in the else
|
||||||
// form of the if statement) implicitly defines a local scope.
|
// form of the if statement) implicitly defines a local scope.
|
||||||
//
|
//
|
||||||
NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
ParseScope InnerScope(this, Scope::DeclScope,
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
C99orCXX && Tok.isNot(tok::l_brace));
|
||||||
|
|
||||||
ElseStmtLoc = Tok.getLocation();
|
ElseStmtLoc = Tok.getLocation();
|
||||||
ElseStmt = ParseStatement();
|
ElseStmt = ParseStatement();
|
||||||
|
|
||||||
// Pop the 'else' scope if needed.
|
// Pop the 'else' scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
InnerScope.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C99orCXX)
|
IfScope.Exit();
|
||||||
ExitScope();
|
|
||||||
|
|
||||||
// If the then or else stmt is invalid and the other is valid (and present),
|
// If the then or else stmt is invalid and the other is valid (and present),
|
||||||
// make turn the invalid one into a null stmt to avoid dropping the other
|
// make turn the invalid one into a null stmt to avoid dropping the other
|
||||||
|
@ -572,10 +566,10 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
|
||||||
// while, for, and switch statements are local to the if, while, for, or
|
// while, for, and switch statements are local to the if, while, for, or
|
||||||
// switch statement (including the controlled statement).
|
// switch statement (including the controlled statement).
|
||||||
//
|
//
|
||||||
if (C99orCXX)
|
unsigned ScopeFlags
|
||||||
EnterScope(Scope::BreakScope | Scope::DeclScope | Scope::ControlScope);
|
= C99orCXX? Scope::BreakScope | Scope::DeclScope | Scope::ControlScope
|
||||||
else
|
: Scope::BreakScope;
|
||||||
EnterScope(Scope::BreakScope);
|
ParseScope SwitchScope(this, ScopeFlags);
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
OwningExprResult Cond(Actions);
|
OwningExprResult Cond(Actions);
|
||||||
|
@ -587,10 +581,8 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
|
||||||
Cond = ParseSimpleParenExpression();
|
Cond = ParseSimpleParenExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cond.isInvalid()) {
|
if (Cond.isInvalid())
|
||||||
ExitScope();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
OwningStmtResult Switch(Actions,
|
OwningStmtResult Switch(Actions,
|
||||||
Actions.ActOnStartOfSwitchStmt(Cond.release()));
|
Actions.ActOnStartOfSwitchStmt(Cond.release()));
|
||||||
|
@ -606,21 +598,21 @@ Parser::StmtResult Parser::ParseSwitchStatement() {
|
||||||
// See comments in ParseIfStatement for why we create a scope for the
|
// See comments in ParseIfStatement for why we create a scope for the
|
||||||
// condition and a new scope for substatement in C++.
|
// condition and a new scope for substatement in C++.
|
||||||
//
|
//
|
||||||
bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
ParseScope InnerScope(this, Scope::DeclScope,
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
C99orCXX && Tok.isNot(tok::l_brace));
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
OwningStmtResult Body(Actions, ParseStatement());
|
OwningStmtResult Body(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
InnerScope.Exit();
|
||||||
|
|
||||||
if (Body.isInvalid()) {
|
if (Body.isInvalid()) {
|
||||||
Body = Actions.ActOnNullStmt(Tok.getLocation());
|
Body = Actions.ActOnNullStmt(Tok.getLocation());
|
||||||
// FIXME: Remove the case statement list from the Switch statement.
|
// FIXME: Remove the case statement list from the Switch statement.
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitScope();
|
SwitchScope.Exit();
|
||||||
|
|
||||||
return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(),
|
return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(),
|
||||||
Body.release());
|
Body.release());
|
||||||
|
@ -655,11 +647,13 @@ Parser::StmtResult Parser::ParseWhileStatement() {
|
||||||
// while, for, and switch statements are local to the if, while, for, or
|
// while, for, and switch statements are local to the if, while, for, or
|
||||||
// switch statement (including the controlled statement).
|
// switch statement (including the controlled statement).
|
||||||
//
|
//
|
||||||
|
unsigned ScopeFlags;
|
||||||
if (C99orCXX)
|
if (C99orCXX)
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope |
|
ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
|
||||||
Scope::DeclScope | Scope::ControlScope);
|
Scope::DeclScope | Scope::ControlScope;
|
||||||
else
|
else
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
|
||||||
|
ParseScope WhileScope(this, ScopeFlags);
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
OwningExprResult Cond(Actions);
|
OwningExprResult Cond(Actions);
|
||||||
|
@ -682,16 +676,15 @@ Parser::StmtResult Parser::ParseWhileStatement() {
|
||||||
// See comments in ParseIfStatement for why we create a scope for the
|
// See comments in ParseIfStatement for why we create a scope for the
|
||||||
// condition and a new scope for substatement in C++.
|
// condition and a new scope for substatement in C++.
|
||||||
//
|
//
|
||||||
bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
ParseScope InnerScope(this, Scope::DeclScope,
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
C99orCXX && Tok.isNot(tok::l_brace));
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
OwningStmtResult Body(Actions, ParseStatement());
|
OwningStmtResult Body(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
InnerScope.Exit();
|
||||||
|
WhileScope.Exit();
|
||||||
ExitScope();
|
|
||||||
|
|
||||||
if (Cond.isInvalid() || Body.isInvalid()) return true;
|
if (Cond.isInvalid() || Body.isInvalid()) return true;
|
||||||
|
|
||||||
|
@ -708,10 +701,13 @@ Parser::StmtResult Parser::ParseDoStatement() {
|
||||||
|
|
||||||
// C99 6.8.5p5 - In C99, the do statement is a block. This is not
|
// C99 6.8.5p5 - In C99, the do statement is a block. This is not
|
||||||
// the case for C90. Start the loop scope.
|
// the case for C90. Start the loop scope.
|
||||||
|
unsigned ScopeFlags;
|
||||||
if (getLang().C99)
|
if (getLang().C99)
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
|
ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
|
||||||
else
|
else
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
|
||||||
|
|
||||||
|
ParseScope DoScope(this, ScopeFlags);
|
||||||
|
|
||||||
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
|
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
|
||||||
// there is no compound stmt. C90 does not have this clause. We only do this
|
// there is no compound stmt. C90 does not have this clause. We only do this
|
||||||
|
@ -721,18 +717,17 @@ Parser::StmtResult Parser::ParseDoStatement() {
|
||||||
// The substatement in an iteration-statement implicitly defines a local scope
|
// The substatement in an iteration-statement implicitly defines a local scope
|
||||||
// which is entered and exited each time through the loop.
|
// which is entered and exited each time through the loop.
|
||||||
//
|
//
|
||||||
bool NeedsInnerScope =
|
ParseScope InnerScope(this, Scope::DeclScope,
|
||||||
(getLang().C99 || getLang().CPlusPlus) && Tok.isNot(tok::l_brace);
|
(getLang().C99 || getLang().CPlusPlus) &&
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
Tok.isNot(tok::l_brace));
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
OwningStmtResult Body(Actions, ParseStatement());
|
OwningStmtResult Body(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
InnerScope.Exit();
|
||||||
|
|
||||||
if (Tok.isNot(tok::kw_while)) {
|
if (Tok.isNot(tok::kw_while)) {
|
||||||
ExitScope();
|
|
||||||
if (!Body.isInvalid()) {
|
if (!Body.isInvalid()) {
|
||||||
Diag(Tok, diag::err_expected_while);
|
Diag(Tok, diag::err_expected_while);
|
||||||
Diag(DoLoc, diag::note_matching) << "do";
|
Diag(DoLoc, diag::note_matching) << "do";
|
||||||
|
@ -743,7 +738,6 @@ Parser::StmtResult Parser::ParseDoStatement() {
|
||||||
SourceLocation WhileLoc = ConsumeToken();
|
SourceLocation WhileLoc = ConsumeToken();
|
||||||
|
|
||||||
if (Tok.isNot(tok::l_paren)) {
|
if (Tok.isNot(tok::l_paren)) {
|
||||||
ExitScope();
|
|
||||||
Diag(Tok, diag::err_expected_lparen_after) << "do/while";
|
Diag(Tok, diag::err_expected_lparen_after) << "do/while";
|
||||||
SkipUntil(tok::semi, false, true);
|
SkipUntil(tok::semi, false, true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -751,8 +745,7 @@ Parser::StmtResult Parser::ParseDoStatement() {
|
||||||
|
|
||||||
// Parse the condition.
|
// Parse the condition.
|
||||||
OwningExprResult Cond(Actions, ParseSimpleParenExpression());
|
OwningExprResult Cond(Actions, ParseSimpleParenExpression());
|
||||||
|
DoScope.Exit();
|
||||||
ExitScope();
|
|
||||||
|
|
||||||
if (Cond.isInvalid() || Body.isInvalid()) return true;
|
if (Cond.isInvalid() || Body.isInvalid()) return true;
|
||||||
|
|
||||||
|
@ -799,11 +792,14 @@ Parser::StmtResult Parser::ParseForStatement() {
|
||||||
// Names declared in the for-init-statement are in the same declarative-region
|
// Names declared in the for-init-statement are in the same declarative-region
|
||||||
// as those declared in the condition.
|
// as those declared in the condition.
|
||||||
//
|
//
|
||||||
|
unsigned ScopeFlags;
|
||||||
if (C99orCXX)
|
if (C99orCXX)
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope |
|
ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
|
||||||
Scope::DeclScope | Scope::ControlScope);
|
Scope::DeclScope | Scope::ControlScope;
|
||||||
else
|
else
|
||||||
EnterScope(Scope::BreakScope | Scope::ContinueScope);
|
ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
|
||||||
|
|
||||||
|
ParseScope ForScope(this, ScopeFlags);
|
||||||
|
|
||||||
SourceLocation LParenLoc = ConsumeParen();
|
SourceLocation LParenLoc = ConsumeParen();
|
||||||
OwningExprResult Value(Actions);
|
OwningExprResult Value(Actions);
|
||||||
|
@ -891,17 +887,17 @@ Parser::StmtResult Parser::ParseForStatement() {
|
||||||
// See comments in ParseIfStatement for why we create a scope for
|
// See comments in ParseIfStatement for why we create a scope for
|
||||||
// for-init-statement/condition and a new scope for substatement in C++.
|
// for-init-statement/condition and a new scope for substatement in C++.
|
||||||
//
|
//
|
||||||
bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
|
ParseScope InnerScope(this, Scope::DeclScope,
|
||||||
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
|
C99orCXX && Tok.isNot(tok::l_brace));
|
||||||
|
|
||||||
// Read the body statement.
|
// Read the body statement.
|
||||||
OwningStmtResult Body(Actions, ParseStatement());
|
OwningStmtResult Body(Actions, ParseStatement());
|
||||||
|
|
||||||
// Pop the body scope if needed.
|
// Pop the body scope if needed.
|
||||||
if (NeedsInnerScope) ExitScope();
|
InnerScope.Exit();
|
||||||
|
|
||||||
// Leave the for-scope.
|
// Leave the for-scope.
|
||||||
ExitScope();
|
ForScope.Exit();
|
||||||
|
|
||||||
if (Body.isInvalid())
|
if (Body.isInvalid())
|
||||||
return true;
|
return true;
|
||||||
|
@ -1214,8 +1210,5 @@ Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl,
|
||||||
if (FnBody.isInvalid())
|
if (FnBody.isInvalid())
|
||||||
FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
|
FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
|
||||||
|
|
||||||
// Leave the function body scope.
|
|
||||||
ExitScope();
|
|
||||||
|
|
||||||
return Actions.ActOnFinishFunctionBody(Decl, FnBody.release());
|
return Actions.ActOnFinishFunctionBody(Decl, FnBody.release());
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ Parser::DeclTy *Parser::ParseTemplateDeclaration(unsigned Context) {
|
||||||
SourceLocation TemplateLoc = ConsumeToken();
|
SourceLocation TemplateLoc = ConsumeToken();
|
||||||
|
|
||||||
// Enter template-parameter scope.
|
// Enter template-parameter scope.
|
||||||
EnterScope(Scope::TemplateParamScope);
|
ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
|
||||||
|
|
||||||
// Try to parse the template parameters, and the declaration if
|
// Try to parse the template parameters, and the declaration if
|
||||||
// successful.
|
// successful.
|
||||||
|
@ -49,9 +49,6 @@ Parser::DeclTy *Parser::ParseTemplateDeclaration(unsigned Context) {
|
||||||
if(ParseTemplateParameters(0))
|
if(ParseTemplateParameters(0))
|
||||||
TemplateDecl = ParseDeclarationOrFunctionDefinition();
|
TemplateDecl = ParseDeclarationOrFunctionDefinition();
|
||||||
|
|
||||||
// Leave template-parameter scope.
|
|
||||||
ExitScope();
|
|
||||||
|
|
||||||
return TemplateDecl;
|
return TemplateDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -287,7 +287,7 @@ bool Parser::ParseTopLevelDecl(DeclTy*& Result) {
|
||||||
/// external-declaration
|
/// external-declaration
|
||||||
/// translation-unit external-declaration
|
/// translation-unit external-declaration
|
||||||
void Parser::ParseTranslationUnit() {
|
void Parser::ParseTranslationUnit() {
|
||||||
Initialize(); // pushes a scope.
|
Initialize();
|
||||||
|
|
||||||
DeclTy *Res;
|
DeclTy *Res;
|
||||||
while (!ParseTopLevelDecl(Res))
|
while (!ParseTopLevelDecl(Res))
|
||||||
|
@ -526,7 +526,7 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter a scope for the function body.
|
// Enter a scope for the function body.
|
||||||
EnterScope(Scope::FnScope|Scope::DeclScope);
|
ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
|
||||||
|
|
||||||
// Tell the actions module that we have entered a function definition with the
|
// Tell the actions module that we have entered a function definition with the
|
||||||
// specified Declarator for the function.
|
// specified Declarator for the function.
|
||||||
|
@ -549,7 +549,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
|
||||||
|
|
||||||
// Enter function-declaration scope, limiting any declarators to the
|
// Enter function-declaration scope, limiting any declarators to the
|
||||||
// function prototype scope, including parameter declarators.
|
// function prototype scope, including parameter declarators.
|
||||||
EnterScope(Scope::FnScope|Scope::DeclScope);
|
ParseScope PrototypeScope(this, Scope::FnScope|Scope::DeclScope);
|
||||||
|
|
||||||
// Read all the argument declarations.
|
// Read all the argument declarations.
|
||||||
while (isDeclarationSpecifier()) {
|
while (isDeclarationSpecifier()) {
|
||||||
|
@ -653,9 +653,6 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave prototype scope.
|
|
||||||
ExitScope();
|
|
||||||
|
|
||||||
// The actions module must verify that all arguments were declared.
|
// The actions module must verify that all arguments were declared.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue