Thanks to visit codestin.com
Credit goes to clang.llvm.org

clang 22.0.0git
StmtProfile.cpp
Go to the documentation of this file.
1//===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
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 implements the Stmt::Profile method, which builds a unique bit
10// representation that identifies a statement/expression.
11//
12//===----------------------------------------------------------------------===//
14#include "clang/AST/DeclCXX.h"
15#include "clang/AST/DeclObjC.h"
17#include "clang/AST/Expr.h"
18#include "clang/AST/ExprCXX.h"
19#include "clang/AST/ExprObjC.h"
21#include "clang/AST/ODRHash.h"
24#include "llvm/ADT/FoldingSet.h"
25using namespace clang;
26
27namespace {
28 class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
29 protected:
30 llvm::FoldingSetNodeID &ID;
31 bool Canonical;
32 bool ProfileLambdaExpr;
33
34 public:
35 StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical,
36 bool ProfileLambdaExpr)
37 : ID(ID), Canonical(Canonical), ProfileLambdaExpr(ProfileLambdaExpr) {}
38
39 virtual ~StmtProfiler() {}
40
41 void VisitStmt(const Stmt *S);
42
43 void VisitStmtNoChildren(const Stmt *S) {
44 HandleStmtClass(S->getStmtClass());
45 }
46
47 virtual void HandleStmtClass(Stmt::StmtClass SC) = 0;
48
49#define STMT(Node, Base) void Visit##Node(const Node *S);
50#include "clang/AST/StmtNodes.inc"
51
52 /// Visit a declaration that is referenced within an expression
53 /// or statement.
54 virtual void VisitDecl(const Decl *D) = 0;
55
56 /// Visit a type that is referenced within an expression or
57 /// statement.
58 virtual void VisitType(QualType T) = 0;
59
60 /// Visit a name that occurs within an expression or statement.
61 virtual void VisitName(DeclarationName Name, bool TreatAsDecl = false) = 0;
62
63 /// Visit identifiers that are not in Decl's or Type's.
64 virtual void VisitIdentifierInfo(const IdentifierInfo *II) = 0;
65
66 /// Visit a nested-name-specifier that occurs within an expression
67 /// or statement.
68 virtual void VisitNestedNameSpecifier(NestedNameSpecifier NNS) = 0;
69
70 /// Visit a template name that occurs within an expression or
71 /// statement.
72 virtual void VisitTemplateName(TemplateName Name) = 0;
73
74 /// Visit template arguments that occur within an expression or
75 /// statement.
76 void VisitTemplateArguments(const TemplateArgumentLoc *Args,
77 unsigned NumArgs);
78
79 /// Visit a single template argument.
80 void VisitTemplateArgument(const TemplateArgument &Arg);
81 };
82
83 class StmtProfilerWithPointers : public StmtProfiler {
84 const ASTContext &Context;
85
86 public:
87 StmtProfilerWithPointers(llvm::FoldingSetNodeID &ID,
88 const ASTContext &Context, bool Canonical,
89 bool ProfileLambdaExpr)
90 : StmtProfiler(ID, Canonical, ProfileLambdaExpr), Context(Context) {}
91
92 private:
93 void HandleStmtClass(Stmt::StmtClass SC) override {
94 ID.AddInteger(SC);
95 }
96
97 void VisitDecl(const Decl *D) override {
98 ID.AddInteger(D ? D->getKind() : 0);
99
100 if (Canonical && D) {
101 if (const NonTypeTemplateParmDecl *NTTP =
102 dyn_cast<NonTypeTemplateParmDecl>(D)) {
103 ID.AddInteger(NTTP->getDepth());
104 ID.AddInteger(NTTP->getIndex());
105 ID.AddBoolean(NTTP->isParameterPack());
106 // C++20 [temp.over.link]p6:
107 // Two template-parameters are equivalent under the following
108 // conditions: [...] if they declare non-type template parameters,
109 // they have equivalent types ignoring the use of type-constraints
110 // for placeholder types
111 //
112 // TODO: Why do we need to include the type in the profile? It's not
113 // part of the mangling.
114 VisitType(Context.getUnconstrainedType(NTTP->getType()));
115 return;
116 }
117
118 if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
119 // The Itanium C++ ABI uses the type, scope depth, and scope
120 // index of a parameter when mangling expressions that involve
121 // function parameters, so we will use the parameter's type for
122 // establishing function parameter identity. That way, our
123 // definition of "equivalent" (per C++ [temp.over.link]) is at
124 // least as strong as the definition of "equivalent" used for
125 // name mangling.
126 //
127 // TODO: The Itanium C++ ABI only uses the top-level cv-qualifiers,
128 // not the entirety of the type.
129 VisitType(Parm->getType());
130 ID.AddInteger(Parm->getFunctionScopeDepth());
131 ID.AddInteger(Parm->getFunctionScopeIndex());
132 return;
133 }
134
135 if (const TemplateTypeParmDecl *TTP =
136 dyn_cast<TemplateTypeParmDecl>(D)) {
137 ID.AddInteger(TTP->getDepth());
138 ID.AddInteger(TTP->getIndex());
139 ID.AddBoolean(TTP->isParameterPack());
140 return;
141 }
142
143 if (const TemplateTemplateParmDecl *TTP =
144 dyn_cast<TemplateTemplateParmDecl>(D)) {
145 ID.AddInteger(TTP->getDepth());
146 ID.AddInteger(TTP->getIndex());
147 ID.AddBoolean(TTP->isParameterPack());
148 return;
149 }
150 }
151
152 ID.AddPointer(D ? D->getCanonicalDecl() : nullptr);
153 }
154
155 void VisitType(QualType T) override {
156 if (Canonical && !T.isNull())
157 T = Context.getCanonicalType(T);
158
159 ID.AddPointer(T.getAsOpaquePtr());
160 }
161
162 void VisitName(DeclarationName Name, bool /*TreatAsDecl*/) override {
163 ID.AddPointer(Name.getAsOpaquePtr());
164 }
165
166 void VisitIdentifierInfo(const IdentifierInfo *II) override {
167 ID.AddPointer(II);
168 }
169
170 void VisitNestedNameSpecifier(NestedNameSpecifier NNS) override {
171 if (Canonical)
172 NNS = NNS.getCanonical();
173 NNS.Profile(ID);
174 }
175
176 void VisitTemplateName(TemplateName Name) override {
177 if (Canonical)
178 Name = Context.getCanonicalTemplateName(Name);
179
180 Name.Profile(ID);
181 }
182 };
183
184 class StmtProfilerWithoutPointers : public StmtProfiler {
185 ODRHash &Hash;
186 public:
187 StmtProfilerWithoutPointers(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
188 : StmtProfiler(ID, /*Canonical=*/false, /*ProfileLambdaExpr=*/false),
189 Hash(Hash) {}
190
191 private:
192 void HandleStmtClass(Stmt::StmtClass SC) override {
193 if (SC == Stmt::UnresolvedLookupExprClass) {
194 // Pretend that the name looked up is a Decl due to how templates
195 // handle some Decl lookups.
196 ID.AddInteger(Stmt::DeclRefExprClass);
197 } else {
198 ID.AddInteger(SC);
199 }
200 }
201
202 void VisitType(QualType T) override {
203 Hash.AddQualType(T);
204 }
205
206 void VisitName(DeclarationName Name, bool TreatAsDecl) override {
207 if (TreatAsDecl) {
208 // A Decl can be null, so each Decl is preceded by a boolean to
209 // store its nullness. Add a boolean here to match.
210 ID.AddBoolean(true);
211 }
212 Hash.AddDeclarationName(Name, TreatAsDecl);
213 }
214 void VisitIdentifierInfo(const IdentifierInfo *II) override {
215 ID.AddBoolean(II);
216 if (II) {
217 Hash.AddIdentifierInfo(II);
218 }
219 }
220 void VisitDecl(const Decl *D) override {
221 ID.AddBoolean(D);
222 if (D) {
223 Hash.AddDecl(D);
224 }
225 }
226 void VisitTemplateName(TemplateName Name) override {
227 Hash.AddTemplateName(Name);
228 }
229 void VisitNestedNameSpecifier(NestedNameSpecifier NNS) override {
230 ID.AddBoolean(bool(NNS));
231 if (NNS)
232 Hash.AddNestedNameSpecifier(NNS);
233 }
234 };
235}
236
237void StmtProfiler::VisitStmt(const Stmt *S) {
238 assert(S && "Requires non-null Stmt pointer");
239
240 VisitStmtNoChildren(S);
241
242 for (const Stmt *SubStmt : S->children()) {
243 if (SubStmt)
244 Visit(SubStmt);
245 else
246 ID.AddInteger(0);
247 }
248}
249
250void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
251 VisitStmt(S);
252 for (const auto *D : S->decls())
253 VisitDecl(D);
254}
255
256void StmtProfiler::VisitNullStmt(const NullStmt *S) {
257 VisitStmt(S);
258}
259
260void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
261 VisitStmt(S);
262}
263
264void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
265 VisitStmt(S);
266}
267
268void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
269 VisitStmt(S);
270}
271
272void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
273 VisitStmt(S);
274 VisitDecl(S->getDecl());
275}
276
277void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
278 VisitStmt(S);
279 // TODO: maybe visit attributes?
280}
281
282void StmtProfiler::VisitIfStmt(const IfStmt *S) {
283 VisitStmt(S);
284 VisitDecl(S->getConditionVariable());
285}
286
287void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
288 VisitStmt(S);
289 VisitDecl(S->getConditionVariable());
290}
291
292void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
293 VisitStmt(S);
294 VisitDecl(S->getConditionVariable());
295}
296
297void StmtProfiler::VisitDoStmt(const DoStmt *S) {
298 VisitStmt(S);
299}
300
301void StmtProfiler::VisitForStmt(const ForStmt *S) {
302 VisitStmt(S);
303}
304
305void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
306 VisitStmt(S);
307 VisitDecl(S->getLabel());
308}
309
310void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
311 VisitStmt(S);
312}
313
314void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
315 VisitStmt(S);
316}
317
318void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
319 VisitStmt(S);
320}
321
322void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
323 VisitStmt(S);
324}
325
326void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
327 VisitStmt(S);
328 ID.AddBoolean(S->isVolatile());
329 ID.AddBoolean(S->isSimple());
330 VisitExpr(S->getAsmStringExpr());
331 ID.AddInteger(S->getNumOutputs());
332 for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
333 ID.AddString(S->getOutputName(I));
334 VisitExpr(S->getOutputConstraintExpr(I));
335 }
336 ID.AddInteger(S->getNumInputs());
337 for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
338 ID.AddString(S->getInputName(I));
339 VisitExpr(S->getInputConstraintExpr(I));
340 }
341 ID.AddInteger(S->getNumClobbers());
342 for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
343 VisitExpr(S->getClobberExpr(I));
344 ID.AddInteger(S->getNumLabels());
345 for (auto *L : S->labels())
346 VisitDecl(L->getLabel());
347}
348
349void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) {
350 // FIXME: Implement MS style inline asm statement profiler.
351 VisitStmt(S);
352}
353
354void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
355 VisitStmt(S);
356 VisitType(S->getCaughtType());
357}
358
359void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
360 VisitStmt(S);
361}
362
363void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
364 VisitStmt(S);
365}
366
367void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
368 VisitStmt(S);
369 ID.AddBoolean(S->isIfExists());
370 VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
371 VisitName(S->getNameInfo().getName());
372}
373
374void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
375 VisitStmt(S);
376}
377
378void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
379 VisitStmt(S);
380}
381
382void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
383 VisitStmt(S);
384}
385
386void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
387 VisitStmt(S);
388}
389
390void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
391 VisitStmt(S);
392}
393
394void StmtProfiler::VisitSYCLKernelCallStmt(const SYCLKernelCallStmt *S) {
395 VisitStmt(S);
396}
397
398void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
399 VisitStmt(S);
400}
401
402void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
403 VisitStmt(S);
404 ID.AddBoolean(S->hasEllipsis());
405 if (S->getCatchParamDecl())
406 VisitType(S->getCatchParamDecl()->getType());
407}
408
409void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
410 VisitStmt(S);
411}
412
413void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
414 VisitStmt(S);
415}
416
417void
418StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
419 VisitStmt(S);
420}
421
422void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
423 VisitStmt(S);
424}
425
426void
427StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
428 VisitStmt(S);
429}
430
431namespace {
432class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
433 StmtProfiler *Profiler;
434 /// Process clauses with list of variables.
435 template <typename T>
436 void VisitOMPClauseList(T *Node);
437
438public:
439 OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
440#define GEN_CLANG_CLAUSE_CLASS
441#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
442#include "llvm/Frontend/OpenMP/OMP.inc"
443 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
444 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
445};
446
447void OMPClauseProfiler::VisitOMPClauseWithPreInit(
448 const OMPClauseWithPreInit *C) {
449 if (auto *S = C->getPreInitStmt())
450 Profiler->VisitStmt(S);
451}
452
453void OMPClauseProfiler::VisitOMPClauseWithPostUpdate(
454 const OMPClauseWithPostUpdate *C) {
455 VisitOMPClauseWithPreInit(C);
456 if (auto *E = C->getPostUpdateExpr())
457 Profiler->VisitStmt(E);
458}
459
460void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
461 VisitOMPClauseWithPreInit(C);
462 if (C->getCondition())
463 Profiler->VisitStmt(C->getCondition());
464}
465
466void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
467 VisitOMPClauseWithPreInit(C);
468 if (C->getCondition())
469 Profiler->VisitStmt(C->getCondition());
470}
471
472void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
473 VisitOMPClauseWithPreInit(C);
474 if (C->getNumThreads())
475 Profiler->VisitStmt(C->getNumThreads());
476}
477
478void OMPClauseProfiler::VisitOMPAlignClause(const OMPAlignClause *C) {
479 if (C->getAlignment())
480 Profiler->VisitStmt(C->getAlignment());
481}
482
483void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
484 if (C->getSafelen())
485 Profiler->VisitStmt(C->getSafelen());
486}
487
488void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
489 if (C->getSimdlen())
490 Profiler->VisitStmt(C->getSimdlen());
491}
492
493void OMPClauseProfiler::VisitOMPSizesClause(const OMPSizesClause *C) {
494 for (auto *E : C->getSizesRefs())
495 if (E)
496 Profiler->VisitExpr(E);
497}
498
499void OMPClauseProfiler::VisitOMPPermutationClause(
500 const OMPPermutationClause *C) {
501 for (Expr *E : C->getArgsRefs())
502 if (E)
503 Profiler->VisitExpr(E);
504}
505
506void OMPClauseProfiler::VisitOMPFullClause(const OMPFullClause *C) {}
507
508void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause *C) {
509 if (const Expr *Factor = C->getFactor())
510 Profiler->VisitExpr(Factor);
511}
512
513void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
514 if (C->getAllocator())
515 Profiler->VisitStmt(C->getAllocator());
516}
517
518void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
519 if (C->getNumForLoops())
520 Profiler->VisitStmt(C->getNumForLoops());
521}
522
523void OMPClauseProfiler::VisitOMPDetachClause(const OMPDetachClause *C) {
524 if (Expr *Evt = C->getEventHandler())
525 Profiler->VisitStmt(Evt);
526}
527
528void OMPClauseProfiler::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
529 VisitOMPClauseWithPreInit(C);
530 if (C->getCondition())
531 Profiler->VisitStmt(C->getCondition());
532}
533
534void OMPClauseProfiler::VisitOMPNocontextClause(const OMPNocontextClause *C) {
535 VisitOMPClauseWithPreInit(C);
536 if (C->getCondition())
537 Profiler->VisitStmt(C->getCondition());
538}
539
540void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
541
542void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
543
544void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
545 const OMPUnifiedAddressClause *C) {}
546
547void OMPClauseProfiler::VisitOMPUnifiedSharedMemoryClause(
548 const OMPUnifiedSharedMemoryClause *C) {}
549
550void OMPClauseProfiler::VisitOMPReverseOffloadClause(
551 const OMPReverseOffloadClause *C) {}
552
553void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause(
554 const OMPDynamicAllocatorsClause *C) {}
555
556void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
557 const OMPAtomicDefaultMemOrderClause *C) {}
558
559void OMPClauseProfiler::VisitOMPSelfMapsClause(const OMPSelfMapsClause *C) {}
560
561void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
562
563void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {}
564
565void OMPClauseProfiler::VisitOMPMessageClause(const OMPMessageClause *C) {
566 if (C->getMessageString())
567 Profiler->VisitStmt(C->getMessageString());
568}
569
570void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
571 VisitOMPClauseWithPreInit(C);
572 if (auto *S = C->getChunkSize())
573 Profiler->VisitStmt(S);
574}
575
576void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) {
577 if (auto *Num = C->getNumForLoops())
578 Profiler->VisitStmt(Num);
579}
580
581void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
582
583void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
584
585void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
586
587void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}
588
589void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {}
590
591void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
592
593void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
594
595void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
596
597void OMPClauseProfiler::VisitOMPFailClause(const OMPFailClause *) {}
598
599void OMPClauseProfiler::VisitOMPAbsentClause(const OMPAbsentClause *) {}
600
601void OMPClauseProfiler::VisitOMPHoldsClause(const OMPHoldsClause *) {}
602
603void OMPClauseProfiler::VisitOMPContainsClause(const OMPContainsClause *) {}
604
605void OMPClauseProfiler::VisitOMPNoOpenMPClause(const OMPNoOpenMPClause *) {}
606
607void OMPClauseProfiler::VisitOMPNoOpenMPRoutinesClause(
608 const OMPNoOpenMPRoutinesClause *) {}
609
610void OMPClauseProfiler::VisitOMPNoOpenMPConstructsClause(
611 const OMPNoOpenMPConstructsClause *) {}
612
613void OMPClauseProfiler::VisitOMPNoParallelismClause(
614 const OMPNoParallelismClause *) {}
615
616void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
617
618void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
619
620void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause *) {}
621
622void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause *) {}
623
624void OMPClauseProfiler::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
625
626void OMPClauseProfiler::VisitOMPWeakClause(const OMPWeakClause *) {}
627
628void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
629
630void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
631
632void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {}
633
634void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) {
635 VisitOMPClauseList(C);
636}
637
638void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause *C) {
639 if (C->getInteropVar())
640 Profiler->VisitStmt(C->getInteropVar());
641}
642
643void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *C) {
644 if (C->getInteropVar())
645 Profiler->VisitStmt(C->getInteropVar());
646}
647
648void OMPClauseProfiler::VisitOMPFilterClause(const OMPFilterClause *C) {
649 VisitOMPClauseWithPreInit(C);
650 if (C->getThreadID())
651 Profiler->VisitStmt(C->getThreadID());
652}
653
654template<typename T>
655void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
656 for (auto *E : Node->varlist()) {
657 if (E)
658 Profiler->VisitStmt(E);
659 }
660}
661
662void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
663 VisitOMPClauseList(C);
664 for (auto *E : C->private_copies()) {
665 if (E)
666 Profiler->VisitStmt(E);
667 }
668}
669void
670OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
671 VisitOMPClauseList(C);
672 VisitOMPClauseWithPreInit(C);
673 for (auto *E : C->private_copies()) {
674 if (E)
675 Profiler->VisitStmt(E);
676 }
677 for (auto *E : C->inits()) {
678 if (E)
679 Profiler->VisitStmt(E);
680 }
681}
682void
683OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
684 VisitOMPClauseList(C);
685 VisitOMPClauseWithPostUpdate(C);
686 for (auto *E : C->source_exprs()) {
687 if (E)
688 Profiler->VisitStmt(E);
689 }
690 for (auto *E : C->destination_exprs()) {
691 if (E)
692 Profiler->VisitStmt(E);
693 }
694 for (auto *E : C->assignment_ops()) {
695 if (E)
696 Profiler->VisitStmt(E);
697 }
698}
699void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
700 VisitOMPClauseList(C);
701}
702void OMPClauseProfiler::VisitOMPReductionClause(
703 const OMPReductionClause *C) {
704 Profiler->VisitNestedNameSpecifier(
705 C->getQualifierLoc().getNestedNameSpecifier());
706 Profiler->VisitName(C->getNameInfo().getName());
707 VisitOMPClauseList(C);
708 VisitOMPClauseWithPostUpdate(C);
709 for (auto *E : C->privates()) {
710 if (E)
711 Profiler->VisitStmt(E);
712 }
713 for (auto *E : C->lhs_exprs()) {
714 if (E)
715 Profiler->VisitStmt(E);
716 }
717 for (auto *E : C->rhs_exprs()) {
718 if (E)
719 Profiler->VisitStmt(E);
720 }
721 for (auto *E : C->reduction_ops()) {
722 if (E)
723 Profiler->VisitStmt(E);
724 }
725 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
726 for (auto *E : C->copy_ops()) {
727 if (E)
728 Profiler->VisitStmt(E);
729 }
730 for (auto *E : C->copy_array_temps()) {
731 if (E)
732 Profiler->VisitStmt(E);
733 }
734 for (auto *E : C->copy_array_elems()) {
735 if (E)
736 Profiler->VisitStmt(E);
737 }
738 }
739}
740void OMPClauseProfiler::VisitOMPTaskReductionClause(
741 const OMPTaskReductionClause *C) {
742 Profiler->VisitNestedNameSpecifier(
743 C->getQualifierLoc().getNestedNameSpecifier());
744 Profiler->VisitName(C->getNameInfo().getName());
745 VisitOMPClauseList(C);
746 VisitOMPClauseWithPostUpdate(C);
747 for (auto *E : C->privates()) {
748 if (E)
749 Profiler->VisitStmt(E);
750 }
751 for (auto *E : C->lhs_exprs()) {
752 if (E)
753 Profiler->VisitStmt(E);
754 }
755 for (auto *E : C->rhs_exprs()) {
756 if (E)
757 Profiler->VisitStmt(E);
758 }
759 for (auto *E : C->reduction_ops()) {
760 if (E)
761 Profiler->VisitStmt(E);
762 }
763}
764void OMPClauseProfiler::VisitOMPInReductionClause(
765 const OMPInReductionClause *C) {
766 Profiler->VisitNestedNameSpecifier(
767 C->getQualifierLoc().getNestedNameSpecifier());
768 Profiler->VisitName(C->getNameInfo().getName());
769 VisitOMPClauseList(C);
770 VisitOMPClauseWithPostUpdate(C);
771 for (auto *E : C->privates()) {
772 if (E)
773 Profiler->VisitStmt(E);
774 }
775 for (auto *E : C->lhs_exprs()) {
776 if (E)
777 Profiler->VisitStmt(E);
778 }
779 for (auto *E : C->rhs_exprs()) {
780 if (E)
781 Profiler->VisitStmt(E);
782 }
783 for (auto *E : C->reduction_ops()) {
784 if (E)
785 Profiler->VisitStmt(E);
786 }
787 for (auto *E : C->taskgroup_descriptors()) {
788 if (E)
789 Profiler->VisitStmt(E);
790 }
791}
792void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
793 VisitOMPClauseList(C);
794 VisitOMPClauseWithPostUpdate(C);
795 for (auto *E : C->privates()) {
796 if (E)
797 Profiler->VisitStmt(E);
798 }
799 for (auto *E : C->inits()) {
800 if (E)
801 Profiler->VisitStmt(E);
802 }
803 for (auto *E : C->updates()) {
804 if (E)
805 Profiler->VisitStmt(E);
806 }
807 for (auto *E : C->finals()) {
808 if (E)
809 Profiler->VisitStmt(E);
810 }
811 if (C->getStep())
812 Profiler->VisitStmt(C->getStep());
813 if (C->getCalcStep())
814 Profiler->VisitStmt(C->getCalcStep());
815}
816void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
817 VisitOMPClauseList(C);
818 if (C->getAlignment())
819 Profiler->VisitStmt(C->getAlignment());
820}
821void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
822 VisitOMPClauseList(C);
823 for (auto *E : C->source_exprs()) {
824 if (E)
825 Profiler->VisitStmt(E);
826 }
827 for (auto *E : C->destination_exprs()) {
828 if (E)
829 Profiler->VisitStmt(E);
830 }
831 for (auto *E : C->assignment_ops()) {
832 if (E)
833 Profiler->VisitStmt(E);
834 }
835}
836void
837OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
838 VisitOMPClauseList(C);
839 for (auto *E : C->source_exprs()) {
840 if (E)
841 Profiler->VisitStmt(E);
842 }
843 for (auto *E : C->destination_exprs()) {
844 if (E)
845 Profiler->VisitStmt(E);
846 }
847 for (auto *E : C->assignment_ops()) {
848 if (E)
849 Profiler->VisitStmt(E);
850 }
851}
852void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
853 VisitOMPClauseList(C);
854}
855void OMPClauseProfiler::VisitOMPDepobjClause(const OMPDepobjClause *C) {
856 if (const Expr *Depobj = C->getDepobj())
857 Profiler->VisitStmt(Depobj);
858}
859void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) {
860 VisitOMPClauseList(C);
861}
862void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) {
863 if (C->getDevice())
864 Profiler->VisitStmt(C->getDevice());
865}
866void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) {
867 VisitOMPClauseList(C);
868}
869void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) {
870 if (Expr *Allocator = C->getAllocator())
871 Profiler->VisitStmt(Allocator);
872 VisitOMPClauseList(C);
873}
874void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
875 VisitOMPClauseList(C);
876 VisitOMPClauseWithPreInit(C);
877}
878void OMPClauseProfiler::VisitOMPThreadLimitClause(
879 const OMPThreadLimitClause *C) {
880 VisitOMPClauseList(C);
881 VisitOMPClauseWithPreInit(C);
882}
883void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) {
884 VisitOMPClauseWithPreInit(C);
885 if (C->getPriority())
886 Profiler->VisitStmt(C->getPriority());
887}
888void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
889 VisitOMPClauseWithPreInit(C);
890 if (C->getGrainsize())
891 Profiler->VisitStmt(C->getGrainsize());
892}
893void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
894 VisitOMPClauseWithPreInit(C);
895 if (C->getNumTasks())
896 Profiler->VisitStmt(C->getNumTasks());
897}
898void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
899 if (C->getHint())
900 Profiler->VisitStmt(C->getHint());
901}
902void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) {
903 VisitOMPClauseList(C);
904}
905void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) {
906 VisitOMPClauseList(C);
907}
908void OMPClauseProfiler::VisitOMPUseDevicePtrClause(
909 const OMPUseDevicePtrClause *C) {
910 VisitOMPClauseList(C);
911}
912void OMPClauseProfiler::VisitOMPUseDeviceAddrClause(
913 const OMPUseDeviceAddrClause *C) {
914 VisitOMPClauseList(C);
915}
916void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
917 const OMPIsDevicePtrClause *C) {
918 VisitOMPClauseList(C);
919}
920void OMPClauseProfiler::VisitOMPHasDeviceAddrClause(
921 const OMPHasDeviceAddrClause *C) {
922 VisitOMPClauseList(C);
923}
924void OMPClauseProfiler::VisitOMPNontemporalClause(
925 const OMPNontemporalClause *C) {
926 VisitOMPClauseList(C);
927 for (auto *E : C->private_refs())
928 Profiler->VisitStmt(E);
929}
930void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
931 VisitOMPClauseList(C);
932}
933void OMPClauseProfiler::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
934 VisitOMPClauseList(C);
935}
936void OMPClauseProfiler::VisitOMPUsesAllocatorsClause(
937 const OMPUsesAllocatorsClause *C) {
938 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
939 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
940 Profiler->VisitStmt(D.Allocator);
941 if (D.AllocatorTraits)
942 Profiler->VisitStmt(D.AllocatorTraits);
943 }
944}
945void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
946 if (const Expr *Modifier = C->getModifier())
947 Profiler->VisitStmt(Modifier);
948 for (const Expr *E : C->varlist())
949 Profiler->VisitStmt(E);
950}
951void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
952void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause *C) {}
953void OMPClauseProfiler::VisitOMPXDynCGroupMemClause(
954 const OMPXDynCGroupMemClause *C) {
955 VisitOMPClauseWithPreInit(C);
956 if (Expr *Size = C->getSize())
957 Profiler->VisitStmt(Size);
958}
959void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {
960 VisitOMPClauseList(C);
961}
962void OMPClauseProfiler::VisitOMPXAttributeClause(const OMPXAttributeClause *C) {
963}
964void OMPClauseProfiler::VisitOMPXBareClause(const OMPXBareClause *C) {}
965} // namespace
966
967void
968StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
969 VisitStmt(S);
970 OMPClauseProfiler P(this);
971 ArrayRef<OMPClause *> Clauses = S->clauses();
972 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
973 I != E; ++I)
974 if (*I)
975 P.Visit(*I);
976}
977
978void StmtProfiler::VisitOMPCanonicalLoop(const OMPCanonicalLoop *L) {
979 VisitStmt(L);
980}
981
982void StmtProfiler::VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *S) {
983 VisitOMPExecutableDirective(S);
984}
985
986void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
987 VisitOMPLoopBasedDirective(S);
988}
989
990void StmtProfiler::VisitOMPMetaDirective(const OMPMetaDirective *S) {
991 VisitOMPExecutableDirective(S);
992}
993
994void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
995 VisitOMPExecutableDirective(S);
996}
997
998void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
999 VisitOMPLoopDirective(S);
1000}
1001
1002void StmtProfiler::VisitOMPCanonicalLoopNestTransformationDirective(
1003 const OMPCanonicalLoopNestTransformationDirective *S) {
1004 VisitOMPLoopBasedDirective(S);
1005}
1006
1007void StmtProfiler::VisitOMPTileDirective(const OMPTileDirective *S) {
1008 VisitOMPCanonicalLoopNestTransformationDirective(S);
1009}
1010
1011void StmtProfiler::VisitOMPStripeDirective(const OMPStripeDirective *S) {
1012 VisitOMPCanonicalLoopNestTransformationDirective(S);
1013}
1014
1015void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) {
1016 VisitOMPCanonicalLoopNestTransformationDirective(S);
1017}
1018
1019void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) {
1020 VisitOMPCanonicalLoopNestTransformationDirective(S);
1021}
1022
1023void StmtProfiler::VisitOMPInterchangeDirective(
1024 const OMPInterchangeDirective *S) {
1025 VisitOMPCanonicalLoopNestTransformationDirective(S);
1026}
1027
1028void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
1029 VisitOMPLoopDirective(S);
1030}
1031
1032void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
1033 VisitOMPLoopDirective(S);
1034}
1035
1036void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
1037 VisitOMPExecutableDirective(S);
1038}
1039
1040void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
1041 VisitOMPExecutableDirective(S);
1042}
1043
1044void StmtProfiler::VisitOMPScopeDirective(const OMPScopeDirective *S) {
1045 VisitOMPExecutableDirective(S);
1046}
1047
1048void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
1049 VisitOMPExecutableDirective(S);
1050}
1051
1052void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
1053 VisitOMPExecutableDirective(S);
1054}
1055
1056void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
1057 VisitOMPExecutableDirective(S);
1058 VisitName(S->getDirectiveName().getName());
1059}
1060
1061void
1062StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
1063 VisitOMPLoopDirective(S);
1064}
1065
1066void StmtProfiler::VisitOMPParallelForSimdDirective(
1067 const OMPParallelForSimdDirective *S) {
1068 VisitOMPLoopDirective(S);
1069}
1070
1071void StmtProfiler::VisitOMPParallelMasterDirective(
1072 const OMPParallelMasterDirective *S) {
1073 VisitOMPExecutableDirective(S);
1074}
1075
1076void StmtProfiler::VisitOMPParallelMaskedDirective(
1077 const OMPParallelMaskedDirective *S) {
1078 VisitOMPExecutableDirective(S);
1079}
1080
1081void StmtProfiler::VisitOMPParallelSectionsDirective(
1082 const OMPParallelSectionsDirective *S) {
1083 VisitOMPExecutableDirective(S);
1084}
1085
1086void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
1087 VisitOMPExecutableDirective(S);
1088}
1089
1090void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
1091 VisitOMPExecutableDirective(S);
1092}
1093
1094void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
1095 VisitOMPExecutableDirective(S);
1096}
1097
1098void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
1099 VisitOMPExecutableDirective(S);
1100}
1101
1102void StmtProfiler::VisitOMPAssumeDirective(const OMPAssumeDirective *S) {
1103 VisitOMPExecutableDirective(S);
1104}
1105
1106void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) {
1107 VisitOMPExecutableDirective(S);
1108}
1109void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
1110 VisitOMPExecutableDirective(S);
1111 if (const Expr *E = S->getReductionRef())
1112 VisitStmt(E);
1113}
1114
1115void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
1116 VisitOMPExecutableDirective(S);
1117}
1118
1119void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective *S) {
1120 VisitOMPExecutableDirective(S);
1121}
1122
1123void StmtProfiler::VisitOMPScanDirective(const OMPScanDirective *S) {
1124 VisitOMPExecutableDirective(S);
1125}
1126
1127void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
1128 VisitOMPExecutableDirective(S);
1129}
1130
1131void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
1132 VisitOMPExecutableDirective(S);
1133}
1134
1135void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
1136 VisitOMPExecutableDirective(S);
1137}
1138
1139void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) {
1140 VisitOMPExecutableDirective(S);
1141}
1142
1143void StmtProfiler::VisitOMPTargetEnterDataDirective(
1144 const OMPTargetEnterDataDirective *S) {
1145 VisitOMPExecutableDirective(S);
1146}
1147
1148void StmtProfiler::VisitOMPTargetExitDataDirective(
1149 const OMPTargetExitDataDirective *S) {
1150 VisitOMPExecutableDirective(S);
1151}
1152
1153void StmtProfiler::VisitOMPTargetParallelDirective(
1154 const OMPTargetParallelDirective *S) {
1155 VisitOMPExecutableDirective(S);
1156}
1157
1158void StmtProfiler::VisitOMPTargetParallelForDirective(
1159 const OMPTargetParallelForDirective *S) {
1160 VisitOMPExecutableDirective(S);
1161}
1162
1163void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
1164 VisitOMPExecutableDirective(S);
1165}
1166
1167void StmtProfiler::VisitOMPCancellationPointDirective(
1168 const OMPCancellationPointDirective *S) {
1169 VisitOMPExecutableDirective(S);
1170}
1171
1172void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) {
1173 VisitOMPExecutableDirective(S);
1174}
1175
1176void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) {
1177 VisitOMPLoopDirective(S);
1178}
1179
1180void StmtProfiler::VisitOMPTaskLoopSimdDirective(
1181 const OMPTaskLoopSimdDirective *S) {
1182 VisitOMPLoopDirective(S);
1183}
1184
1185void StmtProfiler::VisitOMPMasterTaskLoopDirective(
1186 const OMPMasterTaskLoopDirective *S) {
1187 VisitOMPLoopDirective(S);
1188}
1189
1190void StmtProfiler::VisitOMPMaskedTaskLoopDirective(
1191 const OMPMaskedTaskLoopDirective *S) {
1192 VisitOMPLoopDirective(S);
1193}
1194
1195void StmtProfiler::VisitOMPMasterTaskLoopSimdDirective(
1196 const OMPMasterTaskLoopSimdDirective *S) {
1197 VisitOMPLoopDirective(S);
1198}
1199
1200void StmtProfiler::VisitOMPMaskedTaskLoopSimdDirective(
1201 const OMPMaskedTaskLoopSimdDirective *S) {
1202 VisitOMPLoopDirective(S);
1203}
1204
1205void StmtProfiler::VisitOMPParallelMasterTaskLoopDirective(
1206 const OMPParallelMasterTaskLoopDirective *S) {
1207 VisitOMPLoopDirective(S);
1208}
1209
1210void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective(
1211 const OMPParallelMaskedTaskLoopDirective *S) {
1212 VisitOMPLoopDirective(S);
1213}
1214
1215void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective(
1216 const OMPParallelMasterTaskLoopSimdDirective *S) {
1217 VisitOMPLoopDirective(S);
1218}
1219
1220void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective(
1221 const OMPParallelMaskedTaskLoopSimdDirective *S) {
1222 VisitOMPLoopDirective(S);
1223}
1224
1225void StmtProfiler::VisitOMPDistributeDirective(
1226 const OMPDistributeDirective *S) {
1227 VisitOMPLoopDirective(S);
1228}
1229
1230void OMPClauseProfiler::VisitOMPDistScheduleClause(
1231 const OMPDistScheduleClause *C) {
1232 VisitOMPClauseWithPreInit(C);
1233 if (auto *S = C->getChunkSize())
1234 Profiler->VisitStmt(S);
1235}
1236
1237void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {}
1238
1239void StmtProfiler::VisitOMPTargetUpdateDirective(
1240 const OMPTargetUpdateDirective *S) {
1241 VisitOMPExecutableDirective(S);
1242}
1243
1244void StmtProfiler::VisitOMPDistributeParallelForDirective(
1245 const OMPDistributeParallelForDirective *S) {
1246 VisitOMPLoopDirective(S);
1247}
1248
1249void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
1250 const OMPDistributeParallelForSimdDirective *S) {
1251 VisitOMPLoopDirective(S);
1252}
1253
1254void StmtProfiler::VisitOMPDistributeSimdDirective(
1255 const OMPDistributeSimdDirective *S) {
1256 VisitOMPLoopDirective(S);
1257}
1258
1259void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
1260 const OMPTargetParallelForSimdDirective *S) {
1261 VisitOMPLoopDirective(S);
1262}
1263
1264void StmtProfiler::VisitOMPTargetSimdDirective(
1265 const OMPTargetSimdDirective *S) {
1266 VisitOMPLoopDirective(S);
1267}
1268
1269void StmtProfiler::VisitOMPTeamsDistributeDirective(
1270 const OMPTeamsDistributeDirective *S) {
1271 VisitOMPLoopDirective(S);
1272}
1273
1274void StmtProfiler::VisitOMPTeamsDistributeSimdDirective(
1275 const OMPTeamsDistributeSimdDirective *S) {
1276 VisitOMPLoopDirective(S);
1277}
1278
1279void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
1280 const OMPTeamsDistributeParallelForSimdDirective *S) {
1281 VisitOMPLoopDirective(S);
1282}
1283
1284void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
1285 const OMPTeamsDistributeParallelForDirective *S) {
1286 VisitOMPLoopDirective(S);
1287}
1288
1289void StmtProfiler::VisitOMPTargetTeamsDirective(
1290 const OMPTargetTeamsDirective *S) {
1291 VisitOMPExecutableDirective(S);
1292}
1293
1294void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
1295 const OMPTargetTeamsDistributeDirective *S) {
1296 VisitOMPLoopDirective(S);
1297}
1298
1299void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
1300 const OMPTargetTeamsDistributeParallelForDirective *S) {
1301 VisitOMPLoopDirective(S);
1302}
1303
1304void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1305 const OMPTargetTeamsDistributeParallelForSimdDirective *S) {
1306 VisitOMPLoopDirective(S);
1307}
1308
1309void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
1310 const OMPTargetTeamsDistributeSimdDirective *S) {
1311 VisitOMPLoopDirective(S);
1312}
1313
1314void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective *S) {
1315 VisitOMPExecutableDirective(S);
1316}
1317
1318void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective *S) {
1319 VisitOMPExecutableDirective(S);
1320}
1321
1322void StmtProfiler::VisitOMPMaskedDirective(const OMPMaskedDirective *S) {
1323 VisitOMPExecutableDirective(S);
1324}
1325
1326void StmtProfiler::VisitOMPGenericLoopDirective(
1327 const OMPGenericLoopDirective *S) {
1328 VisitOMPLoopDirective(S);
1329}
1330
1331void StmtProfiler::VisitOMPTeamsGenericLoopDirective(
1332 const OMPTeamsGenericLoopDirective *S) {
1333 VisitOMPLoopDirective(S);
1334}
1335
1336void StmtProfiler::VisitOMPTargetTeamsGenericLoopDirective(
1337 const OMPTargetTeamsGenericLoopDirective *S) {
1338 VisitOMPLoopDirective(S);
1339}
1340
1341void StmtProfiler::VisitOMPParallelGenericLoopDirective(
1342 const OMPParallelGenericLoopDirective *S) {
1343 VisitOMPLoopDirective(S);
1344}
1345
1346void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective(
1347 const OMPTargetParallelGenericLoopDirective *S) {
1348 VisitOMPLoopDirective(S);
1349}
1350
1351void StmtProfiler::VisitExpr(const Expr *S) {
1352 VisitStmt(S);
1353}
1354
1355void StmtProfiler::VisitConstantExpr(const ConstantExpr *S) {
1356 // Profile exactly as the sub-expression.
1357 Visit(S->getSubExpr());
1358}
1359
1360void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
1361 VisitExpr(S);
1362 if (!Canonical)
1363 VisitNestedNameSpecifier(S->getQualifier());
1364 VisitDecl(S->getDecl());
1365 if (!Canonical) {
1366 ID.AddBoolean(S->hasExplicitTemplateArgs());
1367 if (S->hasExplicitTemplateArgs())
1368 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
1369 }
1370}
1371
1372void StmtProfiler::VisitSYCLUniqueStableNameExpr(
1373 const SYCLUniqueStableNameExpr *S) {
1374 VisitExpr(S);
1375 VisitType(S->getTypeSourceInfo()->getType());
1376}
1377
1378void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
1379 VisitExpr(S);
1380 ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
1381}
1382
1383void StmtProfiler::VisitOpenACCAsteriskSizeExpr(
1384 const OpenACCAsteriskSizeExpr *S) {
1385 VisitExpr(S);
1386}
1387
1388void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
1389 VisitExpr(S);
1390 S->getValue().Profile(ID);
1391
1392 QualType T = S->getType();
1393 if (Canonical)
1394 T = T.getCanonicalType();
1395 ID.AddInteger(T->getTypeClass());
1396 if (auto BitIntT = T->getAs<BitIntType>())
1397 BitIntT->Profile(ID);
1398 else
1399 ID.AddInteger(T->castAs<BuiltinType>()->getKind());
1400}
1401
1402void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
1403 VisitExpr(S);
1404 S->getValue().Profile(ID);
1405 ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1406}
1407
1408void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
1409 VisitExpr(S);
1410 ID.AddInteger(llvm::to_underlying(S->getKind()));
1411 ID.AddInteger(S->getValue());
1412}
1413
1414void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
1415 VisitExpr(S);
1416 S->getValue().Profile(ID);
1417 ID.AddBoolean(S->isExact());
1418 ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1419}
1420
1421void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
1422 VisitExpr(S);
1423}
1424
1425void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
1426 VisitExpr(S);
1427 ID.AddString(S->getBytes());
1428 ID.AddInteger(llvm::to_underlying(S->getKind()));
1429}
1430
1431void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
1432 VisitExpr(S);
1433}
1434
1435void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
1436 VisitExpr(S);
1437}
1438
1439void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
1440 VisitExpr(S);
1441 ID.AddInteger(S->getOpcode());
1442}
1443
1444void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
1445 VisitType(S->getTypeSourceInfo()->getType());
1446 unsigned n = S->getNumComponents();
1447 for (unsigned i = 0; i < n; ++i) {
1448 const OffsetOfNode &ON = S->getComponent(i);
1449 ID.AddInteger(ON.getKind());
1450 switch (ON.getKind()) {
1452 // Expressions handled below.
1453 break;
1454
1456 VisitDecl(ON.getField());
1457 break;
1458
1460 VisitIdentifierInfo(ON.getFieldName());
1461 break;
1462
1463 case OffsetOfNode::Base:
1464 // These nodes are implicit, and therefore don't need profiling.
1465 break;
1466 }
1467 }
1468
1469 VisitExpr(S);
1470}
1471
1472void
1473StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
1474 VisitExpr(S);
1475 ID.AddInteger(S->getKind());
1476 if (S->isArgumentType())
1477 VisitType(S->getArgumentType());
1478}
1479
1480void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
1481 VisitExpr(S);
1482}
1483
1484void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) {
1485 VisitExpr(S);
1486}
1487
1488void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) {
1489 VisitExpr(S);
1490}
1491
1492void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
1493 VisitExpr(S);
1494}
1495
1496void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) {
1497 VisitExpr(S);
1498 for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I)
1499 VisitDecl(S->getIteratorDecl(I));
1500}
1501
1502void StmtProfiler::VisitCallExpr(const CallExpr *S) {
1503 VisitExpr(S);
1504}
1505
1506void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
1507 VisitExpr(S);
1508 VisitDecl(S->getMemberDecl());
1509 if (!Canonical)
1510 VisitNestedNameSpecifier(S->getQualifier());
1511 ID.AddBoolean(S->isArrow());
1512}
1513
1514void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
1515 VisitExpr(S);
1516 ID.AddBoolean(S->isFileScope());
1517}
1518
1519void StmtProfiler::VisitCastExpr(const CastExpr *S) {
1520 VisitExpr(S);
1521}
1522
1523void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
1524 VisitCastExpr(S);
1525 ID.AddInteger(S->getValueKind());
1526}
1527
1528void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
1529 VisitCastExpr(S);
1530 VisitType(S->getTypeAsWritten());
1531}
1532
1533void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
1534 VisitExplicitCastExpr(S);
1535}
1536
1537void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
1538 VisitExpr(S);
1539 ID.AddInteger(S->getOpcode());
1540}
1541
1542void
1543StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
1544 VisitBinaryOperator(S);
1545}
1546
1547void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
1548 VisitExpr(S);
1549}
1550
1551void StmtProfiler::VisitBinaryConditionalOperator(
1552 const BinaryConditionalOperator *S) {
1553 VisitExpr(S);
1554}
1555
1556void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
1557 VisitExpr(S);
1558 VisitDecl(S->getLabel());
1559}
1560
1561void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
1562 VisitExpr(S);
1563}
1564
1565void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
1566 VisitExpr(S);
1567}
1568
1569void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
1570 VisitExpr(S);
1571}
1572
1573void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
1574 VisitExpr(S);
1575}
1576
1577void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
1578 VisitExpr(S);
1579}
1580
1581void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
1582 VisitExpr(S);
1583}
1584
1585void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
1586 if (S->getSyntacticForm()) {
1587 VisitInitListExpr(S->getSyntacticForm());
1588 return;
1589 }
1590
1591 VisitExpr(S);
1592}
1593
1594void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
1595 VisitExpr(S);
1596 ID.AddBoolean(S->usesGNUSyntax());
1597 for (const DesignatedInitExpr::Designator &D : S->designators()) {
1598 if (D.isFieldDesignator()) {
1599 ID.AddInteger(0);
1600 VisitName(D.getFieldName());
1601 continue;
1602 }
1603
1604 if (D.isArrayDesignator()) {
1605 ID.AddInteger(1);
1606 } else {
1607 assert(D.isArrayRangeDesignator());
1608 ID.AddInteger(2);
1609 }
1610 ID.AddInteger(D.getArrayIndex());
1611 }
1612}
1613
1614// Seems that if VisitInitListExpr() only works on the syntactic form of an
1615// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
1616void StmtProfiler::VisitDesignatedInitUpdateExpr(
1617 const DesignatedInitUpdateExpr *S) {
1618 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
1619 "initializer");
1620}
1621
1622void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
1623 VisitExpr(S);
1624}
1625
1626void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
1627 VisitExpr(S);
1628}
1629
1630void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
1631 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
1632}
1633
1634void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
1635 VisitExpr(S);
1636}
1637
1638void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
1639 VisitExpr(S);
1640 VisitName(&S->getAccessor());
1641}
1642
1643void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
1644 VisitExpr(S);
1645 VisitDecl(S->getBlockDecl());
1646}
1647
1648void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
1649 VisitExpr(S);
1651 S->associations()) {
1652 QualType T = Assoc.getType();
1653 if (T.isNull())
1654 ID.AddPointer(nullptr);
1655 else
1656 VisitType(T);
1657 VisitExpr(Assoc.getAssociationExpr());
1658 }
1659}
1660
1661void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
1662 VisitExpr(S);
1664 i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
1665 // Normally, we would not profile the source expressions of OVEs.
1666 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
1667 Visit(OVE->getSourceExpr());
1668}
1669
1670void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
1671 VisitExpr(S);
1672 ID.AddInteger(S->getOp());
1673}
1674
1675void StmtProfiler::VisitConceptSpecializationExpr(
1676 const ConceptSpecializationExpr *S) {
1677 VisitExpr(S);
1678 VisitDecl(S->getNamedConcept());
1679 for (const TemplateArgument &Arg : S->getTemplateArguments())
1680 VisitTemplateArgument(Arg);
1681}
1682
1683void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
1684 VisitExpr(S);
1685 ID.AddInteger(S->getLocalParameters().size());
1686 for (ParmVarDecl *LocalParam : S->getLocalParameters())
1687 VisitDecl(LocalParam);
1688 ID.AddInteger(S->getRequirements().size());
1689 for (concepts::Requirement *Req : S->getRequirements()) {
1690 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
1691 ID.AddInteger(concepts::Requirement::RK_Type);
1692 ID.AddBoolean(TypeReq->isSubstitutionFailure());
1693 if (!TypeReq->isSubstitutionFailure())
1694 VisitType(TypeReq->getType()->getType());
1695 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
1697 ID.AddBoolean(ExprReq->isExprSubstitutionFailure());
1698 if (!ExprReq->isExprSubstitutionFailure())
1699 Visit(ExprReq->getExpr());
1700 // C++2a [expr.prim.req.compound]p1 Example:
1701 // [...] The compound-requirement in C1 requires that x++ is a valid
1702 // expression. It is equivalent to the simple-requirement x++; [...]
1703 // We therefore do not profile isSimple() here.
1704 ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());
1705 const concepts::ExprRequirement::ReturnTypeRequirement &RetReq =
1706 ExprReq->getReturnTypeRequirement();
1707 if (RetReq.isEmpty()) {
1708 ID.AddInteger(0);
1709 } else if (RetReq.isTypeConstraint()) {
1710 ID.AddInteger(1);
1712 } else {
1713 assert(RetReq.isSubstitutionFailure());
1714 ID.AddInteger(2);
1715 }
1716 } else {
1717 ID.AddInteger(concepts::Requirement::RK_Nested);
1718 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
1719 ID.AddBoolean(NestedReq->hasInvalidConstraint());
1720 if (!NestedReq->hasInvalidConstraint())
1721 Visit(NestedReq->getConstraintExpr());
1722 }
1723 }
1724}
1725
1727 UnaryOperatorKind &UnaryOp,
1728 BinaryOperatorKind &BinaryOp,
1729 unsigned &NumArgs) {
1730 switch (S->getOperator()) {
1731 case OO_None:
1732 case OO_New:
1733 case OO_Delete:
1734 case OO_Array_New:
1735 case OO_Array_Delete:
1736 case OO_Arrow:
1737 case OO_Conditional:
1739 llvm_unreachable("Invalid operator call kind");
1740
1741 case OO_Plus:
1742 if (NumArgs == 1) {
1743 UnaryOp = UO_Plus;
1744 return Stmt::UnaryOperatorClass;
1745 }
1746
1747 BinaryOp = BO_Add;
1748 return Stmt::BinaryOperatorClass;
1749
1750 case OO_Minus:
1751 if (NumArgs == 1) {
1752 UnaryOp = UO_Minus;
1753 return Stmt::UnaryOperatorClass;
1754 }
1755
1756 BinaryOp = BO_Sub;
1757 return Stmt::BinaryOperatorClass;
1758
1759 case OO_Star:
1760 if (NumArgs == 1) {
1761 UnaryOp = UO_Deref;
1762 return Stmt::UnaryOperatorClass;
1763 }
1764
1765 BinaryOp = BO_Mul;
1766 return Stmt::BinaryOperatorClass;
1767
1768 case OO_Slash:
1769 BinaryOp = BO_Div;
1770 return Stmt::BinaryOperatorClass;
1771
1772 case OO_Percent:
1773 BinaryOp = BO_Rem;
1774 return Stmt::BinaryOperatorClass;
1775
1776 case OO_Caret:
1777 BinaryOp = BO_Xor;
1778 return Stmt::BinaryOperatorClass;
1779
1780 case OO_Amp:
1781 if (NumArgs == 1) {
1782 UnaryOp = UO_AddrOf;
1783 return Stmt::UnaryOperatorClass;
1784 }
1785
1786 BinaryOp = BO_And;
1787 return Stmt::BinaryOperatorClass;
1788
1789 case OO_Pipe:
1790 BinaryOp = BO_Or;
1791 return Stmt::BinaryOperatorClass;
1792
1793 case OO_Tilde:
1794 UnaryOp = UO_Not;
1795 return Stmt::UnaryOperatorClass;
1796
1797 case OO_Exclaim:
1798 UnaryOp = UO_LNot;
1799 return Stmt::UnaryOperatorClass;
1800
1801 case OO_Equal:
1802 BinaryOp = BO_Assign;
1803 return Stmt::BinaryOperatorClass;
1804
1805 case OO_Less:
1806 BinaryOp = BO_LT;
1807 return Stmt::BinaryOperatorClass;
1808
1809 case OO_Greater:
1810 BinaryOp = BO_GT;
1811 return Stmt::BinaryOperatorClass;
1812
1813 case OO_PlusEqual:
1814 BinaryOp = BO_AddAssign;
1815 return Stmt::CompoundAssignOperatorClass;
1816
1817 case OO_MinusEqual:
1818 BinaryOp = BO_SubAssign;
1819 return Stmt::CompoundAssignOperatorClass;
1820
1821 case OO_StarEqual:
1822 BinaryOp = BO_MulAssign;
1823 return Stmt::CompoundAssignOperatorClass;
1824
1825 case OO_SlashEqual:
1826 BinaryOp = BO_DivAssign;
1827 return Stmt::CompoundAssignOperatorClass;
1828
1829 case OO_PercentEqual:
1830 BinaryOp = BO_RemAssign;
1831 return Stmt::CompoundAssignOperatorClass;
1832
1833 case OO_CaretEqual:
1834 BinaryOp = BO_XorAssign;
1835 return Stmt::CompoundAssignOperatorClass;
1836
1837 case OO_AmpEqual:
1838 BinaryOp = BO_AndAssign;
1839 return Stmt::CompoundAssignOperatorClass;
1840
1841 case OO_PipeEqual:
1842 BinaryOp = BO_OrAssign;
1843 return Stmt::CompoundAssignOperatorClass;
1844
1845 case OO_LessLess:
1846 BinaryOp = BO_Shl;
1847 return Stmt::BinaryOperatorClass;
1848
1849 case OO_GreaterGreater:
1850 BinaryOp = BO_Shr;
1851 return Stmt::BinaryOperatorClass;
1852
1853 case OO_LessLessEqual:
1854 BinaryOp = BO_ShlAssign;
1855 return Stmt::CompoundAssignOperatorClass;
1856
1857 case OO_GreaterGreaterEqual:
1858 BinaryOp = BO_ShrAssign;
1859 return Stmt::CompoundAssignOperatorClass;
1860
1861 case OO_EqualEqual:
1862 BinaryOp = BO_EQ;
1863 return Stmt::BinaryOperatorClass;
1864
1865 case OO_ExclaimEqual:
1866 BinaryOp = BO_NE;
1867 return Stmt::BinaryOperatorClass;
1868
1869 case OO_LessEqual:
1870 BinaryOp = BO_LE;
1871 return Stmt::BinaryOperatorClass;
1872
1873 case OO_GreaterEqual:
1874 BinaryOp = BO_GE;
1875 return Stmt::BinaryOperatorClass;
1876
1877 case OO_Spaceship:
1878 BinaryOp = BO_Cmp;
1879 return Stmt::BinaryOperatorClass;
1880
1881 case OO_AmpAmp:
1882 BinaryOp = BO_LAnd;
1883 return Stmt::BinaryOperatorClass;
1884
1885 case OO_PipePipe:
1886 BinaryOp = BO_LOr;
1887 return Stmt::BinaryOperatorClass;
1888
1889 case OO_PlusPlus:
1890 UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc;
1891 NumArgs = 1;
1892 return Stmt::UnaryOperatorClass;
1893
1894 case OO_MinusMinus:
1895 UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec;
1896 NumArgs = 1;
1897 return Stmt::UnaryOperatorClass;
1898
1899 case OO_Comma:
1900 BinaryOp = BO_Comma;
1901 return Stmt::BinaryOperatorClass;
1902
1903 case OO_ArrowStar:
1904 BinaryOp = BO_PtrMemI;
1905 return Stmt::BinaryOperatorClass;
1906
1907 case OO_Subscript:
1908 return Stmt::ArraySubscriptExprClass;
1909
1910 case OO_Call:
1911 return Stmt::CallExprClass;
1912
1913 case OO_Coawait:
1914 UnaryOp = UO_Coawait;
1915 return Stmt::UnaryOperatorClass;
1916 }
1917
1918 llvm_unreachable("Invalid overloaded operator expression");
1919}
1920
1921#if defined(_MSC_VER) && !defined(__clang__)
1922#if _MSC_VER == 1911
1923// Work around https://developercommunity.visualstudio.com/content/problem/84002/clang-cl-when-built-with-vc-2017-crashes-cause-vc.html
1924// MSVC 2017 update 3 miscompiles this function, and a clang built with it
1925// will crash in stage 2 of a bootstrap build.
1926#pragma optimize("", off)
1927#endif
1928#endif
1929
1930void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
1931 if (S->isTypeDependent()) {
1932 // Type-dependent operator calls are profiled like their underlying
1933 // syntactic operator.
1934 //
1935 // An operator call to operator-> is always implicit, so just skip it. The
1936 // enclosing MemberExpr will profile the actual member access.
1937 if (S->getOperator() == OO_Arrow)
1938 return Visit(S->getArg(0));
1939
1940 UnaryOperatorKind UnaryOp = UO_Extension;
1941 BinaryOperatorKind BinaryOp = BO_Comma;
1942 unsigned NumArgs = S->getNumArgs();
1943 Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs);
1944
1945 ID.AddInteger(SC);
1946 for (unsigned I = 0; I != NumArgs; ++I)
1947 Visit(S->getArg(I));
1948 if (SC == Stmt::UnaryOperatorClass)
1949 ID.AddInteger(UnaryOp);
1950 else if (SC == Stmt::BinaryOperatorClass ||
1951 SC == Stmt::CompoundAssignOperatorClass)
1952 ID.AddInteger(BinaryOp);
1953 else
1954 assert(SC == Stmt::ArraySubscriptExprClass || SC == Stmt::CallExprClass);
1955
1956 return;
1957 }
1958
1959 VisitCallExpr(S);
1960 ID.AddInteger(S->getOperator());
1961}
1962
1963void StmtProfiler::VisitCXXRewrittenBinaryOperator(
1964 const CXXRewrittenBinaryOperator *S) {
1965 // If a rewritten operator were ever to be type-dependent, we should profile
1966 // it following its syntactic operator.
1967 assert(!S->isTypeDependent() &&
1968 "resolved rewritten operator should never be type-dependent");
1969 ID.AddBoolean(S->isReversed());
1970 VisitExpr(S->getSemanticForm());
1971}
1972
1973#if defined(_MSC_VER) && !defined(__clang__)
1974#if _MSC_VER == 1911
1975#pragma optimize("", on)
1976#endif
1977#endif
1978
1979void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
1980 VisitCallExpr(S);
1981}
1982
1983void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
1984 VisitCallExpr(S);
1985}
1986
1987void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
1988 VisitExpr(S);
1989}
1990
1991void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
1992 VisitExplicitCastExpr(S);
1993}
1994
1995void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
1996 VisitCXXNamedCastExpr(S);
1997}
1998
1999void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
2000 VisitCXXNamedCastExpr(S);
2001}
2002
2003void
2004StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
2005 VisitCXXNamedCastExpr(S);
2006}
2007
2008void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
2009 VisitCXXNamedCastExpr(S);
2010}
2011
2012void StmtProfiler::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *S) {
2013 VisitExpr(S);
2014 VisitType(S->getTypeInfoAsWritten()->getType());
2015}
2016
2017void StmtProfiler::VisitCXXAddrspaceCastExpr(const CXXAddrspaceCastExpr *S) {
2018 VisitCXXNamedCastExpr(S);
2019}
2020
2021void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
2022 VisitCallExpr(S);
2023}
2024
2025void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
2026 VisitExpr(S);
2027 ID.AddBoolean(S->getValue());
2028}
2029
2030void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
2031 VisitExpr(S);
2032}
2033
2034void StmtProfiler::VisitCXXStdInitializerListExpr(
2035 const CXXStdInitializerListExpr *S) {
2036 VisitExpr(S);
2037}
2038
2039void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
2040 VisitExpr(S);
2041 if (S->isTypeOperand())
2042 VisitType(S->getTypeOperandSourceInfo()->getType());
2043}
2044
2045void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
2046 VisitExpr(S);
2047 if (S->isTypeOperand())
2048 VisitType(S->getTypeOperandSourceInfo()->getType());
2049}
2050
2051void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
2052 VisitExpr(S);
2053 VisitDecl(S->getPropertyDecl());
2054}
2055
2056void StmtProfiler::VisitMSPropertySubscriptExpr(
2057 const MSPropertySubscriptExpr *S) {
2058 VisitExpr(S);
2059}
2060
2061void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
2062 VisitExpr(S);
2063 ID.AddBoolean(S->isImplicit());
2065}
2066
2067void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
2068 VisitExpr(S);
2069}
2070
2071void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
2072 VisitExpr(S);
2073 VisitDecl(S->getParam());
2074}
2075
2076void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
2077 VisitExpr(S);
2078 VisitDecl(S->getField());
2079}
2080
2081void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
2082 VisitExpr(S);
2083 VisitDecl(
2084 const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
2085}
2086
2087void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
2088 VisitExpr(S);
2089 VisitDecl(S->getConstructor());
2090 ID.AddBoolean(S->isElidable());
2091}
2092
2093void StmtProfiler::VisitCXXInheritedCtorInitExpr(
2094 const CXXInheritedCtorInitExpr *S) {
2095 VisitExpr(S);
2096 VisitDecl(S->getConstructor());
2097}
2098
2099void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
2100 VisitExplicitCastExpr(S);
2101}
2102
2103void
2104StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
2105 VisitCXXConstructExpr(S);
2106}
2107
2108void
2109StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
2110 if (!ProfileLambdaExpr) {
2111 // Do not recursively visit the children of this expression. Profiling the
2112 // body would result in unnecessary work, and is not safe to do during
2113 // deserialization.
2114 VisitStmtNoChildren(S);
2115
2116 // C++20 [temp.over.link]p5:
2117 // Two lambda-expressions are never considered equivalent.
2118 VisitDecl(S->getLambdaClass());
2119
2120 return;
2121 }
2122
2123 CXXRecordDecl *Lambda = S->getLambdaClass();
2124 for (const auto &Capture : Lambda->captures()) {
2125 ID.AddInteger(Capture.getCaptureKind());
2126 if (Capture.capturesVariable())
2127 VisitDecl(Capture.getCapturedVar());
2128 }
2129
2130 // Profiling the body of the lambda may be dangerous during deserialization.
2131 // So we'd like only to profile the signature here.
2132 ODRHash Hasher;
2133 // FIXME: We can't get the operator call easily by
2134 // `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization.
2135 // So we have to do something raw here.
2136 for (auto *SubDecl : Lambda->decls()) {
2137 FunctionDecl *Call = nullptr;
2138 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(SubDecl))
2139 Call = FTD->getTemplatedDecl();
2140 else if (auto *FD = dyn_cast<FunctionDecl>(SubDecl))
2141 Call = FD;
2142
2143 if (!Call)
2144 continue;
2145
2146 Hasher.AddFunctionDecl(Call, /*SkipBody=*/true);
2147 }
2148 ID.AddInteger(Hasher.CalculateHash());
2149}
2150
2151void
2152StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
2153 VisitExpr(S);
2154}
2155
2156void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
2157 VisitExpr(S);
2158 ID.AddBoolean(S->isGlobalDelete());
2159 ID.AddBoolean(S->isArrayForm());
2160 VisitDecl(S->getOperatorDelete());
2161}
2162
2163void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
2164 VisitExpr(S);
2165 VisitType(S->getAllocatedType());
2166 VisitDecl(S->getOperatorNew());
2167 VisitDecl(S->getOperatorDelete());
2168 ID.AddBoolean(S->isArray());
2169 ID.AddInteger(S->getNumPlacementArgs());
2170 ID.AddBoolean(S->isGlobalNew());
2171 ID.AddBoolean(S->isParenTypeId());
2172 ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
2173}
2174
2175void
2176StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
2177 VisitExpr(S);
2178 ID.AddBoolean(S->isArrow());
2179 VisitNestedNameSpecifier(S->getQualifier());
2180 ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
2181 if (S->getScopeTypeInfo())
2182 VisitType(S->getScopeTypeInfo()->getType());
2183 ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
2184 if (S->getDestroyedTypeInfo())
2185 VisitType(S->getDestroyedType());
2186 else
2187 VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
2188}
2189
2190void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
2191 VisitExpr(S);
2192 bool DescribingDependentVarTemplate =
2193 S->getNumDecls() == 1 && isa<VarTemplateDecl>(*S->decls_begin());
2194 if (DescribingDependentVarTemplate) {
2195 VisitDecl(*S->decls_begin());
2196 } else {
2197 VisitNestedNameSpecifier(S->getQualifier());
2198 VisitName(S->getName(), /*TreatAsDecl*/ true);
2199 }
2200 ID.AddBoolean(S->hasExplicitTemplateArgs());
2201 if (S->hasExplicitTemplateArgs())
2202 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2203}
2204
2205void
2206StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
2207 VisitOverloadExpr(S);
2208}
2209
2210void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
2211 VisitExpr(S);
2212 ID.AddInteger(S->getTrait());
2213 ID.AddInteger(S->getNumArgs());
2214 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2215 VisitType(S->getArg(I)->getType());
2216}
2217
2218void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
2219 VisitExpr(S);
2220 ID.AddInteger(S->getTrait());
2221 VisitType(S->getQueriedType());
2222}
2223
2224void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
2225 VisitExpr(S);
2226 ID.AddInteger(S->getTrait());
2227 VisitExpr(S->getQueriedExpression());
2228}
2229
2230void StmtProfiler::VisitDependentScopeDeclRefExpr(
2231 const DependentScopeDeclRefExpr *S) {
2232 VisitExpr(S);
2233 VisitName(S->getDeclName());
2234 VisitNestedNameSpecifier(S->getQualifier());
2235 ID.AddBoolean(S->hasExplicitTemplateArgs());
2236 if (S->hasExplicitTemplateArgs())
2237 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2238}
2239
2240void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
2241 VisitExpr(S);
2242}
2243
2244void StmtProfiler::VisitCXXUnresolvedConstructExpr(
2245 const CXXUnresolvedConstructExpr *S) {
2246 VisitExpr(S);
2247 VisitType(S->getTypeAsWritten());
2248 ID.AddInteger(S->isListInitialization());
2249}
2250
2251void StmtProfiler::VisitCXXDependentScopeMemberExpr(
2252 const CXXDependentScopeMemberExpr *S) {
2253 ID.AddBoolean(S->isImplicitAccess());
2254 if (!S->isImplicitAccess()) {
2255 VisitExpr(S);
2256 ID.AddBoolean(S->isArrow());
2257 }
2258 VisitNestedNameSpecifier(S->getQualifier());
2259 VisitName(S->getMember());
2260 ID.AddBoolean(S->hasExplicitTemplateArgs());
2261 if (S->hasExplicitTemplateArgs())
2262 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2263}
2264
2265void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
2266 ID.AddBoolean(S->isImplicitAccess());
2267 if (!S->isImplicitAccess()) {
2268 VisitExpr(S);
2269 ID.AddBoolean(S->isArrow());
2270 }
2271 VisitNestedNameSpecifier(S->getQualifier());
2272 VisitName(S->getMemberName());
2273 ID.AddBoolean(S->hasExplicitTemplateArgs());
2274 if (S->hasExplicitTemplateArgs())
2275 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2276}
2277
2278void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
2279 VisitExpr(S);
2280}
2281
2282void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
2283 VisitExpr(S);
2284}
2285
2286void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
2287 VisitExpr(S);
2288 if (S->isPartiallySubstituted()) {
2289 auto Args = S->getPartialArguments();
2290 ID.AddInteger(Args.size());
2291 for (const auto &TA : Args)
2292 VisitTemplateArgument(TA);
2293 } else {
2294 VisitDecl(S->getPack());
2295 ID.AddInteger(0);
2296 }
2297}
2298
2299void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
2300 VisitExpr(E->getIndexExpr());
2301
2302 if (E->expandsToEmptyPack() || E->getExpressions().size() != 0) {
2303 ID.AddInteger(E->getExpressions().size());
2304 for (const Expr *Sub : E->getExpressions())
2305 Visit(Sub);
2306 } else {
2307 VisitExpr(E->getPackIdExpression());
2308 }
2309}
2310
2311void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
2312 const SubstNonTypeTemplateParmPackExpr *S) {
2313 VisitExpr(S);
2314 VisitDecl(S->getParameterPack());
2315 VisitTemplateArgument(S->getArgumentPack());
2316}
2317
2318void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
2319 const SubstNonTypeTemplateParmExpr *E) {
2320 // Profile exactly as the replacement expression.
2321 Visit(E->getReplacement());
2322}
2323
2324void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
2325 VisitExpr(S);
2326 VisitDecl(S->getParameterPack());
2327 ID.AddInteger(S->getNumExpansions());
2328 for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
2329 VisitDecl(*I);
2330}
2331
2332void StmtProfiler::VisitMaterializeTemporaryExpr(
2333 const MaterializeTemporaryExpr *S) {
2334 VisitExpr(S);
2335}
2336
2337void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
2338 VisitExpr(S);
2339 ID.AddInteger(S->getOperator());
2340}
2341
2342void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
2343 VisitExpr(S);
2344}
2345
2346void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
2347 VisitStmt(S);
2348}
2349
2350void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
2351 VisitStmt(S);
2352}
2353
2354void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
2355 VisitExpr(S);
2356}
2357
2358void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
2359 VisitExpr(S);
2360}
2361
2362void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
2363 VisitExpr(S);
2364}
2365
2366void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2367 VisitExpr(E);
2368}
2369
2370void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
2371 VisitExpr(E);
2372}
2373
2374void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); }
2375
2376void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
2377
2378void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
2379 VisitExpr(S);
2380}
2381
2382void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
2383 VisitExpr(E);
2384}
2385
2386void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
2387 VisitExpr(E);
2388}
2389
2390void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
2391 VisitExpr(E);
2392}
2393
2394void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
2395 VisitExpr(S);
2396 VisitType(S->getEncodedType());
2397}
2398
2399void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
2400 VisitExpr(S);
2401 VisitName(S->getSelector());
2402}
2403
2404void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
2405 VisitExpr(S);
2406 VisitDecl(S->getProtocol());
2407}
2408
2409void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
2410 VisitExpr(S);
2411 VisitDecl(S->getDecl());
2412 ID.AddBoolean(S->isArrow());
2413 ID.AddBoolean(S->isFreeIvar());
2414}
2415
2416void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
2417 VisitExpr(S);
2418 if (S->isImplicitProperty()) {
2419 VisitDecl(S->getImplicitPropertyGetter());
2420 VisitDecl(S->getImplicitPropertySetter());
2421 } else {
2422 VisitDecl(S->getExplicitProperty());
2423 }
2424 if (S->isSuperReceiver()) {
2425 ID.AddBoolean(S->isSuperReceiver());
2426 VisitType(S->getSuperReceiverType());
2427 }
2428}
2429
2430void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
2431 VisitExpr(S);
2432 VisitDecl(S->getAtIndexMethodDecl());
2433 VisitDecl(S->setAtIndexMethodDecl());
2434}
2435
2436void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
2437 VisitExpr(S);
2438 VisitName(S->getSelector());
2439 VisitDecl(S->getMethodDecl());
2440}
2441
2442void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
2443 VisitExpr(S);
2444 ID.AddBoolean(S->isArrow());
2445}
2446
2447void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
2448 VisitExpr(S);
2449 ID.AddBoolean(S->getValue());
2450}
2451
2452void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
2453 const ObjCIndirectCopyRestoreExpr *S) {
2454 VisitExpr(S);
2455 ID.AddBoolean(S->shouldCopy());
2456}
2457
2458void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
2459 VisitExplicitCastExpr(S);
2460 ID.AddBoolean(S->getBridgeKind());
2461}
2462
2463void StmtProfiler::VisitObjCAvailabilityCheckExpr(
2464 const ObjCAvailabilityCheckExpr *S) {
2465 VisitExpr(S);
2466}
2467
2468void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
2469 unsigned NumArgs) {
2470 ID.AddInteger(NumArgs);
2471 for (unsigned I = 0; I != NumArgs; ++I)
2472 VisitTemplateArgument(Args[I].getArgument());
2473}
2474
2475void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
2476 // Mostly repetitive with TemplateArgument::Profile!
2477 ID.AddInteger(Arg.getKind());
2478 switch (Arg.getKind()) {
2480 break;
2481
2483 VisitType(Arg.getAsType());
2484 break;
2485
2488 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
2489 break;
2490
2492 VisitType(Arg.getParamTypeForDecl());
2493 // FIXME: Do we need to recursively decompose template parameter objects?
2494 VisitDecl(Arg.getAsDecl());
2495 break;
2496
2498 VisitType(Arg.getNullPtrType());
2499 break;
2500
2502 VisitType(Arg.getIntegralType());
2503 Arg.getAsIntegral().Profile(ID);
2504 break;
2505
2507 VisitType(Arg.getStructuralValueType());
2508 // FIXME: Do we need to recursively decompose this ourselves?
2509 Arg.getAsStructuralValue().Profile(ID);
2510 break;
2511
2513 Visit(Arg.getAsExpr());
2514 break;
2515
2517 for (const auto &P : Arg.pack_elements())
2518 VisitTemplateArgument(P);
2519 break;
2520 }
2521}
2522
2523namespace {
2524class OpenACCClauseProfiler
2525 : public OpenACCClauseVisitor<OpenACCClauseProfiler> {
2526 StmtProfiler &Profiler;
2527
2528public:
2529 OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {}
2530
2531 void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) {
2532 for (const OpenACCClause *Clause : Clauses) {
2533 // TODO OpenACC: When we have clauses with expressions, we should
2534 // profile them too.
2535 Visit(Clause);
2536 }
2537 }
2538
2539 void VisitClauseWithVarList(const OpenACCClauseWithVarList &Clause) {
2540 for (auto *E : Clause.getVarList())
2541 Profiler.VisitStmt(E);
2542 }
2543
2544#define VISIT_CLAUSE(CLAUSE_NAME) \
2545 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
2546
2547#include "clang/Basic/OpenACCClauses.def"
2548};
2549
2550/// Nothing to do here, there are no sub-statements.
2551void OpenACCClauseProfiler::VisitDefaultClause(
2552 const OpenACCDefaultClause &Clause) {}
2553
2554void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
2555 assert(Clause.hasConditionExpr() &&
2556 "if clause requires a valid condition expr");
2557 Profiler.VisitStmt(Clause.getConditionExpr());
2558}
2559
2560void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
2561 VisitClauseWithVarList(Clause);
2562}
2563
2564void OpenACCClauseProfiler::VisitLinkClause(const OpenACCLinkClause &Clause) {
2565 VisitClauseWithVarList(Clause);
2566}
2567
2568void OpenACCClauseProfiler::VisitDeviceResidentClause(
2569 const OpenACCDeviceResidentClause &Clause) {
2570 VisitClauseWithVarList(Clause);
2571}
2572
2573void OpenACCClauseProfiler::VisitCopyInClause(
2574 const OpenACCCopyInClause &Clause) {
2575 VisitClauseWithVarList(Clause);
2576}
2577
2578void OpenACCClauseProfiler::VisitCopyOutClause(
2579 const OpenACCCopyOutClause &Clause) {
2580 VisitClauseWithVarList(Clause);
2581}
2582
2583void OpenACCClauseProfiler::VisitCreateClause(
2584 const OpenACCCreateClause &Clause) {
2585 VisitClauseWithVarList(Clause);
2586}
2587
2588void OpenACCClauseProfiler::VisitHostClause(const OpenACCHostClause &Clause) {
2589 VisitClauseWithVarList(Clause);
2590}
2591
2592void OpenACCClauseProfiler::VisitDeviceClause(
2593 const OpenACCDeviceClause &Clause) {
2594 VisitClauseWithVarList(Clause);
2595}
2596
2597void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
2598 if (Clause.isConditionExprClause()) {
2599 if (Clause.hasConditionExpr())
2600 Profiler.VisitStmt(Clause.getConditionExpr());
2601 } else {
2602 for (auto *E : Clause.getVarList())
2603 Profiler.VisitStmt(E);
2604 }
2605}
2606
2607void OpenACCClauseProfiler::VisitFinalizeClause(
2608 const OpenACCFinalizeClause &Clause) {}
2609
2610void OpenACCClauseProfiler::VisitIfPresentClause(
2611 const OpenACCIfPresentClause &Clause) {}
2612
2613void OpenACCClauseProfiler::VisitNumGangsClause(
2614 const OpenACCNumGangsClause &Clause) {
2615 for (auto *E : Clause.getIntExprs())
2616 Profiler.VisitStmt(E);
2617}
2618
2619void OpenACCClauseProfiler::VisitTileClause(const OpenACCTileClause &Clause) {
2620 for (auto *E : Clause.getSizeExprs())
2621 Profiler.VisitStmt(E);
2622}
2623
2624void OpenACCClauseProfiler::VisitNumWorkersClause(
2625 const OpenACCNumWorkersClause &Clause) {
2626 assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr");
2627 Profiler.VisitStmt(Clause.getIntExpr());
2628}
2629
2630void OpenACCClauseProfiler::VisitCollapseClause(
2631 const OpenACCCollapseClause &Clause) {
2632 assert(Clause.getLoopCount() && "collapse clause requires a valid int expr");
2633 Profiler.VisitStmt(Clause.getLoopCount());
2634}
2635
2636void OpenACCClauseProfiler::VisitPrivateClause(
2637 const OpenACCPrivateClause &Clause) {
2638 VisitClauseWithVarList(Clause);
2639
2640 for (auto &Recipe : Clause.getInitRecipes()) {
2641 Profiler.VisitDecl(Recipe.AllocaDecl);
2642 if (Recipe.InitExpr)
2643 Profiler.VisitExpr(Recipe.InitExpr);
2644 }
2645}
2646
2647void OpenACCClauseProfiler::VisitFirstPrivateClause(
2648 const OpenACCFirstPrivateClause &Clause) {
2649 VisitClauseWithVarList(Clause);
2650
2651 for (auto &Recipe : Clause.getInitRecipes()) {
2652 Profiler.VisitDecl(Recipe.AllocaDecl);
2653 if (Recipe.InitExpr)
2654 Profiler.VisitExpr(Recipe.InitExpr);
2655 Profiler.VisitDecl(Recipe.InitFromTemporary);
2656 }
2657}
2658
2659void OpenACCClauseProfiler::VisitAttachClause(
2660 const OpenACCAttachClause &Clause) {
2661 VisitClauseWithVarList(Clause);
2662}
2663
2664void OpenACCClauseProfiler::VisitDetachClause(
2665 const OpenACCDetachClause &Clause) {
2666 VisitClauseWithVarList(Clause);
2667}
2668
2669void OpenACCClauseProfiler::VisitDeleteClause(
2670 const OpenACCDeleteClause &Clause) {
2671 VisitClauseWithVarList(Clause);
2672}
2673
2674void OpenACCClauseProfiler::VisitDevicePtrClause(
2675 const OpenACCDevicePtrClause &Clause) {
2676 VisitClauseWithVarList(Clause);
2677}
2678
2679void OpenACCClauseProfiler::VisitNoCreateClause(
2680 const OpenACCNoCreateClause &Clause) {
2681 VisitClauseWithVarList(Clause);
2682}
2683
2684void OpenACCClauseProfiler::VisitPresentClause(
2685 const OpenACCPresentClause &Clause) {
2686 VisitClauseWithVarList(Clause);
2687}
2688
2689void OpenACCClauseProfiler::VisitUseDeviceClause(
2690 const OpenACCUseDeviceClause &Clause) {
2691 VisitClauseWithVarList(Clause);
2692}
2693
2694void OpenACCClauseProfiler::VisitVectorLengthClause(
2695 const OpenACCVectorLengthClause &Clause) {
2696 assert(Clause.hasIntExpr() &&
2697 "vector_length clause requires a valid int expr");
2698 Profiler.VisitStmt(Clause.getIntExpr());
2699}
2700
2701void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
2702 if (Clause.hasIntExpr())
2703 Profiler.VisitStmt(Clause.getIntExpr());
2704}
2705
2706void OpenACCClauseProfiler::VisitDeviceNumClause(
2707 const OpenACCDeviceNumClause &Clause) {
2708 Profiler.VisitStmt(Clause.getIntExpr());
2709}
2710
2711void OpenACCClauseProfiler::VisitDefaultAsyncClause(
2712 const OpenACCDefaultAsyncClause &Clause) {
2713 Profiler.VisitStmt(Clause.getIntExpr());
2714}
2715
2716void OpenACCClauseProfiler::VisitWorkerClause(
2717 const OpenACCWorkerClause &Clause) {
2718 if (Clause.hasIntExpr())
2719 Profiler.VisitStmt(Clause.getIntExpr());
2720}
2721
2722void OpenACCClauseProfiler::VisitVectorClause(
2723 const OpenACCVectorClause &Clause) {
2724 if (Clause.hasIntExpr())
2725 Profiler.VisitStmt(Clause.getIntExpr());
2726}
2727
2728void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
2729 if (Clause.hasDevNumExpr())
2730 Profiler.VisitStmt(Clause.getDevNumExpr());
2731 for (auto *E : Clause.getQueueIdExprs())
2732 Profiler.VisitStmt(E);
2733}
2734
2735/// Nothing to do here, there are no sub-statements.
2736void OpenACCClauseProfiler::VisitDeviceTypeClause(
2737 const OpenACCDeviceTypeClause &Clause) {}
2738
2739void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}
2740
2741void OpenACCClauseProfiler::VisitIndependentClause(
2742 const OpenACCIndependentClause &Clause) {}
2743
2744void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}
2745void OpenACCClauseProfiler::VisitNoHostClause(
2746 const OpenACCNoHostClause &Clause) {}
2747
2748void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) {
2749 for (unsigned I = 0; I < Clause.getNumExprs(); ++I) {
2750 Profiler.VisitStmt(Clause.getExpr(I).second);
2751 }
2752}
2753
2754void OpenACCClauseProfiler::VisitReductionClause(
2755 const OpenACCReductionClause &Clause) {
2756 VisitClauseWithVarList(Clause);
2757
2758 for (auto &Recipe : Clause.getRecipes()) {
2759 Profiler.VisitDecl(Recipe.AllocaDecl);
2760 if (Recipe.InitExpr)
2761 Profiler.VisitExpr(Recipe.InitExpr);
2762 // TODO: OpenACC: Make sure we remember to update this when we figure out
2763 // what we're adding for the operation recipe, in the meantime, a static
2764 // assert will make sure we don't add something.
2765 static_assert(sizeof(OpenACCReductionRecipe) == 2 * sizeof(int *));
2766 }
2767}
2768
2769void OpenACCClauseProfiler::VisitBindClause(const OpenACCBindClause &Clause) {
2770 assert(false && "not implemented... what can we do about our expr?");
2771}
2772} // namespace
2773
2774void StmtProfiler::VisitOpenACCComputeConstruct(
2775 const OpenACCComputeConstruct *S) {
2776 // VisitStmt handles children, so the AssociatedStmt is handled.
2777 VisitStmt(S);
2778
2779 OpenACCClauseProfiler P{*this};
2780 P.VisitOpenACCClauseList(S->clauses());
2781}
2782
2783void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2784 // VisitStmt handles children, so the Loop is handled.
2785 VisitStmt(S);
2786
2787 OpenACCClauseProfiler P{*this};
2788 P.VisitOpenACCClauseList(S->clauses());
2789}
2790
2791void StmtProfiler::VisitOpenACCCombinedConstruct(
2792 const OpenACCCombinedConstruct *S) {
2793 // VisitStmt handles children, so the Loop is handled.
2794 VisitStmt(S);
2795
2796 OpenACCClauseProfiler P{*this};
2797 P.VisitOpenACCClauseList(S->clauses());
2798}
2799
2800void StmtProfiler::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) {
2801 VisitStmt(S);
2802
2803 OpenACCClauseProfiler P{*this};
2804 P.VisitOpenACCClauseList(S->clauses());
2805}
2806
2807void StmtProfiler::VisitOpenACCEnterDataConstruct(
2808 const OpenACCEnterDataConstruct *S) {
2809 VisitStmt(S);
2810
2811 OpenACCClauseProfiler P{*this};
2812 P.VisitOpenACCClauseList(S->clauses());
2813}
2814
2815void StmtProfiler::VisitOpenACCExitDataConstruct(
2816 const OpenACCExitDataConstruct *S) {
2817 VisitStmt(S);
2818
2819 OpenACCClauseProfiler P{*this};
2820 P.VisitOpenACCClauseList(S->clauses());
2821}
2822
2823void StmtProfiler::VisitOpenACCHostDataConstruct(
2824 const OpenACCHostDataConstruct *S) {
2825 VisitStmt(S);
2826
2827 OpenACCClauseProfiler P{*this};
2828 P.VisitOpenACCClauseList(S->clauses());
2829}
2830
2831void StmtProfiler::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
2832 // VisitStmt covers 'children', so the exprs inside of it are covered.
2833 VisitStmt(S);
2834
2835 OpenACCClauseProfiler P{*this};
2836 P.VisitOpenACCClauseList(S->clauses());
2837}
2838
2839void StmtProfiler::VisitOpenACCCacheConstruct(const OpenACCCacheConstruct *S) {
2840 // VisitStmt covers 'children', so the exprs inside of it are covered.
2841 VisitStmt(S);
2842}
2843
2844void StmtProfiler::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
2845 VisitStmt(S);
2846 OpenACCClauseProfiler P{*this};
2847 P.VisitOpenACCClauseList(S->clauses());
2848}
2849
2850void StmtProfiler::VisitOpenACCShutdownConstruct(
2851 const OpenACCShutdownConstruct *S) {
2852 VisitStmt(S);
2853 OpenACCClauseProfiler P{*this};
2854 P.VisitOpenACCClauseList(S->clauses());
2855}
2856
2857void StmtProfiler::VisitOpenACCSetConstruct(const OpenACCSetConstruct *S) {
2858 VisitStmt(S);
2859 OpenACCClauseProfiler P{*this};
2860 P.VisitOpenACCClauseList(S->clauses());
2861}
2862
2863void StmtProfiler::VisitOpenACCUpdateConstruct(
2864 const OpenACCUpdateConstruct *S) {
2865 VisitStmt(S);
2866 OpenACCClauseProfiler P{*this};
2867 P.VisitOpenACCClauseList(S->clauses());
2868}
2869
2870void StmtProfiler::VisitOpenACCAtomicConstruct(
2871 const OpenACCAtomicConstruct *S) {
2872 VisitStmt(S);
2873 OpenACCClauseProfiler P{*this};
2874 P.VisitOpenACCClauseList(S->clauses());
2875}
2876
2877void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) {
2878 VisitStmt(S);
2879}
2880
2881void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2882 bool Canonical, bool ProfileLambdaExpr) const {
2883 StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr);
2884 Profiler.Visit(this);
2885}
2886
2887void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
2888 class ODRHash &Hash) const {
2889 StmtProfilerWithoutPointers Profiler(ID, Hash);
2890 Profiler.Visit(this);
2891}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
This file defines OpenMP AST classes for clauses.
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, UnaryOperatorKind &UnaryOp, BinaryOperatorKind &BinaryOp, unsigned &NumArgs)
static const TemplateArgument & getArgument(const TemplateArgument &A)
llvm::APInt getValue() const
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
Definition APValue.cpp:489
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
LabelDecl * getLabel() const
Definition Expr.h:4507
ArrayTypeTrait getTrait() const
Definition ExprCXX.h:3030
QualType getQueriedType() const
Definition ExprCXX.h:3034
bool isVolatile() const
Definition Stmt.h:3272
unsigned getNumClobbers() const
Definition Stmt.h:3317
unsigned getNumOutputs() const
Definition Stmt.h:3285
unsigned getNumInputs() const
Definition Stmt.h:3307
bool isSimple() const
Definition Stmt.h:3269
AtomicOp getOp() const
Definition Expr.h:6877
Opcode getOpcode() const
Definition Expr.h:4017
const BlockDecl * getBlockDecl() const
Definition Expr.h:6570
CXXTemporary * getTemporary()
Definition ExprCXX.h:1512
bool getValue() const
Definition ExprCXX.h:740
QualType getCaughtType() const
Definition StmtCXX.cpp:19
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1618
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1612
const ParmVarDecl * getParam() const
Definition ExprCXX.h:1313
FieldDecl * getField()
Get the field whose initializer will be used.
Definition ExprCXX.h:1412
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2659
bool isArrayForm() const
Definition ExprCXX.h:2646
bool isGlobalDelete() const
Definition ExprCXX.h:2645
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:3963
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the member name.
Definition ExprCXX.h:3971
unsigned getNumTemplateArgs() const
Retrieve the number of template arguments provided as part of this template-id.
Definition ExprCXX.h:4058
const TemplateArgumentLoc * getTemplateArgs() const
Retrieve the template arguments provided as part of this template-id.
Definition ExprCXX.h:4049
bool hasExplicitTemplateArgs() const
Determines whether this member expression actually had a C++ template argument list explicitly specif...
Definition ExprCXX.h:4037
DeclarationName getMember() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4002
bool isImplicitAccess() const
True if this is an implicit access, i.e.
Definition ExprCXX.h:3946
BinaryOperatorKind getOperator() const
Definition ExprCXX.h:5071
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition ExprCXX.h:1790
bool isArray() const
Definition ExprCXX.h:2458
QualType getAllocatedType() const
Definition ExprCXX.h:2428
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition ExprCXX.h:2521
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2455
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2488
bool isParenTypeId() const
Definition ExprCXX.h:2509
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2453
bool isGlobalNew() const
Definition ExprCXX.h:2515
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:84
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Definition ExprCXX.h:114
TypeSourceInfo * getDestroyedTypeInfo() const
Retrieve the source location information for the type being destroyed.
Definition ExprCXX.h:2833
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition ExprCXX.h:2803
TypeSourceInfo * getScopeTypeInfo() const
Retrieve the scope type in a qualified pseudo-destructor expression.
Definition ExprCXX.h:2817
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:385
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition ExprCXX.h:2797
const IdentifierInfo * getDestroyedTypeIdentifier() const
In a dependent pseudo-destructor expression for which we do not have full type information on the des...
Definition ExprCXX.h:2840
capture_const_range captures() const
Definition DeclCXX.h:1097
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition ExprCXX.h:304
bool isReversed() const
Determine whether this expression was rewritten in reverse form.
Definition ExprCXX.h:322
const CXXDestructorDecl * getDestructor() const
Definition ExprCXX.h:1471
bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const
Definition ExprCXX.h:1181
bool isImplicit() const
Definition ExprCXX.h:1178
bool isTypeOperand() const
Definition ExprCXX.h:884
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:891
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:3793
QualType getTypeAsWritten() const
Retrieve the type that is being constructed, as specified in the source code.
Definition ExprCXX.h:3772
bool isTypeOperand() const
Definition ExprCXX.h:1099
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:1106
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3081
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3068
unsigned getValue() const
Definition Expr.h:1629
CharacterLiteralKind getKind() const
Definition Expr.h:1622
bool isFileScope() const
Definition Expr.h:3571
ArrayRef< TemplateArgument > getTemplateArguments() const
ConceptDecl * getNamedConcept() const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2373
unsigned getNumTemplateArgs() const
Retrieve the number of template arguments provided as part of this template-id.
Definition Expr.h:1445
bool hasExplicitTemplateArgs() const
Determines whether this declaration reference was followed by an explicit template argument list.
Definition Expr.h:1425
NestedNameSpecifier getQualifier() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name.
Definition Expr.h:1371
ValueDecl * getDecl()
Definition Expr.h:1338
const TemplateArgumentLoc * getTemplateArgs() const
Retrieve the template arguments provided as part of this template-id.
Definition Expr.h:1437
decl_range decls()
Definition Stmt.h:1659
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:978
Kind getKind() const
Definition DeclBase.h:442
The name of a declaration.
void * getAsOpaquePtr() const
Get the representation of this declaration name as an opaque pointer.
bool hasExplicitTemplateArgs() const
Determines whether this lookup had explicit template arguments.
Definition ExprCXX.h:3588
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3556
unsigned getNumTemplateArgs() const
Definition ExprCXX.h:3605
DeclarationName getDeclName() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3543
TemplateArgumentLoc const * getTemplateArgs() const
Definition ExprCXX.h:3598
bool usesGNUSyntax() const
Determines whether this designated initializer used the deprecated GNU syntax for designated initiali...
Definition Expr.h:5749
MutableArrayRef< Designator > designators()
Definition Expr.h:5718
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition Expr.h:3884
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:3889
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition Expr.h:444
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:194
QualType getType() const
Definition Expr.h:144
Expr * getQueriedExpression() const
Definition ExprCXX.h:3102
ExpressionTrait getTrait() const
Definition ExprCXX.h:3098
IdentifierInfo & getAccessor() const
Definition Expr.h:6519
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
Definition Expr.h:1575
llvm::APFloat getValue() const
Definition Expr.h:1666
bool isExact() const
Definition Expr.h:1699
const Expr * getSubExpr() const
Definition Expr.h:1062
ValueDecl *const * iterator
Iterators over the parameters which the parameter pack expanded into.
Definition ExprCXX.h:4868
ValueDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition ExprCXX.h:4861
iterator end() const
Definition ExprCXX.h:4870
unsigned getNumExpansions() const
Get the number of parameters in this parameter pack.
Definition ExprCXX.h:4873
iterator begin() const
Definition ExprCXX.h:4869
unsigned getNumLabels() const
Definition Stmt.h:3545
labels_range labels()
Definition Stmt.h:3568
const Expr * getOutputConstraintExpr(unsigned i) const
Definition Stmt.h:3497
StringRef getInputName(unsigned i) const
Definition Stmt.h:3514
StringRef getOutputName(unsigned i) const
Definition Stmt.h:3488
const Expr * getInputConstraintExpr(unsigned i) const
Definition Stmt.h:3523
const Expr * getAsmStringExpr() const
Definition Stmt.h:3422
Expr * getClobberExpr(unsigned i)
Definition Stmt.h:3602
association_range associations()
Definition Expr.h:6443
AssociationTy< true > ConstAssociation
Definition Expr.h:6344
LabelDecl * getLabel() const
Definition Stmt.h:2982
One of these records is kept for each identifier that is lexed.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
Definition Stmt.cpp:1026
InitListExpr * getSyntacticForm() const
Definition Expr.h:5406
LabelDecl * getDecl() const
Definition Stmt.h:2164
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1400
bool isIfExists() const
Determine whether this is an __if_exists statement.
Definition StmtCXX.h:278
DeclarationNameInfo getNameInfo() const
Retrieve the name of the entity we're testing for, along with location information.
Definition StmtCXX.h:289
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies this name, if any.
Definition StmtCXX.h:285
MSPropertyDecl * getPropertyDecl() const
Definition ExprCXX.h:990
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition Expr.h:3409
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3381
bool isArrow() const
Definition Expr.h:3482
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NestedNameSpecifier getCanonical() const
Retrieves the "canonical" nested name specifier for a given nested name specifier.
void Profile(llvm::FoldingSetNodeID &ID) const
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition ODRHash.cpp:670
unsigned CalculateHash()
Definition ODRHash.cpp:231
Class that handles post-update expression for some clauses, like 'lastprivate', 'reduction' etc.
Class that handles pre-initialization statement for some clauses, like 'schedule',...
unsigned numOfIterators() const
Returns number of iterator definitions.
Definition ExprOpenMP.h:275
Decl * getIteratorDecl(unsigned I)
Gets the iterator declaration for the given iterator.
Definition Expr.cpp:5403
const VarDecl * getCatchParamDecl() const
Definition StmtObjC.h:97
bool hasEllipsis() const
Definition StmtObjC.h:113
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition ExprObjC.h:1669
QualType getEncodedType() const
Definition ExprObjC.h:428
bool shouldCopy() const
shouldCopy - True if we should do the 'copy' part of the copy-restore.
Definition ExprObjC.h:1610
bool isArrow() const
Definition ExprObjC.h:1525
ObjCIvarDecl * getDecl()
Definition ExprObjC.h:578
bool isArrow() const
Definition ExprObjC.h:586
bool isFreeIvar() const
Definition ExprObjC.h:587
Selector getSelector() const
Definition ExprObjC.cpp:289
const ObjCMethodDecl * getMethodDecl() const
Definition ExprObjC.h:1364
ObjCPropertyDecl * getExplicitProperty() const
Definition ExprObjC.h:705
ObjCMethodDecl * getImplicitPropertyGetter() const
Definition ExprObjC.h:710
QualType getSuperReceiverType() const
Definition ExprObjC.h:761
bool isImplicitProperty() const
Definition ExprObjC.h:702
ObjCMethodDecl * getImplicitPropertySetter() const
Definition ExprObjC.h:715
bool isSuperReceiver() const
Definition ExprObjC.h:770
ObjCProtocolDecl * getProtocol() const
Definition ExprObjC.h:521
Selector getSelector() const
Definition ExprObjC.h:468
ObjCMethodDecl * getAtIndexMethodDecl() const
Definition ExprObjC.h:884
ObjCMethodDecl * setAtIndexMethodDecl() const
Definition ExprObjC.h:888
const OffsetOfNode & getComponent(unsigned Idx) const
Definition Expr.h:2574
TypeSourceInfo * getTypeSourceInfo() const
Definition Expr.h:2567
unsigned getNumComponents() const
Definition Expr.h:2582
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition Expr.h:2485
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1684
@ Array
An index into an array.
Definition Expr.h:2426
@ Identifier
A field in a dependent type, known only by its name.
Definition Expr.h:2430
@ Field
A field.
Definition Expr.h:2428
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition Expr.h:2433
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2475
const Expr * getConditionExpr() const
ArrayRef< Expr * > getVarList()
const Expr * getLoopCount() const
ArrayRef< OpenACCFirstPrivateRecipe > getInitRecipes()
unsigned getNumExprs() const
std::pair< OpenACCGangKind, const Expr * > getExpr(unsigned I) const
ArrayRef< Expr * > getIntExprs()
ArrayRef< OpenACCPrivateRecipe > getInitRecipes()
ArrayRef< OpenACCReductionRecipe > getRecipes()
const Expr * getConditionExpr() const
bool isConditionExprClause() const
ArrayRef< Expr * > getVarList()
ArrayRef< Expr * > getSizeExprs()
ArrayRef< Expr * > getQueueIdExprs()
Expr * getDevNumExpr() const
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition ExprCXX.h:3274
NestedNameSpecifier getQualifier() const
Fetches the nested-name qualifier, if one was given.
Definition ExprCXX.h:3238
decls_iterator decls_begin() const
Definition ExprCXX.h:3215
unsigned getNumDecls() const
Gets the number of declarations in the unresolved set.
Definition ExprCXX.h:3226
TemplateArgumentLoc const * getTemplateArgs() const
Definition ExprCXX.h:3318
unsigned getNumTemplateArgs() const
Definition ExprCXX.h:3324
DeclarationName getName() const
Gets the name looked up.
Definition ExprCXX.h:3232
Expr * getIndexExpr() const
Definition ExprCXX.h:4622
ArrayRef< Expr * > getExpressions() const
Return the trailing expressions, regardless of the expansion.
Definition ExprCXX.h:4640
bool expandsToEmptyPack() const
Determine if the expression was expanded to empty.
Definition ExprCXX.h:4601
Expr * getPackIdExpression() const
Definition ExprCXX.h:4618
PredefinedIdentKind getIdentKind() const
Definition Expr.h:2040
semantics_iterator semantics_end()
Definition Expr.h:6755
semantics_iterator semantics_begin()
Definition Expr.h:6751
const Expr *const * const_semantics_iterator
Definition Expr.h:6750
A (possibly-)qualified type.
Definition TypeBase.h:937
ArrayRef< concepts::Requirement * > getRequirements() const
ArrayRef< ParmVarDecl * > getLocalParameters() const
TypeSourceInfo * getTypeSourceInfo()
Definition Expr.h:2143
bool isPartiallySubstituted() const
Determine whether this represents a partially-substituted sizeof... expression, such as is produced f...
Definition ExprCXX.h:4520
ArrayRef< TemplateArgument > getPartialArguments() const
Get.
Definition ExprCXX.h:4525
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition ExprCXX.h:4503
Stmt - This represents one statement.
Definition Stmt.h:85
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash &Hash) const
Calculate a unique representation for a statement that is stable across compiler invocations.
child_range children()
Definition Stmt.cpp:295
StmtClass getStmtClass() const
Definition Stmt.h:1472
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
StringLiteralKind getKind() const
Definition Expr.h:1912
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Definition Expr.h:1875
TemplateArgument getArgumentPack() const
Retrieve the template argument pack containing the substituted template arguments.
Definition ExprCXX.cpp:1799
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Definition ExprCXX.cpp:1794
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
Definition Stmt.cpp:1144
Location wrapper for a TemplateArgument.
Represents a template argument.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Represents a C++ template name within the type system.
void Profile(llvm::FoldingSetNodeID &ID)
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition ASTConcept.h:240
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8269
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition ExprCXX.h:2955
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition ExprCXX.h:2952
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition ExprCXX.h:2933
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9167
TypeClass getTypeClass() const
Definition TypeBase.h:2385
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9100
QualType getArgumentType() const
Definition Expr.h:2668
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2657
Opcode getOpcode() const
Definition Expr.h:2280
DeclarationName getMemberName() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4228
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4212
bool isImplicitAccess() const
True if this is an implicit access, i.e., one in which the member being accessed was not written in t...
Definition ExprCXX.cpp:1645
QualType getType() const
Definition Decl.h:722
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Definition Stmt.cpp:1205
The JSON file list parser is used to communicate input to InstallAPI.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Definition Address.h:327
#define false
Definition stdbool.h:26
DeclarationName getName() const
getName - Returns the embedded declaration name.
Expr * AllocatorTraits
Allocator traits.