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