forked from OSchip/llvm-project
parent
78b917603c
commit
e4e38595b0
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue