File: | clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp |
Warning: | line 448, column 18 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- FunctionCognitiveComplexityCheck.cpp - clang-tidy ------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "FunctionCognitiveComplexityCheck.h" | |||
10 | #include "../ClangTidyDiagnosticConsumer.h" | |||
11 | #include "clang/AST/Decl.h" | |||
12 | #include "clang/AST/DeclBase.h" | |||
13 | #include "clang/AST/Expr.h" | |||
14 | #include "clang/AST/RecursiveASTVisitor.h" | |||
15 | #include "clang/AST/Stmt.h" | |||
16 | #include "clang/ASTMatchers/ASTMatchFinder.h" | |||
17 | #include "clang/ASTMatchers/ASTMatchers.h" | |||
18 | #include "clang/ASTMatchers/ASTMatchersInternal.h" | |||
19 | #include "clang/Basic/Diagnostic.h" | |||
20 | #include "clang/Basic/DiagnosticIDs.h" | |||
21 | #include "clang/Basic/LLVM.h" | |||
22 | #include "clang/Basic/SourceLocation.h" | |||
23 | #include "llvm/ADT/Optional.h" | |||
24 | #include "llvm/ADT/SmallVector.h" | |||
25 | #include "llvm/Support/Casting.h" | |||
26 | #include "llvm/Support/ErrorHandling.h" | |||
27 | #include <array> | |||
28 | #include <cassert> | |||
29 | #include <stack> | |||
30 | #include <tuple> | |||
31 | #include <type_traits> | |||
32 | #include <utility> | |||
33 | ||||
34 | using namespace clang::ast_matchers; | |||
35 | ||||
36 | namespace clang { | |||
37 | namespace tidy { | |||
38 | namespace readability { | |||
39 | namespace { | |||
40 | ||||
41 | struct CognitiveComplexity final { | |||
42 | // Any increment is based on some combination of reasons. | |||
43 | // For details you can look at the Specification at | |||
44 | // https://www.sonarsource.com/docs/CognitiveComplexity.pdf | |||
45 | // or user-facing docs at | |||
46 | // http://clang.llvm.org/extra/clang-tidy/checks/readability-function-cognitive-complexity.html | |||
47 | // Here are all the possible reasons: | |||
48 | enum Criteria : uint8_t { | |||
49 | None = 0U, | |||
50 | ||||
51 | // B1, increases cognitive complexity (by 1) | |||
52 | // What causes it: | |||
53 | // * if, else if, else, ConditionalOperator (not BinaryConditionalOperator) | |||
54 | // * SwitchStmt | |||
55 | // * ForStmt, CXXForRangeStmt | |||
56 | // * WhileStmt, DoStmt | |||
57 | // * CXXCatchStmt | |||
58 | // * GotoStmt, IndirectGotoStmt (but not BreakStmt, ContinueStmt) | |||
59 | // * sequences of binary logical operators (BinOpLAnd, BinOpLOr) | |||
60 | // * each method in a recursion cycle (not implemented) | |||
61 | Increment = 1U << 0, | |||
62 | ||||
63 | // B2, increases current nesting level (by 1) | |||
64 | // What causes it: | |||
65 | // * if, else if, else, ConditionalOperator (not BinaryConditionalOperator) | |||
66 | // * SwitchStmt | |||
67 | // * ForStmt, CXXForRangeStmt | |||
68 | // * WhileStmt, DoStmt | |||
69 | // * CXXCatchStmt | |||
70 | // * nested CXXConstructor, CXXDestructor, CXXMethod (incl. C++11 Lambda) | |||
71 | // * GNU Statement Expression | |||
72 | // * Apple Block declaration | |||
73 | IncrementNesting = 1U << 1, | |||
74 | ||||
75 | // B3, increases cognitive complexity by the current nesting level | |||
76 | // Applied before IncrementNesting | |||
77 | // What causes it: | |||
78 | // * IfStmt, ConditionalOperator (not BinaryConditionalOperator) | |||
79 | // * SwitchStmt | |||
80 | // * ForStmt, CXXForRangeStmt | |||
81 | // * WhileStmt, DoStmt | |||
82 | // * CXXCatchStmt | |||
83 | PenalizeNesting = 1U << 2, | |||
84 | ||||
85 | All = Increment | PenalizeNesting | IncrementNesting, | |||
86 | }; | |||
87 | ||||
88 | // The helper struct used to record one increment occurrence, with all the | |||
89 | // details necessary. | |||
90 | struct Detail { | |||
91 | const SourceLocation Loc; // What caused the increment? | |||
92 | const unsigned short Nesting; // How deeply nested is Loc located? | |||
93 | const Criteria C; // The criteria of the increment | |||
94 | ||||
95 | Detail(SourceLocation SLoc, unsigned short CurrentNesting, Criteria Crit) | |||
96 | : Loc(SLoc), Nesting(CurrentNesting), C(Crit) {} | |||
97 | ||||
98 | // To minimize the sizeof(Detail), we only store the minimal info there. | |||
99 | // This function is used to convert from the stored info into the usable | |||
100 | // information - what message to output, how much of an increment did this | |||
101 | // occurrence actually result in. | |||
102 | std::pair<unsigned, unsigned short> process() const { | |||
103 | assert(C != Criteria::None && "invalid criteria")(static_cast <bool> (C != Criteria::None && "invalid criteria" ) ? void (0) : __assert_fail ("C != Criteria::None && \"invalid criteria\"" , "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 103, __extension__ __PRETTY_FUNCTION__)); | |||
104 | ||||
105 | unsigned MsgId; // The id of the message to output. | |||
106 | unsigned short Increment; // How much of an increment? | |||
107 | ||||
108 | if (C == Criteria::All) { | |||
109 | Increment = 1 + Nesting; | |||
110 | MsgId = 0; | |||
111 | } else if (C == (Criteria::Increment | Criteria::IncrementNesting)) { | |||
112 | Increment = 1; | |||
113 | MsgId = 1; | |||
114 | } else if (C == Criteria::Increment) { | |||
115 | Increment = 1; | |||
116 | MsgId = 2; | |||
117 | } else if (C == Criteria::IncrementNesting) { | |||
118 | Increment = 0; // Unused in this message. | |||
119 | MsgId = 3; | |||
120 | } else | |||
121 | llvm_unreachable("should not get to here.")::llvm::llvm_unreachable_internal("should not get to here.", "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 121); | |||
122 | ||||
123 | return std::make_pair(MsgId, Increment); | |||
124 | } | |||
125 | }; | |||
126 | ||||
127 | // Limit of 25 is the "upstream"'s default. | |||
128 | static constexpr unsigned DefaultLimit = 25U; | |||
129 | ||||
130 | // Based on the publicly-avaliable numbers for some big open-source projects | |||
131 | // https://sonarcloud.io/projects?languages=c%2Ccpp&size=5 we can estimate: | |||
132 | // value ~20 would result in no allocs for 98% of functions, ~12 for 96%, ~10 | |||
133 | // for 91%, ~8 for 88%, ~6 for 84%, ~4 for 77%, ~2 for 64%, and ~1 for 37%. | |||
134 | static_assert(sizeof(Detail) <= 8, | |||
135 | "Since we use SmallVector to minimize the amount of " | |||
136 | "allocations, we also need to consider the price we pay for " | |||
137 | "that in terms of stack usage. " | |||
138 | "Thus, it is good to minimize the size of the Detail struct."); | |||
139 | SmallVector<Detail, DefaultLimit> Details; // 25 elements is 200 bytes. | |||
140 | // Yes, 25 is a magic number. This is the seemingly-sane default for the | |||
141 | // upper limit for function cognitive complexity. Thus it would make sense | |||
142 | // to avoid allocations for any function that does not violate the limit. | |||
143 | ||||
144 | // The grand total Cognitive Complexity of the function. | |||
145 | unsigned Total = 0; | |||
146 | ||||
147 | // The function used to store new increment, calculate the total complexity. | |||
148 | void account(SourceLocation Loc, unsigned short Nesting, Criteria C); | |||
149 | }; | |||
150 | ||||
151 | // All the possible messages that can be output. The choice of the message | |||
152 | // to use is based of the combination of the CognitiveComplexity::Criteria. | |||
153 | // It would be nice to have it in CognitiveComplexity struct, but then it is | |||
154 | // not static. | |||
155 | static const std::array<const StringRef, 4> Msgs = {{ | |||
156 | // B1 + B2 + B3 | |||
157 | "+%0, including nesting penalty of %1, nesting level increased to %2", | |||
158 | ||||
159 | // B1 + B2 | |||
160 | "+%0, nesting level increased to %2", | |||
161 | ||||
162 | // B1 | |||
163 | "+%0", | |||
164 | ||||
165 | // B2 | |||
166 | "nesting level increased to %2", | |||
167 | }}; | |||
168 | ||||
169 | // Criteria is a bitset, thus a few helpers are needed. | |||
170 | CognitiveComplexity::Criteria operator|(CognitiveComplexity::Criteria LHS, | |||
171 | CognitiveComplexity::Criteria RHS) { | |||
172 | return static_cast<CognitiveComplexity::Criteria>( | |||
173 | static_cast<std::underlying_type<CognitiveComplexity::Criteria>::type>( | |||
174 | LHS) | | |||
175 | static_cast<std::underlying_type<CognitiveComplexity::Criteria>::type>( | |||
176 | RHS)); | |||
177 | } | |||
178 | CognitiveComplexity::Criteria operator&(CognitiveComplexity::Criteria LHS, | |||
179 | CognitiveComplexity::Criteria RHS) { | |||
180 | return static_cast<CognitiveComplexity::Criteria>( | |||
181 | static_cast<std::underlying_type<CognitiveComplexity::Criteria>::type>( | |||
182 | LHS) & | |||
183 | static_cast<std::underlying_type<CognitiveComplexity::Criteria>::type>( | |||
184 | RHS)); | |||
185 | } | |||
186 | CognitiveComplexity::Criteria &operator|=(CognitiveComplexity::Criteria &LHS, | |||
187 | CognitiveComplexity::Criteria RHS) { | |||
188 | LHS = operator|(LHS, RHS); | |||
189 | return LHS; | |||
190 | } | |||
191 | CognitiveComplexity::Criteria &operator&=(CognitiveComplexity::Criteria &LHS, | |||
192 | CognitiveComplexity::Criteria RHS) { | |||
193 | LHS = operator&(LHS, RHS); | |||
194 | return LHS; | |||
195 | } | |||
196 | ||||
197 | void CognitiveComplexity::account(SourceLocation Loc, unsigned short Nesting, | |||
198 | Criteria C) { | |||
199 | C &= Criteria::All; | |||
200 | assert(C != Criteria::None && "invalid criteria")(static_cast <bool> (C != Criteria::None && "invalid criteria" ) ? void (0) : __assert_fail ("C != Criteria::None && \"invalid criteria\"" , "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 200, __extension__ __PRETTY_FUNCTION__)); | |||
201 | ||||
202 | Details.emplace_back(Loc, Nesting, C); | |||
203 | const Detail &D = Details.back(); | |||
204 | ||||
205 | unsigned MsgId; | |||
206 | unsigned short Increase; | |||
207 | std::tie(MsgId, Increase) = D.process(); | |||
208 | ||||
209 | Total += Increase; | |||
210 | } | |||
211 | ||||
212 | class FunctionASTVisitor final | |||
213 | : public RecursiveASTVisitor<FunctionASTVisitor> { | |||
214 | using Base = RecursiveASTVisitor<FunctionASTVisitor>; | |||
215 | ||||
216 | // If set to true, macros are ignored during analysis. | |||
217 | const bool IgnoreMacros; | |||
218 | ||||
219 | // The current nesting level (increased by Criteria::IncrementNesting). | |||
220 | unsigned short CurrentNestingLevel = 0; | |||
221 | ||||
222 | // Used to efficiently know the last type of the binary sequence operator | |||
223 | // that was encountered. It would make sense for the function call to start | |||
224 | // the new sequence, thus it is a stack. | |||
225 | using OBO = Optional<BinaryOperator::Opcode>; | |||
226 | std::stack<OBO, SmallVector<OBO, 4>> BinaryOperatorsStack; | |||
227 | ||||
228 | public: | |||
229 | explicit FunctionASTVisitor(const bool IgnoreMacros) | |||
230 | : IgnoreMacros(IgnoreMacros) {} | |||
231 | ||||
232 | bool traverseStmtWithIncreasedNestingLevel(Stmt *Node) { | |||
233 | ++CurrentNestingLevel; | |||
234 | bool ShouldContinue = Base::TraverseStmt(Node); | |||
235 | --CurrentNestingLevel; | |||
236 | return ShouldContinue; | |||
237 | } | |||
238 | ||||
239 | bool traverseDeclWithIncreasedNestingLevel(Decl *Node) { | |||
240 | ++CurrentNestingLevel; | |||
241 | bool ShouldContinue = Base::TraverseDecl(Node); | |||
242 | --CurrentNestingLevel; | |||
243 | return ShouldContinue; | |||
244 | } | |||
245 | ||||
246 | bool TraverseIfStmt(IfStmt *Node, bool InElseIf = false) { | |||
247 | if (!Node) | |||
248 | return Base::TraverseIfStmt(Node); | |||
249 | ||||
250 | { | |||
251 | CognitiveComplexity::Criteria Reasons; | |||
252 | ||||
253 | Reasons = CognitiveComplexity::Criteria::None; | |||
254 | ||||
255 | // "If" increases cognitive complexity. | |||
256 | Reasons |= CognitiveComplexity::Criteria::Increment; | |||
257 | // "If" increases nesting level. | |||
258 | Reasons |= CognitiveComplexity::Criteria::IncrementNesting; | |||
259 | ||||
260 | if (!InElseIf) { | |||
261 | // "If" receives a nesting increment commensurate with it's nested | |||
262 | // depth, if it is not part of "else if". | |||
263 | Reasons |= CognitiveComplexity::Criteria::PenalizeNesting; | |||
264 | } | |||
265 | ||||
266 | CC.account(Node->getIfLoc(), CurrentNestingLevel, Reasons); | |||
267 | } | |||
268 | ||||
269 | // If this IfStmt is *NOT* "else if", then only the body (i.e. "Then" and | |||
270 | // "Else") is traversed with increased Nesting level. | |||
271 | // However if this IfStmt *IS* "else if", then Nesting level is increased | |||
272 | // for the whole IfStmt (i.e. for "Init", "Cond", "Then" and "Else"). | |||
273 | ||||
274 | if (!InElseIf) { | |||
275 | if (!TraverseStmt(Node->getInit())) | |||
276 | return false; | |||
277 | ||||
278 | if (!TraverseStmt(Node->getCond())) | |||
279 | return false; | |||
280 | } else { | |||
281 | if (!traverseStmtWithIncreasedNestingLevel(Node->getInit())) | |||
282 | return false; | |||
283 | ||||
284 | if (!traverseStmtWithIncreasedNestingLevel(Node->getCond())) | |||
285 | return false; | |||
286 | } | |||
287 | ||||
288 | // "Then" always increases nesting level. | |||
289 | if (!traverseStmtWithIncreasedNestingLevel(Node->getThen())) | |||
290 | return false; | |||
291 | ||||
292 | if (!Node->getElse()) | |||
293 | return true; | |||
294 | ||||
295 | if (auto *E = dyn_cast<IfStmt>(Node->getElse())) | |||
296 | return TraverseIfStmt(E, true); | |||
297 | ||||
298 | { | |||
299 | CognitiveComplexity::Criteria Reasons; | |||
300 | ||||
301 | Reasons = CognitiveComplexity::Criteria::None; | |||
302 | ||||
303 | // "Else" increases cognitive complexity. | |||
304 | Reasons |= CognitiveComplexity::Criteria::Increment; | |||
305 | // "Else" increases nesting level. | |||
306 | Reasons |= CognitiveComplexity::Criteria::IncrementNesting; | |||
307 | // "Else" DOES NOT receive a nesting increment commensurate with it's | |||
308 | // nested depth. | |||
309 | ||||
310 | CC.account(Node->getElseLoc(), CurrentNestingLevel, Reasons); | |||
311 | } | |||
312 | ||||
313 | // "Else" always increases nesting level. | |||
314 | return traverseStmtWithIncreasedNestingLevel(Node->getElse()); | |||
315 | } | |||
316 | ||||
317 | // The currently-being-processed stack entry, which is always the top. | |||
318 | #define CurrentBinaryOperator BinaryOperatorsStack.top() | |||
319 | ||||
320 | // In a sequence of binary logical operators, if the new operator is different | |||
321 | // from the previous one, then the cognitive complexity is increased. | |||
322 | bool TraverseBinaryOperator(BinaryOperator *Op) { | |||
323 | if (!Op || !Op->isLogicalOp()) | |||
324 | return Base::TraverseBinaryOperator(Op); | |||
325 | ||||
326 | // Make sure that there is always at least one frame in the stack. | |||
327 | if (BinaryOperatorsStack.empty()) | |||
328 | BinaryOperatorsStack.emplace(); | |||
329 | ||||
330 | // If this is the first binary operator that we are processing, or the | |||
331 | // previous binary operator was different, there is an increment. | |||
332 | if (!CurrentBinaryOperator || Op->getOpcode() != CurrentBinaryOperator) | |||
333 | CC.account(Op->getOperatorLoc(), CurrentNestingLevel, | |||
334 | CognitiveComplexity::Criteria::Increment); | |||
335 | ||||
336 | // We might encounter a function call, which starts a new sequence, thus | |||
337 | // we need to save the current previous binary operator. | |||
338 | const Optional<BinaryOperator::Opcode> BinOpCopy(CurrentBinaryOperator); | |||
339 | ||||
340 | // Record the operator that we are currently processing and traverse it. | |||
341 | CurrentBinaryOperator = Op->getOpcode(); | |||
342 | bool ShouldContinue = Base::TraverseBinaryOperator(Op); | |||
343 | ||||
344 | // And restore the previous binary operator, which might be nonexistent. | |||
345 | CurrentBinaryOperator = BinOpCopy; | |||
346 | ||||
347 | return ShouldContinue; | |||
348 | } | |||
349 | ||||
350 | // It would make sense for the function call to start the new binary | |||
351 | // operator sequence, thus let's make sure that it creates a new stack frame. | |||
352 | bool TraverseCallExpr(CallExpr *Node) { | |||
353 | // If we are not currently processing any binary operator sequence, then | |||
354 | // no Node-handling is needed. | |||
355 | if (!Node || BinaryOperatorsStack.empty() || !CurrentBinaryOperator) | |||
| ||||
356 | return Base::TraverseCallExpr(Node); | |||
357 | ||||
358 | // Else, do add [uninitialized] frame to the stack, and traverse call. | |||
359 | BinaryOperatorsStack.emplace(); | |||
360 | bool ShouldContinue = Base::TraverseCallExpr(Node); | |||
361 | // And remove the top frame. | |||
362 | BinaryOperatorsStack.pop(); | |||
363 | ||||
364 | return ShouldContinue; | |||
365 | } | |||
366 | ||||
367 | #undef CurrentBinaryOperator | |||
368 | ||||
369 | bool TraverseStmt(Stmt *Node) { | |||
370 | if (!Node) | |||
371 | return Base::TraverseStmt(Node); | |||
372 | ||||
373 | if (IgnoreMacros && Node->getBeginLoc().isMacroID()) | |||
374 | return true; | |||
375 | ||||
376 | // Three following switch()'es have huge duplication, but it is better to | |||
377 | // keep them separate, to simplify comparing them with the Specification. | |||
378 | ||||
379 | CognitiveComplexity::Criteria Reasons = CognitiveComplexity::Criteria::None; | |||
380 | SourceLocation Location = Node->getBeginLoc(); | |||
381 | ||||
382 | // B1. Increments | |||
383 | // There is an increment for each of the following: | |||
384 | switch (Node->getStmtClass()) { | |||
385 | // if, else if, else are handled in TraverseIfStmt(), | |||
386 | // FIXME: "each method in a recursion cycle" Increment is not implemented. | |||
387 | case Stmt::ConditionalOperatorClass: | |||
388 | case Stmt::SwitchStmtClass: | |||
389 | case Stmt::ForStmtClass: | |||
390 | case Stmt::CXXForRangeStmtClass: | |||
391 | case Stmt::WhileStmtClass: | |||
392 | case Stmt::DoStmtClass: | |||
393 | case Stmt::CXXCatchStmtClass: | |||
394 | case Stmt::GotoStmtClass: | |||
395 | case Stmt::IndirectGotoStmtClass: | |||
396 | Reasons |= CognitiveComplexity::Criteria::Increment; | |||
397 | break; | |||
398 | default: | |||
399 | // break LABEL, continue LABEL increase cognitive complexity, | |||
400 | // but they are not supported in C++ or C. | |||
401 | // Regular break/continue do not increase cognitive complexity. | |||
402 | break; | |||
403 | } | |||
404 | ||||
405 | // B2. Nesting level | |||
406 | // The following structures increment the nesting level: | |||
407 | switch (Node->getStmtClass()) { | |||
408 | // if, else if, else are handled in TraverseIfStmt(), | |||
409 | // Nested methods and such are handled in TraverseDecl. | |||
410 | case Stmt::ConditionalOperatorClass: | |||
411 | case Stmt::SwitchStmtClass: | |||
412 | case Stmt::ForStmtClass: | |||
413 | case Stmt::CXXForRangeStmtClass: | |||
414 | case Stmt::WhileStmtClass: | |||
415 | case Stmt::DoStmtClass: | |||
416 | case Stmt::CXXCatchStmtClass: | |||
417 | case Stmt::LambdaExprClass: | |||
418 | case Stmt::StmtExprClass: | |||
419 | Reasons |= CognitiveComplexity::Criteria::IncrementNesting; | |||
420 | break; | |||
421 | default: | |||
422 | break; | |||
423 | } | |||
424 | ||||
425 | // B3. Nesting increments | |||
426 | // The following structures receive a nesting increment | |||
427 | // commensurate with their nested depth inside B2 structures: | |||
428 | switch (Node->getStmtClass()) { | |||
429 | // if, else if, else are handled in TraverseIfStmt(). | |||
430 | case Stmt::ConditionalOperatorClass: | |||
431 | case Stmt::SwitchStmtClass: | |||
432 | case Stmt::ForStmtClass: | |||
433 | case Stmt::CXXForRangeStmtClass: | |||
434 | case Stmt::WhileStmtClass: | |||
435 | case Stmt::DoStmtClass: | |||
436 | case Stmt::CXXCatchStmtClass: | |||
437 | Reasons |= CognitiveComplexity::Criteria::PenalizeNesting; | |||
438 | break; | |||
439 | default: | |||
440 | break; | |||
441 | } | |||
442 | ||||
443 | if (Node->getStmtClass() == Stmt::ConditionalOperatorClass) { | |||
444 | // A little beautification. | |||
445 | // For conditional operator "cond ? true : false" point at the "?" | |||
446 | // symbol. | |||
447 | ConditionalOperator *COp = dyn_cast<ConditionalOperator>(Node); | |||
448 | Location = COp->getQuestionLoc(); | |||
| ||||
449 | } | |||
450 | ||||
451 | // If we have found any reasons, let's account it. | |||
452 | if (Reasons & CognitiveComplexity::Criteria::All) | |||
453 | CC.account(Location, CurrentNestingLevel, Reasons); | |||
454 | ||||
455 | // Did we decide that the nesting level should be increased? | |||
456 | if (!(Reasons & CognitiveComplexity::Criteria::IncrementNesting)) | |||
457 | return Base::TraverseStmt(Node); | |||
458 | ||||
459 | return traverseStmtWithIncreasedNestingLevel(Node); | |||
460 | } | |||
461 | ||||
462 | // The parameter MainAnalyzedFunction is needed to differentiate between the | |||
463 | // cases where TraverseDecl() is the entry point from | |||
464 | // FunctionCognitiveComplexityCheck::check() and the cases where it was called | |||
465 | // from the FunctionASTVisitor itself. Explanation: if we get a function | |||
466 | // definition (e.g. constructor, destructor, method), the Cognitive Complexity | |||
467 | // specification states that the Nesting level shall be increased. But if this | |||
468 | // function is the entry point, then the Nesting level should not be | |||
469 | // increased. Thus that parameter is there and is used to fall-through | |||
470 | // directly to traversing if this is the main function that is being analyzed. | |||
471 | bool TraverseDecl(Decl *Node, bool MainAnalyzedFunction = false) { | |||
472 | if (!Node || MainAnalyzedFunction) | |||
473 | return Base::TraverseDecl(Node); | |||
474 | ||||
475 | // B2. Nesting level | |||
476 | // The following structures increment the nesting level: | |||
477 | switch (Node->getKind()) { | |||
478 | case Decl::Function: | |||
479 | case Decl::CXXMethod: | |||
480 | case Decl::CXXConstructor: | |||
481 | case Decl::CXXDestructor: | |||
482 | case Decl::Block: | |||
483 | break; | |||
484 | default: | |||
485 | // If this is something else, we use early return! | |||
486 | return Base::TraverseDecl(Node); | |||
487 | break; | |||
488 | } | |||
489 | ||||
490 | CC.account(Node->getBeginLoc(), CurrentNestingLevel, | |||
491 | CognitiveComplexity::Criteria::IncrementNesting); | |||
492 | ||||
493 | return traverseDeclWithIncreasedNestingLevel(Node); | |||
494 | } | |||
495 | ||||
496 | CognitiveComplexity CC; | |||
497 | }; | |||
498 | ||||
499 | } // namespace | |||
500 | ||||
501 | FunctionCognitiveComplexityCheck::FunctionCognitiveComplexityCheck( | |||
502 | StringRef Name, ClangTidyContext *Context) | |||
503 | : ClangTidyCheck(Name, Context), | |||
504 | Threshold(Options.get("Threshold", CognitiveComplexity::DefaultLimit)), | |||
505 | DescribeBasicIncrements(Options.get("DescribeBasicIncrements", true)), | |||
506 | IgnoreMacros(Options.get("IgnoreMacros", false)) {} | |||
507 | ||||
508 | void FunctionCognitiveComplexityCheck::storeOptions( | |||
509 | ClangTidyOptions::OptionMap &Opts) { | |||
510 | Options.store(Opts, "Threshold", Threshold); | |||
511 | Options.store(Opts, "DescribeBasicIncrements", DescribeBasicIncrements); | |||
512 | Options.store(Opts, "IgnoreMacros", IgnoreMacros); | |||
513 | } | |||
514 | ||||
515 | void FunctionCognitiveComplexityCheck::registerMatchers(MatchFinder *Finder) { | |||
516 | Finder->addMatcher( | |||
517 | functionDecl(isDefinition(), | |||
518 | unless(anyOf(isDefaulted(), isDeleted(), isWeak()))) | |||
519 | .bind("func"), | |||
520 | this); | |||
521 | Finder->addMatcher(lambdaExpr().bind("lambda"), this); | |||
522 | } | |||
523 | ||||
524 | void FunctionCognitiveComplexityCheck::check( | |||
525 | const MatchFinder::MatchResult &Result) { | |||
526 | ||||
527 | FunctionASTVisitor Visitor(IgnoreMacros); | |||
528 | SourceLocation Loc; | |||
529 | ||||
530 | const auto *TheDecl = Result.Nodes.getNodeAs<FunctionDecl>("func"); | |||
531 | const auto *TheLambdaExpr = Result.Nodes.getNodeAs<LambdaExpr>("lambda"); | |||
532 | if (TheDecl) { | |||
533 | assert(TheDecl->hasBody() &&(static_cast <bool> (TheDecl->hasBody() && "The matchers should only match the functions that " "have user-provided body.") ? void (0) : __assert_fail ("TheDecl->hasBody() && \"The matchers should only match the functions that \" \"have user-provided body.\"" , "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 535, __extension__ __PRETTY_FUNCTION__)) | |||
534 | "The matchers should only match the functions that "(static_cast <bool> (TheDecl->hasBody() && "The matchers should only match the functions that " "have user-provided body.") ? void (0) : __assert_fail ("TheDecl->hasBody() && \"The matchers should only match the functions that \" \"have user-provided body.\"" , "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 535, __extension__ __PRETTY_FUNCTION__)) | |||
535 | "have user-provided body.")(static_cast <bool> (TheDecl->hasBody() && "The matchers should only match the functions that " "have user-provided body.") ? void (0) : __assert_fail ("TheDecl->hasBody() && \"The matchers should only match the functions that \" \"have user-provided body.\"" , "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 535, __extension__ __PRETTY_FUNCTION__)); | |||
536 | Loc = TheDecl->getLocation(); | |||
537 | Visitor.TraverseDecl(const_cast<FunctionDecl *>(TheDecl), true); | |||
538 | } else { | |||
539 | Loc = TheLambdaExpr->getBeginLoc(); | |||
540 | Visitor.TraverseLambdaExpr(const_cast<LambdaExpr *>(TheLambdaExpr)); | |||
541 | } | |||
542 | ||||
543 | if (Visitor.CC.Total <= Threshold) | |||
544 | return; | |||
545 | ||||
546 | if (TheDecl) | |||
547 | diag(Loc, "function %0 has cognitive complexity of %1 (threshold %2)") | |||
548 | << TheDecl << Visitor.CC.Total << Threshold; | |||
549 | else | |||
550 | diag(Loc, "lambda has cognitive complexity of %0 (threshold %1)") | |||
551 | << Visitor.CC.Total << Threshold; | |||
552 | ||||
553 | if (!DescribeBasicIncrements) | |||
554 | return; | |||
555 | ||||
556 | // Output all the basic increments of complexity. | |||
557 | for (const auto &Detail : Visitor.CC.Details) { | |||
558 | unsigned MsgId; // The id of the message to output. | |||
559 | unsigned short Increase; // How much of an increment? | |||
560 | std::tie(MsgId, Increase) = Detail.process(); | |||
561 | assert(MsgId < Msgs.size() && "MsgId should always be valid")(static_cast <bool> (MsgId < Msgs.size() && "MsgId should always be valid" ) ? void (0) : __assert_fail ("MsgId < Msgs.size() && \"MsgId should always be valid\"" , "clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp" , 561, __extension__ __PRETTY_FUNCTION__)); | |||
562 | // Increase, on the other hand, can be 0. | |||
563 | ||||
564 | diag(Detail.Loc, Msgs[MsgId], DiagnosticIDs::Note) | |||
565 | << (unsigned)Increase << (unsigned)Detail.Nesting << 1 + Detail.Nesting; | |||
566 | } | |||
567 | } | |||
568 | ||||
569 | } // namespace readability | |||
570 | } // namespace tidy | |||
571 | } // namespace clang |
1 | //===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the RecursiveASTVisitor interface, which recursively |
10 | // traverses the entire AST. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H |
14 | #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H |
15 | |
16 | #include "clang/AST/Attr.h" |
17 | #include "clang/AST/Decl.h" |
18 | #include "clang/AST/DeclarationName.h" |
19 | #include "clang/AST/DeclBase.h" |
20 | #include "clang/AST/DeclCXX.h" |
21 | #include "clang/AST/DeclFriend.h" |
22 | #include "clang/AST/DeclObjC.h" |
23 | #include "clang/AST/DeclOpenMP.h" |
24 | #include "clang/AST/DeclTemplate.h" |
25 | #include "clang/AST/Expr.h" |
26 | #include "clang/AST/ExprConcepts.h" |
27 | #include "clang/AST/ExprCXX.h" |
28 | #include "clang/AST/ExprObjC.h" |
29 | #include "clang/AST/ExprOpenMP.h" |
30 | #include "clang/AST/LambdaCapture.h" |
31 | #include "clang/AST/NestedNameSpecifier.h" |
32 | #include "clang/AST/OpenMPClause.h" |
33 | #include "clang/AST/Stmt.h" |
34 | #include "clang/AST/StmtCXX.h" |
35 | #include "clang/AST/StmtObjC.h" |
36 | #include "clang/AST/StmtOpenMP.h" |
37 | #include "clang/AST/TemplateBase.h" |
38 | #include "clang/AST/TemplateName.h" |
39 | #include "clang/AST/Type.h" |
40 | #include "clang/AST/TypeLoc.h" |
41 | #include "clang/Basic/LLVM.h" |
42 | #include "clang/Basic/OpenMPKinds.h" |
43 | #include "clang/Basic/Specifiers.h" |
44 | #include "llvm/ADT/PointerIntPair.h" |
45 | #include "llvm/ADT/SmallVector.h" |
46 | #include "llvm/Support/Casting.h" |
47 | #include <algorithm> |
48 | #include <cstddef> |
49 | #include <type_traits> |
50 | |
51 | namespace clang { |
52 | |
53 | // A helper macro to implement short-circuiting when recursing. It |
54 | // invokes CALL_EXPR, which must be a method call, on the derived |
55 | // object (s.t. a user of RecursiveASTVisitor can override the method |
56 | // in CALL_EXPR). |
57 | #define TRY_TO(CALL_EXPR) \ |
58 | do { \ |
59 | if (!getDerived().CALL_EXPR) \ |
60 | return false; \ |
61 | } while (false) |
62 | |
63 | namespace detail { |
64 | |
65 | template <typename T, typename U> |
66 | struct has_same_member_pointer_type : std::false_type {}; |
67 | template <typename T, typename U, typename R, typename... P> |
68 | struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)> |
69 | : std::true_type {}; |
70 | |
71 | template <bool has_same_type> struct is_same_method_impl { |
72 | template <typename FirstMethodPtrTy, typename SecondMethodPtrTy> |
73 | static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, |
74 | SecondMethodPtrTy SecondMethodPtr) { |
75 | return false; |
76 | } |
77 | }; |
78 | |
79 | template <> struct is_same_method_impl<true> { |
80 | template <typename FirstMethodPtrTy, typename SecondMethodPtrTy> |
81 | static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, |
82 | SecondMethodPtrTy SecondMethodPtr) { |
83 | return FirstMethodPtr == SecondMethodPtr; |
84 | } |
85 | }; |
86 | |
87 | /// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr |
88 | /// are pointers to the same non-static member function. |
89 | template <typename FirstMethodPtrTy, typename SecondMethodPtrTy> |
90 | bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, |
91 | SecondMethodPtrTy SecondMethodPtr) { |
92 | return is_same_method_impl<has_same_member_pointer_type< |
93 | FirstMethodPtrTy, |
94 | SecondMethodPtrTy>::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr); |
95 | } |
96 | |
97 | } // end namespace detail |
98 | |
99 | /// A class that does preorder or postorder |
100 | /// depth-first traversal on the entire Clang AST and visits each node. |
101 | /// |
102 | /// This class performs three distinct tasks: |
103 | /// 1. traverse the AST (i.e. go to each node); |
104 | /// 2. at a given node, walk up the class hierarchy, starting from |
105 | /// the node's dynamic type, until the top-most class (e.g. Stmt, |
106 | /// Decl, or Type) is reached. |
107 | /// 3. given a (node, class) combination, where 'class' is some base |
108 | /// class of the dynamic type of 'node', call a user-overridable |
109 | /// function to actually visit the node. |
110 | /// |
111 | /// These tasks are done by three groups of methods, respectively: |
112 | /// 1. TraverseDecl(Decl *x) does task #1. It is the entry point |
113 | /// for traversing an AST rooted at x. This method simply |
114 | /// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo |
115 | /// is the dynamic type of *x, which calls WalkUpFromFoo(x) and |
116 | /// then recursively visits the child nodes of x. |
117 | /// TraverseStmt(Stmt *x) and TraverseType(QualType x) work |
118 | /// similarly. |
119 | /// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit |
120 | /// any child node of x. Instead, it first calls WalkUpFromBar(x) |
121 | /// where Bar is the direct parent class of Foo (unless Foo has |
122 | /// no parent), and then calls VisitFoo(x) (see the next list item). |
123 | /// 3. VisitFoo(Foo *x) does task #3. |
124 | /// |
125 | /// These three method groups are tiered (Traverse* > WalkUpFrom* > |
126 | /// Visit*). A method (e.g. Traverse*) may call methods from the same |
127 | /// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*). |
128 | /// It may not call methods from a higher tier. |
129 | /// |
130 | /// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar |
131 | /// is Foo's super class) before calling VisitFoo(), the result is |
132 | /// that the Visit*() methods for a given node are called in the |
133 | /// top-down order (e.g. for a node of type NamespaceDecl, the order will |
134 | /// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()). |
135 | /// |
136 | /// This scheme guarantees that all Visit*() calls for the same AST |
137 | /// node are grouped together. In other words, Visit*() methods for |
138 | /// different nodes are never interleaved. |
139 | /// |
140 | /// Clients of this visitor should subclass the visitor (providing |
141 | /// themselves as the template argument, using the curiously recurring |
142 | /// template pattern) and override any of the Traverse*, WalkUpFrom*, |
143 | /// and Visit* methods for declarations, types, statements, |
144 | /// expressions, or other AST nodes where the visitor should customize |
145 | /// behavior. Most users only need to override Visit*. Advanced |
146 | /// users may override Traverse* and WalkUpFrom* to implement custom |
147 | /// traversal strategies. Returning false from one of these overridden |
148 | /// functions will abort the entire traversal. |
149 | /// |
150 | /// By default, this visitor tries to visit every part of the explicit |
151 | /// source code exactly once. The default policy towards templates |
152 | /// is to descend into the 'pattern' class or function body, not any |
153 | /// explicit or implicit instantiations. Explicit specializations |
154 | /// are still visited, and the patterns of partial specializations |
155 | /// are visited separately. This behavior can be changed by |
156 | /// overriding shouldVisitTemplateInstantiations() in the derived class |
157 | /// to return true, in which case all known implicit and explicit |
158 | /// instantiations will be visited at the same time as the pattern |
159 | /// from which they were produced. |
160 | /// |
161 | /// By default, this visitor preorder traverses the AST. If postorder traversal |
162 | /// is needed, the \c shouldTraversePostOrder method needs to be overridden |
163 | /// to return \c true. |
164 | template <typename Derived> class RecursiveASTVisitor { |
165 | public: |
166 | /// A queue used for performing data recursion over statements. |
167 | /// Parameters involving this type are used to implement data |
168 | /// recursion over Stmts and Exprs within this class, and should |
169 | /// typically not be explicitly specified by derived classes. |
170 | /// The bool bit indicates whether the statement has been traversed or not. |
171 | typedef SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>> |
172 | DataRecursionQueue; |
173 | |
174 | /// Return a reference to the derived class. |
175 | Derived &getDerived() { return *static_cast<Derived *>(this); } |
176 | |
177 | /// Return whether this visitor should recurse into |
178 | /// template instantiations. |
179 | bool shouldVisitTemplateInstantiations() const { return false; } |
180 | |
181 | /// Return whether this visitor should recurse into the types of |
182 | /// TypeLocs. |
183 | bool shouldWalkTypesOfTypeLocs() const { return true; } |
184 | |
185 | /// Return whether this visitor should recurse into implicit |
186 | /// code, e.g., implicit constructors and destructors. |
187 | bool shouldVisitImplicitCode() const { return false; } |
188 | |
189 | /// Return whether this visitor should recurse into lambda body |
190 | bool shouldVisitLambdaBody() const { return true; } |
191 | |
192 | /// Return whether this visitor should traverse post-order. |
193 | bool shouldTraversePostOrder() const { return false; } |
194 | |
195 | /// Recursively visits an entire AST, starting from the TranslationUnitDecl. |
196 | /// \returns false if visitation was terminated early. |
197 | bool TraverseAST(ASTContext &AST) { |
198 | // Currently just an alias for TraverseDecl(TUDecl), but kept in case |
199 | // we change the implementation again. |
200 | return getDerived().TraverseDecl(AST.getTranslationUnitDecl()); |
201 | } |
202 | |
203 | /// Recursively visit a statement or expression, by |
204 | /// dispatching to Traverse*() based on the argument's dynamic type. |
205 | /// |
206 | /// \returns false if the visitation was terminated early, true |
207 | /// otherwise (including when the argument is nullptr). |
208 | bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr); |
209 | |
210 | /// Invoked before visiting a statement or expression via data recursion. |
211 | /// |
212 | /// \returns false to skip visiting the node, true otherwise. |
213 | bool dataTraverseStmtPre(Stmt *S) { return true; } |
214 | |
215 | /// Invoked after visiting a statement or expression via data recursion. |
216 | /// This is not invoked if the previously invoked \c dataTraverseStmtPre |
217 | /// returned false. |
218 | /// |
219 | /// \returns false if the visitation was terminated early, true otherwise. |
220 | bool dataTraverseStmtPost(Stmt *S) { return true; } |
221 | |
222 | /// Recursively visit a type, by dispatching to |
223 | /// Traverse*Type() based on the argument's getTypeClass() property. |
224 | /// |
225 | /// \returns false if the visitation was terminated early, true |
226 | /// otherwise (including when the argument is a Null type). |
227 | bool TraverseType(QualType T); |
228 | |
229 | /// Recursively visit a type with location, by dispatching to |
230 | /// Traverse*TypeLoc() based on the argument type's getTypeClass() property. |
231 | /// |
232 | /// \returns false if the visitation was terminated early, true |
233 | /// otherwise (including when the argument is a Null type location). |
234 | bool TraverseTypeLoc(TypeLoc TL); |
235 | |
236 | /// Recursively visit an attribute, by dispatching to |
237 | /// Traverse*Attr() based on the argument's dynamic type. |
238 | /// |
239 | /// \returns false if the visitation was terminated early, true |
240 | /// otherwise (including when the argument is a Null type location). |
241 | bool TraverseAttr(Attr *At); |
242 | |
243 | /// Recursively visit a declaration, by dispatching to |
244 | /// Traverse*Decl() based on the argument's dynamic type. |
245 | /// |
246 | /// \returns false if the visitation was terminated early, true |
247 | /// otherwise (including when the argument is NULL). |
248 | bool TraverseDecl(Decl *D); |
249 | |
250 | /// Recursively visit a C++ nested-name-specifier. |
251 | /// |
252 | /// \returns false if the visitation was terminated early, true otherwise. |
253 | bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); |
254 | |
255 | /// Recursively visit a C++ nested-name-specifier with location |
256 | /// information. |
257 | /// |
258 | /// \returns false if the visitation was terminated early, true otherwise. |
259 | bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); |
260 | |
261 | /// Recursively visit a name with its location information. |
262 | /// |
263 | /// \returns false if the visitation was terminated early, true otherwise. |
264 | bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo); |
265 | |
266 | /// Recursively visit a template name and dispatch to the |
267 | /// appropriate method. |
268 | /// |
269 | /// \returns false if the visitation was terminated early, true otherwise. |
270 | bool TraverseTemplateName(TemplateName Template); |
271 | |
272 | /// Recursively visit a template argument and dispatch to the |
273 | /// appropriate method for the argument type. |
274 | /// |
275 | /// \returns false if the visitation was terminated early, true otherwise. |
276 | // FIXME: migrate callers to TemplateArgumentLoc instead. |
277 | bool TraverseTemplateArgument(const TemplateArgument &Arg); |
278 | |
279 | /// Recursively visit a template argument location and dispatch to the |
280 | /// appropriate method for the argument type. |
281 | /// |
282 | /// \returns false if the visitation was terminated early, true otherwise. |
283 | bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc); |
284 | |
285 | /// Recursively visit a set of template arguments. |
286 | /// This can be overridden by a subclass, but it's not expected that |
287 | /// will be needed -- this visitor always dispatches to another. |
288 | /// |
289 | /// \returns false if the visitation was terminated early, true otherwise. |
290 | // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead. |
291 | bool TraverseTemplateArguments(const TemplateArgument *Args, |
292 | unsigned NumArgs); |
293 | |
294 | /// Recursively visit a base specifier. This can be overridden by a |
295 | /// subclass. |
296 | /// |
297 | /// \returns false if the visitation was terminated early, true otherwise. |
298 | bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base); |
299 | |
300 | /// Recursively visit a constructor initializer. This |
301 | /// automatically dispatches to another visitor for the initializer |
302 | /// expression, but not for the name of the initializer, so may |
303 | /// be overridden for clients that need access to the name. |
304 | /// |
305 | /// \returns false if the visitation was terminated early, true otherwise. |
306 | bool TraverseConstructorInitializer(CXXCtorInitializer *Init); |
307 | |
308 | /// Recursively visit a lambda capture. \c Init is the expression that |
309 | /// will be used to initialize the capture. |
310 | /// |
311 | /// \returns false if the visitation was terminated early, true otherwise. |
312 | bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, |
313 | Expr *Init); |
314 | |
315 | /// Recursively visit the syntactic or semantic form of an |
316 | /// initialization list. |
317 | /// |
318 | /// \returns false if the visitation was terminated early, true otherwise. |
319 | bool TraverseSynOrSemInitListExpr(InitListExpr *S, |
320 | DataRecursionQueue *Queue = nullptr); |
321 | |
322 | /// Recursively visit a reference to a concept with potential arguments. |
323 | /// |
324 | /// \returns false if the visitation was terminated early, true otherwise. |
325 | bool TraverseConceptReference(const ConceptReference &C); |
326 | |
327 | // ---- Methods on Attrs ---- |
328 | |
329 | // Visit an attribute. |
330 | bool VisitAttr(Attr *A) { return true; } |
331 | |
332 | // Declare Traverse* and empty Visit* for all Attr classes. |
333 | #define ATTR_VISITOR_DECLS_ONLY |
334 | #include "clang/AST/AttrVisitor.inc" |
335 | #undef ATTR_VISITOR_DECLS_ONLY |
336 | |
337 | // ---- Methods on Stmts ---- |
338 | |
339 | Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); } |
340 | |
341 | private: |
342 | // Traverse the given statement. If the most-derived traverse function takes a |
343 | // data recursion queue, pass it on; otherwise, discard it. Note that the |
344 | // first branch of this conditional must compile whether or not the derived |
345 | // class can take a queue, so if we're taking the second arm, make the first |
346 | // arm call our function rather than the derived class version. |
347 | #define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \ |
348 | (::clang::detail::has_same_member_pointer_type< \ |
349 | decltype(&RecursiveASTVisitor::Traverse##NAME), \ |
350 | decltype(&Derived::Traverse##NAME)>::value \ |
351 | ? static_cast<std::conditional_t< \ |
352 | ::clang::detail::has_same_member_pointer_type< \ |
353 | decltype(&RecursiveASTVisitor::Traverse##NAME), \ |
354 | decltype(&Derived::Traverse##NAME)>::value, \ |
355 | Derived &, RecursiveASTVisitor &>>(*this) \ |
356 | .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \ |
357 | : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))) |
358 | |
359 | // Try to traverse the given statement, or enqueue it if we're performing data |
360 | // recursion in the middle of traversing another statement. Can only be called |
361 | // from within a DEF_TRAVERSE_STMT body or similar context. |
362 | #define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S)do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) return false ; } while (false) \ |
363 | do { \ |
364 | if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \ |
365 | return false; \ |
366 | } while (false) |
367 | |
368 | public: |
369 | // Declare Traverse*() for all concrete Stmt classes. |
370 | #define ABSTRACT_STMT(STMT) |
371 | #define STMT(CLASS, PARENT) \ |
372 | bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr); |
373 | #include "clang/AST/StmtNodes.inc" |
374 | // The above header #undefs ABSTRACT_STMT and STMT upon exit. |
375 | |
376 | // Define WalkUpFrom*() and empty Visit*() for all Stmt classes. |
377 | bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); } |
378 | bool VisitStmt(Stmt *S) { return true; } |
379 | #define STMT(CLASS, PARENT) \ |
380 | bool WalkUpFrom##CLASS(CLASS *S) { \ |
381 | TRY_TO(WalkUpFrom##PARENT(S)); \ |
382 | TRY_TO(Visit##CLASS(S)); \ |
383 | return true; \ |
384 | } \ |
385 | bool Visit##CLASS(CLASS *S) { return true; } |
386 | #include "clang/AST/StmtNodes.inc" |
387 | |
388 | // ---- Methods on Types ---- |
389 | // FIXME: revamp to take TypeLoc's rather than Types. |
390 | |
391 | // Declare Traverse*() for all concrete Type classes. |
392 | #define ABSTRACT_TYPE(CLASS, BASE) |
393 | #define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T); |
394 | #include "clang/AST/TypeNodes.inc" |
395 | // The above header #undefs ABSTRACT_TYPE and TYPE upon exit. |
396 | |
397 | // Define WalkUpFrom*() and empty Visit*() for all Type classes. |
398 | bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); } |
399 | bool VisitType(Type *T) { return true; } |
400 | #define TYPE(CLASS, BASE) \ |
401 | bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \ |
402 | TRY_TO(WalkUpFrom##BASE(T)); \ |
403 | TRY_TO(Visit##CLASS##Type(T)); \ |
404 | return true; \ |
405 | } \ |
406 | bool Visit##CLASS##Type(CLASS##Type *T) { return true; } |
407 | #include "clang/AST/TypeNodes.inc" |
408 | |
409 | // ---- Methods on TypeLocs ---- |
410 | // FIXME: this currently just calls the matching Type methods |
411 | |
412 | // Declare Traverse*() for all concrete TypeLoc classes. |
413 | #define ABSTRACT_TYPELOC(CLASS, BASE) |
414 | #define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); |
415 | #include "clang/AST/TypeLocNodes.def" |
416 | // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit. |
417 | |
418 | // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes. |
419 | bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); } |
420 | bool VisitTypeLoc(TypeLoc TL) { return true; } |
421 | |
422 | // QualifiedTypeLoc and UnqualTypeLoc are not declared in |
423 | // TypeNodes.inc and thus need to be handled specially. |
424 | bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) { |
425 | return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); |
426 | } |
427 | bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; } |
428 | bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) { |
429 | return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); |
430 | } |
431 | bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; } |
432 | |
433 | // Note that BASE includes trailing 'Type' which CLASS doesn't. |
434 | #define TYPE(CLASS, BASE) \ |
435 | bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ |
436 | TRY_TO(WalkUpFrom##BASE##Loc(TL)); \ |
437 | TRY_TO(Visit##CLASS##TypeLoc(TL)); \ |
438 | return true; \ |
439 | } \ |
440 | bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; } |
441 | #include "clang/AST/TypeNodes.inc" |
442 | |
443 | // ---- Methods on Decls ---- |
444 | |
445 | // Declare Traverse*() for all concrete Decl classes. |
446 | #define ABSTRACT_DECL(DECL) |
447 | #define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D); |
448 | #include "clang/AST/DeclNodes.inc" |
449 | // The above header #undefs ABSTRACT_DECL and DECL upon exit. |
450 | |
451 | // Define WalkUpFrom*() and empty Visit*() for all Decl classes. |
452 | bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); } |
453 | bool VisitDecl(Decl *D) { return true; } |
454 | #define DECL(CLASS, BASE) \ |
455 | bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \ |
456 | TRY_TO(WalkUpFrom##BASE(D)); \ |
457 | TRY_TO(Visit##CLASS##Decl(D)); \ |
458 | return true; \ |
459 | } \ |
460 | bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } |
461 | #include "clang/AST/DeclNodes.inc" |
462 | |
463 | bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child); |
464 | |
465 | #define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ |
466 | bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D); |
467 | DEF_TRAVERSE_TMPL_INST(Class) |
468 | DEF_TRAVERSE_TMPL_INST(Var) |
469 | DEF_TRAVERSE_TMPL_INST(Function) |
470 | #undef DEF_TRAVERSE_TMPL_INST |
471 | |
472 | bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue); |
473 | |
474 | private: |
475 | // These are helper methods used by more than one Traverse* method. |
476 | bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); |
477 | |
478 | // Traverses template parameter lists of either a DeclaratorDecl or TagDecl. |
479 | template <typename T> |
480 | bool TraverseDeclTemplateParameterLists(T *D); |
481 | |
482 | bool TraverseTemplateTypeParamDeclConstraints(const TemplateTypeParmDecl *D); |
483 | |
484 | bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, |
485 | unsigned Count); |
486 | bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); |
487 | bool TraverseRecordHelper(RecordDecl *D); |
488 | bool TraverseCXXRecordHelper(CXXRecordDecl *D); |
489 | bool TraverseDeclaratorHelper(DeclaratorDecl *D); |
490 | bool TraverseDeclContextHelper(DeclContext *DC); |
491 | bool TraverseFunctionHelper(FunctionDecl *D); |
492 | bool TraverseVarHelper(VarDecl *D); |
493 | bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); |
494 | bool TraverseOMPLoopDirective(OMPLoopDirective *S); |
495 | bool TraverseOMPClause(OMPClause *C); |
496 | #define GEN_CLANG_CLAUSE_CLASS |
497 | #define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); |
498 | #include "llvm/Frontend/OpenMP/OMP.inc" |
499 | /// Process clauses with list of variables. |
500 | template <typename T> bool VisitOMPClauseList(T *Node); |
501 | /// Process clauses with pre-initis. |
502 | bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node); |
503 | bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node); |
504 | |
505 | bool PostVisitStmt(Stmt *S); |
506 | }; |
507 | |
508 | template <typename Derived> |
509 | bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, |
510 | DataRecursionQueue *Queue) { |
511 | // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. |
512 | switch (S->getStmtClass()) { |
513 | case Stmt::NoStmtClass: |
514 | break; |
515 | #define ABSTRACT_STMT(STMT) |
516 | #define STMT(CLASS, PARENT) \ |
517 | case Stmt::CLASS##Class: \ |
518 | return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue); |
519 | #include "clang/AST/StmtNodes.inc" |
520 | } |
521 | |
522 | return true; |
523 | } |
524 | |
525 | #undef DISPATCH_STMT |
526 | |
527 | template <typename Derived> |
528 | bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) { |
529 | // In pre-order traversal mode, each Traverse##STMT method is responsible for |
530 | // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and |
531 | // does not call the default implementation, the WalkUpFrom callback is not |
532 | // called. Post-order traversal mode should provide the same behavior |
533 | // regarding method overrides. |
534 | // |
535 | // In post-order traversal mode the Traverse##STMT method, when it receives a |
536 | // DataRecursionQueue, can't call WalkUpFrom after traversing children because |
537 | // it only enqueues the children and does not traverse them. TraverseStmt |
538 | // traverses the enqueued children, and we call WalkUpFrom here. |
539 | // |
540 | // However, to make pre-order and post-order modes identical with regards to |
541 | // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the |
542 | // user did not override the Traverse##STMT method. We implement the override |
543 | // check with isSameMethod calls below. |
544 | |
545 | switch (S->getStmtClass()) { |
546 | case Stmt::NoStmtClass: |
547 | break; |
548 | #define ABSTRACT_STMT(STMT) |
549 | #define STMT(CLASS, PARENT) \ |
550 | case Stmt::CLASS##Class: \ |
551 | if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \ |
552 | &Derived::Traverse##CLASS)) { \ |
553 | TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \ |
554 | } \ |
555 | break; |
556 | #define INITLISTEXPR(CLASS, PARENT) \ |
557 | case Stmt::CLASS##Class: \ |
558 | if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \ |
559 | &Derived::Traverse##CLASS)) { \ |
560 | auto ILE = static_cast<CLASS *>(S); \ |
561 | if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \ |
562 | TRY_TO(WalkUpFrom##CLASS(Syn)); \ |
563 | if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \ |
564 | TRY_TO(WalkUpFrom##CLASS(Sem)); \ |
565 | } \ |
566 | break; |
567 | #include "clang/AST/StmtNodes.inc" |
568 | } |
569 | |
570 | return true; |
571 | } |
572 | |
573 | #undef DISPATCH_STMT |
574 | |
575 | template <typename Derived> |
576 | bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, |
577 | DataRecursionQueue *Queue) { |
578 | if (!S) |
579 | return true; |
580 | |
581 | if (Queue) { |
582 | Queue->push_back({S, false}); |
583 | return true; |
584 | } |
585 | |
586 | SmallVector<llvm::PointerIntPair<Stmt *, 1, bool>, 8> LocalQueue; |
587 | LocalQueue.push_back({S, false}); |
588 | |
589 | while (!LocalQueue.empty()) { |
590 | auto &CurrSAndVisited = LocalQueue.back(); |
591 | Stmt *CurrS = CurrSAndVisited.getPointer(); |
592 | bool Visited = CurrSAndVisited.getInt(); |
593 | if (Visited) { |
594 | LocalQueue.pop_back(); |
595 | TRY_TO(dataTraverseStmtPost(CurrS)); |
596 | if (getDerived().shouldTraversePostOrder()) { |
597 | TRY_TO(PostVisitStmt(CurrS)); |
598 | } |
599 | continue; |
600 | } |
601 | |
602 | if (getDerived().dataTraverseStmtPre(CurrS)) { |
603 | CurrSAndVisited.setInt(true); |
604 | size_t N = LocalQueue.size(); |
605 | TRY_TO(dataTraverseNode(CurrS, &LocalQueue)); |
606 | // Process new children in the order they were added. |
607 | std::reverse(LocalQueue.begin() + N, LocalQueue.end()); |
608 | } else { |
609 | LocalQueue.pop_back(); |
610 | } |
611 | } |
612 | |
613 | return true; |
614 | } |
615 | |
616 | template <typename Derived> |
617 | bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { |
618 | if (T.isNull()) |
619 | return true; |
620 | |
621 | switch (T->getTypeClass()) { |
622 | #define ABSTRACT_TYPE(CLASS, BASE) |
623 | #define TYPE(CLASS, BASE) \ |
624 | case Type::CLASS: \ |
625 | return getDerived().Traverse##CLASS##Type( \ |
626 | static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr()))); |
627 | #include "clang/AST/TypeNodes.inc" |
628 | } |
629 | |
630 | return true; |
631 | } |
632 | |
633 | template <typename Derived> |
634 | bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) { |
635 | if (TL.isNull()) |
636 | return true; |
637 | |
638 | switch (TL.getTypeLocClass()) { |
639 | #define ABSTRACT_TYPELOC(CLASS, BASE) |
640 | #define TYPELOC(CLASS, BASE) \ |
641 | case TypeLoc::CLASS: \ |
642 | return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>()); |
643 | #include "clang/AST/TypeLocNodes.def" |
644 | } |
645 | |
646 | return true; |
647 | } |
648 | |
649 | // Define the Traverse*Attr(Attr* A) methods |
650 | #define VISITORCLASS RecursiveASTVisitor |
651 | #include "clang/AST/AttrVisitor.inc" |
652 | #undef VISITORCLASS |
653 | |
654 | template <typename Derived> |
655 | bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) { |
656 | if (!D) |
657 | return true; |
658 | |
659 | // As a syntax visitor, by default we want to ignore declarations for |
660 | // implicit declarations (ones not typed explicitly by the user). |
661 | if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) { |
662 | // For an implicit template type parameter, its type constraints are not |
663 | // implicit and are not represented anywhere else. We still need to visit |
664 | // them. |
665 | if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D)) |
666 | return TraverseTemplateTypeParamDeclConstraints(TTPD); |
667 | return true; |
668 | } |
669 | |
670 | switch (D->getKind()) { |
671 | #define ABSTRACT_DECL(DECL) |
672 | #define DECL(CLASS, BASE) \ |
673 | case Decl::CLASS: \ |
674 | if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \ |
675 | return false; \ |
676 | break; |
677 | #include "clang/AST/DeclNodes.inc" |
678 | } |
679 | return true; |
680 | } |
681 | |
682 | template <typename Derived> |
683 | bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier( |
684 | NestedNameSpecifier *NNS) { |
685 | if (!NNS) |
686 | return true; |
687 | |
688 | if (NNS->getPrefix()) |
689 | TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix())); |
690 | |
691 | switch (NNS->getKind()) { |
692 | case NestedNameSpecifier::Identifier: |
693 | case NestedNameSpecifier::Namespace: |
694 | case NestedNameSpecifier::NamespaceAlias: |
695 | case NestedNameSpecifier::Global: |
696 | case NestedNameSpecifier::Super: |
697 | return true; |
698 | |
699 | case NestedNameSpecifier::TypeSpec: |
700 | case NestedNameSpecifier::TypeSpecWithTemplate: |
701 | TRY_TO(TraverseType(QualType(NNS->getAsType(), 0))); |
702 | } |
703 | |
704 | return true; |
705 | } |
706 | |
707 | template <typename Derived> |
708 | bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc( |
709 | NestedNameSpecifierLoc NNS) { |
710 | if (!NNS) |
711 | return true; |
712 | |
713 | if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) |
714 | TRY_TO(TraverseNestedNameSpecifierLoc(Prefix)); |
715 | |
716 | switch (NNS.getNestedNameSpecifier()->getKind()) { |
717 | case NestedNameSpecifier::Identifier: |
718 | case NestedNameSpecifier::Namespace: |
719 | case NestedNameSpecifier::NamespaceAlias: |
720 | case NestedNameSpecifier::Global: |
721 | case NestedNameSpecifier::Super: |
722 | return true; |
723 | |
724 | case NestedNameSpecifier::TypeSpec: |
725 | case NestedNameSpecifier::TypeSpecWithTemplate: |
726 | TRY_TO(TraverseTypeLoc(NNS.getTypeLoc())); |
727 | break; |
728 | } |
729 | |
730 | return true; |
731 | } |
732 | |
733 | template <typename Derived> |
734 | bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo( |
735 | DeclarationNameInfo NameInfo) { |
736 | switch (NameInfo.getName().getNameKind()) { |
737 | case DeclarationName::CXXConstructorName: |
738 | case DeclarationName::CXXDestructorName: |
739 | case DeclarationName::CXXConversionFunctionName: |
740 | if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) |
741 | TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc())); |
742 | break; |
743 | |
744 | case DeclarationName::CXXDeductionGuideName: |
745 | TRY_TO(TraverseTemplateName( |
746 | TemplateName(NameInfo.getName().getCXXDeductionGuideTemplate()))); |
747 | break; |
748 | |
749 | case DeclarationName::Identifier: |
750 | case DeclarationName::ObjCZeroArgSelector: |
751 | case DeclarationName::ObjCOneArgSelector: |
752 | case DeclarationName::ObjCMultiArgSelector: |
753 | case DeclarationName::CXXOperatorName: |
754 | case DeclarationName::CXXLiteralOperatorName: |
755 | case DeclarationName::CXXUsingDirective: |
756 | break; |
757 | } |
758 | |
759 | return true; |
760 | } |
761 | |
762 | template <typename Derived> |
763 | bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) { |
764 | if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) |
765 | TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier())); |
766 | else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) |
767 | TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); |
768 | |
769 | return true; |
770 | } |
771 | |
772 | template <typename Derived> |
773 | bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( |
774 | const TemplateArgument &Arg) { |
775 | switch (Arg.getKind()) { |
776 | case TemplateArgument::Null: |
777 | case TemplateArgument::Declaration: |
778 | case TemplateArgument::Integral: |
779 | case TemplateArgument::NullPtr: |
780 | return true; |
781 | |
782 | case TemplateArgument::Type: |
783 | return getDerived().TraverseType(Arg.getAsType()); |
784 | |
785 | case TemplateArgument::Template: |
786 | case TemplateArgument::TemplateExpansion: |
787 | return getDerived().TraverseTemplateName( |
788 | Arg.getAsTemplateOrTemplatePattern()); |
789 | |
790 | case TemplateArgument::Expression: |
791 | return getDerived().TraverseStmt(Arg.getAsExpr()); |
792 | |
793 | case TemplateArgument::Pack: |
794 | return getDerived().TraverseTemplateArguments(Arg.pack_begin(), |
795 | Arg.pack_size()); |
796 | } |
797 | |
798 | return true; |
799 | } |
800 | |
801 | // FIXME: no template name location? |
802 | // FIXME: no source locations for a template argument pack? |
803 | template <typename Derived> |
804 | bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( |
805 | const TemplateArgumentLoc &ArgLoc) { |
806 | const TemplateArgument &Arg = ArgLoc.getArgument(); |
807 | |
808 | switch (Arg.getKind()) { |
809 | case TemplateArgument::Null: |
810 | case TemplateArgument::Declaration: |
811 | case TemplateArgument::Integral: |
812 | case TemplateArgument::NullPtr: |
813 | return true; |
814 | |
815 | case TemplateArgument::Type: { |
816 | // FIXME: how can TSI ever be NULL? |
817 | if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo()) |
818 | return getDerived().TraverseTypeLoc(TSI->getTypeLoc()); |
819 | else |
820 | return getDerived().TraverseType(Arg.getAsType()); |
821 | } |
822 | |
823 | case TemplateArgument::Template: |
824 | case TemplateArgument::TemplateExpansion: |
825 | if (ArgLoc.getTemplateQualifierLoc()) |
826 | TRY_TO(getDerived().TraverseNestedNameSpecifierLoc( |
827 | ArgLoc.getTemplateQualifierLoc())); |
828 | return getDerived().TraverseTemplateName( |
829 | Arg.getAsTemplateOrTemplatePattern()); |
830 | |
831 | case TemplateArgument::Expression: |
832 | return getDerived().TraverseStmt(ArgLoc.getSourceExpression()); |
833 | |
834 | case TemplateArgument::Pack: |
835 | return getDerived().TraverseTemplateArguments(Arg.pack_begin(), |
836 | Arg.pack_size()); |
837 | } |
838 | |
839 | return true; |
840 | } |
841 | |
842 | template <typename Derived> |
843 | bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments( |
844 | const TemplateArgument *Args, unsigned NumArgs) { |
845 | for (unsigned I = 0; I != NumArgs; ++I) { |
846 | TRY_TO(TraverseTemplateArgument(Args[I])); |
847 | } |
848 | |
849 | return true; |
850 | } |
851 | |
852 | template <typename Derived> |
853 | bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( |
854 | CXXCtorInitializer *Init) { |
855 | if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) |
856 | TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); |
857 | |
858 | if (Init->isWritten() || getDerived().shouldVisitImplicitCode()) |
859 | TRY_TO(TraverseStmt(Init->getInit())); |
860 | |
861 | return true; |
862 | } |
863 | |
864 | template <typename Derived> |
865 | bool |
866 | RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE, |
867 | const LambdaCapture *C, |
868 | Expr *Init) { |
869 | if (LE->isInitCapture(C)) |
870 | TRY_TO(TraverseDecl(C->getCapturedVar())); |
871 | else |
872 | TRY_TO(TraverseStmt(Init)); |
873 | return true; |
874 | } |
875 | |
876 | // ----------------- Type traversal ----------------- |
877 | |
878 | // This macro makes available a variable T, the passed-in type. |
879 | #define DEF_TRAVERSE_TYPE(TYPE, CODE) \ |
880 | template <typename Derived> \ |
881 | bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \ |
882 | if (!getDerived().shouldTraversePostOrder()) \ |
883 | TRY_TO(WalkUpFrom##TYPE(T)); \ |
884 | { CODE; } \ |
885 | if (getDerived().shouldTraversePostOrder()) \ |
886 | TRY_TO(WalkUpFrom##TYPE(T)); \ |
887 | return true; \ |
888 | } |
889 | |
890 | DEF_TRAVERSE_TYPE(BuiltinType, {}) |
891 | |
892 | DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); }) |
893 | |
894 | DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); }) |
895 | |
896 | DEF_TRAVERSE_TYPE(BlockPointerType, |
897 | { TRY_TO(TraverseType(T->getPointeeType())); }) |
898 | |
899 | DEF_TRAVERSE_TYPE(LValueReferenceType, |
900 | { TRY_TO(TraverseType(T->getPointeeType())); }) |
901 | |
902 | DEF_TRAVERSE_TYPE(RValueReferenceType, |
903 | { TRY_TO(TraverseType(T->getPointeeType())); }) |
904 | |
905 | DEF_TRAVERSE_TYPE(MemberPointerType, { |
906 | TRY_TO(TraverseType(QualType(T->getClass(), 0))); |
907 | TRY_TO(TraverseType(T->getPointeeType())); |
908 | }) |
909 | |
910 | DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); }) |
911 | |
912 | DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); }) |
913 | |
914 | DEF_TRAVERSE_TYPE(ConstantArrayType, { |
915 | TRY_TO(TraverseType(T->getElementType())); |
916 | if (T->getSizeExpr()) |
917 | TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr()))); |
918 | }) |
919 | |
920 | DEF_TRAVERSE_TYPE(IncompleteArrayType, |
921 | { TRY_TO(TraverseType(T->getElementType())); }) |
922 | |
923 | DEF_TRAVERSE_TYPE(VariableArrayType, { |
924 | TRY_TO(TraverseType(T->getElementType())); |
925 | TRY_TO(TraverseStmt(T->getSizeExpr())); |
926 | }) |
927 | |
928 | DEF_TRAVERSE_TYPE(DependentSizedArrayType, { |
929 | TRY_TO(TraverseType(T->getElementType())); |
930 | if (T->getSizeExpr()) |
931 | TRY_TO(TraverseStmt(T->getSizeExpr())); |
932 | }) |
933 | |
934 | DEF_TRAVERSE_TYPE(DependentAddressSpaceType, { |
935 | TRY_TO(TraverseStmt(T->getAddrSpaceExpr())); |
936 | TRY_TO(TraverseType(T->getPointeeType())); |
937 | }) |
938 | |
939 | DEF_TRAVERSE_TYPE(DependentVectorType, { |
940 | if (T->getSizeExpr()) |
941 | TRY_TO(TraverseStmt(T->getSizeExpr())); |
942 | TRY_TO(TraverseType(T->getElementType())); |
943 | }) |
944 | |
945 | DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, { |
946 | if (T->getSizeExpr()) |
947 | TRY_TO(TraverseStmt(T->getSizeExpr())); |
948 | TRY_TO(TraverseType(T->getElementType())); |
949 | }) |
950 | |
951 | DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); }) |
952 | |
953 | DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); }) |
954 | |
955 | DEF_TRAVERSE_TYPE(ConstantMatrixType, |
956 | { TRY_TO(TraverseType(T->getElementType())); }) |
957 | |
958 | DEF_TRAVERSE_TYPE(DependentSizedMatrixType, { |
959 | if (T->getRowExpr()) |
960 | TRY_TO(TraverseStmt(T->getRowExpr())); |
961 | if (T->getColumnExpr()) |
962 | TRY_TO(TraverseStmt(T->getColumnExpr())); |
963 | TRY_TO(TraverseType(T->getElementType())); |
964 | }) |
965 | |
966 | DEF_TRAVERSE_TYPE(FunctionNoProtoType, |
967 | { TRY_TO(TraverseType(T->getReturnType())); }) |
968 | |
969 | DEF_TRAVERSE_TYPE(FunctionProtoType, { |
970 | TRY_TO(TraverseType(T->getReturnType())); |
971 | |
972 | for (const auto &A : T->param_types()) { |
973 | TRY_TO(TraverseType(A)); |
974 | } |
975 | |
976 | for (const auto &E : T->exceptions()) { |
977 | TRY_TO(TraverseType(E)); |
978 | } |
979 | |
980 | if (Expr *NE = T->getNoexceptExpr()) |
981 | TRY_TO(TraverseStmt(NE)); |
982 | }) |
983 | |
984 | DEF_TRAVERSE_TYPE(UsingType, {}) |
985 | DEF_TRAVERSE_TYPE(UnresolvedUsingType, {}) |
986 | DEF_TRAVERSE_TYPE(TypedefType, {}) |
987 | |
988 | DEF_TRAVERSE_TYPE(TypeOfExprType, |
989 | { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) |
990 | |
991 | DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); }) |
992 | |
993 | DEF_TRAVERSE_TYPE(DecltypeType, |
994 | { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) |
995 | |
996 | DEF_TRAVERSE_TYPE(UnaryTransformType, { |
997 | TRY_TO(TraverseType(T->getBaseType())); |
998 | TRY_TO(TraverseType(T->getUnderlyingType())); |
999 | }) |
1000 | |
1001 | DEF_TRAVERSE_TYPE(AutoType, { |
1002 | TRY_TO(TraverseType(T->getDeducedType())); |
1003 | if (T->isConstrained()) { |
1004 | TRY_TO(TraverseDecl(T->getTypeConstraintConcept())); |
1005 | TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); |
1006 | } |
1007 | }) |
1008 | DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, { |
1009 | TRY_TO(TraverseTemplateName(T->getTemplateName())); |
1010 | TRY_TO(TraverseType(T->getDeducedType())); |
1011 | }) |
1012 | |
1013 | DEF_TRAVERSE_TYPE(RecordType, {}) |
1014 | DEF_TRAVERSE_TYPE(EnumType, {}) |
1015 | DEF_TRAVERSE_TYPE(TemplateTypeParmType, {}) |
1016 | DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { |
1017 | TRY_TO(TraverseType(T->getReplacementType())); |
1018 | }) |
1019 | DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { |
1020 | TRY_TO(TraverseTemplateArgument(T->getArgumentPack())); |
1021 | }) |
1022 | |
1023 | DEF_TRAVERSE_TYPE(TemplateSpecializationType, { |
1024 | TRY_TO(TraverseTemplateName(T->getTemplateName())); |
1025 | TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); |
1026 | }) |
1027 | |
1028 | DEF_TRAVERSE_TYPE(InjectedClassNameType, {}) |
1029 | |
1030 | DEF_TRAVERSE_TYPE(AttributedType, |
1031 | { TRY_TO(TraverseType(T->getModifiedType())); }) |
1032 | |
1033 | DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); }) |
1034 | |
1035 | DEF_TRAVERSE_TYPE(MacroQualifiedType, |
1036 | { TRY_TO(TraverseType(T->getUnderlyingType())); }) |
1037 | |
1038 | DEF_TRAVERSE_TYPE(ElaboratedType, { |
1039 | if (T->getQualifier()) { |
1040 | TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); |
1041 | } |
1042 | TRY_TO(TraverseType(T->getNamedType())); |
1043 | }) |
1044 | |
1045 | DEF_TRAVERSE_TYPE(DependentNameType, |
1046 | { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); }) |
1047 | |
1048 | DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, { |
1049 | TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); |
1050 | TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); |
1051 | }) |
1052 | |
1053 | DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); }) |
1054 | |
1055 | DEF_TRAVERSE_TYPE(ObjCTypeParamType, {}) |
1056 | |
1057 | DEF_TRAVERSE_TYPE(ObjCInterfaceType, {}) |
1058 | |
1059 | DEF_TRAVERSE_TYPE(ObjCObjectType, { |
1060 | // We have to watch out here because an ObjCInterfaceType's base |
1061 | // type is itself. |
1062 | if (T->getBaseType().getTypePtr() != T) |
1063 | TRY_TO(TraverseType(T->getBaseType())); |
1064 | for (auto typeArg : T->getTypeArgsAsWritten()) { |
1065 | TRY_TO(TraverseType(typeArg)); |
1066 | } |
1067 | }) |
1068 | |
1069 | DEF_TRAVERSE_TYPE(ObjCObjectPointerType, |
1070 | { TRY_TO(TraverseType(T->getPointeeType())); }) |
1071 | |
1072 | DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); }) |
1073 | |
1074 | DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); }) |
1075 | |
1076 | DEF_TRAVERSE_TYPE(BitIntType, {}) |
1077 | DEF_TRAVERSE_TYPE(DependentBitIntType, |
1078 | { TRY_TO(TraverseStmt(T->getNumBitsExpr())); }) |
1079 | |
1080 | #undef DEF_TRAVERSE_TYPE |
1081 | |
1082 | // ----------------- TypeLoc traversal ----------------- |
1083 | |
1084 | // This macro makes available a variable TL, the passed-in TypeLoc. |
1085 | // If requested, it calls WalkUpFrom* for the Type in the given TypeLoc, |
1086 | // in addition to WalkUpFrom* for the TypeLoc itself, such that existing |
1087 | // clients that override the WalkUpFrom*Type() and/or Visit*Type() methods |
1088 | // continue to work. |
1089 | #define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \ |
1090 | template <typename Derived> \ |
1091 | bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \ |
1092 | if (!getDerived().shouldTraversePostOrder()) { \ |
1093 | TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ |
1094 | if (getDerived().shouldWalkTypesOfTypeLocs()) \ |
1095 | TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \ |
1096 | } \ |
1097 | { CODE; } \ |
1098 | if (getDerived().shouldTraversePostOrder()) { \ |
1099 | TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ |
1100 | if (getDerived().shouldWalkTypesOfTypeLocs()) \ |
1101 | TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \ |
1102 | } \ |
1103 | return true; \ |
1104 | } |
1105 | |
1106 | template <typename Derived> |
1107 | bool |
1108 | RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) { |
1109 | // Move this over to the 'main' typeloc tree. Note that this is a |
1110 | // move -- we pretend that we were really looking at the unqualified |
1111 | // typeloc all along -- rather than a recursion, so we don't follow |
1112 | // the normal CRTP plan of going through |
1113 | // getDerived().TraverseTypeLoc. If we did, we'd be traversing |
1114 | // twice for the same type (once as a QualifiedTypeLoc version of |
1115 | // the type, once as an UnqualifiedTypeLoc version of the type), |
1116 | // which in effect means we'd call VisitTypeLoc twice with the |
1117 | // 'same' type. This solves that problem, at the cost of never |
1118 | // seeing the qualified version of the type (unless the client |
1119 | // subclasses TraverseQualifiedTypeLoc themselves). It's not a |
1120 | // perfect solution. A perfect solution probably requires making |
1121 | // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a |
1122 | // wrapper around Type* -- rather than being its own class in the |
1123 | // type hierarchy. |
1124 | return TraverseTypeLoc(TL.getUnqualifiedLoc()); |
1125 | } |
1126 | |
1127 | DEF_TRAVERSE_TYPELOC(BuiltinType, {}) |
1128 | |
1129 | // FIXME: ComplexTypeLoc is unfinished |
1130 | DEF_TRAVERSE_TYPELOC(ComplexType, { |
1131 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1132 | }) |
1133 | |
1134 | DEF_TRAVERSE_TYPELOC(PointerType, |
1135 | { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) |
1136 | |
1137 | DEF_TRAVERSE_TYPELOC(BlockPointerType, |
1138 | { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) |
1139 | |
1140 | DEF_TRAVERSE_TYPELOC(LValueReferenceType, |
1141 | { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) |
1142 | |
1143 | DEF_TRAVERSE_TYPELOC(RValueReferenceType, |
1144 | { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) |
1145 | |
1146 | // We traverse this in the type case as well, but how is it not reached through |
1147 | // the pointee type? |
1148 | DEF_TRAVERSE_TYPELOC(MemberPointerType, { |
1149 | if (auto *TSI = TL.getClassTInfo()) |
1150 | TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); |
1151 | else |
1152 | TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0))); |
1153 | TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); |
1154 | }) |
1155 | |
1156 | DEF_TRAVERSE_TYPELOC(AdjustedType, |
1157 | { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); }) |
1158 | |
1159 | DEF_TRAVERSE_TYPELOC(DecayedType, |
1160 | { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); }) |
1161 | |
1162 | template <typename Derived> |
1163 | bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { |
1164 | // This isn't available for ArrayType, but is for the ArrayTypeLoc. |
1165 | TRY_TO(TraverseStmt(TL.getSizeExpr())); |
1166 | return true; |
1167 | } |
1168 | |
1169 | DEF_TRAVERSE_TYPELOC(ConstantArrayType, { |
1170 | TRY_TO(TraverseTypeLoc(TL.getElementLoc())); |
1171 | TRY_TO(TraverseArrayTypeLocHelper(TL)); |
1172 | }) |
1173 | |
1174 | DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { |
1175 | TRY_TO(TraverseTypeLoc(TL.getElementLoc())); |
1176 | TRY_TO(TraverseArrayTypeLocHelper(TL)); |
1177 | }) |
1178 | |
1179 | DEF_TRAVERSE_TYPELOC(VariableArrayType, { |
1180 | TRY_TO(TraverseTypeLoc(TL.getElementLoc())); |
1181 | TRY_TO(TraverseArrayTypeLocHelper(TL)); |
1182 | }) |
1183 | |
1184 | DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, { |
1185 | TRY_TO(TraverseTypeLoc(TL.getElementLoc())); |
1186 | TRY_TO(TraverseArrayTypeLocHelper(TL)); |
1187 | }) |
1188 | |
1189 | DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, { |
1190 | TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr())); |
1191 | TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType())); |
1192 | }) |
1193 | |
1194 | // FIXME: order? why not size expr first? |
1195 | // FIXME: base VectorTypeLoc is unfinished |
1196 | DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, { |
1197 | if (TL.getTypePtr()->getSizeExpr()) |
1198 | TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr())); |
1199 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1200 | }) |
1201 | |
1202 | // FIXME: VectorTypeLoc is unfinished |
1203 | DEF_TRAVERSE_TYPELOC(VectorType, { |
1204 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1205 | }) |
1206 | |
1207 | DEF_TRAVERSE_TYPELOC(DependentVectorType, { |
1208 | if (TL.getTypePtr()->getSizeExpr()) |
1209 | TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr())); |
1210 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1211 | }) |
1212 | |
1213 | // FIXME: size and attributes |
1214 | // FIXME: base VectorTypeLoc is unfinished |
1215 | DEF_TRAVERSE_TYPELOC(ExtVectorType, { |
1216 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1217 | }) |
1218 | |
1219 | DEF_TRAVERSE_TYPELOC(ConstantMatrixType, { |
1220 | TRY_TO(TraverseStmt(TL.getAttrRowOperand())); |
1221 | TRY_TO(TraverseStmt(TL.getAttrColumnOperand())); |
1222 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1223 | }) |
1224 | |
1225 | DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, { |
1226 | TRY_TO(TraverseStmt(TL.getAttrRowOperand())); |
1227 | TRY_TO(TraverseStmt(TL.getAttrColumnOperand())); |
1228 | TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); |
1229 | }) |
1230 | |
1231 | DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, |
1232 | { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); }) |
1233 | |
1234 | // FIXME: location of exception specifications (attributes?) |
1235 | DEF_TRAVERSE_TYPELOC(FunctionProtoType, { |
1236 | TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); |
1237 | |
1238 | const FunctionProtoType *T = TL.getTypePtr(); |
1239 | |
1240 | for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) { |
1241 | if (TL.getParam(I)) { |
1242 | TRY_TO(TraverseDecl(TL.getParam(I))); |
1243 | } else if (I < T->getNumParams()) { |
1244 | TRY_TO(TraverseType(T->getParamType(I))); |
1245 | } |
1246 | } |
1247 | |
1248 | for (const auto &E : T->exceptions()) { |
1249 | TRY_TO(TraverseType(E)); |
1250 | } |
1251 | |
1252 | if (Expr *NE = T->getNoexceptExpr()) |
1253 | TRY_TO(TraverseStmt(NE)); |
1254 | }) |
1255 | |
1256 | DEF_TRAVERSE_TYPELOC(UsingType, {}) |
1257 | DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {}) |
1258 | DEF_TRAVERSE_TYPELOC(TypedefType, {}) |
1259 | |
1260 | DEF_TRAVERSE_TYPELOC(TypeOfExprType, |
1261 | { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); }) |
1262 | |
1263 | DEF_TRAVERSE_TYPELOC(TypeOfType, { |
1264 | TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); |
1265 | }) |
1266 | |
1267 | // FIXME: location of underlying expr |
1268 | DEF_TRAVERSE_TYPELOC(DecltypeType, { |
1269 | TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); |
1270 | }) |
1271 | |
1272 | DEF_TRAVERSE_TYPELOC(UnaryTransformType, { |
1273 | TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); |
1274 | }) |
1275 | |
1276 | DEF_TRAVERSE_TYPELOC(AutoType, { |
1277 | TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); |
1278 | if (TL.isConstrained()) { |
1279 | TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc())); |
1280 | TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo())); |
1281 | for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) |
1282 | TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); |
1283 | } |
1284 | }) |
1285 | |
1286 | DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, { |
1287 | TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName())); |
1288 | TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); |
1289 | }) |
1290 | |
1291 | DEF_TRAVERSE_TYPELOC(RecordType, {}) |
1292 | DEF_TRAVERSE_TYPELOC(EnumType, {}) |
1293 | DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {}) |
1294 | DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { |
1295 | TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType())); |
1296 | }) |
1297 | DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { |
1298 | TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack())); |
1299 | }) |
1300 | |
1301 | // FIXME: use the loc for the template name? |
1302 | DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, { |
1303 | TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName())); |
1304 | for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { |
1305 | TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); |
1306 | } |
1307 | }) |
1308 | |
1309 | DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {}) |
1310 | |
1311 | DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) |
1312 | |
1313 | DEF_TRAVERSE_TYPELOC(MacroQualifiedType, |
1314 | { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) |
1315 | |
1316 | DEF_TRAVERSE_TYPELOC(AttributedType, |
1317 | { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) |
1318 | |
1319 | DEF_TRAVERSE_TYPELOC(ElaboratedType, { |
1320 | if (TL.getQualifierLoc()) { |
1321 | TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); |
1322 | } |
1323 | TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc())); |
1324 | }) |
1325 | |
1326 | DEF_TRAVERSE_TYPELOC(DependentNameType, { |
1327 | TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); |
1328 | }) |
1329 | |
1330 | DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, { |
1331 | if (TL.getQualifierLoc()) { |
1332 | TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); |
1333 | } |
1334 | |
1335 | for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { |
1336 | TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); |
1337 | } |
1338 | }) |
1339 | |
1340 | DEF_TRAVERSE_TYPELOC(PackExpansionType, |
1341 | { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); }) |
1342 | |
1343 | DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {}) |
1344 | |
1345 | DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {}) |
1346 | |
1347 | DEF_TRAVERSE_TYPELOC(ObjCObjectType, { |
1348 | // We have to watch out here because an ObjCInterfaceType's base |
1349 | // type is itself. |
1350 | if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr()) |
1351 | TRY_TO(TraverseTypeLoc(TL.getBaseLoc())); |
1352 | for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) |
1353 | TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc())); |
1354 | }) |
1355 | |
1356 | DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, |
1357 | { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) |
1358 | |
1359 | DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) |
1360 | |
1361 | DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) |
1362 | |
1363 | DEF_TRAVERSE_TYPELOC(BitIntType, {}) |
1364 | DEF_TRAVERSE_TYPELOC(DependentBitIntType, { |
1365 | TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr())); |
1366 | }) |
1367 | |
1368 | #undef DEF_TRAVERSE_TYPELOC |
1369 | |
1370 | // ----------------- Decl traversal ----------------- |
1371 | // |
1372 | // For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing |
1373 | // the children that come from the DeclContext associated with it. |
1374 | // Therefore each Traverse* only needs to worry about children other |
1375 | // than those. |
1376 | |
1377 | template <typename Derived> |
1378 | bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext( |
1379 | const Decl *Child) { |
1380 | // BlockDecls are traversed through BlockExprs, |
1381 | // CapturedDecls are traversed through CapturedStmts. |
1382 | if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child)) |
1383 | return true; |
1384 | // Lambda classes are traversed through LambdaExprs. |
1385 | if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child)) |
1386 | return Cls->isLambda(); |
1387 | return false; |
1388 | } |
1389 | |
1390 | template <typename Derived> |
1391 | bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { |
1392 | if (!DC) |
1393 | return true; |
1394 | |
1395 | for (auto *Child : DC->decls()) { |
1396 | if (!canIgnoreChildDeclWhileTraversingDeclContext(Child)) |
1397 | TRY_TO(TraverseDecl(Child)); |
1398 | } |
1399 | |
1400 | return true; |
1401 | } |
1402 | |
1403 | // This macro makes available a variable D, the passed-in decl. |
1404 | #define DEF_TRAVERSE_DECL(DECL, CODE) \ |
1405 | template <typename Derived> \ |
1406 | bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \ |
1407 | bool ShouldVisitChildren = true; \ |
1408 | bool ReturnValue = true; \ |
1409 | if (!getDerived().shouldTraversePostOrder()) \ |
1410 | TRY_TO(WalkUpFrom##DECL(D)); \ |
1411 | { CODE; } \ |
1412 | if (ReturnValue && ShouldVisitChildren) \ |
1413 | TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \ |
1414 | if (ReturnValue) { \ |
1415 | /* Visit any attributes attached to this declaration. */ \ |
1416 | for (auto *I : D->attrs()) \ |
1417 | TRY_TO(getDerived().TraverseAttr(I)); \ |
1418 | } \ |
1419 | if (ReturnValue && getDerived().shouldTraversePostOrder()) \ |
1420 | TRY_TO(WalkUpFrom##DECL(D)); \ |
1421 | return ReturnValue; \ |
1422 | } |
1423 | |
1424 | DEF_TRAVERSE_DECL(AccessSpecDecl, {}) |
1425 | |
1426 | DEF_TRAVERSE_DECL(BlockDecl, { |
1427 | if (TypeSourceInfo *TInfo = D->getSignatureAsWritten()) |
1428 | TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); |
1429 | TRY_TO(TraverseStmt(D->getBody())); |
1430 | for (const auto &I : D->captures()) { |
1431 | if (I.hasCopyExpr()) { |
1432 | TRY_TO(TraverseStmt(I.getCopyExpr())); |
1433 | } |
1434 | } |
1435 | ShouldVisitChildren = false; |
1436 | }) |
1437 | |
1438 | DEF_TRAVERSE_DECL(CapturedDecl, { |
1439 | TRY_TO(TraverseStmt(D->getBody())); |
1440 | ShouldVisitChildren = false; |
1441 | }) |
1442 | |
1443 | DEF_TRAVERSE_DECL(EmptyDecl, {}) |
1444 | |
1445 | DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, { |
1446 | TRY_TO(TraverseStmt(D->getTemporaryExpr())); |
1447 | }) |
1448 | |
1449 | DEF_TRAVERSE_DECL(FileScopeAsmDecl, |
1450 | { TRY_TO(TraverseStmt(D->getAsmString())); }) |
1451 | |
1452 | DEF_TRAVERSE_DECL(ImportDecl, {}) |
1453 | |
1454 | DEF_TRAVERSE_DECL(FriendDecl, { |
1455 | // Friend is either decl or a type. |
1456 | if (D->getFriendType()) |
1457 | TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); |
1458 | else |
1459 | TRY_TO(TraverseDecl(D->getFriendDecl())); |
1460 | }) |
1461 | |
1462 | DEF_TRAVERSE_DECL(FriendTemplateDecl, { |
1463 | if (D->getFriendType()) |
1464 | TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); |
1465 | else |
1466 | TRY_TO(TraverseDecl(D->getFriendDecl())); |
1467 | for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) { |
1468 | TemplateParameterList *TPL = D->getTemplateParameterList(I); |
1469 | for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end(); |
1470 | ITPL != ETPL; ++ITPL) { |
1471 | TRY_TO(TraverseDecl(*ITPL)); |
1472 | } |
1473 | } |
1474 | }) |
1475 | |
1476 | DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, { |
1477 | TRY_TO(TraverseDecl(D->getSpecialization())); |
1478 | |
1479 | if (D->hasExplicitTemplateArgs()) { |
1480 | TRY_TO(TraverseTemplateArgumentLocsHelper( |
1481 | D->getTemplateArgsAsWritten()->getTemplateArgs(), |
1482 | D->getTemplateArgsAsWritten()->NumTemplateArgs)); |
1483 | } |
1484 | }) |
1485 | |
1486 | DEF_TRAVERSE_DECL(LinkageSpecDecl, {}) |
1487 | |
1488 | DEF_TRAVERSE_DECL(ExportDecl, {}) |
1489 | |
1490 | DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this |
1491 | }) |
1492 | |
1493 | DEF_TRAVERSE_DECL(StaticAssertDecl, { |
1494 | TRY_TO(TraverseStmt(D->getAssertExpr())); |
1495 | TRY_TO(TraverseStmt(D->getMessage())); |
1496 | }) |
1497 | |
1498 | DEF_TRAVERSE_DECL(TranslationUnitDecl, { |
1499 | // Code in an unnamed namespace shows up automatically in |
1500 | // decls_begin()/decls_end(). Thus we don't need to recurse on |
1501 | // D->getAnonymousNamespace(). |
1502 | |
1503 | // If the traversal scope is set, then consider them to be the children of |
1504 | // the TUDecl, rather than traversing (and loading?) all top-level decls. |
1505 | auto Scope = D->getASTContext().getTraversalScope(); |
1506 | bool HasLimitedScope = |
1507 | Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front()); |
1508 | if (HasLimitedScope) { |
1509 | ShouldVisitChildren = false; // we'll do that here instead |
1510 | for (auto *Child : Scope) { |
1511 | if (!canIgnoreChildDeclWhileTraversingDeclContext(Child)) |
1512 | TRY_TO(TraverseDecl(Child)); |
1513 | } |
1514 | } |
1515 | }) |
1516 | |
1517 | DEF_TRAVERSE_DECL(PragmaCommentDecl, {}) |
1518 | |
1519 | DEF_TRAVERSE_DECL(PragmaDetectMismatchDecl, {}) |
1520 | |
1521 | DEF_TRAVERSE_DECL(ExternCContextDecl, {}) |
1522 | |
1523 | DEF_TRAVERSE_DECL(NamespaceAliasDecl, { |
1524 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1525 | |
1526 | // We shouldn't traverse an aliased namespace, since it will be |
1527 | // defined (and, therefore, traversed) somewhere else. |
1528 | ShouldVisitChildren = false; |
1529 | }) |
1530 | |
1531 | DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl. |
1532 | }) |
1533 | |
1534 | DEF_TRAVERSE_DECL( |
1535 | NamespaceDecl, |
1536 | {// Code in an unnamed namespace shows up automatically in |
1537 | // decls_begin()/decls_end(). Thus we don't need to recurse on |
1538 | // D->getAnonymousNamespace(). |
1539 | }) |
1540 | |
1541 | DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement |
1542 | }) |
1543 | |
1544 | DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement |
1545 | if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) { |
1546 | for (auto typeParam : *typeParamList) { |
1547 | TRY_TO(TraverseObjCTypeParamDecl(typeParam)); |
1548 | } |
1549 | } |
1550 | }) |
1551 | |
1552 | DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement |
1553 | }) |
1554 | |
1555 | DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement |
1556 | }) |
1557 | |
1558 | DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement |
1559 | if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) { |
1560 | for (auto typeParam : *typeParamList) { |
1561 | TRY_TO(TraverseObjCTypeParamDecl(typeParam)); |
1562 | } |
1563 | } |
1564 | |
1565 | if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) { |
1566 | TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc())); |
1567 | } |
1568 | }) |
1569 | |
1570 | DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement |
1571 | }) |
1572 | |
1573 | DEF_TRAVERSE_DECL(ObjCMethodDecl, { |
1574 | if (D->getReturnTypeSourceInfo()) { |
1575 | TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc())); |
1576 | } |
1577 | for (ParmVarDecl *Parameter : D->parameters()) { |
1578 | TRY_TO(TraverseDecl(Parameter)); |
1579 | } |
1580 | if (D->isThisDeclarationADefinition()) { |
1581 | TRY_TO(TraverseStmt(D->getBody())); |
1582 | } |
1583 | ShouldVisitChildren = false; |
1584 | }) |
1585 | |
1586 | DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { |
1587 | if (D->hasExplicitBound()) { |
1588 | TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); |
1589 | // We shouldn't traverse D->getTypeForDecl(); it's a result of |
1590 | // declaring the type alias, not something that was written in the |
1591 | // source. |
1592 | } |
1593 | }) |
1594 | |
1595 | DEF_TRAVERSE_DECL(ObjCPropertyDecl, { |
1596 | if (D->getTypeSourceInfo()) |
1597 | TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); |
1598 | else |
1599 | TRY_TO(TraverseType(D->getType())); |
1600 | ShouldVisitChildren = false; |
1601 | }) |
1602 | |
1603 | DEF_TRAVERSE_DECL(UsingDecl, { |
1604 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1605 | TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); |
1606 | }) |
1607 | |
1608 | DEF_TRAVERSE_DECL(UsingEnumDecl, {}) |
1609 | |
1610 | DEF_TRAVERSE_DECL(UsingPackDecl, {}) |
1611 | |
1612 | DEF_TRAVERSE_DECL(UsingDirectiveDecl, { |
1613 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1614 | }) |
1615 | |
1616 | DEF_TRAVERSE_DECL(UsingShadowDecl, {}) |
1617 | |
1618 | DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {}) |
1619 | |
1620 | DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { |
1621 | for (auto *I : D->varlists()) { |
1622 | TRY_TO(TraverseStmt(I)); |
1623 | } |
1624 | }) |
1625 | |
1626 | DEF_TRAVERSE_DECL(OMPRequiresDecl, { |
1627 | for (auto *C : D->clauselists()) { |
1628 | TRY_TO(TraverseOMPClause(C)); |
1629 | } |
1630 | }) |
1631 | |
1632 | DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, { |
1633 | TRY_TO(TraverseStmt(D->getCombiner())); |
1634 | if (auto *Initializer = D->getInitializer()) |
1635 | TRY_TO(TraverseStmt(Initializer)); |
1636 | TRY_TO(TraverseType(D->getType())); |
1637 | return true; |
1638 | }) |
1639 | |
1640 | DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, { |
1641 | for (auto *C : D->clauselists()) |
1642 | TRY_TO(TraverseOMPClause(C)); |
1643 | TRY_TO(TraverseType(D->getType())); |
1644 | return true; |
1645 | }) |
1646 | |
1647 | DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); }) |
1648 | |
1649 | DEF_TRAVERSE_DECL(OMPAllocateDecl, { |
1650 | for (auto *I : D->varlists()) |
1651 | TRY_TO(TraverseStmt(I)); |
1652 | for (auto *C : D->clauselists()) |
1653 | TRY_TO(TraverseOMPClause(C)); |
1654 | }) |
1655 | |
1656 | // A helper method for TemplateDecl's children. |
1657 | template <typename Derived> |
1658 | bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( |
1659 | TemplateParameterList *TPL) { |
1660 | if (TPL) { |
1661 | for (NamedDecl *D : *TPL) { |
1662 | TRY_TO(TraverseDecl(D)); |
1663 | } |
1664 | if (Expr *RequiresClause = TPL->getRequiresClause()) { |
1665 | TRY_TO(TraverseStmt(RequiresClause)); |
1666 | } |
1667 | } |
1668 | return true; |
1669 | } |
1670 | |
1671 | template <typename Derived> |
1672 | template <typename T> |
1673 | bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) { |
1674 | for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) { |
1675 | TemplateParameterList *TPL = D->getTemplateParameterList(i); |
1676 | TraverseTemplateParameterListHelper(TPL); |
1677 | } |
1678 | return true; |
1679 | } |
1680 | |
1681 | template <typename Derived> |
1682 | bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( |
1683 | ClassTemplateDecl *D) { |
1684 | for (auto *SD : D->specializations()) { |
1685 | for (auto *RD : SD->redecls()) { |
1686 | assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName())(static_cast <bool> (!cast<CXXRecordDecl>(RD)-> isInjectedClassName()) ? void (0) : __assert_fail ("!cast<CXXRecordDecl>(RD)->isInjectedClassName()" , "clang/include/clang/AST/RecursiveASTVisitor.h", 1686, __extension__ __PRETTY_FUNCTION__)); |
1687 | switch ( |
1688 | cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) { |
1689 | // Visit the implicit instantiations with the requested pattern. |
1690 | case TSK_Undeclared: |
1691 | case TSK_ImplicitInstantiation: |
1692 | TRY_TO(TraverseDecl(RD)); |
1693 | break; |
1694 | |
1695 | // We don't need to do anything on an explicit instantiation |
1696 | // or explicit specialization because there will be an explicit |
1697 | // node for it elsewhere. |
1698 | case TSK_ExplicitInstantiationDeclaration: |
1699 | case TSK_ExplicitInstantiationDefinition: |
1700 | case TSK_ExplicitSpecialization: |
1701 | break; |
1702 | } |
1703 | } |
1704 | } |
1705 | |
1706 | return true; |
1707 | } |
1708 | |
1709 | template <typename Derived> |
1710 | bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( |
1711 | VarTemplateDecl *D) { |
1712 | for (auto *SD : D->specializations()) { |
1713 | for (auto *RD : SD->redecls()) { |
1714 | switch ( |
1715 | cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) { |
1716 | case TSK_Undeclared: |
1717 | case TSK_ImplicitInstantiation: |
1718 | TRY_TO(TraverseDecl(RD)); |
1719 | break; |
1720 | |
1721 | case TSK_ExplicitInstantiationDeclaration: |
1722 | case TSK_ExplicitInstantiationDefinition: |
1723 | case TSK_ExplicitSpecialization: |
1724 | break; |
1725 | } |
1726 | } |
1727 | } |
1728 | |
1729 | return true; |
1730 | } |
1731 | |
1732 | // A helper method for traversing the instantiations of a |
1733 | // function while skipping its specializations. |
1734 | template <typename Derived> |
1735 | bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( |
1736 | FunctionTemplateDecl *D) { |
1737 | for (auto *FD : D->specializations()) { |
1738 | for (auto *RD : FD->redecls()) { |
1739 | switch (RD->getTemplateSpecializationKind()) { |
1740 | case TSK_Undeclared: |
1741 | case TSK_ImplicitInstantiation: |
1742 | // We don't know what kind of FunctionDecl this is. |
1743 | TRY_TO(TraverseDecl(RD)); |
1744 | break; |
1745 | |
1746 | // FIXME: For now traverse explicit instantiations here. Change that |
1747 | // once they are represented as dedicated nodes in the AST. |
1748 | case TSK_ExplicitInstantiationDeclaration: |
1749 | case TSK_ExplicitInstantiationDefinition: |
1750 | TRY_TO(TraverseDecl(RD)); |
1751 | break; |
1752 | |
1753 | case TSK_ExplicitSpecialization: |
1754 | break; |
1755 | } |
1756 | } |
1757 | } |
1758 | |
1759 | return true; |
1760 | } |
1761 | |
1762 | // This macro unifies the traversal of class, variable and function |
1763 | // template declarations. |
1764 | #define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)DEF_TRAVERSE_DECL(TMPLDECLKINDTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper (D->getTemplateParameters())); TRY_TO(TraverseDecl(D->getTemplatedDecl ())); if (getDerived().shouldVisitTemplateInstantiations() && D == D->getCanonicalDecl()) TRY_TO(TraverseTemplateInstantiations (D)); }) \ |
1765 | DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \ |
1766 | TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ |
1767 | TRY_TO(TraverseDecl(D->getTemplatedDecl())); \ |
1768 | \ |
1769 | /* By default, we do not traverse the instantiations of \ |
1770 | class templates since they do not appear in the user code. The \ |
1771 | following code optionally traverses them. \ |
1772 | \ |
1773 | We only traverse the class instantiations when we see the canonical \ |
1774 | declaration of the template, to ensure we only visit them once. */ \ |
1775 | if (getDerived().shouldVisitTemplateInstantiations() && \ |
1776 | D == D->getCanonicalDecl()) \ |
1777 | TRY_TO(TraverseTemplateInstantiations(D)); \ |
1778 | \ |
1779 | /* Note that getInstantiatedFromMemberTemplate() is just a link \ |
1780 | from a template instantiation back to the template from which \ |
1781 | it was instantiated, and thus should not be traversed. */ \ |
1782 | }) |
1783 | |
1784 | DEF_TRAVERSE_TMPL_DECL(Class)DEF_TRAVERSE_DECL(ClassTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper (D->getTemplateParameters())); TRY_TO(TraverseDecl(D->getTemplatedDecl ())); if (getDerived().shouldVisitTemplateInstantiations() && D == D->getCanonicalDecl()) TRY_TO(TraverseTemplateInstantiations (D)); }) |
1785 | DEF_TRAVERSE_TMPL_DECL(Var)DEF_TRAVERSE_DECL(VarTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper (D->getTemplateParameters())); TRY_TO(TraverseDecl(D->getTemplatedDecl ())); if (getDerived().shouldVisitTemplateInstantiations() && D == D->getCanonicalDecl()) TRY_TO(TraverseTemplateInstantiations (D)); }) |
1786 | DEF_TRAVERSE_TMPL_DECL(Function)DEF_TRAVERSE_DECL(FunctionTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper (D->getTemplateParameters())); TRY_TO(TraverseDecl(D->getTemplatedDecl ())); if (getDerived().shouldVisitTemplateInstantiations() && D == D->getCanonicalDecl()) TRY_TO(TraverseTemplateInstantiations (D)); }) |
1787 | |
1788 | DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { |
1789 | // D is the "T" in something like |
1790 | // template <template <typename> class T> class container { }; |
1791 | TRY_TO(TraverseDecl(D->getTemplatedDecl())); |
1792 | if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) |
1793 | TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); |
1794 | TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); |
1795 | }) |
1796 | |
1797 | DEF_TRAVERSE_DECL(BuiltinTemplateDecl, { |
1798 | TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); |
1799 | }) |
1800 | |
1801 | template <typename Derived> |
1802 | bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints( |
1803 | const TemplateTypeParmDecl *D) { |
1804 | if (const auto *TC = D->getTypeConstraint()) { |
1805 | if (Expr *IDC = TC->getImmediatelyDeclaredConstraint()) { |
1806 | TRY_TO(TraverseStmt(IDC)); |
1807 | } else { |
1808 | // Avoid traversing the ConceptReference in the TypeCosntraint |
1809 | // if we have an immediately-declared-constraint, otherwise |
1810 | // we'll end up visiting the concept and the arguments in |
1811 | // the TC twice. |
1812 | TRY_TO(TraverseConceptReference(*TC)); |
1813 | } |
1814 | } |
1815 | return true; |
1816 | } |
1817 | |
1818 | DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { |
1819 | // D is the "T" in something like "template<typename T> class vector;" |
1820 | if (D->getTypeForDecl()) |
1821 | TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); |
1822 | TRY_TO(TraverseTemplateTypeParamDeclConstraints(D)); |
1823 | if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) |
1824 | TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc())); |
1825 | }) |
1826 | |
1827 | DEF_TRAVERSE_DECL(TypedefDecl, { |
1828 | TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); |
1829 | // We shouldn't traverse D->getTypeForDecl(); it's a result of |
1830 | // declaring the typedef, not something that was written in the |
1831 | // source. |
1832 | }) |
1833 | |
1834 | DEF_TRAVERSE_DECL(TypeAliasDecl, { |
1835 | TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); |
1836 | // We shouldn't traverse D->getTypeForDecl(); it's a result of |
1837 | // declaring the type alias, not something that was written in the |
1838 | // source. |
1839 | }) |
1840 | |
1841 | DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { |
1842 | TRY_TO(TraverseDecl(D->getTemplatedDecl())); |
1843 | TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); |
1844 | }) |
1845 | |
1846 | DEF_TRAVERSE_DECL(ConceptDecl, { |
1847 | TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); |
1848 | TRY_TO(TraverseStmt(D->getConstraintExpr())); |
1849 | }) |
1850 | |
1851 | DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { |
1852 | // A dependent using declaration which was marked with 'typename'. |
1853 | // template<class T> class A : public B<T> { using typename B<T>::foo; }; |
1854 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1855 | // We shouldn't traverse D->getTypeForDecl(); it's a result of |
1856 | // declaring the type, not something that was written in the |
1857 | // source. |
1858 | }) |
1859 | |
1860 | DEF_TRAVERSE_DECL(UnresolvedUsingIfExistsDecl, {}) |
1861 | |
1862 | DEF_TRAVERSE_DECL(EnumDecl, { |
1863 | TRY_TO(TraverseDeclTemplateParameterLists(D)); |
1864 | |
1865 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1866 | if (auto *TSI = D->getIntegerTypeSourceInfo()) |
1867 | TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); |
1868 | // The enumerators are already traversed by |
1869 | // decls_begin()/decls_end(). |
1870 | }) |
1871 | |
1872 | // Helper methods for RecordDecl and its children. |
1873 | template <typename Derived> |
1874 | bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) { |
1875 | // We shouldn't traverse D->getTypeForDecl(); it's a result of |
1876 | // declaring the type, not something that was written in the source. |
1877 | |
1878 | TRY_TO(TraverseDeclTemplateParameterLists(D)); |
1879 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1880 | return true; |
1881 | } |
1882 | |
1883 | template <typename Derived> |
1884 | bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier( |
1885 | const CXXBaseSpecifier &Base) { |
1886 | TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc())); |
1887 | return true; |
1888 | } |
1889 | |
1890 | template <typename Derived> |
1891 | bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) { |
1892 | if (!TraverseRecordHelper(D)) |
1893 | return false; |
1894 | if (D->isCompleteDefinition()) { |
1895 | for (const auto &I : D->bases()) { |
1896 | TRY_TO(TraverseCXXBaseSpecifier(I)); |
1897 | } |
1898 | // We don't traverse the friends or the conversions, as they are |
1899 | // already in decls_begin()/decls_end(). |
1900 | } |
1901 | return true; |
1902 | } |
1903 | |
1904 | DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); }) |
1905 | |
1906 | DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) |
1907 | |
1908 | #define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND)DEF_TRAVERSE_DECL(TMPLDECLKINDTemplateSpecializationDecl, { if (TypeSourceInfo *TSI = D->getTypeAsWritten()) TRY_TO(TraverseTypeLoc (TSI->getTypeLoc())); TRY_TO(TraverseNestedNameSpecifierLoc (D->getQualifierLoc())); if (!getDerived().shouldVisitTemplateInstantiations () && D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization ) return true; }) \ |
1909 | DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \ |
1910 | /* For implicit instantiations ("set<int> x;"), we don't want to \ |
1911 | recurse at all, since the instatiated template isn't written in \ |
1912 | the source code anywhere. (Note the instatiated *type* -- \ |
1913 | set<int> -- is written, and will still get a callback of \ |
1914 | TemplateSpecializationType). For explicit instantiations \ |
1915 | ("template set<int>;"), we do need a callback, since this \ |
1916 | is the only callback that's made for this instantiation. \ |
1917 | We use getTypeAsWritten() to distinguish. */ \ |
1918 | if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ |
1919 | TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ |
1920 | \ |
1921 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \ |
1922 | if (!getDerived().shouldVisitTemplateInstantiations() && \ |
1923 | D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \ |
1924 | /* Returning from here skips traversing the \ |
1925 | declaration context of the *TemplateSpecializationDecl \ |
1926 | (embedded in the DEF_TRAVERSE_DECL() macro) \ |
1927 | which contains the instantiated members of the template. */ \ |
1928 | return true; \ |
1929 | }) |
1930 | |
1931 | DEF_TRAVERSE_TMPL_SPEC_DECL(Class)DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, { if (TypeSourceInfo *TSI = D->getTypeAsWritten()) TRY_TO(TraverseTypeLoc(TSI-> getTypeLoc())); TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc ())); if (!getDerived().shouldVisitTemplateInstantiations() && D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization ) return true; }) |
1932 | DEF_TRAVERSE_TMPL_SPEC_DECL(Var)DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, { if (TypeSourceInfo *TSI = D->getTypeAsWritten()) TRY_TO(TraverseTypeLoc(TSI-> getTypeLoc())); TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc ())); if (!getDerived().shouldVisitTemplateInstantiations() && D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization ) return true; }) |
1933 | |
1934 | template <typename Derived> |
1935 | bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper( |
1936 | const TemplateArgumentLoc *TAL, unsigned Count) { |
1937 | for (unsigned I = 0; I < Count; ++I) { |
1938 | TRY_TO(TraverseTemplateArgumentLoc(TAL[I])); |
1939 | } |
1940 | return true; |
1941 | } |
1942 | |
1943 | #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND)DEF_TRAVERSE_DECL(TMPLDECLKINDTemplatePartialSpecializationDecl , { if (TemplateParameterList *TPL = D->getTemplateParameters ()) { for (TemplateParameterList::iterator I = TPL->begin( ), E = TPL->end(); I != E; ++I) { TRY_TO(TraverseDecl(*I)) ; } } TRY_TO(TraverseTemplateArgumentLocsHelper( D->getTemplateArgsAsWritten ()->getTemplateArgs(), D->getTemplateArgsAsWritten()-> NumTemplateArgs)); TRY_TO(TraverseDECLKINDHelper(D)); }) \ |
1944 | DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ |
1945 | /* The partial specialization. */ \ |
1946 | if (TemplateParameterList *TPL = D->getTemplateParameters()) { \ |
1947 | for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \ |
1948 | I != E; ++I) { \ |
1949 | TRY_TO(TraverseDecl(*I)); \ |
1950 | } \ |
1951 | } \ |
1952 | /* The args that remains unspecialized. */ \ |
1953 | TRY_TO(TraverseTemplateArgumentLocsHelper( \ |
1954 | D->getTemplateArgsAsWritten()->getTemplateArgs(), \ |
1955 | D->getTemplateArgsAsWritten()->NumTemplateArgs)); \ |
1956 | \ |
1957 | /* Don't need the *TemplatePartialSpecializationHelper, even \ |
1958 | though that's our parent class -- we already visit all the \ |
1959 | template args here. */ \ |
1960 | TRY_TO(Traverse##DECLKIND##Helper(D)); \ |
1961 | \ |
1962 | /* Instantiations will have been visited with the primary template. */ \ |
1963 | }) |
1964 | |
1965 | DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, { if (TemplateParameterList *TPL = D->getTemplateParameters()) { for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); I != E; ++I) { TRY_TO(TraverseDecl(*I)); } } TRY_TO(TraverseTemplateArgumentLocsHelper( D->getTemplateArgsAsWritten ()->getTemplateArgs(), D->getTemplateArgsAsWritten()-> NumTemplateArgs)); TRY_TO(TraverseCXXRecordHelper(D)); }) |
1966 | DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl, { if ( TemplateParameterList *TPL = D->getTemplateParameters()) { for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); I != E; ++I) { TRY_TO(TraverseDecl(*I)); } } TRY_TO (TraverseTemplateArgumentLocsHelper( D->getTemplateArgsAsWritten ()->getTemplateArgs(), D->getTemplateArgsAsWritten()-> NumTemplateArgs)); TRY_TO(TraverseVarHelper(D)); }) |
1967 | |
1968 | DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); }) |
1969 | |
1970 | DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, { |
1971 | // Like UnresolvedUsingTypenameDecl, but without the 'typename': |
1972 | // template <class T> Class A : public Base<T> { using Base<T>::foo; }; |
1973 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1974 | TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); |
1975 | }) |
1976 | |
1977 | DEF_TRAVERSE_DECL(IndirectFieldDecl, {}) |
1978 | |
1979 | template <typename Derived> |
1980 | bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) { |
1981 | TRY_TO(TraverseDeclTemplateParameterLists(D)); |
1982 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
1983 | if (D->getTypeSourceInfo()) |
1984 | TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); |
1985 | else |
1986 | TRY_TO(TraverseType(D->getType())); |
1987 | return true; |
1988 | } |
1989 | |
1990 | DEF_TRAVERSE_DECL(DecompositionDecl, { |
1991 | TRY_TO(TraverseVarHelper(D)); |
1992 | for (auto *Binding : D->bindings()) { |
1993 | TRY_TO(TraverseDecl(Binding)); |
1994 | } |
1995 | }) |
1996 | |
1997 | DEF_TRAVERSE_DECL(BindingDecl, { |
1998 | if (getDerived().shouldVisitImplicitCode()) |
1999 | TRY_TO(TraverseStmt(D->getBinding())); |
2000 | }) |
2001 | |
2002 | DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); }) |
2003 | |
2004 | DEF_TRAVERSE_DECL(MSGuidDecl, {}) |
2005 | |
2006 | DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {}) |
2007 | |
2008 | DEF_TRAVERSE_DECL(FieldDecl, { |
2009 | TRY_TO(TraverseDeclaratorHelper(D)); |
2010 | if (D->isBitField()) |
2011 | TRY_TO(TraverseStmt(D->getBitWidth())); |
2012 | else if (D->hasInClassInitializer()) |
2013 | TRY_TO(TraverseStmt(D->getInClassInitializer())); |
2014 | }) |
2015 | |
2016 | DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, { |
2017 | TRY_TO(TraverseDeclaratorHelper(D)); |
2018 | if (D->isBitField()) |
2019 | TRY_TO(TraverseStmt(D->getBitWidth())); |
2020 | // FIXME: implement the rest. |
2021 | }) |
2022 | |
2023 | DEF_TRAVERSE_DECL(ObjCIvarDecl, { |
2024 | TRY_TO(TraverseDeclaratorHelper(D)); |
2025 | if (D->isBitField()) |
2026 | TRY_TO(TraverseStmt(D->getBitWidth())); |
2027 | // FIXME: implement the rest. |
2028 | }) |
2029 | |
2030 | template <typename Derived> |
2031 | bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { |
2032 | TRY_TO(TraverseDeclTemplateParameterLists(D)); |
2033 | TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); |
2034 | TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); |
2035 | |
2036 | // If we're an explicit template specialization, iterate over the |
2037 | // template args that were explicitly specified. If we were doing |
2038 | // this in typing order, we'd do it between the return type and |
2039 | // the function args, but both are handled by the FunctionTypeLoc |
2040 | // above, so we have to choose one side. I've decided to do before. |
2041 | if (const FunctionTemplateSpecializationInfo *FTSI = |
2042 | D->getTemplateSpecializationInfo()) { |
2043 | if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared && |
2044 | FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) { |
2045 | // A specialization might not have explicit template arguments if it has |
2046 | // a templated return type and concrete arguments. |
2047 | if (const ASTTemplateArgumentListInfo *TALI = |
2048 | FTSI->TemplateArgumentsAsWritten) { |
2049 | TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(), |
2050 | TALI->NumTemplateArgs)); |
2051 | } |
2052 | } |
2053 | } |
2054 | |
2055 | // Visit the function type itself, which can be either |
2056 | // FunctionNoProtoType or FunctionProtoType, or a typedef. This |
2057 | // also covers the return type and the function parameters, |
2058 | // including exception specifications. |
2059 | if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) { |
2060 | TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); |
2061 | } else if (getDerived().shouldVisitImplicitCode()) { |
2062 | // Visit parameter variable declarations of the implicit function |
2063 | // if the traverser is visiting implicit code. Parameter variable |
2064 | // declarations do not have valid TypeSourceInfo, so to visit them |
2065 | // we need to traverse the declarations explicitly. |
2066 | for (ParmVarDecl *Parameter : D->parameters()) { |
2067 | TRY_TO(TraverseDecl(Parameter)); |
2068 | } |
2069 | } |
2070 | |
2071 | // Visit the trailing requires clause, if any. |
2072 | if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) { |
2073 | TRY_TO(TraverseStmt(TrailingRequiresClause)); |
2074 | } |
2075 | |
2076 | if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { |
2077 | // Constructor initializers. |
2078 | for (auto *I : Ctor->inits()) { |
2079 | if (I->isWritten() || getDerived().shouldVisitImplicitCode()) |
2080 | TRY_TO(TraverseConstructorInitializer(I)); |
2081 | } |
2082 | } |
2083 | |
2084 | bool VisitBody = |
2085 | D->isThisDeclarationADefinition() && |
2086 | // Don't visit the function body if the function definition is generated |
2087 | // by clang. |
2088 | (!D->isDefaulted() || getDerived().shouldVisitImplicitCode()); |
2089 | |
2090 | if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { |
2091 | if (const CXXRecordDecl *RD = MD->getParent()) { |
2092 | if (RD->isLambda() && |
2093 | declaresSameEntity(RD->getLambdaCallOperator(), MD)) { |
2094 | VisitBody = VisitBody && getDerived().shouldVisitLambdaBody(); |
2095 | } |
2096 | } |
2097 | } |
2098 | |
2099 | if (VisitBody) { |
2100 | TRY_TO(TraverseStmt(D->getBody())); |
2101 | // Body may contain using declarations whose shadows are parented to the |
2102 | // FunctionDecl itself. |
2103 | for (auto *Child : D->decls()) { |
2104 | if (isa<UsingShadowDecl>(Child)) |
2105 | TRY_TO(TraverseDecl(Child)); |
2106 | } |
2107 | } |
2108 | return true; |
2109 | } |
2110 | |
2111 | DEF_TRAVERSE_DECL(FunctionDecl, { |
2112 | // We skip decls_begin/decls_end, which are already covered by |
2113 | // TraverseFunctionHelper(). |
2114 | ShouldVisitChildren = false; |
2115 | ReturnValue = TraverseFunctionHelper(D); |
2116 | }) |
2117 | |
2118 | DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, { |
2119 | // We skip decls_begin/decls_end, which are already covered by |
2120 | // TraverseFunctionHelper(). |
2121 | ShouldVisitChildren = false; |
2122 | ReturnValue = TraverseFunctionHelper(D); |
2123 | }) |
2124 | |
2125 | DEF_TRAVERSE_DECL(CXXMethodDecl, { |
2126 | // We skip decls_begin/decls_end, which are already covered by |
2127 | // TraverseFunctionHelper(). |
2128 | ShouldVisitChildren = false; |
2129 | ReturnValue = TraverseFunctionHelper(D); |
2130 | }) |
2131 | |
2132 | DEF_TRAVERSE_DECL(CXXConstructorDecl, { |
2133 | // We skip decls_begin/decls_end, which are already covered by |
2134 | // TraverseFunctionHelper(). |
2135 | ShouldVisitChildren = false; |
2136 | ReturnValue = TraverseFunctionHelper(D); |
2137 | }) |
2138 | |
2139 | // CXXConversionDecl is the declaration of a type conversion operator. |
2140 | // It's not a cast expression. |
2141 | DEF_TRAVERSE_DECL(CXXConversionDecl, { |
2142 | // We skip decls_begin/decls_end, which are already covered by |
2143 | // TraverseFunctionHelper(). |
2144 | ShouldVisitChildren = false; |
2145 | ReturnValue = TraverseFunctionHelper(D); |
2146 | }) |
2147 | |
2148 | DEF_TRAVERSE_DECL(CXXDestructorDecl, { |
2149 | // We skip decls_begin/decls_end, which are already covered by |
2150 | // TraverseFunctionHelper(). |
2151 | ShouldVisitChildren = false; |
2152 | ReturnValue = TraverseFunctionHelper(D); |
2153 | }) |
2154 | |
2155 | template <typename Derived> |
2156 | bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) { |
2157 | TRY_TO(TraverseDeclaratorHelper(D)); |
2158 | // Default params are taken care of when we traverse the ParmVarDecl. |
2159 | if (!isa<ParmVarDecl>(D) && |
2160 | (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode())) |
2161 | TRY_TO(TraverseStmt(D->getInit())); |
2162 | return true; |
2163 | } |
2164 | |
2165 | DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); }) |
2166 | |
2167 | DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); }) |
2168 | |
2169 | DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, { |
2170 | // A non-type template parameter, e.g. "S" in template<int S> class Foo ... |
2171 | TRY_TO(TraverseDeclaratorHelper(D)); |
2172 | if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) |
2173 | TRY_TO(TraverseStmt(D->getDefaultArgument())); |
2174 | }) |
2175 | |
2176 | DEF_TRAVERSE_DECL(ParmVarDecl, { |
2177 | TRY_TO(TraverseVarHelper(D)); |
2178 | |
2179 | if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() && |
2180 | !D->hasUnparsedDefaultArg()) |
2181 | TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg())); |
2182 | |
2183 | if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() && |
2184 | !D->hasUnparsedDefaultArg()) |
2185 | TRY_TO(TraverseStmt(D->getDefaultArg())); |
2186 | }) |
2187 | |
2188 | DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {}) |
2189 | |
2190 | #undef DEF_TRAVERSE_DECL |
2191 | |
2192 | // ----------------- Stmt traversal ----------------- |
2193 | // |
2194 | // For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating |
2195 | // over the children defined in children() (every stmt defines these, |
2196 | // though sometimes the range is empty). Each individual Traverse* |
2197 | // method only needs to worry about children other than those. To see |
2198 | // what children() does for a given class, see, e.g., |
2199 | // http://clang.llvm.org/doxygen/Stmt_8cpp_source.html |
2200 | |
2201 | // This macro makes available a variable S, the passed-in stmt. |
2202 | #define DEF_TRAVERSE_STMT(STMT, CODE) \ |
2203 | template <typename Derived> \ |
2204 | bool RecursiveASTVisitor<Derived>::Traverse##STMT( \ |
2205 | STMT *S, DataRecursionQueue *Queue) { \ |
2206 | bool ShouldVisitChildren = true; \ |
2207 | bool ReturnValue = true; \ |
2208 | if (!getDerived().shouldTraversePostOrder()) \ |
2209 | TRY_TO(WalkUpFrom##STMT(S)); \ |
2210 | { CODE; } \ |
2211 | if (ShouldVisitChildren) { \ |
2212 | for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \ |
2213 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt)do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, SubStmt, Queue)) return false; } while (false); \ |
2214 | } \ |
2215 | } \ |
2216 | /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \ |
2217 | * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \ |
2218 | * children, PostVisitStmt will call WalkUpFrom after we are done visiting \ |
2219 | * children. */ \ |
2220 | if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \ |
2221 | TRY_TO(WalkUpFrom##STMT(S)); \ |
2222 | } \ |
2223 | return ReturnValue; \ |
2224 | } |
2225 | |
2226 | DEF_TRAVERSE_STMT(GCCAsmStmt, { |
2227 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getAsmString() , Queue)) return false; } while (false); |
2228 | for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { |
2229 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I))do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getInputConstraintLiteral (I), Queue)) return false; } while (false); |
2230 | } |
2231 | for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) { |
2232 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I))do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getOutputConstraintLiteral (I), Queue)) return false; } while (false); |
2233 | } |
2234 | for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { |
2235 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I))do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getClobberStringLiteral (I), Queue)) return false; } while (false); |
2236 | } |
2237 | // children() iterates over inputExpr and outputExpr. |
2238 | }) |
2239 | |
2240 | DEF_TRAVERSE_STMT( |
2241 | MSAsmStmt, |
2242 | {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once |
2243 | // added this needs to be implemented. |
2244 | }) |
2245 | |
2246 | DEF_TRAVERSE_STMT(CXXCatchStmt, { |
2247 | TRY_TO(TraverseDecl(S->getExceptionDecl())); |
2248 | // children() iterates over the handler block. |
2249 | }) |
2250 | |
2251 | DEF_TRAVERSE_STMT(DeclStmt, { |
2252 | for (auto *I : S->decls()) { |
2253 | TRY_TO(TraverseDecl(I)); |
2254 | } |
2255 | // Suppress the default iteration over children() by |
2256 | // returning. Here's why: A DeclStmt looks like 'type var [= |
2257 | // initializer]'. The decls above already traverse over the |
2258 | // initializers, so we don't have to do it again (which |
2259 | // children() would do). |
2260 | ShouldVisitChildren = false; |
2261 | }) |
2262 | |
2263 | // These non-expr stmts (most of them), do not need any action except |
2264 | // iterating over the children. |
2265 | DEF_TRAVERSE_STMT(BreakStmt, {}) |
2266 | DEF_TRAVERSE_STMT(CXXTryStmt, {}) |
2267 | DEF_TRAVERSE_STMT(CaseStmt, {}) |
2268 | DEF_TRAVERSE_STMT(CompoundStmt, {}) |
2269 | DEF_TRAVERSE_STMT(ContinueStmt, {}) |
2270 | DEF_TRAVERSE_STMT(DefaultStmt, {}) |
2271 | DEF_TRAVERSE_STMT(DoStmt, {}) |
2272 | DEF_TRAVERSE_STMT(ForStmt, {}) |
2273 | DEF_TRAVERSE_STMT(GotoStmt, {}) |
2274 | DEF_TRAVERSE_STMT(IfStmt, {}) |
2275 | DEF_TRAVERSE_STMT(IndirectGotoStmt, {}) |
2276 | DEF_TRAVERSE_STMT(LabelStmt, {}) |
2277 | DEF_TRAVERSE_STMT(AttributedStmt, {}) |
2278 | DEF_TRAVERSE_STMT(NullStmt, {}) |
2279 | DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {}) |
2280 | DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {}) |
2281 | DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {}) |
2282 | DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {}) |
2283 | DEF_TRAVERSE_STMT(ObjCAtTryStmt, {}) |
2284 | DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {}) |
2285 | DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {}) |
2286 | |
2287 | DEF_TRAVERSE_STMT(CXXForRangeStmt, { |
2288 | if (!getDerived().shouldVisitImplicitCode()) { |
2289 | if (S->getInit()) |
2290 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getInit(), Queue )) return false; } while (false); |
2291 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getLoopVarStmt (), Queue)) return false; } while (false); |
2292 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getRangeInit() , Queue)) return false; } while (false); |
2293 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getBody(), Queue )) return false; } while (false); |
2294 | // Visit everything else only if shouldVisitImplicitCode(). |
2295 | ShouldVisitChildren = false; |
2296 | } |
2297 | }) |
2298 | |
2299 | DEF_TRAVERSE_STMT(MSDependentExistsStmt, { |
2300 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2301 | TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); |
2302 | }) |
2303 | |
2304 | DEF_TRAVERSE_STMT(ReturnStmt, {}) |
2305 | DEF_TRAVERSE_STMT(SwitchStmt, {}) |
2306 | DEF_TRAVERSE_STMT(WhileStmt, {}) |
2307 | |
2308 | DEF_TRAVERSE_STMT(ConstantExpr, {}) |
2309 | |
2310 | DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { |
2311 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2312 | TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo())); |
2313 | if (S->hasExplicitTemplateArgs()) { |
2314 | TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), |
2315 | S->getNumTemplateArgs())); |
2316 | } |
2317 | }) |
2318 | |
2319 | DEF_TRAVERSE_STMT(DeclRefExpr, { |
2320 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2321 | TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); |
2322 | TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), |
2323 | S->getNumTemplateArgs())); |
2324 | }) |
2325 | |
2326 | DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, { |
2327 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2328 | TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); |
2329 | if (S->hasExplicitTemplateArgs()) { |
2330 | TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), |
2331 | S->getNumTemplateArgs())); |
2332 | } |
2333 | }) |
2334 | |
2335 | DEF_TRAVERSE_STMT(MemberExpr, { |
2336 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2337 | TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo())); |
2338 | TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), |
2339 | S->getNumTemplateArgs())); |
2340 | }) |
2341 | |
2342 | DEF_TRAVERSE_STMT( |
2343 | ImplicitCastExpr, |
2344 | {// We don't traverse the cast type, as it's not written in the |
2345 | // source code. |
2346 | }) |
2347 | |
2348 | DEF_TRAVERSE_STMT(CStyleCastExpr, { |
2349 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2350 | }) |
2351 | |
2352 | DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, { |
2353 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2354 | }) |
2355 | |
2356 | DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, { |
2357 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2358 | }) |
2359 | |
2360 | DEF_TRAVERSE_STMT(CXXConstCastExpr, { |
2361 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2362 | }) |
2363 | |
2364 | DEF_TRAVERSE_STMT(CXXDynamicCastExpr, { |
2365 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2366 | }) |
2367 | |
2368 | DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, { |
2369 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2370 | }) |
2371 | |
2372 | DEF_TRAVERSE_STMT(CXXStaticCastExpr, { |
2373 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2374 | }) |
2375 | |
2376 | DEF_TRAVERSE_STMT(BuiltinBitCastExpr, { |
2377 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2378 | }) |
2379 | |
2380 | template <typename Derived> |
2381 | bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr( |
2382 | InitListExpr *S, DataRecursionQueue *Queue) { |
2383 | if (S) { |
2384 | // Skip this if we traverse postorder. We will visit it later |
2385 | // in PostVisitStmt. |
2386 | if (!getDerived().shouldTraversePostOrder()) |
2387 | TRY_TO(WalkUpFromInitListExpr(S)); |
2388 | |
2389 | // All we need are the default actions. FIXME: use a helper function. |
2390 | for (Stmt *SubStmt : S->children()) { |
2391 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt)do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, SubStmt, Queue)) return false; } while (false); |
2392 | } |
2393 | |
2394 | if (!Queue && getDerived().shouldTraversePostOrder()) |
2395 | TRY_TO(WalkUpFromInitListExpr(S)); |
2396 | } |
2397 | return true; |
2398 | } |
2399 | |
2400 | template<typename Derived> |
2401 | bool RecursiveASTVisitor<Derived>::TraverseConceptReference( |
2402 | const ConceptReference &C) { |
2403 | TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc())); |
2404 | TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo())); |
2405 | if (C.hasExplicitTemplateArgs()) |
2406 | TRY_TO(TraverseTemplateArgumentLocsHelper( |
2407 | C.getTemplateArgsAsWritten()->getTemplateArgs(), |
2408 | C.getTemplateArgsAsWritten()->NumTemplateArgs)); |
2409 | return true; |
2410 | } |
2411 | |
2412 | // If shouldVisitImplicitCode() returns false, this method traverses only the |
2413 | // syntactic form of InitListExpr. |
2414 | // If shouldVisitImplicitCode() return true, this method is called once for |
2415 | // each pair of syntactic and semantic InitListExpr, and it traverses the |
2416 | // subtrees defined by the two forms. This may cause some of the children to be |
2417 | // visited twice, if they appear both in the syntactic and the semantic form. |
2418 | // |
2419 | // There is no guarantee about which form \p S takes when this method is called. |
2420 | template <typename Derived> |
2421 | bool RecursiveASTVisitor<Derived>::TraverseInitListExpr( |
2422 | InitListExpr *S, DataRecursionQueue *Queue) { |
2423 | if (S->isSemanticForm() && S->isSyntacticForm()) { |
2424 | // `S` does not have alternative forms, traverse only once. |
2425 | TRY_TO(TraverseSynOrSemInitListExpr(S, Queue)); |
2426 | return true; |
2427 | } |
2428 | TRY_TO(TraverseSynOrSemInitListExpr( |
2429 | S->isSemanticForm() ? S->getSyntacticForm() : S, Queue)); |
2430 | if (getDerived().shouldVisitImplicitCode()) { |
2431 | // Only visit the semantic form if the clients are interested in implicit |
2432 | // compiler-generated. |
2433 | TRY_TO(TraverseSynOrSemInitListExpr( |
2434 | S->isSemanticForm() ? S : S->getSemanticForm(), Queue)); |
2435 | } |
2436 | return true; |
2437 | } |
2438 | |
2439 | // GenericSelectionExpr is a special case because the types and expressions |
2440 | // are interleaved. We also need to watch out for null types (default |
2441 | // generic associations). |
2442 | DEF_TRAVERSE_STMT(GenericSelectionExpr, { |
2443 | TRY_TO(TraverseStmt(S->getControllingExpr())); |
2444 | for (const GenericSelectionExpr::Association Assoc : S->associations()) { |
2445 | if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo()) |
2446 | TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); |
2447 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, Assoc.getAssociationExpr (), Queue)) return false; } while (false); |
2448 | } |
2449 | ShouldVisitChildren = false; |
2450 | }) |
2451 | |
2452 | // PseudoObjectExpr is a special case because of the weirdness with |
2453 | // syntactic expressions and opaque values. |
2454 | DEF_TRAVERSE_STMT(PseudoObjectExpr, { |
2455 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getSyntacticForm (), Queue)) return false; } while (false); |
2456 | for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(), |
2457 | e = S->semantics_end(); |
2458 | i != e; ++i) { |
2459 | Expr *sub = *i; |
2460 | if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub)) |
2461 | sub = OVE->getSourceExpr(); |
2462 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub)do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, sub, Queue)) return false ; } while (false); |
2463 | } |
2464 | ShouldVisitChildren = false; |
2465 | }) |
2466 | |
2467 | DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { |
2468 | // This is called for code like 'return T()' where T is a built-in |
2469 | // (i.e. non-class) type. |
2470 | TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); |
2471 | }) |
2472 | |
2473 | DEF_TRAVERSE_STMT(CXXNewExpr, { |
2474 | // The child-iterator will pick up the other arguments. |
2475 | TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc())); |
2476 | }) |
2477 | |
2478 | DEF_TRAVERSE_STMT(OffsetOfExpr, { |
2479 | // The child-iterator will pick up the expression representing |
2480 | // the field. |
2481 | // FIMXE: for code like offsetof(Foo, a.b.c), should we get |
2482 | // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c? |
2483 | TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); |
2484 | }) |
2485 | |
2486 | DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, { |
2487 | // The child-iterator will pick up the arg if it's an expression, |
2488 | // but not if it's a type. |
2489 | if (S->isArgumentType()) |
2490 | TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc())); |
2491 | }) |
2492 | |
2493 | DEF_TRAVERSE_STMT(CXXTypeidExpr, { |
2494 | // The child-iterator will pick up the arg if it's an expression, |
2495 | // but not if it's a type. |
2496 | if (S->isTypeOperand()) |
2497 | TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); |
2498 | }) |
2499 | |
2500 | DEF_TRAVERSE_STMT(MSPropertyRefExpr, { |
2501 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2502 | }) |
2503 | |
2504 | DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {}) |
2505 | |
2506 | DEF_TRAVERSE_STMT(CXXUuidofExpr, { |
2507 | // The child-iterator will pick up the arg if it's an expression, |
2508 | // but not if it's a type. |
2509 | if (S->isTypeOperand()) |
2510 | TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); |
2511 | }) |
2512 | |
2513 | DEF_TRAVERSE_STMT(TypeTraitExpr, { |
2514 | for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I) |
2515 | TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc())); |
2516 | }) |
2517 | |
2518 | DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, { |
2519 | TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc())); |
2520 | }) |
2521 | |
2522 | DEF_TRAVERSE_STMT(ExpressionTraitExpr, |
2523 | { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getQueriedExpression (), Queue)) return false; } while (false); }) |
2524 | |
2525 | DEF_TRAVERSE_STMT(VAArgExpr, { |
2526 | // The child-iterator will pick up the expression argument. |
2527 | TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc())); |
2528 | }) |
2529 | |
2530 | DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { |
2531 | // This is called for code like 'return T()' where T is a class type. |
2532 | TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); |
2533 | }) |
2534 | |
2535 | // Walk only the visible parts of lambda expressions. |
2536 | DEF_TRAVERSE_STMT(LambdaExpr, { |
2537 | // Visit the capture list. |
2538 | for (unsigned I = 0, N = S->capture_size(); I != N; ++I) { |
2539 | const LambdaCapture *C = S->capture_begin() + I; |
2540 | if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) { |
2541 | TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I])); |
2542 | } |
2543 | } |
2544 | |
2545 | if (getDerived().shouldVisitImplicitCode()) { |
2546 | // The implicit model is simple: everything else is in the lambda class. |
2547 | TRY_TO(TraverseDecl(S->getLambdaClass())); |
2548 | } else { |
2549 | // We need to poke around to find the bits that might be explicitly written. |
2550 | TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); |
2551 | FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>(); |
2552 | |
2553 | TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList())); |
2554 | if (S->hasExplicitParameters()) { |
2555 | // Visit parameters. |
2556 | for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) |
2557 | TRY_TO(TraverseDecl(Proto.getParam(I))); |
2558 | } |
2559 | |
2560 | auto *T = Proto.getTypePtr(); |
2561 | for (const auto &E : T->exceptions()) |
2562 | TRY_TO(TraverseType(E)); |
2563 | |
2564 | if (Expr *NE = T->getNoexceptExpr()) |
2565 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE)do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, NE, Queue)) return false ; } while (false); |
2566 | |
2567 | if (S->hasExplicitResultType()) |
2568 | TRY_TO(TraverseTypeLoc(Proto.getReturnLoc())); |
2569 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getTrailingRequiresClause())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getTrailingRequiresClause (), Queue)) return false; } while (false); |
2570 | |
2571 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getBody(), Queue )) return false; } while (false); |
2572 | } |
2573 | ShouldVisitChildren = false; |
2574 | }) |
2575 | |
2576 | DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { |
2577 | // This is called for code like 'T()', where T is a template argument. |
2578 | TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); |
2579 | }) |
2580 | |
2581 | // These expressions all might take explicit template arguments. |
2582 | // We traverse those if so. FIXME: implement these. |
2583 | DEF_TRAVERSE_STMT(CXXConstructExpr, {}) |
2584 | DEF_TRAVERSE_STMT(CallExpr, {}) |
2585 | DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) |
2586 | |
2587 | // These exprs (most of them), do not need any action except iterating |
2588 | // over the children. |
2589 | DEF_TRAVERSE_STMT(AddrLabelExpr, {}) |
2590 | DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) |
2591 | DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {}) |
2592 | DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) |
2593 | DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) |
2594 | DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) |
2595 | |
2596 | DEF_TRAVERSE_STMT(BlockExpr, { |
2597 | TRY_TO(TraverseDecl(S->getBlockDecl())); |
2598 | return true; // no child statements to loop through. |
2599 | }) |
2600 | |
2601 | DEF_TRAVERSE_STMT(ChooseExpr, {}) |
2602 | DEF_TRAVERSE_STMT(CompoundLiteralExpr, { |
2603 | TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); |
2604 | }) |
2605 | DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {}) |
2606 | DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {}) |
2607 | |
2608 | DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { |
2609 | if (getDerived().shouldVisitImplicitCode()) |
2610 | TRY_TO(TraverseStmt(S->getExpr())); |
2611 | }) |
2612 | |
2613 | DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {}) |
2614 | DEF_TRAVERSE_STMT(CXXDeleteExpr, {}) |
2615 | DEF_TRAVERSE_STMT(ExprWithCleanups, {}) |
2616 | DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {}) |
2617 | DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {}) |
2618 | DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {}) |
2619 | |
2620 | DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { |
2621 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2622 | if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo()) |
2623 | TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc())); |
2624 | if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo()) |
2625 | TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc())); |
2626 | }) |
2627 | |
2628 | DEF_TRAVERSE_STMT(CXXThisExpr, {}) |
2629 | DEF_TRAVERSE_STMT(CXXThrowExpr, {}) |
2630 | DEF_TRAVERSE_STMT(UserDefinedLiteral, {}) |
2631 | DEF_TRAVERSE_STMT(DesignatedInitExpr, {}) |
2632 | DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {}) |
2633 | DEF_TRAVERSE_STMT(ExtVectorElementExpr, {}) |
2634 | DEF_TRAVERSE_STMT(GNUNullExpr, {}) |
2635 | DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {}) |
2636 | DEF_TRAVERSE_STMT(NoInitExpr, {}) |
2637 | DEF_TRAVERSE_STMT(ArrayInitLoopExpr, { |
2638 | // FIXME: The source expression of the OVE should be listed as |
2639 | // a child of the ArrayInitLoopExpr. |
2640 | if (OpaqueValueExpr *OVE = S->getCommonExpr()) |
2641 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, OVE->getSourceExpr (), Queue)) return false; } while (false); |
2642 | }) |
2643 | DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {}) |
2644 | DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {}) |
2645 | |
2646 | DEF_TRAVERSE_STMT(ObjCEncodeExpr, { |
2647 | if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo()) |
2648 | TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); |
2649 | }) |
2650 | |
2651 | DEF_TRAVERSE_STMT(ObjCIsaExpr, {}) |
2652 | DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {}) |
2653 | |
2654 | DEF_TRAVERSE_STMT(ObjCMessageExpr, { |
2655 | if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo()) |
2656 | TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); |
2657 | }) |
2658 | |
2659 | DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { |
2660 | if (S->isClassReceiver()) { |
2661 | ObjCInterfaceDecl *IDecl = S->getClassReceiver(); |
2662 | QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl); |
2663 | ObjCInterfaceLocInfo Data; |
2664 | Data.NameLoc = S->getReceiverLocation(); |
2665 | Data.NameEndLoc = Data.NameLoc; |
2666 | TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data))); |
2667 | } |
2668 | }) |
2669 | DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {}) |
2670 | DEF_TRAVERSE_STMT(ObjCProtocolExpr, {}) |
2671 | DEF_TRAVERSE_STMT(ObjCSelectorExpr, {}) |
2672 | DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {}) |
2673 | |
2674 | DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, { |
2675 | TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); |
2676 | }) |
2677 | |
2678 | DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {}) |
2679 | DEF_TRAVERSE_STMT(ParenExpr, {}) |
2680 | DEF_TRAVERSE_STMT(ParenListExpr, {}) |
2681 | DEF_TRAVERSE_STMT(SYCLUniqueStableNameExpr, { |
2682 | TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); |
2683 | }) |
2684 | DEF_TRAVERSE_STMT(PredefinedExpr, {}) |
2685 | DEF_TRAVERSE_STMT(ShuffleVectorExpr, {}) |
2686 | DEF_TRAVERSE_STMT(ConvertVectorExpr, {}) |
2687 | DEF_TRAVERSE_STMT(StmtExpr, {}) |
2688 | DEF_TRAVERSE_STMT(SourceLocExpr, {}) |
2689 | |
2690 | DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { |
2691 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2692 | if (S->hasExplicitTemplateArgs()) { |
2693 | TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), |
2694 | S->getNumTemplateArgs())); |
2695 | } |
2696 | }) |
2697 | |
2698 | DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { |
2699 | TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); |
2700 | if (S->hasExplicitTemplateArgs()) { |
2701 | TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), |
2702 | S->getNumTemplateArgs())); |
2703 | } |
2704 | }) |
2705 | |
2706 | DEF_TRAVERSE_STMT(SEHTryStmt, {}) |
2707 | DEF_TRAVERSE_STMT(SEHExceptStmt, {}) |
2708 | DEF_TRAVERSE_STMT(SEHFinallyStmt, {}) |
2709 | DEF_TRAVERSE_STMT(SEHLeaveStmt, {}) |
2710 | DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); }) |
2711 | |
2712 | DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {}) |
2713 | DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, { |
2714 | if (!getDerived().shouldVisitImplicitCode()) { |
2715 | CXXRewrittenBinaryOperator::DecomposedForm Decomposed = |
2716 | S->getDecomposedForm(); |
2717 | TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS))); |
2718 | TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS))); |
2719 | ShouldVisitChildren = false; |
2720 | } |
2721 | }) |
2722 | DEF_TRAVERSE_STMT(OpaqueValueExpr, {}) |
2723 | DEF_TRAVERSE_STMT(TypoExpr, {}) |
2724 | DEF_TRAVERSE_STMT(RecoveryExpr, {}) |
2725 | DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {}) |
2726 | |
2727 | // These operators (all of them) do not need any action except |
2728 | // iterating over the children. |
2729 | DEF_TRAVERSE_STMT(BinaryConditionalOperator, {}) |
2730 | DEF_TRAVERSE_STMT(ConditionalOperator, {}) |
2731 | DEF_TRAVERSE_STMT(UnaryOperator, {}) |
2732 | DEF_TRAVERSE_STMT(BinaryOperator, {}) |
2733 | DEF_TRAVERSE_STMT(CompoundAssignOperator, {}) |
2734 | DEF_TRAVERSE_STMT(CXXNoexceptExpr, {}) |
2735 | DEF_TRAVERSE_STMT(PackExpansionExpr, {}) |
2736 | DEF_TRAVERSE_STMT(SizeOfPackExpr, {}) |
2737 | DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {}) |
2738 | DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {}) |
2739 | DEF_TRAVERSE_STMT(FunctionParmPackExpr, {}) |
2740 | DEF_TRAVERSE_STMT(CXXFoldExpr, {}) |
2741 | DEF_TRAVERSE_STMT(AtomicExpr, {}) |
2742 | |
2743 | DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { |
2744 | if (S->getLifetimeExtendedTemporaryDecl()) { |
2745 | TRY_TO(TraverseLifetimeExtendedTemporaryDecl( |
2746 | S->getLifetimeExtendedTemporaryDecl())); |
2747 | ShouldVisitChildren = false; |
2748 | } |
2749 | }) |
2750 | // For coroutines expressions, traverse either the operand |
2751 | // as written or the implied calls, depending on what the |
2752 | // derived class requests. |
2753 | DEF_TRAVERSE_STMT(CoroutineBodyStmt, { |
2754 | if (!getDerived().shouldVisitImplicitCode()) { |
2755 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getBody(), Queue )) return false; } while (false); |
2756 | ShouldVisitChildren = false; |
2757 | } |
2758 | }) |
2759 | DEF_TRAVERSE_STMT(CoreturnStmt, { |
2760 | if (!getDerived().shouldVisitImplicitCode()) { |
2761 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getOperand(), Queue )) return false; } while (false); |
2762 | ShouldVisitChildren = false; |
2763 | } |
2764 | }) |
2765 | DEF_TRAVERSE_STMT(CoawaitExpr, { |
2766 | if (!getDerived().shouldVisitImplicitCode()) { |
2767 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getOperand(), Queue )) return false; } while (false); |
2768 | ShouldVisitChildren = false; |
2769 | } |
2770 | }) |
2771 | DEF_TRAVERSE_STMT(DependentCoawaitExpr, { |
2772 | if (!getDerived().shouldVisitImplicitCode()) { |
2773 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getOperand(), Queue )) return false; } while (false); |
2774 | ShouldVisitChildren = false; |
2775 | } |
2776 | }) |
2777 | DEF_TRAVERSE_STMT(CoyieldExpr, { |
2778 | if (!getDerived().shouldVisitImplicitCode()) { |
2779 | TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand())do { if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S->getOperand(), Queue )) return false; } while (false); |
2780 | ShouldVisitChildren = false; |
2781 | } |
2782 | }) |
2783 | |
2784 | DEF_TRAVERSE_STMT(ConceptSpecializationExpr, { |
2785 | TRY_TO(TraverseConceptReference(*S)); |
2786 | }) |
2787 | |
2788 | DEF_TRAVERSE_STMT(RequiresExpr, { |
2789 | TRY_TO(TraverseDecl(S->getBody())); |
2790 | for (ParmVarDecl *Parm : S->getLocalParameters()) |
2791 | TRY_TO(TraverseDecl(Parm)); |
2792 | for (concepts::Requirement *Req : S->getRequirements()) |
2793 | if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) { |
2794 | if (!TypeReq->isSubstitutionFailure()) |
2795 | TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc())); |
2796 | } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) { |
2797 | if (!ExprReq->isExprSubstitutionFailure()) |
2798 | TRY_TO(TraverseStmt(ExprReq->getExpr())); |
2799 | auto &RetReq = ExprReq->getReturnTypeRequirement(); |
2800 | if (RetReq.isTypeConstraint()) |
2801 | TRY_TO(TraverseTemplateParameterListHelper( |
2802 | RetReq.getTypeConstraintTemplateParameterList())); |
2803 | } else { |
2804 | auto *NestedReq = cast<concepts::NestedRequirement>(Req); |
2805 | if (!NestedReq->isSubstitutionFailure()) |
2806 | TRY_TO(TraverseStmt(NestedReq->getConstraintExpr())); |
2807 | } |
2808 | }) |
2809 | |
2810 | // These literals (all of them) do not need any action. |
2811 | DEF_TRAVERSE_STMT(IntegerLiteral, {}) |
2812 | DEF_TRAVERSE_STMT(FixedPointLiteral, {}) |
2813 | DEF_TRAVERSE_STMT(CharacterLiteral, {}) |
2814 | DEF_TRAVERSE_STMT(FloatingLiteral, {}) |
2815 | DEF_TRAVERSE_STMT(ImaginaryLiteral, {}) |
2816 | DEF_TRAVERSE_STMT(StringLiteral, {}) |
2817 | DEF_TRAVERSE_STMT(ObjCStringLiteral, {}) |
2818 | DEF_TRAVERSE_STMT(ObjCBoxedExpr, {}) |
2819 | DEF_TRAVERSE_STMT(ObjCArrayLiteral, {}) |
2820 | DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {}) |
2821 | |
2822 | // Traverse OpenCL: AsType, Convert. |
2823 | DEF_TRAVERSE_STMT(AsTypeExpr, {}) |
2824 | |
2825 | // OpenMP directives. |
2826 | template <typename Derived> |
2827 | bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective( |
2828 | OMPExecutableDirective *S) { |
2829 | for (auto *C : S->clauses()) { |
2830 | TRY_TO(TraverseOMPClause(C)); |
2831 | } |
2832 | return true; |
2833 | } |
2834 | |
2835 | DEF_TRAVERSE_STMT(OMPCanonicalLoop, { |
2836 | if (!getDerived().shouldVisitImplicitCode()) { |
2837 | // Visit only the syntactical loop. |
2838 | TRY_TO(TraverseStmt(S->getLoopStmt())); |
2839 | ShouldVisitChildren = false; |
2840 | } |
2841 | }) |
2842 | |
2843 | template <typename Derived> |
2844 | bool |
2845 | RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) { |
2846 | return TraverseOMPExecutableDirective(S); |
2847 | } |
2848 | |
2849 | DEF_TRAVERSE_STMT(OMPMetaDirective, |
2850 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2851 | |
2852 | DEF_TRAVERSE_STMT(OMPParallelDirective, |
2853 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2854 | |
2855 | DEF_TRAVERSE_STMT(OMPSimdDirective, |
2856 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2857 | |
2858 | DEF_TRAVERSE_STMT(OMPTileDirective, |
2859 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2860 | |
2861 | DEF_TRAVERSE_STMT(OMPUnrollDirective, |
2862 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2863 | |
2864 | DEF_TRAVERSE_STMT(OMPForDirective, |
2865 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2866 | |
2867 | DEF_TRAVERSE_STMT(OMPForSimdDirective, |
2868 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2869 | |
2870 | DEF_TRAVERSE_STMT(OMPSectionsDirective, |
2871 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2872 | |
2873 | DEF_TRAVERSE_STMT(OMPSectionDirective, |
2874 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2875 | |
2876 | DEF_TRAVERSE_STMT(OMPSingleDirective, |
2877 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2878 | |
2879 | DEF_TRAVERSE_STMT(OMPMasterDirective, |
2880 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2881 | |
2882 | DEF_TRAVERSE_STMT(OMPCriticalDirective, { |
2883 | TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName())); |
2884 | TRY_TO(TraverseOMPExecutableDirective(S)); |
2885 | }) |
2886 | |
2887 | DEF_TRAVERSE_STMT(OMPParallelForDirective, |
2888 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2889 | |
2890 | DEF_TRAVERSE_STMT(OMPParallelForSimdDirective, |
2891 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2892 | |
2893 | DEF_TRAVERSE_STMT(OMPParallelMasterDirective, |
2894 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2895 | |
2896 | DEF_TRAVERSE_STMT(OMPParallelSectionsDirective, |
2897 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2898 | |
2899 | DEF_TRAVERSE_STMT(OMPTaskDirective, |
2900 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2901 | |
2902 | DEF_TRAVERSE_STMT(OMPTaskyieldDirective, |
2903 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2904 | |
2905 | DEF_TRAVERSE_STMT(OMPBarrierDirective, |
2906 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2907 | |
2908 | DEF_TRAVERSE_STMT(OMPTaskwaitDirective, |
2909 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2910 | |
2911 | DEF_TRAVERSE_STMT(OMPTaskgroupDirective, |
2912 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2913 | |
2914 | DEF_TRAVERSE_STMT(OMPCancellationPointDirective, |
2915 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2916 | |
2917 | DEF_TRAVERSE_STMT(OMPCancelDirective, |
2918 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2919 | |
2920 | DEF_TRAVERSE_STMT(OMPFlushDirective, |
2921 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2922 | |
2923 | DEF_TRAVERSE_STMT(OMPDepobjDirective, |
2924 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2925 | |
2926 | DEF_TRAVERSE_STMT(OMPScanDirective, |
2927 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2928 | |
2929 | DEF_TRAVERSE_STMT(OMPOrderedDirective, |
2930 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2931 | |
2932 | DEF_TRAVERSE_STMT(OMPAtomicDirective, |
2933 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2934 | |
2935 | DEF_TRAVERSE_STMT(OMPTargetDirective, |
2936 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2937 | |
2938 | DEF_TRAVERSE_STMT(OMPTargetDataDirective, |
2939 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2940 | |
2941 | DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective, |
2942 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2943 | |
2944 | DEF_TRAVERSE_STMT(OMPTargetExitDataDirective, |
2945 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2946 | |
2947 | DEF_TRAVERSE_STMT(OMPTargetParallelDirective, |
2948 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2949 | |
2950 | DEF_TRAVERSE_STMT(OMPTargetParallelForDirective, |
2951 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2952 | |
2953 | DEF_TRAVERSE_STMT(OMPTeamsDirective, |
2954 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2955 | |
2956 | DEF_TRAVERSE_STMT(OMPTargetUpdateDirective, |
2957 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2958 | |
2959 | DEF_TRAVERSE_STMT(OMPTaskLoopDirective, |
2960 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2961 | |
2962 | DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective, |
2963 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2964 | |
2965 | DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective, |
2966 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2967 | |
2968 | DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective, |
2969 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2970 | |
2971 | DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective, |
2972 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2973 | |
2974 | DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective, |
2975 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2976 | |
2977 | DEF_TRAVERSE_STMT(OMPDistributeDirective, |
2978 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2979 | |
2980 | DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective, |
2981 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2982 | |
2983 | DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective, |
2984 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2985 | |
2986 | DEF_TRAVERSE_STMT(OMPDistributeSimdDirective, |
2987 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2988 | |
2989 | DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective, |
2990 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2991 | |
2992 | DEF_TRAVERSE_STMT(OMPTargetSimdDirective, |
2993 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2994 | |
2995 | DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective, |
2996 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
2997 | |
2998 | DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective, |
2999 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3000 | |
3001 | DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective, |
3002 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3003 | |
3004 | DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective, |
3005 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3006 | |
3007 | DEF_TRAVERSE_STMT(OMPTargetTeamsDirective, |
3008 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3009 | |
3010 | DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective, |
3011 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3012 | |
3013 | DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective, |
3014 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3015 | |
3016 | DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective, |
3017 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3018 | |
3019 | DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective, |
3020 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3021 | |
3022 | DEF_TRAVERSE_STMT(OMPInteropDirective, |
3023 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3024 | |
3025 | DEF_TRAVERSE_STMT(OMPDispatchDirective, |
3026 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3027 | |
3028 | DEF_TRAVERSE_STMT(OMPMaskedDirective, |
3029 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3030 | |
3031 | DEF_TRAVERSE_STMT(OMPGenericLoopDirective, |
3032 | { TRY_TO(TraverseOMPExecutableDirective(S)); }) |
3033 | |
3034 | // OpenMP clauses. |
3035 | template <typename Derived> |
3036 | bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { |
3037 | if (!C) |
3038 | return true; |
3039 | switch (C->getClauseKind()) { |
3040 | #define GEN_CLANG_CLAUSE_CLASS |
3041 | #define CLAUSE_CLASS(Enum, Str, Class) \ |
3042 | case llvm::omp::Clause::Enum: \ |
3043 | TRY_TO(Visit##Class(static_cast<Class *>(C))); \ |
3044 | break; |
3045 | #define CLAUSE_NO_CLASS(Enum, Str) \ |
3046 | case llvm::omp::Clause::Enum: \ |
3047 | break; |
3048 | #include "llvm/Frontend/OpenMP/OMP.inc" |
3049 | } |
3050 | return true; |
3051 | } |
3052 | |
3053 | template <typename Derived> |
3054 | bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit( |
3055 | OMPClauseWithPreInit *Node) { |
3056 | TRY_TO(TraverseStmt(Node->getPreInitStmt())); |
3057 | return true; |
3058 | } |
3059 | |
3060 | template <typename Derived> |
3061 | bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate( |
3062 | OMPClauseWithPostUpdate *Node) { |
3063 | TRY_TO(VisitOMPClauseWithPreInit(Node)); |
3064 | TRY_TO(TraverseStmt(Node->getPostUpdateExpr())); |
3065 | return true; |
3066 | } |
3067 | |
3068 | template <typename Derived> |
3069 | bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause( |
3070 | OMPAllocatorClause *C) { |
3071 | TRY_TO(TraverseStmt(C->getAllocator())); |
3072 | return true; |
3073 | } |
3074 | |
3075 | template <typename Derived> |
3076 | bool RecursiveASTVisitor<Derived>::VisitOMPAllocateClause(OMPAllocateClause *C) { |
3077 | TRY_TO(TraverseStmt(C->getAllocator())); |
3078 | TRY_TO(VisitOMPClauseList(C)); |
3079 | return true; |
3080 | } |
3081 | |
3082 | template <typename Derived> |
3083 | bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) { |
3084 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3085 | TRY_TO(TraverseStmt(C->getCondition())); |
3086 | return true; |
3087 | } |
3088 | |
3089 | template <typename Derived> |
3090 | bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) { |
3091 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3092 | TRY_TO(TraverseStmt(C->getCondition())); |
3093 | return true; |
3094 | } |
3095 | |
3096 | template <typename Derived> |
3097 | bool |
3098 | RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) { |
3099 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3100 | TRY_TO(TraverseStmt(C->getNumThreads())); |
3101 | return true; |
3102 | } |
3103 | |
3104 | template <typename Derived> |
3105 | bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) { |
3106 | TRY_TO(TraverseStmt(C->getAlignment())); |
3107 | return true; |
3108 | } |
3109 | |
3110 | template <typename Derived> |
3111 | bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) { |
3112 | TRY_TO(TraverseStmt(C->getSafelen())); |
3113 | return true; |
3114 | } |
3115 | |
3116 | template <typename Derived> |
3117 | bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) { |
3118 | TRY_TO(TraverseStmt(C->getSimdlen())); |
3119 | return true; |
3120 | } |
3121 | |
3122 | template <typename Derived> |
3123 | bool RecursiveASTVisitor<Derived>::VisitOMPSizesClause(OMPSizesClause *C) { |
3124 | for (Expr *E : C->getSizesRefs()) |
3125 | TRY_TO(TraverseStmt(E)); |
3126 | return true; |
3127 | } |
3128 | |
3129 | template <typename Derived> |
3130 | bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) { |
3131 | return true; |
3132 | } |
3133 | |
3134 | template <typename Derived> |
3135 | bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) { |
3136 | TRY_TO(TraverseStmt(C->getFactor())); |
3137 | return true; |
3138 | } |
3139 | |
3140 | template <typename Derived> |
3141 | bool |
3142 | RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) { |
3143 | TRY_TO(TraverseStmt(C->getNumForLoops())); |
3144 | return true; |
3145 | } |
3146 | |
3147 | template <typename Derived> |
3148 | bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) { |
3149 | return true; |
3150 | } |
3151 | |
3152 | template <typename Derived> |
3153 | bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) { |
3154 | return true; |
3155 | } |
3156 | |
3157 | template <typename Derived> |
3158 | bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause( |
3159 | OMPUnifiedAddressClause *) { |
3160 | return true; |
3161 | } |
3162 | |
3163 | template <typename Derived> |
3164 | bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedSharedMemoryClause( |
3165 | OMPUnifiedSharedMemoryClause *) { |
3166 | return true; |
3167 | } |
3168 | |
3169 | template <typename Derived> |
3170 | bool RecursiveASTVisitor<Derived>::VisitOMPReverseOffloadClause( |
3171 | OMPReverseOffloadClause *) { |
3172 | return true; |
3173 | } |
3174 | |
3175 | template <typename Derived> |
3176 | bool RecursiveASTVisitor<Derived>::VisitOMPDynamicAllocatorsClause( |
3177 | OMPDynamicAllocatorsClause *) { |
3178 | return true; |
3179 | } |
3180 | |
3181 | template <typename Derived> |
3182 | bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause( |
3183 | OMPAtomicDefaultMemOrderClause *) { |
3184 | return true; |
3185 | } |
3186 | |
3187 | template <typename Derived> |
3188 | bool |
3189 | RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { |
3190 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3191 | TRY_TO(TraverseStmt(C->getChunkSize())); |
3192 | return true; |
3193 | } |
3194 | |
3195 | template <typename Derived> |
3196 | bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) { |
3197 | TRY_TO(TraverseStmt(C->getNumForLoops())); |
3198 | return true; |
3199 | } |
3200 | |
3201 | template <typename Derived> |
3202 | bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) { |
3203 | return true; |
3204 | } |
3205 | |
3206 | template <typename Derived> |
3207 | bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) { |
3208 | return true; |
3209 | } |
3210 | |
3211 | template <typename Derived> |
3212 | bool |
3213 | RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) { |
3214 | return true; |
3215 | } |
3216 | |
3217 | template <typename Derived> |
3218 | bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) { |
3219 | return true; |
3220 | } |
3221 | |
3222 | template <typename Derived> |
3223 | bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) { |
3224 | return true; |
3225 | } |
3226 | |
3227 | template <typename Derived> |
3228 | bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) { |
3229 | return true; |
3230 | } |
3231 | |
3232 | template <typename Derived> |
3233 | bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) { |
3234 | return true; |
3235 | } |
3236 | |
3237 | template <typename Derived> |
3238 | bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) { |
3239 | return true; |
3240 | } |
3241 | |
3242 | template <typename Derived> |
3243 | bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) { |
3244 | return true; |
3245 | } |
3246 | |
3247 | template <typename Derived> |
3248 | bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) { |
3249 | return true; |
3250 | } |
3251 | |
3252 | template <typename Derived> |
3253 | bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) { |
3254 | return true; |
3255 | } |
3256 | |
3257 | template <typename Derived> |
3258 | bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) { |
3259 | return true; |
3260 | } |
3261 | |
3262 | template <typename Derived> |
3263 | bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) { |
3264 | return true; |
3265 | } |
3266 | |
3267 | template <typename Derived> |
3268 | bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) { |
3269 | return true; |
3270 | } |
3271 | |
3272 | template <typename Derived> |
3273 | bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) { |
3274 | return true; |
3275 | } |
3276 | |
3277 | template <typename Derived> |
3278 | bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) { |
3279 | return true; |
3280 | } |
3281 | |
3282 | template <typename Derived> |
3283 | bool RecursiveASTVisitor<Derived>::VisitOMPInitClause(OMPInitClause *C) { |
3284 | TRY_TO(VisitOMPClauseList(C)); |
3285 | return true; |
3286 | } |
3287 | |
3288 | template <typename Derived> |
3289 | bool RecursiveASTVisitor<Derived>::VisitOMPUseClause(OMPUseClause *C) { |
3290 | TRY_TO(TraverseStmt(C->getInteropVar())); |
3291 | return true; |
3292 | } |
3293 | |
3294 | template <typename Derived> |
3295 | bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *C) { |
3296 | TRY_TO(TraverseStmt(C->getInteropVar())); |
3297 | return true; |
3298 | } |
3299 | |
3300 | template <typename Derived> |
3301 | bool RecursiveASTVisitor<Derived>::VisitOMPNovariantsClause( |
3302 | OMPNovariantsClause *C) { |
3303 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3304 | TRY_TO(TraverseStmt(C->getCondition())); |
3305 | return true; |
3306 | } |
3307 | |
3308 | template <typename Derived> |
3309 | bool RecursiveASTVisitor<Derived>::VisitOMPNocontextClause( |
3310 | OMPNocontextClause *C) { |
3311 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3312 | TRY_TO(TraverseStmt(C->getCondition())); |
3313 | return true; |
3314 | } |
3315 | |
3316 | template <typename Derived> |
3317 | template <typename T> |
3318 | bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { |
3319 | for (auto *E : Node->varlists()) { |
3320 | TRY_TO(TraverseStmt(E)); |
3321 | } |
3322 | return true; |
3323 | } |
3324 | |
3325 | template <typename Derived> |
3326 | bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause( |
3327 | OMPInclusiveClause *C) { |
3328 | TRY_TO(VisitOMPClauseList(C)); |
3329 | return true; |
3330 | } |
3331 | |
3332 | template <typename Derived> |
3333 | bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause( |
3334 | OMPExclusiveClause *C) { |
3335 | TRY_TO(VisitOMPClauseList(C)); |
3336 | return true; |
3337 | } |
3338 | |
3339 | template <typename Derived> |
3340 | bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) { |
3341 | TRY_TO(VisitOMPClauseList(C)); |
3342 | for (auto *E : C->private_copies()) { |
3343 | TRY_TO(TraverseStmt(E)); |
3344 | } |
3345 | return true; |
3346 | } |
3347 | |
3348 | template <typename Derived> |
3349 | bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause( |
3350 | OMPFirstprivateClause *C) { |
3351 | TRY_TO(VisitOMPClauseList(C)); |
3352 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3353 | for (auto *E : C->private_copies()) { |
3354 | TRY_TO(TraverseStmt(E)); |
3355 | } |
3356 | for (auto *E : C->inits()) { |
3357 | TRY_TO(TraverseStmt(E)); |
3358 | } |
3359 | return true; |
3360 | } |
3361 | |
3362 | template <typename Derived> |
3363 | bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause( |
3364 | OMPLastprivateClause *C) { |
3365 | TRY_TO(VisitOMPClauseList(C)); |
3366 | TRY_TO(VisitOMPClauseWithPostUpdate(C)); |
3367 | for (auto *E : C->private_copies()) { |
3368 | TRY_TO(TraverseStmt(E)); |
3369 | } |
3370 | for (auto *E : C->source_exprs()) { |
3371 | TRY_TO(TraverseStmt(E)); |
3372 | } |
3373 | for (auto *E : C->destination_exprs()) { |
3374 | TRY_TO(TraverseStmt(E)); |
3375 | } |
3376 | for (auto *E : C->assignment_ops()) { |
3377 | TRY_TO(TraverseStmt(E)); |
3378 | } |
3379 | return true; |
3380 | } |
3381 | |
3382 | template <typename Derived> |
3383 | bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) { |
3384 | TRY_TO(VisitOMPClauseList(C)); |
3385 | return true; |
3386 | } |
3387 | |
3388 | template <typename Derived> |
3389 | bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) { |
3390 | TRY_TO(TraverseStmt(C->getStep())); |
3391 | TRY_TO(TraverseStmt(C->getCalcStep())); |
3392 | TRY_TO(VisitOMPClauseList(C)); |
3393 | TRY_TO(VisitOMPClauseWithPostUpdate(C)); |
3394 | for (auto *E : C->privates()) { |
3395 | TRY_TO(TraverseStmt(E)); |
3396 | } |
3397 | for (auto *E : C->inits()) { |
3398 | TRY_TO(TraverseStmt(E)); |
3399 | } |
3400 | for (auto *E : C->updates()) { |
3401 | TRY_TO(TraverseStmt(E)); |
3402 | } |
3403 | for (auto *E : C->finals()) { |
3404 | TRY_TO(TraverseStmt(E)); |
3405 | } |
3406 | return true; |
3407 | } |
3408 | |
3409 | template <typename Derived> |
3410 | bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) { |
3411 | TRY_TO(TraverseStmt(C->getAlignment())); |
3412 | TRY_TO(VisitOMPClauseList(C)); |
3413 | return true; |
3414 | } |
3415 | |
3416 | template <typename Derived> |
3417 | bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) { |
3418 | TRY_TO(VisitOMPClauseList(C)); |
3419 | for (auto *E : C->source_exprs()) { |
3420 | TRY_TO(TraverseStmt(E)); |
3421 | } |
3422 | for (auto *E : C->destination_exprs()) { |
3423 | TRY_TO(TraverseStmt(E)); |
3424 | } |
3425 | for (auto *E : C->assignment_ops()) { |
3426 | TRY_TO(TraverseStmt(E)); |
3427 | } |
3428 | return true; |
3429 | } |
3430 | |
3431 | template <typename Derived> |
3432 | bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause( |
3433 | OMPCopyprivateClause *C) { |
3434 | TRY_TO(VisitOMPClauseList(C)); |
3435 | for (auto *E : C->source_exprs()) { |
3436 | TRY_TO(TraverseStmt(E)); |
3437 | } |
3438 | for (auto *E : C->destination_exprs()) { |
3439 | TRY_TO(TraverseStmt(E)); |
3440 | } |
3441 | for (auto *E : C->assignment_ops()) { |
3442 | TRY_TO(TraverseStmt(E)); |
3443 | } |
3444 | return true; |
3445 | } |
3446 | |
3447 | template <typename Derived> |
3448 | bool |
3449 | RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { |
3450 | TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); |
3451 | TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); |
3452 | TRY_TO(VisitOMPClauseList(C)); |
3453 | TRY_TO(VisitOMPClauseWithPostUpdate(C)); |
3454 | for (auto *E : C->privates()) { |
3455 | TRY_TO(TraverseStmt(E)); |
3456 | } |
3457 | for (auto *E : C->lhs_exprs()) { |
3458 | TRY_TO(TraverseStmt(E)); |
3459 | } |
3460 | for (auto *E : C->rhs_exprs()) { |
3461 | TRY_TO(TraverseStmt(E)); |
3462 | } |
3463 | for (auto *E : C->reduction_ops()) { |
3464 | TRY_TO(TraverseStmt(E)); |
3465 | } |
3466 | if (C->getModifier() == OMPC_REDUCTION_inscan) { |
3467 | for (auto *E : C->copy_ops()) { |
3468 | TRY_TO(TraverseStmt(E)); |
3469 | } |
3470 | for (auto *E : C->copy_array_temps()) { |
3471 | TRY_TO(TraverseStmt(E)); |
3472 | } |
3473 | for (auto *E : C->copy_array_elems()) { |
3474 | TRY_TO(TraverseStmt(E)); |
3475 | } |
3476 | } |
3477 | return true; |
3478 | } |
3479 | |
3480 | template <typename Derived> |
3481 | bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause( |
3482 | OMPTaskReductionClause *C) { |
3483 | TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); |
3484 | TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); |
3485 | TRY_TO(VisitOMPClauseList(C)); |
3486 | TRY_TO(VisitOMPClauseWithPostUpdate(C)); |
3487 | for (auto *E : C->privates()) { |
3488 | TRY_TO(TraverseStmt(E)); |
3489 | } |
3490 | for (auto *E : C->lhs_exprs()) { |
3491 | TRY_TO(TraverseStmt(E)); |
3492 | } |
3493 | for (auto *E : C->rhs_exprs()) { |
3494 | TRY_TO(TraverseStmt(E)); |
3495 | } |
3496 | for (auto *E : C->reduction_ops()) { |
3497 | TRY_TO(TraverseStmt(E)); |
3498 | } |
3499 | return true; |
3500 | } |
3501 | |
3502 | template <typename Derived> |
3503 | bool RecursiveASTVisitor<Derived>::VisitOMPInReductionClause( |
3504 | OMPInReductionClause *C) { |
3505 | TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); |
3506 | TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); |
3507 | TRY_TO(VisitOMPClauseList(C)); |
3508 | TRY_TO(VisitOMPClauseWithPostUpdate(C)); |
3509 | for (auto *E : C->privates()) { |
3510 | TRY_TO(TraverseStmt(E)); |
3511 | } |
3512 | for (auto *E : C->lhs_exprs()) { |
3513 | TRY_TO(TraverseStmt(E)); |
3514 | } |
3515 | for (auto *E : C->rhs_exprs()) { |
3516 | TRY_TO(TraverseStmt(E)); |
3517 | } |
3518 | for (auto *E : C->reduction_ops()) { |
3519 | TRY_TO(TraverseStmt(E)); |
3520 | } |
3521 | for (auto *E : C->taskgroup_descriptors()) |
3522 | TRY_TO(TraverseStmt(E)); |
3523 | return true; |
3524 | } |
3525 | |
3526 | template <typename Derived> |
3527 | bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) { |
3528 | TRY_TO(VisitOMPClauseList(C)); |
3529 | return true; |
3530 | } |
3531 | |
3532 | template <typename Derived> |
3533 | bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) { |
3534 | TRY_TO(TraverseStmt(C->getDepobj())); |
3535 | return true; |
3536 | } |
3537 | |
3538 | template <typename Derived> |
3539 | bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) { |
3540 | TRY_TO(VisitOMPClauseList(C)); |
3541 | return true; |
3542 | } |
3543 | |
3544 | template <typename Derived> |
3545 | bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) { |
3546 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3547 | TRY_TO(TraverseStmt(C->getDevice())); |
3548 | return true; |
3549 | } |
3550 | |
3551 | template <typename Derived> |
3552 | bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) { |
3553 | TRY_TO(VisitOMPClauseList(C)); |
3554 | return true; |
3555 | } |
3556 | |
3557 | template <typename Derived> |
3558 | bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause( |
3559 | OMPNumTeamsClause *C) { |
3560 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3561 | TRY_TO(TraverseStmt(C->getNumTeams())); |
3562 | return true; |
3563 | } |
3564 | |
3565 | template <typename Derived> |
3566 | bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause( |
3567 | OMPThreadLimitClause *C) { |
3568 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3569 | TRY_TO(TraverseStmt(C->getThreadLimit())); |
3570 | return true; |
3571 | } |
3572 | |
3573 | template <typename Derived> |
3574 | bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause( |
3575 | OMPPriorityClause *C) { |
3576 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3577 | TRY_TO(TraverseStmt(C->getPriority())); |
3578 | return true; |
3579 | } |
3580 | |
3581 | template <typename Derived> |
3582 | bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause( |
3583 | OMPGrainsizeClause *C) { |
3584 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3585 | TRY_TO(TraverseStmt(C->getGrainsize())); |
3586 | return true; |
3587 | } |
3588 | |
3589 | template <typename Derived> |
3590 | bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause( |
3591 | OMPNumTasksClause *C) { |
3592 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3593 | TRY_TO(TraverseStmt(C->getNumTasks())); |
3594 | return true; |
3595 | } |
3596 | |
3597 | template <typename Derived> |
3598 | bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) { |
3599 | TRY_TO(TraverseStmt(C->getHint())); |
3600 | return true; |
3601 | } |
3602 | |
3603 | template <typename Derived> |
3604 | bool RecursiveASTVisitor<Derived>::VisitOMPDistScheduleClause( |
3605 | OMPDistScheduleClause *C) { |
3606 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3607 | TRY_TO(TraverseStmt(C->getChunkSize())); |
3608 | return true; |
3609 | } |
3610 | |
3611 | template <typename Derived> |
3612 | bool |
3613 | RecursiveASTVisitor<Derived>::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) { |
3614 | return true; |
3615 | } |
3616 | |
3617 | template <typename Derived> |
3618 | bool RecursiveASTVisitor<Derived>::VisitOMPToClause(OMPToClause *C) { |
3619 | TRY_TO(VisitOMPClauseList(C)); |
3620 | return true; |
3621 | } |
3622 | |
3623 | template <typename Derived> |
3624 | bool RecursiveASTVisitor<Derived>::VisitOMPFromClause(OMPFromClause *C) { |
3625 | TRY_TO(VisitOMPClauseList(C)); |
3626 | return true; |
3627 | } |
3628 | |
3629 | template <typename Derived> |
3630 | bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause( |
3631 | OMPUseDevicePtrClause *C) { |
3632 | TRY_TO(VisitOMPClauseList(C)); |
3633 | return true; |
3634 | } |
3635 | |
3636 | template <typename Derived> |
3637 | bool RecursiveASTVisitor<Derived>::VisitOMPUseDeviceAddrClause( |
3638 | OMPUseDeviceAddrClause *C) { |
3639 | TRY_TO(VisitOMPClauseList(C)); |
3640 | return true; |
3641 | } |
3642 | |
3643 | template <typename Derived> |
3644 | bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause( |
3645 | OMPIsDevicePtrClause *C) { |
3646 | TRY_TO(VisitOMPClauseList(C)); |
3647 | return true; |
3648 | } |
3649 | |
3650 | template <typename Derived> |
3651 | bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause( |
3652 | OMPNontemporalClause *C) { |
3653 | TRY_TO(VisitOMPClauseList(C)); |
3654 | for (auto *E : C->private_refs()) { |
3655 | TRY_TO(TraverseStmt(E)); |
3656 | } |
3657 | return true; |
3658 | } |
3659 | |
3660 | template <typename Derived> |
3661 | bool RecursiveASTVisitor<Derived>::VisitOMPOrderClause(OMPOrderClause *) { |
3662 | return true; |
3663 | } |
3664 | |
3665 | template <typename Derived> |
3666 | bool RecursiveASTVisitor<Derived>::VisitOMPDetachClause(OMPDetachClause *C) { |
3667 | TRY_TO(TraverseStmt(C->getEventHandler())); |
3668 | return true; |
3669 | } |
3670 | |
3671 | template <typename Derived> |
3672 | bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause( |
3673 | OMPUsesAllocatorsClause *C) { |
3674 | for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { |
3675 | const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I); |
3676 | TRY_TO(TraverseStmt(Data.Allocator)); |
3677 | TRY_TO(TraverseStmt(Data.AllocatorTraits)); |
3678 | } |
3679 | return true; |
3680 | } |
3681 | |
3682 | template <typename Derived> |
3683 | bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause( |
3684 | OMPAffinityClause *C) { |
3685 | TRY_TO(TraverseStmt(C->getModifier())); |
3686 | for (Expr *E : C->varlists()) |
3687 | TRY_TO(TraverseStmt(E)); |
3688 | return true; |
3689 | } |
3690 | |
3691 | template <typename Derived> |
3692 | bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) { |
3693 | TRY_TO(VisitOMPClauseWithPreInit(C)); |
3694 | TRY_TO(TraverseStmt(C->getThreadID())); |
3695 | return true; |
3696 | } |
3697 | |
3698 | template <typename Derived> |
3699 | bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) { |
3700 | return true; |
3701 | } |
3702 | |
3703 | // FIXME: look at the following tricky-seeming exprs to see if we |
3704 | // need to recurse on anything. These are ones that have methods |
3705 | // returning decls or qualtypes or nestednamespecifier -- though I'm |
3706 | // not sure if they own them -- or just seemed very complicated, or |
3707 | // had lots of sub-types to explore. |
3708 | // |
3709 | // VisitOverloadExpr and its children: recurse on template args? etc? |
3710 | |
3711 | // FIXME: go through all the stmts and exprs again, and see which of them |
3712 | // create new types, and recurse on the types (TypeLocs?) of those. |
3713 | // Candidates: |
3714 | // |
3715 | // http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html |
3716 | // http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html |
3717 | // http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html |
3718 | // Every class that has getQualifier. |
3719 | |
3720 | #undef DEF_TRAVERSE_STMT |
3721 | #undef TRAVERSE_STMT |
3722 | #undef TRAVERSE_STMT_BASE |
3723 | |
3724 | #undef TRY_TO |
3725 | |
3726 | } // end namespace clang |
3727 | |
3728 | #endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H |
1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ |
2 | |* *| |
3 | |* List of AST nodes of a particular kind *| |
4 | |* *| |
5 | |* Automatically generated file, do not edit! *| |
6 | |* *| |
7 | \*===----------------------------------------------------------------------===*/ |
8 | |
9 | #ifndef ABSTRACT_STMT |
10 | # define ABSTRACT_STMT(Type) Type |
11 | #endif |
12 | #ifndef STMT_RANGE |
13 | # define STMT_RANGE(Base, First, Last) |
14 | #endif |
15 | |
16 | #ifndef LAST_STMT_RANGE |
17 | # define LAST_STMT_RANGE(Base, First, Last) STMT_RANGE(Base, First, Last) |
18 | #endif |
19 | |
20 | #ifndef ASMSTMT |
21 | # define ASMSTMT(Type, Base) STMT(Type, Base) |
22 | #endif |
23 | ABSTRACT_STMT(ASMSTMT(AsmStmt, Stmt)) |
24 | #ifndef GCCASMSTMT |
25 | # define GCCASMSTMT(Type, Base) ASMSTMT(Type, Base) |
26 | #endif |
27 | GCCASMSTMT(GCCAsmStmt, AsmStmt) |
28 | #undef GCCASMSTMT |
29 | |
30 | #ifndef MSASMSTMT |
31 | # define MSASMSTMT(Type, Base) ASMSTMT(Type, Base) |
32 | #endif |
33 | MSASMSTMT(MSAsmStmt, AsmStmt) |
34 | #undef MSASMSTMT |
35 | |
36 | STMT_RANGE(AsmStmt, GCCAsmStmt, MSAsmStmt) |
37 | |
38 | #undef ASMSTMT |
39 | |
40 | #ifndef BREAKSTMT |
41 | # define BREAKSTMT(Type, Base) STMT(Type, Base) |
42 | #endif |
43 | BREAKSTMT(BreakStmt, Stmt) |
44 | #undef BREAKSTMT |
45 | |
46 | #ifndef CXXCATCHSTMT |
47 | # define CXXCATCHSTMT(Type, Base) STMT(Type, Base) |
48 | #endif |
49 | CXXCATCHSTMT(CXXCatchStmt, Stmt) |
50 | #undef CXXCATCHSTMT |
51 | |
52 | #ifndef CXXFORRANGESTMT |
53 | # define CXXFORRANGESTMT(Type, Base) STMT(Type, Base) |
54 | #endif |
55 | CXXFORRANGESTMT(CXXForRangeStmt, Stmt) |
56 | #undef CXXFORRANGESTMT |
57 | |
58 | #ifndef CXXTRYSTMT |
59 | # define CXXTRYSTMT(Type, Base) STMT(Type, Base) |
60 | #endif |
61 | CXXTRYSTMT(CXXTryStmt, Stmt) |
62 | #undef CXXTRYSTMT |
63 | |
64 | #ifndef CAPTUREDSTMT |
65 | # define CAPTUREDSTMT(Type, Base) STMT(Type, Base) |
66 | #endif |
67 | CAPTUREDSTMT(CapturedStmt, Stmt) |
68 | #undef CAPTUREDSTMT |
69 | |
70 | #ifndef COMPOUNDSTMT |
71 | # define COMPOUNDSTMT(Type, Base) STMT(Type, Base) |
72 | #endif |
73 | COMPOUNDSTMT(CompoundStmt, Stmt) |
74 | #undef COMPOUNDSTMT |
75 | |
76 | #ifndef CONTINUESTMT |
77 | # define CONTINUESTMT(Type, Base) STMT(Type, Base) |
78 | #endif |
79 | CONTINUESTMT(ContinueStmt, Stmt) |
80 | #undef CONTINUESTMT |
81 | |
82 | #ifndef CORETURNSTMT |
83 | # define CORETURNSTMT(Type, Base) STMT(Type, Base) |
84 | #endif |
85 | CORETURNSTMT(CoreturnStmt, Stmt) |
86 | #undef CORETURNSTMT |
87 | |
88 | #ifndef COROUTINEBODYSTMT |
89 | # define COROUTINEBODYSTMT(Type, Base) STMT(Type, Base) |
90 | #endif |
91 | COROUTINEBODYSTMT(CoroutineBodyStmt, Stmt) |
92 | #undef COROUTINEBODYSTMT |
93 | |
94 | #ifndef DECLSTMT |
95 | # define DECLSTMT(Type, Base) STMT(Type, Base) |
96 | #endif |
97 | DECLSTMT(DeclStmt, Stmt) |
98 | #undef DECLSTMT |
99 | |
100 | #ifndef DOSTMT |
101 | # define DOSTMT(Type, Base) STMT(Type, Base) |
102 | #endif |
103 | DOSTMT(DoStmt, Stmt) |
104 | #undef DOSTMT |
105 | |
106 | #ifndef FORSTMT |
107 | # define FORSTMT(Type, Base) STMT(Type, Base) |
108 | #endif |
109 | FORSTMT(ForStmt, Stmt) |
110 | #undef FORSTMT |
111 | |
112 | #ifndef GOTOSTMT |
113 | # define GOTOSTMT(Type, Base) STMT(Type, Base) |
114 | #endif |
115 | GOTOSTMT(GotoStmt, Stmt) |
116 | #undef GOTOSTMT |
117 | |
118 | #ifndef IFSTMT |
119 | # define IFSTMT(Type, Base) STMT(Type, Base) |
120 | #endif |
121 | IFSTMT(IfStmt, Stmt) |
122 | #undef IFSTMT |
123 | |
124 | #ifndef INDIRECTGOTOSTMT |
125 | # define INDIRECTGOTOSTMT(Type, Base) STMT(Type, Base) |
126 | #endif |
127 | INDIRECTGOTOSTMT(IndirectGotoStmt, Stmt) |
128 | #undef INDIRECTGOTOSTMT |
129 | |
130 | #ifndef MSDEPENDENTEXISTSSTMT |
131 | # define MSDEPENDENTEXISTSSTMT(Type, Base) STMT(Type, Base) |
132 | #endif |
133 | MSDEPENDENTEXISTSSTMT(MSDependentExistsStmt, Stmt) |
134 | #undef MSDEPENDENTEXISTSSTMT |
135 | |
136 | #ifndef NULLSTMT |
137 | # define NULLSTMT(Type, Base) STMT(Type, Base) |
138 | #endif |
139 | NULLSTMT(NullStmt, Stmt) |
140 | #undef NULLSTMT |
141 | |
142 | #ifndef OMPCANONICALLOOP |
143 | # define OMPCANONICALLOOP(Type, Base) STMT(Type, Base) |
144 | #endif |
145 | OMPCANONICALLOOP(OMPCanonicalLoop, Stmt) |
146 | #undef OMPCANONICALLOOP |
147 | |
148 | #ifndef OMPEXECUTABLEDIRECTIVE |
149 | # define OMPEXECUTABLEDIRECTIVE(Type, Base) STMT(Type, Base) |
150 | #endif |
151 | ABSTRACT_STMT(OMPEXECUTABLEDIRECTIVE(OMPExecutableDirective, Stmt)) |
152 | #ifndef OMPATOMICDIRECTIVE |
153 | # define OMPATOMICDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
154 | #endif |
155 | OMPATOMICDIRECTIVE(OMPAtomicDirective, OMPExecutableDirective) |
156 | #undef OMPATOMICDIRECTIVE |
157 | |
158 | #ifndef OMPBARRIERDIRECTIVE |
159 | # define OMPBARRIERDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
160 | #endif |
161 | OMPBARRIERDIRECTIVE(OMPBarrierDirective, OMPExecutableDirective) |
162 | #undef OMPBARRIERDIRECTIVE |
163 | |
164 | #ifndef OMPCANCELDIRECTIVE |
165 | # define OMPCANCELDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
166 | #endif |
167 | OMPCANCELDIRECTIVE(OMPCancelDirective, OMPExecutableDirective) |
168 | #undef OMPCANCELDIRECTIVE |
169 | |
170 | #ifndef OMPCANCELLATIONPOINTDIRECTIVE |
171 | # define OMPCANCELLATIONPOINTDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
172 | #endif |
173 | OMPCANCELLATIONPOINTDIRECTIVE(OMPCancellationPointDirective, OMPExecutableDirective) |
174 | #undef OMPCANCELLATIONPOINTDIRECTIVE |
175 | |
176 | #ifndef OMPCRITICALDIRECTIVE |
177 | # define OMPCRITICALDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
178 | #endif |
179 | OMPCRITICALDIRECTIVE(OMPCriticalDirective, OMPExecutableDirective) |
180 | #undef OMPCRITICALDIRECTIVE |
181 | |
182 | #ifndef OMPDEPOBJDIRECTIVE |
183 | # define OMPDEPOBJDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
184 | #endif |
185 | OMPDEPOBJDIRECTIVE(OMPDepobjDirective, OMPExecutableDirective) |
186 | #undef OMPDEPOBJDIRECTIVE |
187 | |
188 | #ifndef OMPDISPATCHDIRECTIVE |
189 | # define OMPDISPATCHDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
190 | #endif |
191 | OMPDISPATCHDIRECTIVE(OMPDispatchDirective, OMPExecutableDirective) |
192 | #undef OMPDISPATCHDIRECTIVE |
193 | |
194 | #ifndef OMPFLUSHDIRECTIVE |
195 | # define OMPFLUSHDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
196 | #endif |
197 | OMPFLUSHDIRECTIVE(OMPFlushDirective, OMPExecutableDirective) |
198 | #undef OMPFLUSHDIRECTIVE |
199 | |
200 | #ifndef OMPINTEROPDIRECTIVE |
201 | # define OMPINTEROPDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
202 | #endif |
203 | OMPINTEROPDIRECTIVE(OMPInteropDirective, OMPExecutableDirective) |
204 | #undef OMPINTEROPDIRECTIVE |
205 | |
206 | #ifndef OMPLOOPBASEDDIRECTIVE |
207 | # define OMPLOOPBASEDDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
208 | #endif |
209 | ABSTRACT_STMT(OMPLOOPBASEDDIRECTIVE(OMPLoopBasedDirective, OMPExecutableDirective)) |
210 | #ifndef OMPLOOPDIRECTIVE |
211 | # define OMPLOOPDIRECTIVE(Type, Base) OMPLOOPBASEDDIRECTIVE(Type, Base) |
212 | #endif |
213 | ABSTRACT_STMT(OMPLOOPDIRECTIVE(OMPLoopDirective, OMPLoopBasedDirective)) |
214 | #ifndef OMPDISTRIBUTEDIRECTIVE |
215 | # define OMPDISTRIBUTEDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
216 | #endif |
217 | OMPDISTRIBUTEDIRECTIVE(OMPDistributeDirective, OMPLoopDirective) |
218 | #undef OMPDISTRIBUTEDIRECTIVE |
219 | |
220 | #ifndef OMPDISTRIBUTEPARALLELFORDIRECTIVE |
221 | # define OMPDISTRIBUTEPARALLELFORDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
222 | #endif |
223 | OMPDISTRIBUTEPARALLELFORDIRECTIVE(OMPDistributeParallelForDirective, OMPLoopDirective) |
224 | #undef OMPDISTRIBUTEPARALLELFORDIRECTIVE |
225 | |
226 | #ifndef OMPDISTRIBUTEPARALLELFORSIMDDIRECTIVE |
227 | # define OMPDISTRIBUTEPARALLELFORSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
228 | #endif |
229 | OMPDISTRIBUTEPARALLELFORSIMDDIRECTIVE(OMPDistributeParallelForSimdDirective, OMPLoopDirective) |
230 | #undef OMPDISTRIBUTEPARALLELFORSIMDDIRECTIVE |
231 | |
232 | #ifndef OMPDISTRIBUTESIMDDIRECTIVE |
233 | # define OMPDISTRIBUTESIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
234 | #endif |
235 | OMPDISTRIBUTESIMDDIRECTIVE(OMPDistributeSimdDirective, OMPLoopDirective) |
236 | #undef OMPDISTRIBUTESIMDDIRECTIVE |
237 | |
238 | #ifndef OMPFORDIRECTIVE |
239 | # define OMPFORDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
240 | #endif |
241 | OMPFORDIRECTIVE(OMPForDirective, OMPLoopDirective) |
242 | #undef OMPFORDIRECTIVE |
243 | |
244 | #ifndef OMPFORSIMDDIRECTIVE |
245 | # define OMPFORSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
246 | #endif |
247 | OMPFORSIMDDIRECTIVE(OMPForSimdDirective, OMPLoopDirective) |
248 | #undef OMPFORSIMDDIRECTIVE |
249 | |
250 | #ifndef OMPGENERICLOOPDIRECTIVE |
251 | # define OMPGENERICLOOPDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
252 | #endif |
253 | OMPGENERICLOOPDIRECTIVE(OMPGenericLoopDirective, OMPLoopDirective) |
254 | #undef OMPGENERICLOOPDIRECTIVE |
255 | |
256 | #ifndef OMPMASTERTASKLOOPDIRECTIVE |
257 | # define OMPMASTERTASKLOOPDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
258 | #endif |
259 | OMPMASTERTASKLOOPDIRECTIVE(OMPMasterTaskLoopDirective, OMPLoopDirective) |
260 | #undef OMPMASTERTASKLOOPDIRECTIVE |
261 | |
262 | #ifndef OMPMASTERTASKLOOPSIMDDIRECTIVE |
263 | # define OMPMASTERTASKLOOPSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
264 | #endif |
265 | OMPMASTERTASKLOOPSIMDDIRECTIVE(OMPMasterTaskLoopSimdDirective, OMPLoopDirective) |
266 | #undef OMPMASTERTASKLOOPSIMDDIRECTIVE |
267 | |
268 | #ifndef OMPPARALLELFORDIRECTIVE |
269 | # define OMPPARALLELFORDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
270 | #endif |
271 | OMPPARALLELFORDIRECTIVE(OMPParallelForDirective, OMPLoopDirective) |
272 | #undef OMPPARALLELFORDIRECTIVE |
273 | |
274 | #ifndef OMPPARALLELFORSIMDDIRECTIVE |
275 | # define OMPPARALLELFORSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
276 | #endif |
277 | OMPPARALLELFORSIMDDIRECTIVE(OMPParallelForSimdDirective, OMPLoopDirective) |
278 | #undef OMPPARALLELFORSIMDDIRECTIVE |
279 | |
280 | #ifndef OMPPARALLELMASTERTASKLOOPDIRECTIVE |
281 | # define OMPPARALLELMASTERTASKLOOPDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
282 | #endif |
283 | OMPPARALLELMASTERTASKLOOPDIRECTIVE(OMPParallelMasterTaskLoopDirective, OMPLoopDirective) |
284 | #undef OMPPARALLELMASTERTASKLOOPDIRECTIVE |
285 | |
286 | #ifndef OMPPARALLELMASTERTASKLOOPSIMDDIRECTIVE |
287 | # define OMPPARALLELMASTERTASKLOOPSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
288 | #endif |
289 | OMPPARALLELMASTERTASKLOOPSIMDDIRECTIVE(OMPParallelMasterTaskLoopSimdDirective, OMPLoopDirective) |
290 | #undef OMPPARALLELMASTERTASKLOOPSIMDDIRECTIVE |
291 | |
292 | #ifndef OMPSIMDDIRECTIVE |
293 | # define OMPSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
294 | #endif |
295 | OMPSIMDDIRECTIVE(OMPSimdDirective, OMPLoopDirective) |
296 | #undef OMPSIMDDIRECTIVE |
297 | |
298 | #ifndef OMPTARGETPARALLELFORSIMDDIRECTIVE |
299 | # define OMPTARGETPARALLELFORSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
300 | #endif |
301 | OMPTARGETPARALLELFORSIMDDIRECTIVE(OMPTargetParallelForSimdDirective, OMPLoopDirective) |
302 | #undef OMPTARGETPARALLELFORSIMDDIRECTIVE |
303 | |
304 | #ifndef OMPTARGETSIMDDIRECTIVE |
305 | # define OMPTARGETSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
306 | #endif |
307 | OMPTARGETSIMDDIRECTIVE(OMPTargetSimdDirective, OMPLoopDirective) |
308 | #undef OMPTARGETSIMDDIRECTIVE |
309 | |
310 | #ifndef OMPTARGETTEAMSDISTRIBUTEDIRECTIVE |
311 | # define OMPTARGETTEAMSDISTRIBUTEDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
312 | #endif |
313 | OMPTARGETTEAMSDISTRIBUTEDIRECTIVE(OMPTargetTeamsDistributeDirective, OMPLoopDirective) |
314 | #undef OMPTARGETTEAMSDISTRIBUTEDIRECTIVE |
315 | |
316 | #ifndef OMPTARGETTEAMSDISTRIBUTEPARALLELFORDIRECTIVE |
317 | # define OMPTARGETTEAMSDISTRIBUTEPARALLELFORDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
318 | #endif |
319 | OMPTARGETTEAMSDISTRIBUTEPARALLELFORDIRECTIVE(OMPTargetTeamsDistributeParallelForDirective, OMPLoopDirective) |
320 | #undef OMPTARGETTEAMSDISTRIBUTEPARALLELFORDIRECTIVE |
321 | |
322 | #ifndef OMPTARGETTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE |
323 | # define OMPTARGETTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
324 | #endif |
325 | OMPTARGETTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE(OMPTargetTeamsDistributeParallelForSimdDirective, OMPLoopDirective) |
326 | #undef OMPTARGETTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE |
327 | |
328 | #ifndef OMPTARGETTEAMSDISTRIBUTESIMDDIRECTIVE |
329 | # define OMPTARGETTEAMSDISTRIBUTESIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
330 | #endif |
331 | OMPTARGETTEAMSDISTRIBUTESIMDDIRECTIVE(OMPTargetTeamsDistributeSimdDirective, OMPLoopDirective) |
332 | #undef OMPTARGETTEAMSDISTRIBUTESIMDDIRECTIVE |
333 | |
334 | #ifndef OMPTASKLOOPDIRECTIVE |
335 | # define OMPTASKLOOPDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
336 | #endif |
337 | OMPTASKLOOPDIRECTIVE(OMPTaskLoopDirective, OMPLoopDirective) |
338 | #undef OMPTASKLOOPDIRECTIVE |
339 | |
340 | #ifndef OMPTASKLOOPSIMDDIRECTIVE |
341 | # define OMPTASKLOOPSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
342 | #endif |
343 | OMPTASKLOOPSIMDDIRECTIVE(OMPTaskLoopSimdDirective, OMPLoopDirective) |
344 | #undef OMPTASKLOOPSIMDDIRECTIVE |
345 | |
346 | #ifndef OMPTEAMSDISTRIBUTEDIRECTIVE |
347 | # define OMPTEAMSDISTRIBUTEDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
348 | #endif |
349 | OMPTEAMSDISTRIBUTEDIRECTIVE(OMPTeamsDistributeDirective, OMPLoopDirective) |
350 | #undef OMPTEAMSDISTRIBUTEDIRECTIVE |
351 | |
352 | #ifndef OMPTEAMSDISTRIBUTEPARALLELFORDIRECTIVE |
353 | # define OMPTEAMSDISTRIBUTEPARALLELFORDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
354 | #endif |
355 | OMPTEAMSDISTRIBUTEPARALLELFORDIRECTIVE(OMPTeamsDistributeParallelForDirective, OMPLoopDirective) |
356 | #undef OMPTEAMSDISTRIBUTEPARALLELFORDIRECTIVE |
357 | |
358 | #ifndef OMPTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE |
359 | # define OMPTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
360 | #endif |
361 | OMPTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE(OMPTeamsDistributeParallelForSimdDirective, OMPLoopDirective) |
362 | #undef OMPTEAMSDISTRIBUTEPARALLELFORSIMDDIRECTIVE |
363 | |
364 | #ifndef OMPTEAMSDISTRIBUTESIMDDIRECTIVE |
365 | # define OMPTEAMSDISTRIBUTESIMDDIRECTIVE(Type, Base) OMPLOOPDIRECTIVE(Type, Base) |
366 | #endif |
367 | OMPTEAMSDISTRIBUTESIMDDIRECTIVE(OMPTeamsDistributeSimdDirective, OMPLoopDirective) |
368 | #undef OMPTEAMSDISTRIBUTESIMDDIRECTIVE |
369 | |
370 | STMT_RANGE(OMPLoopDirective, OMPDistributeDirective, OMPTeamsDistributeSimdDirective) |
371 | |
372 | #undef OMPLOOPDIRECTIVE |
373 | |
374 | #ifndef OMPLOOPTRANSFORMATIONDIRECTIVE |
375 | # define OMPLOOPTRANSFORMATIONDIRECTIVE(Type, Base) OMPLOOPBASEDDIRECTIVE(Type, Base) |
376 | #endif |
377 | ABSTRACT_STMT(OMPLOOPTRANSFORMATIONDIRECTIVE(OMPLoopTransformationDirective, OMPLoopBasedDirective)) |
378 | #ifndef OMPTILEDIRECTIVE |
379 | # define OMPTILEDIRECTIVE(Type, Base) OMPLOOPTRANSFORMATIONDIRECTIVE(Type, Base) |
380 | #endif |
381 | OMPTILEDIRECTIVE(OMPTileDirective, OMPLoopTransformationDirective) |
382 | #undef OMPTILEDIRECTIVE |
383 | |
384 | #ifndef OMPUNROLLDIRECTIVE |
385 | # define OMPUNROLLDIRECTIVE(Type, Base) OMPLOOPTRANSFORMATIONDIRECTIVE(Type, Base) |
386 | #endif |
387 | OMPUNROLLDIRECTIVE(OMPUnrollDirective, OMPLoopTransformationDirective) |
388 | #undef OMPUNROLLDIRECTIVE |
389 | |
390 | STMT_RANGE(OMPLoopTransformationDirective, OMPTileDirective, OMPUnrollDirective) |
391 | |
392 | #undef OMPLOOPTRANSFORMATIONDIRECTIVE |
393 | |
394 | STMT_RANGE(OMPLoopBasedDirective, OMPDistributeDirective, OMPUnrollDirective) |
395 | |
396 | #undef OMPLOOPBASEDDIRECTIVE |
397 | |
398 | #ifndef OMPMASKEDDIRECTIVE |
399 | # define OMPMASKEDDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
400 | #endif |
401 | OMPMASKEDDIRECTIVE(OMPMaskedDirective, OMPExecutableDirective) |
402 | #undef OMPMASKEDDIRECTIVE |
403 | |
404 | #ifndef OMPMASTERDIRECTIVE |
405 | # define OMPMASTERDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
406 | #endif |
407 | OMPMASTERDIRECTIVE(OMPMasterDirective, OMPExecutableDirective) |
408 | #undef OMPMASTERDIRECTIVE |
409 | |
410 | #ifndef OMPMETADIRECTIVE |
411 | # define OMPMETADIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
412 | #endif |
413 | OMPMETADIRECTIVE(OMPMetaDirective, OMPExecutableDirective) |
414 | #undef OMPMETADIRECTIVE |
415 | |
416 | #ifndef OMPORDEREDDIRECTIVE |
417 | # define OMPORDEREDDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
418 | #endif |
419 | OMPORDEREDDIRECTIVE(OMPOrderedDirective, OMPExecutableDirective) |
420 | #undef OMPORDEREDDIRECTIVE |
421 | |
422 | #ifndef OMPPARALLELDIRECTIVE |
423 | # define OMPPARALLELDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
424 | #endif |
425 | OMPPARALLELDIRECTIVE(OMPParallelDirective, OMPExecutableDirective) |
426 | #undef OMPPARALLELDIRECTIVE |
427 | |
428 | #ifndef OMPPARALLELMASTERDIRECTIVE |
429 | # define OMPPARALLELMASTERDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
430 | #endif |
431 | OMPPARALLELMASTERDIRECTIVE(OMPParallelMasterDirective, OMPExecutableDirective) |
432 | #undef OMPPARALLELMASTERDIRECTIVE |
433 | |
434 | #ifndef OMPPARALLELSECTIONSDIRECTIVE |
435 | # define OMPPARALLELSECTIONSDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
436 | #endif |
437 | OMPPARALLELSECTIONSDIRECTIVE(OMPParallelSectionsDirective, OMPExecutableDirective) |
438 | #undef OMPPARALLELSECTIONSDIRECTIVE |
439 | |
440 | #ifndef OMPSCANDIRECTIVE |
441 | # define OMPSCANDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
442 | #endif |
443 | OMPSCANDIRECTIVE(OMPScanDirective, OMPExecutableDirective) |
444 | #undef OMPSCANDIRECTIVE |
445 | |
446 | #ifndef OMPSECTIONDIRECTIVE |
447 | # define OMPSECTIONDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
448 | #endif |
449 | OMPSECTIONDIRECTIVE(OMPSectionDirective, OMPExecutableDirective) |
450 | #undef OMPSECTIONDIRECTIVE |
451 | |
452 | #ifndef OMPSECTIONSDIRECTIVE |
453 | # define OMPSECTIONSDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
454 | #endif |
455 | OMPSECTIONSDIRECTIVE(OMPSectionsDirective, OMPExecutableDirective) |
456 | #undef OMPSECTIONSDIRECTIVE |
457 | |
458 | #ifndef OMPSINGLEDIRECTIVE |
459 | # define OMPSINGLEDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
460 | #endif |
461 | OMPSINGLEDIRECTIVE(OMPSingleDirective, OMPExecutableDirective) |
462 | #undef OMPSINGLEDIRECTIVE |
463 | |
464 | #ifndef OMPTARGETDATADIRECTIVE |
465 | # define OMPTARGETDATADIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
466 | #endif |
467 | OMPTARGETDATADIRECTIVE(OMPTargetDataDirective, OMPExecutableDirective) |
468 | #undef OMPTARGETDATADIRECTIVE |
469 | |
470 | #ifndef OMPTARGETDIRECTIVE |
471 | # define OMPTARGETDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
472 | #endif |
473 | OMPTARGETDIRECTIVE(OMPTargetDirective, OMPExecutableDirective) |
474 | #undef OMPTARGETDIRECTIVE |
475 | |
476 | #ifndef OMPTARGETENTERDATADIRECTIVE |
477 | # define OMPTARGETENTERDATADIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
478 | #endif |
479 | OMPTARGETENTERDATADIRECTIVE(OMPTargetEnterDataDirective, OMPExecutableDirective) |
480 | #undef OMPTARGETENTERDATADIRECTIVE |
481 | |
482 | #ifndef OMPTARGETEXITDATADIRECTIVE |
483 | # define OMPTARGETEXITDATADIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
484 | #endif |
485 | OMPTARGETEXITDATADIRECTIVE(OMPTargetExitDataDirective, OMPExecutableDirective) |
486 | #undef OMPTARGETEXITDATADIRECTIVE |
487 | |
488 | #ifndef OMPTARGETPARALLELDIRECTIVE |
489 | # define OMPTARGETPARALLELDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
490 | #endif |
491 | OMPTARGETPARALLELDIRECTIVE(OMPTargetParallelDirective, OMPExecutableDirective) |
492 | #undef OMPTARGETPARALLELDIRECTIVE |
493 | |
494 | #ifndef OMPTARGETPARALLELFORDIRECTIVE |
495 | # define OMPTARGETPARALLELFORDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
496 | #endif |
497 | OMPTARGETPARALLELFORDIRECTIVE(OMPTargetParallelForDirective, OMPExecutableDirective) |
498 | #undef OMPTARGETPARALLELFORDIRECTIVE |
499 | |
500 | #ifndef OMPTARGETTEAMSDIRECTIVE |
501 | # define OMPTARGETTEAMSDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
502 | #endif |
503 | OMPTARGETTEAMSDIRECTIVE(OMPTargetTeamsDirective, OMPExecutableDirective) |
504 | #undef OMPTARGETTEAMSDIRECTIVE |
505 | |
506 | #ifndef OMPTARGETUPDATEDIRECTIVE |
507 | # define OMPTARGETUPDATEDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
508 | #endif |
509 | OMPTARGETUPDATEDIRECTIVE(OMPTargetUpdateDirective, OMPExecutableDirective) |
510 | #undef OMPTARGETUPDATEDIRECTIVE |
511 | |
512 | #ifndef OMPTASKDIRECTIVE |
513 | # define OMPTASKDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
514 | #endif |
515 | OMPTASKDIRECTIVE(OMPTaskDirective, OMPExecutableDirective) |
516 | #undef OMPTASKDIRECTIVE |
517 | |
518 | #ifndef OMPTASKGROUPDIRECTIVE |
519 | # define OMPTASKGROUPDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
520 | #endif |
521 | OMPTASKGROUPDIRECTIVE(OMPTaskgroupDirective, OMPExecutableDirective) |
522 | #undef OMPTASKGROUPDIRECTIVE |
523 | |
524 | #ifndef OMPTASKWAITDIRECTIVE |
525 | # define OMPTASKWAITDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
526 | #endif |
527 | OMPTASKWAITDIRECTIVE(OMPTaskwaitDirective, OMPExecutableDirective) |
528 | #undef OMPTASKWAITDIRECTIVE |
529 | |
530 | #ifndef OMPTASKYIELDDIRECTIVE |
531 | # define OMPTASKYIELDDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
532 | #endif |
533 | OMPTASKYIELDDIRECTIVE(OMPTaskyieldDirective, OMPExecutableDirective) |
534 | #undef OMPTASKYIELDDIRECTIVE |
535 | |
536 | #ifndef OMPTEAMSDIRECTIVE |
537 | # define OMPTEAMSDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base) |
538 | #endif |
539 | OMPTEAMSDIRECTIVE(OMPTeamsDirective, OMPExecutableDirective) |
540 | #undef OMPTEAMSDIRECTIVE |
541 | |
542 | STMT_RANGE(OMPExecutableDirective, OMPAtomicDirective, OMPTeamsDirective) |
543 | |
544 | #undef OMPEXECUTABLEDIRECTIVE |
545 | |
546 | #ifndef OBJCATCATCHSTMT |
547 | # define OBJCATCATCHSTMT(Type, Base) STMT(Type, Base) |
548 | #endif |
549 | OBJCATCATCHSTMT(ObjCAtCatchStmt, Stmt) |
550 | #undef OBJCATCATCHSTMT |
551 | |
552 | #ifndef OBJCATFINALLYSTMT |
553 | # define OBJCATFINALLYSTMT(Type, Base) STMT(Type, Base) |
554 | #endif |
555 | OBJCATFINALLYSTMT(ObjCAtFinallyStmt, Stmt) |
556 | #undef OBJCATFINALLYSTMT |
557 | |
558 | #ifndef OBJCATSYNCHRONIZEDSTMT |
559 | # define OBJCATSYNCHRONIZEDSTMT(Type, Base) STMT(Type, Base) |
560 | #endif |
561 | OBJCATSYNCHRONIZEDSTMT(ObjCAtSynchronizedStmt, Stmt) |
562 | #undef OBJCATSYNCHRONIZEDSTMT |
563 | |
564 | #ifndef OBJCATTHROWSTMT |
565 | # define OBJCATTHROWSTMT(Type, Base) STMT(Type, Base) |
566 | #endif |
567 | OBJCATTHROWSTMT(ObjCAtThrowStmt, Stmt) |
568 | #undef OBJCATTHROWSTMT |
569 | |
570 | #ifndef OBJCATTRYSTMT |
571 | # define OBJCATTRYSTMT(Type, Base) STMT(Type, Base) |
572 | #endif |
573 | OBJCATTRYSTMT(ObjCAtTryStmt, Stmt) |
574 | #undef OBJCATTRYSTMT |
575 | |
576 | #ifndef OBJCAUTORELEASEPOOLSTMT |
577 | # define OBJCAUTORELEASEPOOLSTMT(Type, Base) STMT(Type, Base) |
578 | #endif |
579 | OBJCAUTORELEASEPOOLSTMT(ObjCAutoreleasePoolStmt, Stmt) |
580 | #undef OBJCAUTORELEASEPOOLSTMT |
581 | |
582 | #ifndef OBJCFORCOLLECTIONSTMT |
583 | # define OBJCFORCOLLECTIONSTMT(Type, Base) STMT(Type, Base) |
584 | #endif |
585 | OBJCFORCOLLECTIONSTMT(ObjCForCollectionStmt, Stmt) |
586 | #undef OBJCFORCOLLECTIONSTMT |
587 | |
588 | #ifndef RETURNSTMT |
589 | # define RETURNSTMT(Type, Base) STMT(Type, Base) |
590 | #endif |
591 | RETURNSTMT(ReturnStmt, Stmt) |
592 | #undef RETURNSTMT |
593 | |
594 | #ifndef SEHEXCEPTSTMT |
595 | # define SEHEXCEPTSTMT(Type, Base) STMT(Type, Base) |
596 | #endif |
597 | SEHEXCEPTSTMT(SEHExceptStmt, Stmt) |
598 | #undef SEHEXCEPTSTMT |
599 | |
600 | #ifndef SEHFINALLYSTMT |
601 | # define SEHFINALLYSTMT(Type, Base) STMT(Type, Base) |
602 | #endif |
603 | SEHFINALLYSTMT(SEHFinallyStmt, Stmt) |
604 | #undef SEHFINALLYSTMT |
605 | |
606 | #ifndef SEHLEAVESTMT |
607 | # define SEHLEAVESTMT(Type, Base) STMT(Type, Base) |
608 | #endif |
609 | SEHLEAVESTMT(SEHLeaveStmt, Stmt) |
610 | #undef SEHLEAVESTMT |
611 | |
612 | #ifndef SEHTRYSTMT |
613 | # define SEHTRYSTMT(Type, Base) STMT(Type, Base) |
614 | #endif |
615 | SEHTRYSTMT(SEHTryStmt, Stmt) |
616 | #undef SEHTRYSTMT |
617 | |
618 | #ifndef SWITCHCASE |
619 | # define SWITCHCASE(Type, Base) STMT(Type, Base) |
620 | #endif |
621 | ABSTRACT_STMT(SWITCHCASE(SwitchCase, Stmt)) |
622 | #ifndef CASESTMT |
623 | # define CASESTMT(Type, Base) SWITCHCASE(Type, Base) |
624 | #endif |
625 | CASESTMT(CaseStmt, SwitchCase) |
626 | #undef CASESTMT |
627 | |
628 | #ifndef DEFAULTSTMT |
629 | # define DEFAULTSTMT(Type, Base) SWITCHCASE(Type, Base) |
630 | #endif |
631 | DEFAULTSTMT(DefaultStmt, SwitchCase) |
632 | #undef DEFAULTSTMT |
633 | |
634 | STMT_RANGE(SwitchCase, CaseStmt, DefaultStmt) |
635 | |
636 | #undef SWITCHCASE |
637 | |
638 | #ifndef SWITCHSTMT |
639 | # define SWITCHSTMT(Type, Base) STMT(Type, Base) |
640 | #endif |
641 | SWITCHSTMT(SwitchStmt, Stmt) |
642 | #undef SWITCHSTMT |
643 | |
644 | #ifndef VALUESTMT |
645 | # define VALUESTMT(Type, Base) STMT(Type, Base) |
646 | #endif |
647 | ABSTRACT_STMT(VALUESTMT(ValueStmt, Stmt)) |
648 | #ifndef ATTRIBUTEDSTMT |
649 | # define ATTRIBUTEDSTMT(Type, Base) VALUESTMT(Type, Base) |
650 | #endif |
651 | ATTRIBUTEDSTMT(AttributedStmt, ValueStmt) |
652 | #undef ATTRIBUTEDSTMT |
653 | |
654 | #ifndef EXPR |
655 | # define EXPR(Type, Base) VALUESTMT(Type, Base) |
656 | #endif |
657 | ABSTRACT_STMT(EXPR(Expr, ValueStmt)) |
658 | #ifndef ABSTRACTCONDITIONALOPERATOR |
659 | # define ABSTRACTCONDITIONALOPERATOR(Type, Base) EXPR(Type, Base) |
660 | #endif |
661 | ABSTRACT_STMT(ABSTRACTCONDITIONALOPERATOR(AbstractConditionalOperator, Expr)) |
662 | #ifndef BINARYCONDITIONALOPERATOR |
663 | # define BINARYCONDITIONALOPERATOR(Type, Base) ABSTRACTCONDITIONALOPERATOR(Type, Base) |
664 | #endif |
665 | BINARYCONDITIONALOPERATOR(BinaryConditionalOperator, AbstractConditionalOperator) |
666 | #undef BINARYCONDITIONALOPERATOR |
667 | |
668 | #ifndef CONDITIONALOPERATOR |
669 | # define CONDITIONALOPERATOR(Type, Base) ABSTRACTCONDITIONALOPERATOR(Type, Base) |
670 | #endif |
671 | CONDITIONALOPERATOR(ConditionalOperator, AbstractConditionalOperator) |
672 | #undef CONDITIONALOPERATOR |
673 | |
674 | STMT_RANGE(AbstractConditionalOperator, BinaryConditionalOperator, ConditionalOperator) |
675 | |
676 | #undef ABSTRACTCONDITIONALOPERATOR |
677 | |
678 | #ifndef ADDRLABELEXPR |
679 | # define ADDRLABELEXPR(Type, Base) EXPR(Type, Base) |
680 | #endif |
681 | ADDRLABELEXPR(AddrLabelExpr, Expr) |
682 | #undef ADDRLABELEXPR |
683 | |
684 | #ifndef ARRAYINITINDEXEXPR |
685 | # define ARRAYINITINDEXEXPR(Type, Base) EXPR(Type, Base) |
686 | #endif |
687 | ARRAYINITINDEXEXPR(ArrayInitIndexExpr, Expr) |
688 | #undef ARRAYINITINDEXEXPR |
689 | |
690 | #ifndef ARRAYINITLOOPEXPR |
691 | # define ARRAYINITLOOPEXPR(Type, Base) EXPR(Type, Base) |
692 | #endif |
693 | ARRAYINITLOOPEXPR(ArrayInitLoopExpr, Expr) |
694 | #undef ARRAYINITLOOPEXPR |
695 | |
696 | #ifndef ARRAYSUBSCRIPTEXPR |
697 | # define ARRAYSUBSCRIPTEXPR(Type, Base) EXPR(Type, Base) |
698 | #endif |
699 | ARRAYSUBSCRIPTEXPR(ArraySubscriptExpr, Expr) |
700 | #undef ARRAYSUBSCRIPTEXPR |
701 | |
702 | #ifndef ARRAYTYPETRAITEXPR |
703 | # define ARRAYTYPETRAITEXPR(Type, Base) EXPR(Type, Base) |
704 | #endif |
705 | ARRAYTYPETRAITEXPR(ArrayTypeTraitExpr, Expr) |
706 | #undef ARRAYTYPETRAITEXPR |
707 | |
708 | #ifndef ASTYPEEXPR |
709 | # define ASTYPEEXPR(Type, Base) EXPR(Type, Base) |
710 | #endif |
711 | ASTYPEEXPR(AsTypeExpr, Expr) |
712 | #undef ASTYPEEXPR |
713 | |
714 | #ifndef ATOMICEXPR |
715 | # define ATOMICEXPR(Type, Base) EXPR(Type, Base) |
716 | #endif |
717 | ATOMICEXPR(AtomicExpr, Expr) |
718 | #undef ATOMICEXPR |
719 | |
720 | #ifndef BINARYOPERATOR |
721 | # define BINARYOPERATOR(Type, Base) EXPR(Type, Base) |
722 | #endif |
723 | BINARYOPERATOR(BinaryOperator, Expr) |
724 | #ifndef COMPOUNDASSIGNOPERATOR |
725 | # define COMPOUNDASSIGNOPERATOR(Type, Base) BINARYOPERATOR(Type, Base) |
726 | #endif |
727 | COMPOUNDASSIGNOPERATOR(CompoundAssignOperator, BinaryOperator) |
728 | #undef COMPOUNDASSIGNOPERATOR |
729 | |
730 | STMT_RANGE(BinaryOperator, BinaryOperator, CompoundAssignOperator) |
731 | |
732 | #undef BINARYOPERATOR |
733 | |
734 | #ifndef BLOCKEXPR |
735 | # define BLOCKEXPR(Type, Base) EXPR(Type, Base) |
736 | #endif |
737 | BLOCKEXPR(BlockExpr, Expr) |
738 | #undef BLOCKEXPR |
739 | |
740 | #ifndef CXXBINDTEMPORARYEXPR |
741 | # define CXXBINDTEMPORARYEXPR(Type, Base) EXPR(Type, Base) |
742 | #endif |
743 | CXXBINDTEMPORARYEXPR(CXXBindTemporaryExpr, Expr) |
744 | #undef CXXBINDTEMPORARYEXPR |
745 | |
746 | #ifndef CXXBOOLLITERALEXPR |
747 | # define CXXBOOLLITERALEXPR(Type, Base) EXPR(Type, Base) |
748 | #endif |
749 | CXXBOOLLITERALEXPR(CXXBoolLiteralExpr, Expr) |
750 | #undef CXXBOOLLITERALEXPR |
751 | |
752 | #ifndef CXXCONSTRUCTEXPR |
753 | # define CXXCONSTRUCTEXPR(Type, Base) EXPR(Type, Base) |
754 | #endif |
755 | CXXCONSTRUCTEXPR(CXXConstructExpr, Expr) |
756 | #ifndef CXXTEMPORARYOBJECTEXPR |
757 | # define CXXTEMPORARYOBJECTEXPR(Type, Base) CXXCONSTRUCTEXPR(Type, Base) |
758 | #endif |
759 | CXXTEMPORARYOBJECTEXPR(CXXTemporaryObjectExpr, CXXConstructExpr) |
760 | #undef CXXTEMPORARYOBJECTEXPR |
761 | |
762 | STMT_RANGE(CXXConstructExpr, CXXConstructExpr, CXXTemporaryObjectExpr) |
763 | |
764 | #undef CXXCONSTRUCTEXPR |
765 | |
766 | #ifndef CXXDEFAULTARGEXPR |
767 | # define CXXDEFAULTARGEXPR(Type, Base) EXPR(Type, Base) |
768 | #endif |
769 | CXXDEFAULTARGEXPR(CXXDefaultArgExpr, Expr) |
770 | #undef CXXDEFAULTARGEXPR |
771 | |
772 | #ifndef CXXDEFAULTINITEXPR |
773 | # define CXXDEFAULTINITEXPR(Type, Base) EXPR(Type, Base) |
774 | #endif |
775 | CXXDEFAULTINITEXPR(CXXDefaultInitExpr, Expr) |
776 | #undef CXXDEFAULTINITEXPR |
777 | |
778 | #ifndef CXXDELETEEXPR |
779 | # define CXXDELETEEXPR(Type, Base) EXPR(Type, Base) |
780 | #endif |
781 | CXXDELETEEXPR(CXXDeleteExpr, Expr) |
782 | #undef CXXDELETEEXPR |
783 | |
784 | #ifndef CXXDEPENDENTSCOPEMEMBEREXPR |
785 | # define CXXDEPENDENTSCOPEMEMBEREXPR(Type, Base) EXPR(Type, Base) |
786 | #endif |
787 | CXXDEPENDENTSCOPEMEMBEREXPR(CXXDependentScopeMemberExpr, Expr) |
788 | #undef CXXDEPENDENTSCOPEMEMBEREXPR |
789 | |
790 | #ifndef CXXFOLDEXPR |
791 | # define CXXFOLDEXPR(Type, Base) EXPR(Type, Base) |
792 | #endif |
793 | CXXFOLDEXPR(CXXFoldExpr, Expr) |
794 | #undef CXXFOLDEXPR |
795 | |
796 | #ifndef CXXINHERITEDCTORINITEXPR |
797 | # define CXXINHERITEDCTORINITEXPR(Type, Base) EXPR(Type, Base) |
798 | #endif |
799 | CXXINHERITEDCTORINITEXPR(CXXInheritedCtorInitExpr, Expr) |
800 | #undef CXXINHERITEDCTORINITEXPR |
801 | |
802 | #ifndef CXXNEWEXPR |
803 | # define CXXNEWEXPR(Type, Base) EXPR(Type, Base) |
804 | #endif |
805 | CXXNEWEXPR(CXXNewExpr, Expr) |
806 | #undef CXXNEWEXPR |
807 | |
808 | #ifndef CXXNOEXCEPTEXPR |
809 | # define CXXNOEXCEPTEXPR(Type, Base) EXPR(Type, Base) |
810 | #endif |
811 | CXXNOEXCEPTEXPR(CXXNoexceptExpr, Expr) |
812 | #undef CXXNOEXCEPTEXPR |
813 | |
814 | #ifndef CXXNULLPTRLITERALEXPR |
815 | # define CXXNULLPTRLITERALEXPR(Type, Base) EXPR(Type, Base) |
816 | #endif |
817 | CXXNULLPTRLITERALEXPR(CXXNullPtrLiteralExpr, Expr) |
818 | #undef CXXNULLPTRLITERALEXPR |
819 | |
820 | #ifndef CXXPSEUDODESTRUCTOREXPR |
821 | # define CXXPSEUDODESTRUCTOREXPR(Type, Base) EXPR(Type, Base) |
822 | #endif |
823 | CXXPSEUDODESTRUCTOREXPR(CXXPseudoDestructorExpr, Expr) |
824 | #undef CXXPSEUDODESTRUCTOREXPR |
825 | |
826 | #ifndef CXXREWRITTENBINARYOPERATOR |
827 | # define CXXREWRITTENBINARYOPERATOR(Type, Base) EXPR(Type, Base) |
828 | #endif |
829 | CXXREWRITTENBINARYOPERATOR(CXXRewrittenBinaryOperator, Expr) |
830 | #undef CXXREWRITTENBINARYOPERATOR |
831 | |
832 | #ifndef CXXSCALARVALUEINITEXPR |
833 | # define CXXSCALARVALUEINITEXPR(Type, Base) EXPR(Type, Base) |
834 | #endif |
835 | CXXSCALARVALUEINITEXPR(CXXScalarValueInitExpr, Expr) |
836 | #undef CXXSCALARVALUEINITEXPR |
837 | |
838 | #ifndef CXXSTDINITIALIZERLISTEXPR |
839 | # define CXXSTDINITIALIZERLISTEXPR(Type, Base) EXPR(Type, Base) |
840 | #endif |
841 | CXXSTDINITIALIZERLISTEXPR(CXXStdInitializerListExpr, Expr) |
842 | #undef CXXSTDINITIALIZERLISTEXPR |
843 | |
844 | #ifndef CXXTHISEXPR |
845 | # define CXXTHISEXPR(Type, Base) EXPR(Type, Base) |
846 | #endif |
847 | CXXTHISEXPR(CXXThisExpr, Expr) |
848 | #undef CXXTHISEXPR |
849 | |
850 | #ifndef CXXTHROWEXPR |
851 | # define CXXTHROWEXPR(Type, Base) EXPR(Type, Base) |
852 | #endif |
853 | CXXTHROWEXPR(CXXThrowExpr, Expr) |
854 | #undef CXXTHROWEXPR |
855 | |
856 | #ifndef CXXTYPEIDEXPR |
857 | # define CXXTYPEIDEXPR(Type, Base) EXPR(Type, Base) |
858 | #endif |
859 | CXXTYPEIDEXPR(CXXTypeidExpr, Expr) |
860 | #undef CXXTYPEIDEXPR |
861 | |
862 | #ifndef CXXUNRESOLVEDCONSTRUCTEXPR |
863 | # define CXXUNRESOLVEDCONSTRUCTEXPR(Type, Base) EXPR(Type, Base) |
864 | #endif |
865 | CXXUNRESOLVEDCONSTRUCTEXPR(CXXUnresolvedConstructExpr, Expr) |
866 | #undef CXXUNRESOLVEDCONSTRUCTEXPR |
867 | |
868 | #ifndef CXXUUIDOFEXPR |
869 | # define CXXUUIDOFEXPR(Type, Base) EXPR(Type, Base) |
870 | #endif |
871 | CXXUUIDOFEXPR(CXXUuidofExpr, Expr) |
872 | #undef CXXUUIDOFEXPR |
873 | |
874 | #ifndef CALLEXPR |
875 | # define CALLEXPR(Type, Base) EXPR(Type, Base) |
876 | #endif |
877 | CALLEXPR(CallExpr, Expr) |
878 | #ifndef CUDAKERNELCALLEXPR |
879 | # define CUDAKERNELCALLEXPR(Type, Base) CALLEXPR(Type, Base) |
880 | #endif |
881 | CUDAKERNELCALLEXPR(CUDAKernelCallExpr, CallExpr) |
882 | #undef CUDAKERNELCALLEXPR |
883 | |
884 | #ifndef CXXMEMBERCALLEXPR |
885 | # define CXXMEMBERCALLEXPR(Type, Base) CALLEXPR(Type, Base) |
886 | #endif |
887 | CXXMEMBERCALLEXPR(CXXMemberCallExpr, CallExpr) |
888 | #undef CXXMEMBERCALLEXPR |
889 | |
890 | #ifndef CXXOPERATORCALLEXPR |
891 | # define CXXOPERATORCALLEXPR(Type, Base) CALLEXPR(Type, Base) |
892 | #endif |
893 | CXXOPERATORCALLEXPR(CXXOperatorCallExpr, CallExpr) |
894 | #undef CXXOPERATORCALLEXPR |
895 | |
896 | #ifndef USERDEFINEDLITERAL |
897 | # define USERDEFINEDLITERAL(Type, Base) CALLEXPR(Type, Base) |
898 | #endif |
899 | USERDEFINEDLITERAL(UserDefinedLiteral, CallExpr) |
900 | #undef USERDEFINEDLITERAL |
901 | |
902 | STMT_RANGE(CallExpr, CallExpr, UserDefinedLiteral) |
903 | |
904 | #undef CALLEXPR |
905 | |
906 | #ifndef CASTEXPR |
907 | # define CASTEXPR(Type, Base) EXPR(Type, Base) |
908 | #endif |
909 | ABSTRACT_STMT(CASTEXPR(CastExpr, Expr)) |
910 | #ifndef EXPLICITCASTEXPR |
911 | # define EXPLICITCASTEXPR(Type, Base) CASTEXPR(Type, Base) |
912 | #endif |
913 | ABSTRACT_STMT(EXPLICITCASTEXPR(ExplicitCastExpr, CastExpr)) |
914 | #ifndef BUILTINBITCASTEXPR |
915 | # define BUILTINBITCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base) |
916 | #endif |
917 | BUILTINBITCASTEXPR(BuiltinBitCastExpr, ExplicitCastExpr) |
918 | #undef BUILTINBITCASTEXPR |
919 | |
920 | #ifndef CSTYLECASTEXPR |
921 | # define CSTYLECASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base) |
922 | #endif |
923 | CSTYLECASTEXPR(CStyleCastExpr, ExplicitCastExpr) |
924 | #undef CSTYLECASTEXPR |
925 | |
926 | #ifndef CXXFUNCTIONALCASTEXPR |
927 | # define CXXFUNCTIONALCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base) |
928 | #endif |
929 | CXXFUNCTIONALCASTEXPR(CXXFunctionalCastExpr, ExplicitCastExpr) |
930 | #undef CXXFUNCTIONALCASTEXPR |
931 | |
932 | #ifndef CXXNAMEDCASTEXPR |
933 | # define CXXNAMEDCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base) |
934 | #endif |
935 | ABSTRACT_STMT(CXXNAMEDCASTEXPR(CXXNamedCastExpr, ExplicitCastExpr)) |
936 | #ifndef CXXADDRSPACECASTEXPR |
937 | # define CXXADDRSPACECASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base) |
938 | #endif |
939 | CXXADDRSPACECASTEXPR(CXXAddrspaceCastExpr, CXXNamedCastExpr) |
940 | #undef CXXADDRSPACECASTEXPR |
941 | |
942 | #ifndef CXXCONSTCASTEXPR |
943 | # define CXXCONSTCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base) |
944 | #endif |
945 | CXXCONSTCASTEXPR(CXXConstCastExpr, CXXNamedCastExpr) |
946 | #undef CXXCONSTCASTEXPR |
947 | |
948 | #ifndef CXXDYNAMICCASTEXPR |
949 | # define CXXDYNAMICCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base) |
950 | #endif |
951 | CXXDYNAMICCASTEXPR(CXXDynamicCastExpr, CXXNamedCastExpr) |
952 | #undef CXXDYNAMICCASTEXPR |
953 | |
954 | #ifndef CXXREINTERPRETCASTEXPR |
955 | # define CXXREINTERPRETCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base) |
956 | #endif |
957 | CXXREINTERPRETCASTEXPR(CXXReinterpretCastExpr, CXXNamedCastExpr) |
958 | #undef CXXREINTERPRETCASTEXPR |
959 | |
960 | #ifndef CXXSTATICCASTEXPR |
961 | # define CXXSTATICCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base) |
962 | #endif |
963 | CXXSTATICCASTEXPR(CXXStaticCastExpr, CXXNamedCastExpr) |
964 | #undef CXXSTATICCASTEXPR |
965 | |
966 | STMT_RANGE(CXXNamedCastExpr, CXXAddrspaceCastExpr, CXXStaticCastExpr) |
967 | |
968 | #undef CXXNAMEDCASTEXPR |
969 | |
970 | #ifndef OBJCBRIDGEDCASTEXPR |
971 | # define OBJCBRIDGEDCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base) |
972 | #endif |
973 | OBJCBRIDGEDCASTEXPR(ObjCBridgedCastExpr, ExplicitCastExpr) |
974 | #undef OBJCBRIDGEDCASTEXPR |
975 | |
976 | STMT_RANGE(ExplicitCastExpr, BuiltinBitCastExpr, ObjCBridgedCastExpr) |
977 | |
978 | #undef EXPLICITCASTEXPR |
979 | |
980 | #ifndef IMPLICITCASTEXPR |
981 | # define IMPLICITCASTEXPR(Type, Base) CASTEXPR(Type, Base) |
982 | #endif |
983 | IMPLICITCASTEXPR(ImplicitCastExpr, CastExpr) |
984 | #undef IMPLICITCASTEXPR |
985 | |
986 | STMT_RANGE(CastExpr, BuiltinBitCastExpr, ImplicitCastExpr) |
987 | |
988 | #undef CASTEXPR |
989 | |
990 | #ifndef CHARACTERLITERAL |
991 | # define CHARACTERLITERAL(Type, Base) EXPR(Type, Base) |
992 | #endif |
993 | CHARACTERLITERAL(CharacterLiteral, Expr) |
994 | #undef CHARACTERLITERAL |
995 | |
996 | #ifndef CHOOSEEXPR |
997 | # define CHOOSEEXPR(Type, Base) EXPR(Type, Base) |
998 | #endif |
999 | CHOOSEEXPR(ChooseExpr, Expr) |
1000 | #undef CHOOSEEXPR |
1001 | |
1002 | #ifndef COMPOUNDLITERALEXPR |
1003 | # define COMPOUNDLITERALEXPR(Type, Base) EXPR(Type, Base) |
1004 | #endif |
1005 | COMPOUNDLITERALEXPR(CompoundLiteralExpr, Expr) |
1006 | #undef COMPOUNDLITERALEXPR |
1007 | |
1008 | #ifndef CONCEPTSPECIALIZATIONEXPR |
1009 | # define CONCEPTSPECIALIZATIONEXPR(Type, Base) EXPR(Type, Base) |
1010 | #endif |
1011 | CONCEPTSPECIALIZATIONEXPR(ConceptSpecializationExpr, Expr) |
1012 | #undef CONCEPTSPECIALIZATIONEXPR |
1013 | |
1014 | #ifndef CONVERTVECTOREXPR |
1015 | # define CONVERTVECTOREXPR(Type, Base) EXPR(Type, Base) |
1016 | #endif |
1017 | CONVERTVECTOREXPR(ConvertVectorExpr, Expr) |
1018 | #undef CONVERTVECTOREXPR |
1019 | |
1020 | #ifndef COROUTINESUSPENDEXPR |
1021 | # define COROUTINESUSPENDEXPR(Type, Base) EXPR(Type, Base) |
1022 | #endif |
1023 | ABSTRACT_STMT(COROUTINESUSPENDEXPR(CoroutineSuspendExpr, Expr)) |
1024 | #ifndef COAWAITEXPR |
1025 | # define COAWAITEXPR(Type, Base) COROUTINESUSPENDEXPR(Type, Base) |
1026 | #endif |
1027 | COAWAITEXPR(CoawaitExpr, CoroutineSuspendExpr) |
1028 | #undef COAWAITEXPR |
1029 | |
1030 | #ifndef COYIELDEXPR |
1031 | # define COYIELDEXPR(Type, Base) COROUTINESUSPENDEXPR(Type, Base) |
1032 | #endif |
1033 | COYIELDEXPR(CoyieldExpr, CoroutineSuspendExpr) |
1034 | #undef COYIELDEXPR |
1035 | |
1036 | STMT_RANGE(CoroutineSuspendExpr, CoawaitExpr, CoyieldExpr) |
1037 | |
1038 | #undef COROUTINESUSPENDEXPR |
1039 | |
1040 | #ifndef DECLREFEXPR |
1041 | # define DECLREFEXPR(Type, Base) EXPR(Type, Base) |
1042 | #endif |
1043 | DECLREFEXPR(DeclRefExpr, Expr) |
1044 | #undef DECLREFEXPR |
1045 | |
1046 | #ifndef DEPENDENTCOAWAITEXPR |
1047 | # define DEPENDENTCOAWAITEXPR(Type, Base) EXPR(Type, Base) |
1048 | #endif |
1049 | DEPENDENTCOAWAITEXPR(DependentCoawaitExpr, Expr) |
1050 | #undef DEPENDENTCOAWAITEXPR |
1051 | |
1052 | #ifndef DEPENDENTSCOPEDECLREFEXPR |
1053 | # define DEPENDENTSCOPEDECLREFEXPR(Type, Base) EXPR(Type, Base) |
1054 | #endif |
1055 | DEPENDENTSCOPEDECLREFEXPR(DependentScopeDeclRefExpr, Expr) |
1056 | #undef DEPENDENTSCOPEDECLREFEXPR |
1057 | |
1058 | #ifndef DESIGNATEDINITEXPR |
1059 | # define DESIGNATEDINITEXPR(Type, Base) EXPR(Type, Base) |
1060 | #endif |
1061 | DESIGNATEDINITEXPR(DesignatedInitExpr, Expr) |
1062 | #undef DESIGNATEDINITEXPR |
1063 | |
1064 | #ifndef DESIGNATEDINITUPDATEEXPR |
1065 | # define DESIGNATEDINITUPDATEEXPR(Type, Base) EXPR(Type, Base) |
1066 | #endif |
1067 | DESIGNATEDINITUPDATEEXPR(DesignatedInitUpdateExpr, Expr) |
1068 | #undef DESIGNATEDINITUPDATEEXPR |
1069 | |
1070 | #ifndef EXPRESSIONTRAITEXPR |
1071 | # define EXPRESSIONTRAITEXPR(Type, Base) EXPR(Type, Base) |
1072 | #endif |
1073 | EXPRESSIONTRAITEXPR(ExpressionTraitExpr, Expr) |
1074 | #undef EXPRESSIONTRAITEXPR |
1075 | |
1076 | #ifndef EXTVECTORELEMENTEXPR |
1077 | # define EXTVECTORELEMENTEXPR(Type, Base) EXPR(Type, Base) |
1078 | #endif |
1079 | EXTVECTORELEMENTEXPR(ExtVectorElementExpr, Expr) |
1080 | #undef EXTVECTORELEMENTEXPR |
1081 | |
1082 | #ifndef FIXEDPOINTLITERAL |
1083 | # define FIXEDPOINTLITERAL(Type, Base) EXPR(Type, Base) |
1084 | #endif |
1085 | FIXEDPOINTLITERAL(FixedPointLiteral, Expr) |
1086 | #undef FIXEDPOINTLITERAL |
1087 | |
1088 | #ifndef FLOATINGLITERAL |
1089 | # define FLOATINGLITERAL(Type, Base) EXPR(Type, Base) |
1090 | #endif |
1091 | FLOATINGLITERAL(FloatingLiteral, Expr) |
1092 | #undef FLOATINGLITERAL |
1093 | |
1094 | #ifndef FULLEXPR |
1095 | # define FULLEXPR(Type, Base) EXPR(Type, Base) |
1096 | #endif |
1097 | ABSTRACT_STMT(FULLEXPR(FullExpr, Expr)) |
1098 | #ifndef CONSTANTEXPR |
1099 | # define CONSTANTEXPR(Type, Base) FULLEXPR(Type, Base) |
1100 | #endif |
1101 | CONSTANTEXPR(ConstantExpr, FullExpr) |
1102 | #undef CONSTANTEXPR |
1103 | |
1104 | #ifndef EXPRWITHCLEANUPS |
1105 | # define EXPRWITHCLEANUPS(Type, Base) FULLEXPR(Type, Base) |
1106 | #endif |
1107 | EXPRWITHCLEANUPS(ExprWithCleanups, FullExpr) |
1108 | #undef EXPRWITHCLEANUPS |
1109 | |
1110 | STMT_RANGE(FullExpr, ConstantExpr, ExprWithCleanups) |
1111 | |
1112 | #undef FULLEXPR |
1113 | |
1114 | #ifndef FUNCTIONPARMPACKEXPR |
1115 | # define FUNCTIONPARMPACKEXPR(Type, Base) EXPR(Type, Base) |
1116 | #endif |
1117 | FUNCTIONPARMPACKEXPR(FunctionParmPackExpr, Expr) |
1118 | #undef FUNCTIONPARMPACKEXPR |
1119 | |
1120 | #ifndef GNUNULLEXPR |
1121 | # define GNUNULLEXPR(Type, Base) EXPR(Type, Base) |
1122 | #endif |
1123 | GNUNULLEXPR(GNUNullExpr, Expr) |
1124 | #undef GNUNULLEXPR |
1125 | |
1126 | #ifndef GENERICSELECTIONEXPR |
1127 | # define GENERICSELECTIONEXPR(Type, Base) EXPR(Type, Base) |
1128 | #endif |
1129 | GENERICSELECTIONEXPR(GenericSelectionExpr, Expr) |
1130 | #undef GENERICSELECTIONEXPR |
1131 | |
1132 | #ifndef IMAGINARYLITERAL |
1133 | # define IMAGINARYLITERAL(Type, Base) EXPR(Type, Base) |
1134 | #endif |
1135 | IMAGINARYLITERAL(ImaginaryLiteral, Expr) |
1136 | #undef IMAGINARYLITERAL |
1137 | |
1138 | #ifndef IMPLICITVALUEINITEXPR |
1139 | # define IMPLICITVALUEINITEXPR(Type, Base) EXPR(Type, Base) |
1140 | #endif |
1141 | IMPLICITVALUEINITEXPR(ImplicitValueInitExpr, Expr) |
1142 | #undef IMPLICITVALUEINITEXPR |
1143 | |
1144 | #ifndef INITLISTEXPR |
1145 | # define INITLISTEXPR(Type, Base) EXPR(Type, Base) |
1146 | #endif |
1147 | INITLISTEXPR(InitListExpr, Expr) |
1148 | #undef INITLISTEXPR |
1149 | |
1150 | #ifndef INTEGERLITERAL |
1151 | # define INTEGERLITERAL(Type, Base) EXPR(Type, Base) |
1152 | #endif |
1153 | INTEGERLITERAL(IntegerLiteral, Expr) |
1154 | #undef INTEGERLITERAL |
1155 | |
1156 | #ifndef LAMBDAEXPR |
1157 | # define LAMBDAEXPR(Type, Base) EXPR(Type, Base) |
1158 | #endif |
1159 | LAMBDAEXPR(LambdaExpr, Expr) |
1160 | #undef LAMBDAEXPR |
1161 | |
1162 | #ifndef MSPROPERTYREFEXPR |
1163 | # define MSPROPERTYREFEXPR(Type, Base) EXPR(Type, Base) |
1164 | #endif |
1165 | MSPROPERTYREFEXPR(MSPropertyRefExpr, Expr) |
1166 | #undef MSPROPERTYREFEXPR |
1167 | |
1168 | #ifndef MSPROPERTYSUBSCRIPTEXPR |
1169 | # define MSPROPERTYSUBSCRIPTEXPR(Type, Base) EXPR(Type, Base) |
1170 | #endif |
1171 | MSPROPERTYSUBSCRIPTEXPR(MSPropertySubscriptExpr, Expr) |
1172 | #undef MSPROPERTYSUBSCRIPTEXPR |
1173 | |
1174 | #ifndef MATERIALIZETEMPORARYEXPR |
1175 | # define MATERIALIZETEMPORARYEXPR(Type, Base) EXPR(Type, Base) |
1176 | #endif |
1177 | MATERIALIZETEMPORARYEXPR(MaterializeTemporaryExpr, Expr) |
1178 | #undef MATERIALIZETEMPORARYEXPR |
1179 | |
1180 | #ifndef MATRIXSUBSCRIPTEXPR |
1181 | # define MATRIXSUBSCRIPTEXPR(Type, Base) EXPR(Type, Base) |
1182 | #endif |
1183 | MATRIXSUBSCRIPTEXPR(MatrixSubscriptExpr, Expr) |
1184 | #undef MATRIXSUBSCRIPTEXPR |
1185 | |
1186 | #ifndef MEMBEREXPR |
1187 | # define MEMBEREXPR(Type, Base) EXPR(Type, Base) |
1188 | #endif |
1189 | MEMBEREXPR(MemberExpr, Expr) |
1190 | #undef MEMBEREXPR |
1191 | |
1192 | #ifndef NOINITEXPR |
1193 | # define NOINITEXPR(Type, Base) EXPR(Type, Base) |
1194 | #endif |
1195 | NOINITEXPR(NoInitExpr, Expr) |
1196 | #undef NOINITEXPR |
1197 | |
1198 | #ifndef OMPARRAYSECTIONEXPR |
1199 | # define OMPARRAYSECTIONEXPR(Type, Base) EXPR(Type, Base) |
1200 | #endif |
1201 | OMPARRAYSECTIONEXPR(OMPArraySectionExpr, Expr) |
1202 | #undef OMPARRAYSECTIONEXPR |
1203 | |
1204 | #ifndef OMPARRAYSHAPINGEXPR |
1205 | # define OMPARRAYSHAPINGEXPR(Type, Base) EXPR(Type, Base) |
1206 | #endif |
1207 | OMPARRAYSHAPINGEXPR(OMPArrayShapingExpr, Expr) |
1208 | #undef OMPARRAYSHAPINGEXPR |
1209 | |
1210 | #ifndef OMPITERATOREXPR |
1211 | # define OMPITERATOREXPR(Type, Base) EXPR(Type, Base) |
1212 | #endif |
1213 | OMPITERATOREXPR(OMPIteratorExpr, Expr) |
1214 | #undef OMPITERATOREXPR |
1215 | |
1216 | #ifndef OBJCARRAYLITERAL |
1217 | # define OBJCARRAYLITERAL(Type, Base) EXPR(Type, Base) |
1218 | #endif |
1219 | OBJCARRAYLITERAL(ObjCArrayLiteral, Expr) |
1220 | #undef OBJCARRAYLITERAL |
1221 | |
1222 | #ifndef OBJCAVAILABILITYCHECKEXPR |
1223 | # define OBJCAVAILABILITYCHECKEXPR(Type, Base) EXPR(Type, Base) |
1224 | #endif |
1225 | OBJCAVAILABILITYCHECKEXPR(ObjCAvailabilityCheckExpr, Expr) |
1226 | #undef OBJCAVAILABILITYCHECKEXPR |
1227 | |
1228 | #ifndef OBJCBOOLLITERALEXPR |
1229 | # define OBJCBOOLLITERALEXPR(Type, Base) EXPR(Type, Base) |
1230 | #endif |
1231 | OBJCBOOLLITERALEXPR(ObjCBoolLiteralExpr, Expr) |
1232 | #undef OBJCBOOLLITERALEXPR |
1233 | |
1234 | #ifndef OBJCBOXEDEXPR |
1235 | # define OBJCBOXEDEXPR(Type, Base) EXPR(Type, Base) |
1236 | #endif |
1237 | OBJCBOXEDEXPR(ObjCBoxedExpr, Expr) |
1238 | #undef OBJCBOXEDEXPR |
1239 | |
1240 | #ifndef OBJCDICTIONARYLITERAL |
1241 | # define OBJCDICTIONARYLITERAL(Type, Base) EXPR(Type, Base) |
1242 | #endif |
1243 | OBJCDICTIONARYLITERAL(ObjCDictionaryLiteral, Expr) |
1244 | #undef OBJCDICTIONARYLITERAL |
1245 | |
1246 | #ifndef OBJCENCODEEXPR |
1247 | # define OBJCENCODEEXPR(Type, Base) EXPR(Type, Base) |
1248 | #endif |
1249 | OBJCENCODEEXPR(ObjCEncodeExpr, Expr) |
1250 | #undef OBJCENCODEEXPR |
1251 | |
1252 | #ifndef OBJCINDIRECTCOPYRESTOREEXPR |
1253 | # define OBJCINDIRECTCOPYRESTOREEXPR(Type, Base) EXPR(Type, Base) |
1254 | #endif |
1255 | OBJCINDIRECTCOPYRESTOREEXPR(ObjCIndirectCopyRestoreExpr, Expr) |
1256 | #undef OBJCINDIRECTCOPYRESTOREEXPR |
1257 | |
1258 | #ifndef OBJCISAEXPR |
1259 | # define OBJCISAEXPR(Type, Base) EXPR(Type, Base) |
1260 | #endif |
1261 | OBJCISAEXPR(ObjCIsaExpr, Expr) |
1262 | #undef OBJCISAEXPR |
1263 | |
1264 | #ifndef OBJCIVARREFEXPR |
1265 | # define OBJCIVARREFEXPR(Type, Base) EXPR(Type, Base) |
1266 | #endif |
1267 | OBJCIVARREFEXPR(ObjCIvarRefExpr, Expr) |
1268 | #undef OBJCIVARREFEXPR |
1269 | |
1270 | #ifndef OBJCMESSAGEEXPR |
1271 | # define OBJCMESSAGEEXPR(Type, Base) EXPR(Type, Base) |
1272 | #endif |
1273 | OBJCMESSAGEEXPR(ObjCMessageExpr, Expr) |
1274 | #undef OBJCMESSAGEEXPR |
1275 | |
1276 | #ifndef OBJCPROPERTYREFEXPR |
1277 | # define OBJCPROPERTYREFEXPR(Type, Base) EXPR(Type, Base) |
1278 | #endif |
1279 | OBJCPROPERTYREFEXPR(ObjCPropertyRefExpr, Expr) |
1280 | #undef OBJCPROPERTYREFEXPR |
1281 | |
1282 | #ifndef OBJCPROTOCOLEXPR |
1283 | # define OBJCPROTOCOLEXPR(Type, Base) EXPR(Type, Base) |
1284 | #endif |
1285 | OBJCPROTOCOLEXPR(ObjCProtocolExpr, Expr) |
1286 | #undef OBJCPROTOCOLEXPR |
1287 | |
1288 | #ifndef OBJCSELECTOREXPR |
1289 | # define OBJCSELECTOREXPR(Type, Base) EXPR(Type, Base) |
1290 | #endif |
1291 | OBJCSELECTOREXPR(ObjCSelectorExpr, Expr) |
1292 | #undef OBJCSELECTOREXPR |
1293 | |
1294 | #ifndef OBJCSTRINGLITERAL |
1295 | # define OBJCSTRINGLITERAL(Type, Base) EXPR(Type, Base) |
1296 | #endif |
1297 | OBJCSTRINGLITERAL(ObjCStringLiteral, Expr) |
1298 | #undef OBJCSTRINGLITERAL |
1299 | |
1300 | #ifndef OBJCSUBSCRIPTREFEXPR |
1301 | # define OBJCSUBSCRIPTREFEXPR(Type, Base) EXPR(Type, Base) |
1302 | #endif |
1303 | OBJCSUBSCRIPTREFEXPR(ObjCSubscriptRefExpr, Expr) |
1304 | #undef OBJCSUBSCRIPTREFEXPR |
1305 | |
1306 | #ifndef OFFSETOFEXPR |
1307 | # define OFFSETOFEXPR(Type, Base) EXPR(Type, Base) |
1308 | #endif |
1309 | OFFSETOFEXPR(OffsetOfExpr, Expr) |
1310 | #undef OFFSETOFEXPR |
1311 | |
1312 | #ifndef OPAQUEVALUEEXPR |
1313 | # define OPAQUEVALUEEXPR(Type, Base) EXPR(Type, Base) |
1314 | #endif |
1315 | OPAQUEVALUEEXPR(OpaqueValueExpr, Expr) |
1316 | #undef OPAQUEVALUEEXPR |
1317 | |
1318 | #ifndef OVERLOADEXPR |
1319 | # define OVERLOADEXPR(Type, Base) EXPR(Type, Base) |
1320 | #endif |
1321 | ABSTRACT_STMT(OVERLOADEXPR(OverloadExpr, Expr)) |
1322 | #ifndef UNRESOLVEDLOOKUPEXPR |
1323 | # define UNRESOLVEDLOOKUPEXPR(Type, Base) OVERLOADEXPR(Type, Base) |
1324 | #endif |
1325 | UNRESOLVEDLOOKUPEXPR(UnresolvedLookupExpr, OverloadExpr) |
1326 | #undef UNRESOLVEDLOOKUPEXPR |
1327 | |
1328 | #ifndef UNRESOLVEDMEMBEREXPR |
1329 | # define UNRESOLVEDMEMBEREXPR(Type, Base) OVERLOADEXPR(Type, Base) |
1330 | #endif |
1331 | UNRESOLVEDMEMBEREXPR(UnresolvedMemberExpr, OverloadExpr) |
1332 | #undef UNRESOLVEDMEMBEREXPR |
1333 | |
1334 | STMT_RANGE(OverloadExpr, UnresolvedLookupExpr, UnresolvedMemberExpr) |
1335 | |
1336 | #undef OVERLOADEXPR |
1337 | |
1338 | #ifndef PACKEXPANSIONEXPR |
1339 | # define PACKEXPANSIONEXPR(Type, Base) EXPR(Type, Base) |
1340 | #endif |
1341 | PACKEXPANSIONEXPR(PackExpansionExpr, Expr) |
1342 | #undef PACKEXPANSIONEXPR |
1343 | |
1344 | #ifndef PARENEXPR |
1345 | # define PARENEXPR(Type, Base) EXPR(Type, Base) |
1346 | #endif |
1347 | PARENEXPR(ParenExpr, Expr) |
1348 | #undef PARENEXPR |
1349 | |
1350 | #ifndef PARENLISTEXPR |
1351 | # define PARENLISTEXPR(Type, Base) EXPR(Type, Base) |
1352 | #endif |
1353 | PARENLISTEXPR(ParenListExpr, Expr) |
1354 | #undef PARENLISTEXPR |
1355 | |
1356 | #ifndef PREDEFINEDEXPR |
1357 | # define PREDEFINEDEXPR(Type, Base) EXPR(Type, Base) |
1358 | #endif |
1359 | PREDEFINEDEXPR(PredefinedExpr, Expr) |
1360 | #undef PREDEFINEDEXPR |
1361 | |
1362 | #ifndef PSEUDOOBJECTEXPR |
1363 | # define PSEUDOOBJECTEXPR(Type, Base) EXPR(Type, Base) |
1364 | #endif |
1365 | PSEUDOOBJECTEXPR(PseudoObjectExpr, Expr) |
1366 | #undef PSEUDOOBJECTEXPR |
1367 | |
1368 | #ifndef RECOVERYEXPR |
1369 | # define RECOVERYEXPR(Type, Base) EXPR(Type, Base) |
1370 | #endif |
1371 | RECOVERYEXPR(RecoveryExpr, Expr) |
1372 | #undef RECOVERYEXPR |
1373 | |
1374 | #ifndef REQUIRESEXPR |
1375 | # define REQUIRESEXPR(Type, Base) EXPR(Type, Base) |
1376 | #endif |
1377 | REQUIRESEXPR(RequiresExpr, Expr) |
1378 | #undef REQUIRESEXPR |
1379 | |
1380 | #ifndef SYCLUNIQUESTABLENAMEEXPR |
1381 | # define SYCLUNIQUESTABLENAMEEXPR(Type, Base) EXPR(Type, Base) |
1382 | #endif |
1383 | SYCLUNIQUESTABLENAMEEXPR(SYCLUniqueStableNameExpr, Expr) |
1384 | #undef SYCLUNIQUESTABLENAMEEXPR |
1385 | |
1386 | #ifndef SHUFFLEVECTOREXPR |
1387 | # define SHUFFLEVECTOREXPR(Type, Base) EXPR(Type, Base) |
1388 | #endif |
1389 | SHUFFLEVECTOREXPR(ShuffleVectorExpr, Expr) |
1390 | #undef SHUFFLEVECTOREXPR |
1391 | |
1392 | #ifndef SIZEOFPACKEXPR |
1393 | # define SIZEOFPACKEXPR(Type, Base) EXPR(Type, Base) |
1394 | #endif |
1395 | SIZEOFPACKEXPR(SizeOfPackExpr, Expr) |
1396 | #undef SIZEOFPACKEXPR |
1397 | |
1398 | #ifndef SOURCELOCEXPR |
1399 | # define SOURCELOCEXPR(Type, Base) EXPR(Type, Base) |
1400 | #endif |
1401 | SOURCELOCEXPR(SourceLocExpr, Expr) |
1402 | #undef SOURCELOCEXPR |
1403 | |
1404 | #ifndef STMTEXPR |
1405 | # define STMTEXPR(Type, Base) EXPR(Type, Base) |
1406 | #endif |
1407 | STMTEXPR(StmtExpr, Expr) |
1408 | #undef STMTEXPR |
1409 | |
1410 | #ifndef STRINGLITERAL |
1411 | # define STRINGLITERAL(Type, Base) EXPR(Type, Base) |
1412 | #endif |
1413 | STRINGLITERAL(StringLiteral, Expr) |
1414 | #undef STRINGLITERAL |
1415 | |
1416 | #ifndef SUBSTNONTYPETEMPLATEPARMEXPR |
1417 | # define SUBSTNONTYPETEMPLATEPARMEXPR(Type, Base) EXPR(Type, Base) |
1418 | #endif |
1419 | SUBSTNONTYPETEMPLATEPARMEXPR(SubstNonTypeTemplateParmExpr, Expr) |
1420 | #undef SUBSTNONTYPETEMPLATEPARMEXPR |
1421 | |
1422 | #ifndef SUBSTNONTYPETEMPLATEPARMPACKEXPR |
1423 | # define SUBSTNONTYPETEMPLATEPARMPACKEXPR(Type, Base) EXPR(Type, Base) |
1424 | #endif |
1425 | SUBSTNONTYPETEMPLATEPARMPACKEXPR(SubstNonTypeTemplateParmPackExpr, Expr) |
1426 | #undef SUBSTNONTYPETEMPLATEPARMPACKEXPR |
1427 | |
1428 | #ifndef TYPETRAITEXPR |
1429 | # define TYPETRAITEXPR(Type, Base) EXPR(Type, Base) |
1430 | #endif |
1431 | TYPETRAITEXPR(TypeTraitExpr, Expr) |
1432 | #undef TYPETRAITEXPR |
1433 | |
1434 | #ifndef TYPOEXPR |
1435 | # define TYPOEXPR(Type, Base) EXPR(Type, Base) |
1436 | #endif |
1437 | TYPOEXPR(TypoExpr, Expr) |
1438 | #undef TYPOEXPR |
1439 | |
1440 | #ifndef UNARYEXPRORTYPETRAITEXPR |
1441 | # define UNARYEXPRORTYPETRAITEXPR(Type, Base) EXPR(Type, Base) |
1442 | #endif |
1443 | UNARYEXPRORTYPETRAITEXPR(UnaryExprOrTypeTraitExpr, Expr) |
1444 | #undef UNARYEXPRORTYPETRAITEXPR |
1445 | |
1446 | #ifndef UNARYOPERATOR |
1447 | # define UNARYOPERATOR(Type, Base) EXPR(Type, Base) |
1448 | #endif |
1449 | UNARYOPERATOR(UnaryOperator, Expr) |
1450 | #undef UNARYOPERATOR |
1451 | |
1452 | #ifndef VAARGEXPR |
1453 | # define VAARGEXPR(Type, Base) EXPR(Type, Base) |
1454 | #endif |
1455 | VAARGEXPR(VAArgExpr, Expr) |
1456 | #undef VAARGEXPR |
1457 | |
1458 | STMT_RANGE(Expr, BinaryConditionalOperator, VAArgExpr) |
1459 | |
1460 | #undef EXPR |
1461 | |
1462 | #ifndef LABELSTMT |
1463 | # define LABELSTMT(Type, Base) VALUESTMT(Type, Base) |
1464 | #endif |
1465 | LABELSTMT(LabelStmt, ValueStmt) |
1466 | #undef LABELSTMT |
1467 | |
1468 | STMT_RANGE(ValueStmt, AttributedStmt, LabelStmt) |
1469 | |
1470 | #undef VALUESTMT |
1471 | |
1472 | #ifndef WHILESTMT |
1473 | # define WHILESTMT(Type, Base) STMT(Type, Base) |
1474 | #endif |
1475 | WHILESTMT(WhileStmt, Stmt) |
1476 | #undef WHILESTMT |
1477 | |
1478 | LAST_STMT_RANGE(Stmt, GCCAsmStmt, WhileStmt) |
1479 | |
1480 | #undef STMT |
1481 | #undef STMT_RANGE |
1482 | #undef LAST_STMT_RANGE |
1483 | #undef ABSTRACT_STMT |