Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include/clang/AST/RecursiveASTVisitor.h
Warning:line 345, column 55
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name FunctionCognitiveComplexityCheck.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-15/lib/clang/15.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/tools/extra/clang-tidy/readability -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang-tools-extra/clang-tidy/readability -I tools/clang/tools/extra/clang-tidy -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-15/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-04-20-140412-16051-1 -x c++ /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp

/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp

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
34using namespace clang::ast_matchers;
35
36namespace clang {
37namespace tidy {
38namespace readability {
39namespace {
40
41struct 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.
155static 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.
170CognitiveComplexity::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}
178CognitiveComplexity::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}
186CognitiveComplexity::Criteria &operator|=(CognitiveComplexity::Criteria &LHS,
187 CognitiveComplexity::Criteria RHS) {
188 LHS = operator|(LHS, RHS);
189 return LHS;
190}
191CognitiveComplexity::Criteria &operator&=(CognitiveComplexity::Criteria &LHS,
192 CognitiveComplexity::Criteria RHS) {
193 LHS = operator&(LHS, RHS);
194 return LHS;
195}
196
197void 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
212class 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
228public:
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)
1
Assuming 'Node' is null
356 return Base::TraverseCallExpr(Node);
2
Passing null pointer value via 1st parameter 'S'
3
Calling 'RecursiveASTVisitor::TraverseCallExpr'
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 Location = cast<ConditionalOperator>(Node)->getQuestionLoc();
448 }
449
450 // If we have found any reasons, let's account it.
451 if (Reasons & CognitiveComplexity::Criteria::All)
452 CC.account(Location, CurrentNestingLevel, Reasons);
453
454 // Did we decide that the nesting level should be increased?
455 if (!(Reasons & CognitiveComplexity::Criteria::IncrementNesting))
456 return Base::TraverseStmt(Node);
457
458 return traverseStmtWithIncreasedNestingLevel(Node);
459 }
460
461 // The parameter MainAnalyzedFunction is needed to differentiate between the
462 // cases where TraverseDecl() is the entry point from
463 // FunctionCognitiveComplexityCheck::check() and the cases where it was called
464 // from the FunctionASTVisitor itself. Explanation: if we get a function
465 // definition (e.g. constructor, destructor, method), the Cognitive Complexity
466 // specification states that the Nesting level shall be increased. But if this
467 // function is the entry point, then the Nesting level should not be
468 // increased. Thus that parameter is there and is used to fall-through
469 // directly to traversing if this is the main function that is being analyzed.
470 bool TraverseDecl(Decl *Node, bool MainAnalyzedFunction = false) {
471 if (!Node || MainAnalyzedFunction)
472 return Base::TraverseDecl(Node);
473
474 // B2. Nesting level
475 // The following structures increment the nesting level:
476 switch (Node->getKind()) {
477 case Decl::Function:
478 case Decl::CXXMethod:
479 case Decl::CXXConstructor:
480 case Decl::CXXDestructor:
481 case Decl::Block:
482 break;
483 default:
484 // If this is something else, we use early return!
485 return Base::TraverseDecl(Node);
486 break;
487 }
488
489 CC.account(Node->getBeginLoc(), CurrentNestingLevel,
490 CognitiveComplexity::Criteria::IncrementNesting);
491
492 return traverseDeclWithIncreasedNestingLevel(Node);
493 }
494
495 CognitiveComplexity CC;
496};
497
498} // namespace
499
500FunctionCognitiveComplexityCheck::FunctionCognitiveComplexityCheck(
501 StringRef Name, ClangTidyContext *Context)
502 : ClangTidyCheck(Name, Context),
503 Threshold(Options.get("Threshold", CognitiveComplexity::DefaultLimit)),
504 DescribeBasicIncrements(Options.get("DescribeBasicIncrements", true)),
505 IgnoreMacros(Options.get("IgnoreMacros", false)) {}
506
507void FunctionCognitiveComplexityCheck::storeOptions(
508 ClangTidyOptions::OptionMap &Opts) {
509 Options.store(Opts, "Threshold", Threshold);
510 Options.store(Opts, "DescribeBasicIncrements", DescribeBasicIncrements);
511 Options.store(Opts, "IgnoreMacros", IgnoreMacros);
512}
513
514void FunctionCognitiveComplexityCheck::registerMatchers(MatchFinder *Finder) {
515 Finder->addMatcher(
516 functionDecl(isDefinition(),
517 unless(anyOf(isDefaulted(), isDeleted(), isWeak())))
518 .bind("func"),
519 this);
520 Finder->addMatcher(lambdaExpr().bind("lambda"), this);
521}
522
523void FunctionCognitiveComplexityCheck::check(
524 const MatchFinder::MatchResult &Result) {
525
526 FunctionASTVisitor Visitor(IgnoreMacros);
527 SourceLocation Loc;
528
529 const auto *TheDecl = Result.Nodes.getNodeAs<FunctionDecl>("func");
530 const auto *TheLambdaExpr = Result.Nodes.getNodeAs<LambdaExpr>("lambda");
531 if (TheDecl) {
532 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"
, 534, __extension__ __PRETTY_FUNCTION__))
533 "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"
, 534, __extension__ __PRETTY_FUNCTION__))
534 "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"
, 534, __extension__ __PRETTY_FUNCTION__))
;
535 Loc = TheDecl->getLocation();
536 Visitor.TraverseDecl(const_cast<FunctionDecl *>(TheDecl), true);
537 } else {
538 Loc = TheLambdaExpr->getBeginLoc();
539 Visitor.TraverseLambdaExpr(const_cast<LambdaExpr *>(TheLambdaExpr));
540 }
541
542 if (Visitor.CC.Total <= Threshold)
543 return;
544
545 if (TheDecl)
546 diag(Loc, "function %0 has cognitive complexity of %1 (threshold %2)")
547 << TheDecl << Visitor.CC.Total << Threshold;
548 else
549 diag(Loc, "lambda has cognitive complexity of %0 (threshold %1)")
550 << Visitor.CC.Total << Threshold;
551
552 if (!DescribeBasicIncrements)
553 return;
554
555 // Output all the basic increments of complexity.
556 for (const auto &Detail : Visitor.CC.Details) {
557 unsigned MsgId; // The id of the message to output.
558 unsigned short Increase; // How much of an increment?
559 std::tie(MsgId, Increase) = Detail.process();
560 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"
, 560, __extension__ __PRETTY_FUNCTION__))
;
561 // Increase, on the other hand, can be 0.
562
563 diag(Detail.Loc, Msgs[MsgId], DiagnosticIDs::Note)
564 << (unsigned)Increase << (unsigned)Detail.Nesting << 1 + Detail.Nesting;
565 }
566}
567
568} // namespace readability
569} // namespace tidy
570} // namespace clang

/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include/clang/AST/RecursiveASTVisitor.h

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