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