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
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
|
//===--- Action.h - Parser Action Interface ---------------------*- 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 Action and EmptyAction interface.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_PARSE_ACTION_H
#define LLVM_CLANG_PARSE_ACTION_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TokenKinds.h"
namespace clang {
// Semantic.
class DeclSpec;
class Declarator;
class AttributeList;
// Parse.
class Scope;
class Action;
// Lex.
class IdentifierInfo;
class Token;
/// Action - As the parser reads the input file and recognizes the productions
/// of the grammar, it invokes methods on this class to turn the parsed input
/// into something useful: e.g. a parse tree.
///
/// The callback methods that this class provides are phrased as actions that
/// the parser has just done or is about to do when the method is called. They
/// are not requests that the actions module do the specified action.
///
/// All of the methods here are optional except isTypeName(), which must be
/// specified in order for the parse to complete accurately. The EmptyAction
/// class does this bare-minimum of tracking to implement this functionality.
class Action {
public:
/// Out-of-line virtual destructor to provide home for this class.
virtual ~Action();
// Types - Though these don't actually enforce strong typing, they document
// what types are required to be identical for the actions.
typedef void ExprTy;
typedef void StmtTy;
typedef void DeclTy;
typedef void TypeTy;
typedef void AttrTy;
/// ActionResult - This structure is used while parsing/acting on expressions,
/// stmts, etc. It encapsulates both the object returned by the action, plus
/// a sense of whether or not it is valid.
template<unsigned UID>
struct ActionResult {
void *Val;
bool isInvalid;
ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
template<typename ActualExprTy>
ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
const ActionResult &operator=(void *RHS) {
Val = RHS;
isInvalid = false;
return *this;
}
};
/// Expr/Stmt/TypeResult - Provide a unique type to wrap ExprTy/StmtTy/TypeTy,
/// providing strong typing and allowing for failure.
typedef ActionResult<0> ExprResult;
typedef ActionResult<1> StmtResult;
typedef ActionResult<2> TypeResult;
//===--------------------------------------------------------------------===//
// Declaration Tracking Callbacks.
//===--------------------------------------------------------------------===//
/// isTypeName - Return non-null if the specified identifier is a typedef name
/// in the current scope.
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const = 0;
/// ParseDeclarator - This callback is invoked when a declarator is parsed and
/// 'Init' specifies the initializer if any. This is for things like:
/// "int X = 4" or "typedef int foo".
///
/// LastInGroup is non-null for cases where one declspec has multiple
/// declarators on it. For example in 'int A, B', ParseDeclarator will be
/// called with LastInGroup=A when invoked for B.
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D,
ExprTy *Init, DeclTy *LastInGroup) {
return 0;
}
/// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
/// gives the actions implementation a chance to process the group as a whole.
virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
return Group;
}
/// ParseStartOfFunctionDef - This is called at the start of a function
/// definition, instead of calling ParseDeclarator. The Declarator includes
/// information about formal arguments that are part of this function.
virtual DeclTy *ParseStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
// Default to ParseDeclarator.
return ParseDeclarator(FnBodyScope, D, 0, 0);
}
/// ParseFunctionDefBody - This is called when a function body has completed
/// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body) {
return Decl;
}
/// PopScope - This callback is called immediately before the specified scope
/// is popped and deleted.
virtual void PopScope(SourceLocation Loc, Scope *S) {}
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
return 0;
}
virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
IdentifierInfo **IdentList,
unsigned NumElts) {
return 0;
}
//===--------------------------------------------------------------------===//
// Type Parsing Callbacks.
//===--------------------------------------------------------------------===//
virtual TypeResult ParseTypeName(Scope *S, Declarator &D) {
return 0;
}
virtual TypeResult ParseParamDeclaratorType(Scope *S, Declarator &D) {
return 0;
}
enum TagKind {
TK_Reference, // Reference to a tag: 'struct foo *X;'
TK_Declaration, // Fwd decl of a tag: 'struct foo;'
TK_Definition // Definition of a tag: 'struct foo { int X; } Y;'
};
virtual DeclTy *ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc, AttributeList *Attr) {
// TagType is an instance of DeclSpec::TST, indicating what kind of tag this
// is (struct/union/enum/class).
return 0;
}
virtual DeclTy *ParseField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth) {
return 0;
}
virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
DeclTy **Fields, unsigned NumFields) {}
virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
DeclTy *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
SourceLocation EqualLoc, ExprTy *Val) {
return 0;
}
virtual void ParseEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
DeclTy **Elements, unsigned NumElements) {}
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks.
//===--------------------------------------------------------------------===//
virtual StmtResult ParseNullStmt(SourceLocation SemiLoc) {
return 0;
}
virtual StmtResult ParseCompoundStmt(SourceLocation L, SourceLocation R,
StmtTy **Elts, unsigned NumElts) {
return 0;
}
virtual StmtResult ParseDeclStmt(DeclTy *Decl) {
return 0;
}
virtual StmtResult ParseExprStmt(ExprTy *Expr) {
return StmtResult(Expr);
}
/// ParseCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
/// which can specify an RHS value.
virtual StmtResult ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
SourceLocation DotDotDotLoc, ExprTy *RHSVal,
SourceLocation ColonLoc, StmtTy *SubStmt) {
return 0;
}
virtual StmtResult ParseDefaultStmt(SourceLocation DefaultLoc,
SourceLocation ColonLoc, StmtTy *SubStmt,
Scope *CurScope){
return 0;
}
virtual StmtResult ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
SourceLocation ColonLoc, StmtTy *SubStmt) {
return 0;
}
virtual StmtResult ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
StmtTy *ThenVal, SourceLocation ElseLoc,
StmtTy *ElseVal) {
return 0;
}
virtual StmtResult StartSwitchStmt(ExprTy *Cond) {
return 0;
}
virtual StmtResult FinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch,
ExprTy *Body) {
return 0;
}
virtual StmtResult ParseWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
StmtTy *Body) {
return 0;
}
virtual StmtResult ParseDoStmt(SourceLocation DoLoc, StmtTy *Body,
SourceLocation WhileLoc, ExprTy *Cond) {
return 0;
}
virtual StmtResult ParseForStmt(SourceLocation ForLoc,
SourceLocation LParenLoc,
StmtTy *First, ExprTy *Second, ExprTy *Third,
SourceLocation RParenLoc, StmtTy *Body) {
return 0;
}
virtual StmtResult ParseGotoStmt(SourceLocation GotoLoc,
SourceLocation LabelLoc,
IdentifierInfo *LabelII) {
return 0;
}
virtual StmtResult ParseIndirectGotoStmt(SourceLocation GotoLoc,
SourceLocation StarLoc,
ExprTy *DestExp) {
return 0;
}
virtual StmtResult ParseContinueStmt(
|