Add methods for scope manipulation.

llvm-svn: 38909
This commit is contained in:
Chris Lattner 2006-08-14 00:15:05 +00:00
parent 78b917603c
commit e4e38595b0
2 changed files with 65 additions and 24 deletions

View File

@ -19,17 +19,20 @@ using namespace clang;
Parser::Parser(Preprocessor &pp, ParserActions &actions)
: PP(pp), Actions(actions), Diags(PP.getDiagnostics()) {
// Create the global scope, install it as the current scope.
CurScope = new Scope(0);
Tok.SetKind(tok::eof);
CurScope = 0;
ParenCount = BracketCount = BraceCount = 0;
}
Parser::~Parser() {
// If we still have scopes active, delete the scope tree.
delete CurScope;
}
/// Out-of-line virtual destructor to provide home for ParserActions class.
ParserActions::~ParserActions() {}
void Parser::Diag(SourceLocation Loc, unsigned DiagID,
const std::string &Msg) {
@ -157,6 +160,31 @@ bool Parser::SkipUntil(tok::TokenKind T, bool StopAtSemi, bool DontConsume) {
}
}
//===----------------------------------------------------------------------===//
// Scope manipulation
//===----------------------------------------------------------------------===//
/// EnterScope - Start a new scope.
void Parser::EnterScope() {
// TODO: Inform actions?
CurScope = new Scope(CurScope);
}
/// ExitScope - Pop a scope off the scope stack.
void Parser::ExitScope() {
assert(CurScope && "Scope imbalance!");
// Inform the actions module that this scope is going away.
Actions.PopScope(Tok.getLocation(), CurScope);
Scope *Old = CurScope;
CurScope = Old->getParent();
delete Old;
}
//===----------------------------------------------------------------------===//
// C99 6.9: External Definitions.
//===----------------------------------------------------------------------===//
@ -166,12 +194,21 @@ bool Parser::SkipUntil(tok::TokenKind T, bool StopAtSemi, bool DontConsume) {
/// external-declaration
/// translation-unit external-declaration
void Parser::ParseTranslationUnit() {
// Prime the lexer look-ahead.
ConsumeToken();
// Create the global scope, install it as the current scope.
assert(CurScope == 0 && "A scope is already active?");
EnterScope();
if (Tok.getKind() == tok::eof) // Empty source file is an extension.
Diag(diag::ext_empty_source_file);
while (Tok.getKind() != tok::eof)
ParseExternalDeclaration();
ExitScope();
assert(CurScope == 0 && "Scope imbalance!");
}
/// ParseExternalDeclaration:
@ -213,13 +250,6 @@ void Parser::ParseExternalDeclaration() {
/// [!C99] init-declarator-list ';' [TODO]
/// [OMP] threadprivate-directive [TODO]
///
/// init-declarator-list: [C99 6.7]
/// init-declarator
/// init-declarator-list ',' init-declarator
/// init-declarator: [C99 6.7]
/// declarator
/// declarator '=' initializer
///
void Parser::ParseDeclarationOrFunctionDefinition() {
// Parse the common declaration-specifiers piece.
DeclSpec DS;
@ -264,9 +294,7 @@ void Parser::ParseDeclarationOrFunctionDefinition() {
Diag(Tok, diag::err_expected_fn_body);
else
Diag(Tok, diag::err_expected_after_declarator);
SkipUntil(tok::r_brace, true);
if (Tok.getKind() == tok::semi)
ConsumeToken();
SkipUntil(tok::semi);
return;
}

View File

@ -52,20 +52,16 @@ public:
void ParseTranslationUnit();
struct ExprResult {
ExprTy Val;
ExprTy *Val;
bool isInvalid;
ExprResult(bool Invalid = false) : isInvalid(Invalid) {}
ExprResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
};
// Diagnostics.
void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg = "");
void Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M = "") {
Diag(Tok.getLocation(), DiagID, M);
}
void Diag(unsigned DiagID, const std::string &Msg = "") {
Diag(Tok, DiagID, Msg);
}
private:
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
//
/// isTokenParen - Return true if the cur token is '(' or ')'.
bool isTokenParen() const {
@ -172,10 +168,27 @@ public:
/// returned.
bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
tok::TokenKind SkipToTok = tok::unknown);
private:
//===--------------------------------------------------------------------===//
// Error recovery.
// Scope manipulation
/// EnterScope - Start a new scope.
void EnterScope();
/// ExitScope - Pop a scope off the scope stack.
void ExitScope();
//===--------------------------------------------------------------------===//
// Diagnostic Emission and Error recovery.
void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg = "");
void Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M = "") {
Diag(Tok.getLocation(), DiagID, M);
}
void Diag(unsigned DiagID, const std::string &Msg = "") {
Diag(Tok, DiagID, Msg);
}
/// SkipUntil - Read tokens until we get to the specified token, then consume
/// it (unless DontConsume is false). Because we cannot guarantee that the
/// token will ever occur, this skips to the next token, or to some likely