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