1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
|
//===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the Parser interface.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_PARSE_PARSER_H
#define LLVM_CLANG_PARSE_PARSER_H
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Action.h"
namespace clang {
class DeclSpec;
class Declarator;
class AttributeList;
class Scope;
/// Parser - This implements a parser for the C family of languages. After
/// parsing units of the grammar, productions are invoked to handle whatever has
/// been read.
///
class Parser {
Preprocessor &PP;
/// Tok - The current token we are peeking head. All parsing methods assume
/// that this is valid.
Token Tok;
unsigned short ParenCount, BracketCount, BraceCount;
/// Actions - These are the callbacks we invoke as we parse various constructs
/// in the file. This refers to the common base class between MinimalActions
/// and SemaActions for those uses that don't matter.
Action &Actions;
Scope *CurScope;
Diagnostic &Diags;
/// ScopeCache - Cache scopes to reduce malloc traffic.
enum { ScopeCacheSize = 16 };
unsigned NumCachedScopes;
Scope *ScopeCache[ScopeCacheSize];
public:
Parser(Preprocessor &PP, Action &Actions);
~Parser();
const LangOptions &getLang() const { return PP.getLangOptions(); }
TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
Action &getActions() const { return Actions; }
// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.
typedef Action::ExprTy ExprTy;
typedef Action::StmtTy StmtTy;
typedef Action::DeclTy DeclTy;
typedef Action::TypeTy TypeTy;
// Parsing methods.
/// ParseTranslationUnit - All in one method that initializes parses, and
/// shuts down the parser.
void ParseTranslationUnit();
/// Initialize - Warm up the parser.
///
void Initialize();
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
/// action tells us to. This returns true if the EOF was encountered.
bool ParseTopLevelDecl(DeclTy*& Result);
/// Finalize - Shut down the parser.
///
void Finalize();
private:
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
//
/// isTokenParen - Return true if the cur token is '(' or ')'.
bool isTokenParen() const {
return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
}
/// isTokenBracket - Return true if the cur token is '[' or ']'.
bool isTokenBracket() const {
return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
}
/// isTokenBrace - Return true if the cur token is '{' or '}'.
bool isTokenBrace() const {
return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
}
/// isTokenStringLiteral - True if this token is a string-literal.
///
bool isTokenStringLiteral() const {
return Tok.getKind() == tok::string_literal ||
Tok.getKind() == tok::wide_string_literal;
}
/// ConsumeToken - Consume the current 'peek token' and lex the next one.
/// This does not work will all kinds of tokens: strings and specific other
/// tokens must be consumed with custom methods below. This returns the
/// location of the consumed token.
SourceLocation ConsumeToken() {
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
!isTokenBrace() &&
"Should consume special tokens with Consume*Token");
SourceLocation L = Tok.getLocation();
PP.Lex(Tok);
return L;
}
/// ConsumeAnyToken - Dispatch to the right Consume* method based on the
/// current token type. This should only be used in cases where the type of
/// the token really isn't known, e.g. in error recovery.
SourceLocation ConsumeAnyToken() {
if (isTokenParen())
return ConsumeParen();
else if (isTokenBracket())
return ConsumeBracket();
else if (isTokenBrace())
return ConsumeBrace();
else
return ConsumeToken();
}
/// ConsumeParen - This consume method keeps the paren count up-to-date.
///
SourceLocation ConsumeParen() {
assert(isTokenParen() && "wrong consume method");
if (Tok.getKind() == tok::l_paren)
++ParenCount;
else if (ParenCount)
--ParenCount; // Don't let unbalanced )'s drive the count negative.
SourceLocation L = Tok.getLocation();
PP.Lex(Tok);
return L;
}
/// ConsumeBracket - This consume method keeps the bracket count up-to-date.
///
SourceLocation ConsumeBracket() {
assert(isTokenBracket() && "wrong consume method");
if (Tok.getKind() == tok::l_square)
++BracketCount;
else if (BracketCount)
--BracketCount; // Don't let unbalanced ]'s drive the count negative.
SourceLocation L = Tok.getLocation();
PP.Lex(Tok);
return L;
}
/// ConsumeBrace - This consume method keeps the brace count up-to-date.
///
SourceLocation ConsumeBrace() {
assert(isTokenBrace() && "wrong consume method");
if (Tok.getKind() == tok::l_brace)
++BraceCount;
else if (BraceCount)
--BraceCount; // Don't let unbalanced }'s drive the count negative.
SourceLocation L = Tok.getLocation();
PP.Lex(Tok);
return L;
}
/// ConsumeStringToken - Consume the current 'peek token', lexing a new one
/// and returning the token kind. This method is specific to strings, as it
/// handles string literal concatenation, as per C99 5.1.1.2, translation
/// phase #6.
SourceLocation ConsumeStringToken() {
assert(isTokenStringLiteral() &&
"Should only consume string literals with this method");
SourceLocation L = Tok.getLocation();
PP.Lex(Tok);
return L;
}
/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
/// this helper function matches and consumes the specified RHS token if
/// present. If not present, it emits the specified diagnostic indicating
/// that the parser failed to match the RHS of the token at LHSLoc. LHSName
/// should be the name of the unmatched LHS token. This returns the location
/// of the consumed token.
SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
SourceLocation LHSLoc);
/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
/// input. If so, it is consumed and false is returned.
///
/// If the input is malformed, this emits the specified diagnostic. Next, if
/// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
/// returned.
bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
const char *DiagMsg = "",
tok::TokenKind SkipToTok = tok::unknown);
//===--------------------------------------------------------------------===//
// Scope manipulation
/// EnterScope - Start a new scope.
void EnterScope(unsigned ScopeFlags);
/// 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 = std::string());
void Diag(const Token &Tok, unsigned DiagID,
const std::string &M = std::string()) {
Diag(Tok.getLocation(), DiagID, M);
}
/// 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
/// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
/// character.
///
/// If SkipUntil finds the specified token, it returns true, otherwise it
/// returns false.
bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
bool DontConsume = false) {
return SkipUntil(&T, 1, StopAtSemi, DontConsume);
}
bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
bool DontConsume = false) {
tok::TokenKind TokArray[] = {T1, T2};
return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
}
bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
bool StopAtSemi = true, bool DontConsume = false);
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
DeclTy *ParseExternalDeclaration();
DeclTy *ParseDeclarationOrFunctionDefinition();
DeclTy *ParseFunctionDefinition(Declarator &D);
void ParseKNRParamDeclarations(Declarator &D);
void ParseSimpleAsm();
void ParseAsmStringLiteral();
// Objective-C External Declarations
void ParseObjCAtDirectives();
void ParseObjCAtClassDeclaration(SourceLocation atLoc);
void ParseObjCAtInterfaceDeclaration();
void ParseObjCAtProtocolDeclaration();
void ParseObjCAtImplementationDeclaration();
void ParseObjCAtEndDeclaration();
void ParseObjCAtAliasDeclaration();
void ParseObjCInstanceMethodDeclaration();
void ParseObjCClassMethodDeclaration();
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
typedef Action::ExprResult ExprResult;
typedef Action::StmtResult StmtResult;
ExprResult ParseExpression();
ExprResult ParseConstantExpression();
ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok);
ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
ExprResult ParseAssignmentExpressionWithLeadingStar(const Token &Tok);
ExprResult ParseRHSOfBinaryExpression(ExprResult
|