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): Add support for Null, TypeSourceInfo,
2272 // TemplateReference and DeclRefExpr
2273 VisitExpr(E);
2274 ID.AddInteger(static_cast<int>(E->getKind()));
2275 switch (E->getKind()) {
2276 case ReflectionKind::Null:
2277 assert(false && "null reflection can't be constructed from parsing a "
2278 "reflection operand");
2279 return;
2280 case ReflectionKind::Type: {
2281 QualType QT = E->getTypeSourceInfo()->getType();
2283 if (const auto *TDT = QT->getAs<TypedefType>()) {
2284 ID.AddBoolean(true);
2285 VisitDecl(TDT->getDecl()->getCanonicalDecl());
2286 return;
2287 }
2288 }
2289 ID.AddBoolean(false);
2290 VisitType(QT);
2291 return;
2292 }
2293 }
2294 assert(false && "unknown or unimplemented reflection entities");
2295}
2296
2297void
2298StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
2299 VisitExpr(S);
2300}
2301
2302void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
2303 VisitExpr(S);
2304 ID.AddBoolean(S->isGlobalDelete());
2305 ID.AddBoolean(S->isArrayForm());
2306 VisitDecl(S->getOperatorDelete());
2307}
2308
2309void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
2310 VisitExpr(S);
2311 VisitType(S->getAllocatedType());
2312 VisitDecl(S->getOperatorNew());
2313 VisitDecl(S->getOperatorDelete());
2314 ID.AddBoolean(S->isArray());
2315 ID.AddInteger(S->getNumPlacementArgs());
2316 ID.AddBoolean(S->isGlobalNew());
2317 ID.AddBoolean(S->isParenTypeId());
2318 ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
2319}
2320
2321void
2322StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
2323 VisitExpr(S);
2324 ID.AddBoolean(S->isArrow());
2325 VisitNestedNameSpecifier(S->getQualifier());
2326 ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
2327 if (S->getScopeTypeInfo())
2328 VisitType(S->getScopeTypeInfo()->getType());
2329 ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
2330 if (S->getDestroyedTypeInfo())
2331 VisitType(S->getDestroyedType());
2332 else
2333 VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
2334}
2335
2336void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
2337 VisitExpr(S);
2338 bool DescribingDependentVarTemplate =
2339 S->getNumDecls() == 1 && isa<VarTemplateDecl>(*S->decls_begin());
2340 if (DescribingDependentVarTemplate) {
2341 VisitDecl(*S->decls_begin());
2342 } else {
2343 VisitNestedNameSpecifier(S->getQualifier());
2344 VisitName(S->getName(), /*TreatAsDecl*/ true);
2345 }
2346 ID.AddBoolean(S->hasExplicitTemplateArgs());
2347 if (S->hasExplicitTemplateArgs())
2348 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2349}
2350
2351void
2352StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
2353 VisitOverloadExpr(S);
2354}
2355
2356void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
2357 VisitExpr(S);
2358 ID.AddInteger(S->getTrait());
2359 ID.AddInteger(S->getNumArgs());
2360 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2361 VisitType(S->getArg(I)->getType());
2362}
2363
2364void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
2365 VisitExpr(S);
2366 ID.AddInteger(S->getTrait());
2367 VisitType(S->getQueriedType());
2368}
2369
2370void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
2371 VisitExpr(S);
2372 ID.AddInteger(S->getTrait());
2373 VisitExpr(S->getQueriedExpression());
2374}
2375
2376void StmtProfiler::VisitDependentScopeDeclRefExpr(
2377 const DependentScopeDeclRefExpr *S) {
2378 VisitExpr(S);
2379 VisitName(S->getDeclName());
2380 VisitNestedNameSpecifier(S->getQualifier());
2381 ID.AddBoolean(S->hasExplicitTemplateArgs());
2382 if (S->hasExplicitTemplateArgs())
2383 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2384}
2385
2386void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
2387 VisitExpr(S);
2388}
2389
2390void StmtProfiler::VisitCXXUnresolvedConstructExpr(
2391 const CXXUnresolvedConstructExpr *S) {
2392 VisitExpr(S);
2393 VisitType(S->getTypeAsWritten());
2394 ID.AddInteger(S->isListInitialization());
2395}
2396
2397void StmtProfiler::VisitDependentTemplateIdExpr(
2398 const DependentTemplateIdExpr *S) {
2399 VisitExpr(S);
2400 VisitTemplateName(S->getTemplateName());
2401 VisitTemplateArguments(S->template_arguments().data(),
2402 S->getNumTemplateArgs());
2403}
2404
2405void StmtProfiler::VisitCXXDependentScopeMemberExpr(
2406 const CXXDependentScopeMemberExpr *S) {
2407 ID.AddBoolean(S->isImplicitAccess());
2408 if (!S->isImplicitAccess()) {
2409 VisitExpr(S);
2410 ID.AddBoolean(S->isArrow());
2411 }
2412 VisitNestedNameSpecifier(S->getQualifier());
2413 VisitName(S->getMember());
2414 ID.AddBoolean(S->hasExplicitTemplateArgs());
2415 if (S->hasExplicitTemplateArgs())
2416 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2417}
2418
2419void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
2420 ID.AddBoolean(S->isImplicitAccess());
2421 if (!S->isImplicitAccess()) {
2422 VisitExpr(S);
2423 ID.AddBoolean(S->isArrow());
2424 }
2425 VisitNestedNameSpecifier(S->getQualifier());
2426 VisitName(S->getMemberName());
2427 ID.AddBoolean(S->hasExplicitTemplateArgs());
2428 if (S->hasExplicitTemplateArgs())
2429 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2430}
2431
2432void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
2433 VisitExpr(S);
2434}
2435
2436void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
2437 VisitExpr(S);
2438}
2439
2440void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
2441 VisitExpr(S);
2442 if (S->isPartiallySubstituted()) {
2443 auto Args = S->getPartialArguments();
2444 ID.AddInteger(Args.size());
2445 for (const auto &TA : Args)
2446 VisitTemplateArgument(TA);
2447 } else {
2448 VisitDecl(S->getPack());
2449 ID.AddInteger(0);
2450 }
2451}
2452
2453void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
2454 VisitStmtNoChildren(E);
2455 Visit(E->getIndexExpr());
2456 if (E->expandsToEmptyPack() || E->getExpressions().size() != 0) {
2457 ID.AddInteger(E->getExpressions().size());
2458 for (const Expr *Sub : E->getExpressions())
2459 Visit(Sub);
2460 } else {
2461 Visit(E->getPackIdExpression());
2462 }
2463}
2464
2465void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
2466 const SubstNonTypeTemplateParmPackExpr *S) {
2467 VisitExpr(S);
2468 VisitDecl(S->getParameterPack());
2469 VisitTemplateArgument(S->getArgumentPack());
2470}
2471
2472void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
2473 const SubstNonTypeTemplateParmExpr *E) {
2474 // Profile exactly as the replacement expression.
2475 Visit(E->getReplacement());
2476}
2477
2478void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
2479 VisitExpr(S);
2480 VisitDecl(S->getParameterPack());
2481 ID.AddInteger(S->getNumExpansions());
2482 for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
2483 VisitDecl(*I);
2484}
2485
2486void StmtProfiler::VisitMaterializeTemporaryExpr(
2487 const MaterializeTemporaryExpr *S) {
2488 VisitExpr(S);
2489}
2490
2491void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
2492 VisitStmtNoChildren(S);
2493 // The callee sub-expression is not part of how the expression is written,
2494 // so it's not added to the profile.
2495 //
2496 // Example:
2497 // template <typename... T> requires ((sizeof(T) > 0) && ...) void f() {}
2498 // class A;
2499 // void operator&&(A, A);
2500 // template <typename... T> requires ((sizeof(T) > 0) && ...) void f() {}
2501 //
2502 // Both definitions have identically written fold expressions, but semantic
2503 // analysis adds the overloaded operator to the second one.
2504 if (S->getLHS())
2505 Visit(S->getLHS());
2506 else
2507 ID.AddInteger(0);
2508 if (S->getRHS())
2509 Visit(S->getRHS());
2510 else
2511 ID.AddInteger(0);
2512 ID.AddInteger(S->getOperator());
2513}
2514
2515void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
2516 VisitExpr(S);
2517}
2518
2519void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
2520 VisitStmt(S);
2521}
2522
2523void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
2524 VisitStmt(S);
2525}
2526
2527void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
2528 VisitExpr(S);
2529}
2530
2531void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
2532 VisitExpr(S);
2533}
2534
2535void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
2536 VisitExpr(S);
2537}
2538
2539void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2540 VisitExpr(E);
2541}
2542
2543void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
2544 VisitExpr(E);
2545}
2546
2547void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); }
2548
2549void StmtProfiler::VisitCXXExpansionSelectExpr(
2550 const CXXExpansionSelectExpr *E) {
2551 VisitExpr(E);
2552}
2553
2554void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
2555
2556void StmtProfiler::VisitObjCObjectLiteral(const ObjCObjectLiteral *E) {
2557 VisitExpr(E);
2558}
2559
2560void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
2561 VisitObjCObjectLiteral(S);
2562}
2563
2564void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
2565 VisitObjCObjectLiteral(E);
2566}
2567
2568void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
2569 VisitObjCObjectLiteral(E);
2570}
2571
2572void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
2573 VisitObjCObjectLiteral(E);
2574}
2575
2576void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
2577 VisitExpr(S);
2578 VisitType(S->getEncodedType());
2579}
2580
2581void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
2582 VisitExpr(S);
2583 VisitName(S->getSelector());
2584}
2585
2586void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
2587 VisitExpr(S);
2588 VisitDecl(S->getProtocol());
2589}
2590
2591void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
2592 VisitExpr(S);
2593 VisitDecl(S->getDecl());
2594 ID.AddBoolean(S->isArrow());
2595 ID.AddBoolean(S->isFreeIvar());
2596}
2597
2598void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
2599 VisitExpr(S);
2600 if (S->isImplicitProperty()) {
2601 VisitDecl(S->getImplicitPropertyGetter());
2602 VisitDecl(S->getImplicitPropertySetter());
2603 } else {
2604 VisitDecl(S->getExplicitProperty());
2605 }
2606 if (S->isSuperReceiver()) {
2607 ID.AddBoolean(S->isSuperReceiver());
2608 VisitType(S->getSuperReceiverType());
2609 }
2610}
2611
2612void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
2613 VisitExpr(S);
2614 VisitDecl(S->getAtIndexMethodDecl());
2615 VisitDecl(S->setAtIndexMethodDecl());
2616}
2617
2618void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
2619 VisitExpr(S);
2620 VisitName(S->getSelector());
2621 VisitDecl(S->getMethodDecl());
2622}
2623
2624void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
2625 VisitExpr(S);
2626 ID.AddBoolean(S->isArrow());
2627}
2628
2629void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
2630 VisitExpr(S);
2631 ID.AddBoolean(S->getValue());
2632}
2633
2634void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
2635 const ObjCIndirectCopyRestoreExpr *S) {
2636 VisitExpr(S);
2637 ID.AddBoolean(S->shouldCopy());
2638}
2639
2640void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
2641 VisitExplicitCastExpr(S);
2642 ID.AddBoolean(S->getBridgeKind());
2643}
2644
2645void StmtProfiler::VisitObjCAvailabilityCheckExpr(
2646 const ObjCAvailabilityCheckExpr *S) {
2647 VisitExpr(S);
2648}
2649
2650void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
2651 unsigned NumArgs) {
2652 ID.AddInteger(NumArgs);
2653 for (unsigned I = 0; I != NumArgs; ++I)
2654 VisitTemplateArgument(Args[I].getArgument());
2655}
2656
2657void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
2658 // Mostly repetitive with TemplateArgument::Profile!
2659 ID.AddInteger(Arg.getKind());
2660 switch (Arg.getKind()) {
2662 break;
2663
2665 VisitType(Arg.getAsType());
2666 break;
2667
2670 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
2671 break;
2672
2674 VisitType(Arg.getParamTypeForDecl());
2675 // FIXME: Do we need to recursively decompose template parameter objects?
2676 VisitDecl(Arg.getAsDecl());
2677 break;
2678
2680 VisitType(Arg.getNullPtrType());
2681 break;
2682
2684 VisitType(Arg.getIntegralType());
2685 Arg.getAsIntegral().Profile(ID);
2686 break;
2687
2689 VisitType(Arg.getStructuralValueType());
2690 // FIXME: Do we need to recursively decompose this ourselves?
2691 Arg.getAsStructuralValue().Profile(ID);
2692 break;
2693
2695 Visit(Arg.getAsExpr());
2696 break;
2697
2699 for (const auto &P : Arg.pack_elements())
2700 VisitTemplateArgument(P);
2701 break;
2702 }
2703}
2704
2705namespace {
2706class OpenACCClauseProfiler
2707 : public OpenACCClauseVisitor<OpenACCClauseProfiler> {
2708 StmtProfiler &Profiler;
2709
2710public:
2711 OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {}
2712
2713 void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) {
2714 for (const OpenACCClause *Clause : Clauses) {
2715 // TODO OpenACC: When we have clauses with expressions, we should
2716 // profile them too.
2717 Visit(Clause);
2718 }
2719 }
2720
2721 void VisitClauseWithVarList(const OpenACCClauseWithVarList &Clause) {
2722 for (auto *E : Clause.getVarList())
2723 Profiler.VisitStmt(E);
2724 }
2725
2726#define VISIT_CLAUSE(CLAUSE_NAME) \
2727 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
2728
2729#include "clang/Basic/OpenACCClauses.def"
2730};
2731
2732/// Nothing to do here, there are no sub-statements.
2733void OpenACCClauseProfiler::VisitDefaultClause(
2734 const OpenACCDefaultClause &Clause) {}
2735
2736void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
2737 assert(Clause.hasConditionExpr() &&
2738 "if clause requires a valid condition expr");
2739 Profiler.VisitStmt(Clause.getConditionExpr());
2740}
2741
2742void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
2743 VisitClauseWithVarList(Clause);
2744}
2745
2746void OpenACCClauseProfiler::VisitLinkClause(const OpenACCLinkClause &Clause) {
2747 VisitClauseWithVarList(Clause);
2748}
2749
2750void OpenACCClauseProfiler::VisitDeviceResidentClause(
2751 const OpenACCDeviceResidentClause &Clause) {
2752 VisitClauseWithVarList(Clause);
2753}
2754
2755void OpenACCClauseProfiler::VisitCopyInClause(
2756 const OpenACCCopyInClause &Clause) {
2757 VisitClauseWithVarList(Clause);
2758}
2759
2760void OpenACCClauseProfiler::VisitCopyOutClause(
2761 const OpenACCCopyOutClause &Clause) {
2762 VisitClauseWithVarList(Clause);
2763}
2764
2765void OpenACCClauseProfiler::VisitCreateClause(
2766 const OpenACCCreateClause &Clause) {
2767 VisitClauseWithVarList(Clause);
2768}
2769
2770void OpenACCClauseProfiler::VisitHostClause(const OpenACCHostClause &Clause) {
2771 VisitClauseWithVarList(Clause);
2772}
2773
2774void OpenACCClauseProfiler::VisitDeviceClause(
2775 const OpenACCDeviceClause &Clause) {
2776 VisitClauseWithVarList(Clause);
2777}
2778
2779void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
2780 if (Clause.isConditionExprClause()) {
2781 if (Clause.hasConditionExpr())
2782 Profiler.VisitStmt(Clause.getConditionExpr());
2783 } else {
2784 for (auto *E : Clause.getVarList())
2785 Profiler.VisitStmt(E);
2786 }
2787}
2788
2789void OpenACCClauseProfiler::VisitFinalizeClause(
2790 const OpenACCFinalizeClause &Clause) {}
2791
2792void OpenACCClauseProfiler::VisitIfPresentClause(
2793 const OpenACCIfPresentClause &Clause) {}
2794
2795void OpenACCClauseProfiler::VisitNumGangsClause(
2796 const OpenACCNumGangsClause &Clause) {
2797 for (auto *E : Clause.getIntExprs())
2798 Profiler.VisitStmt(E);
2799}
2800
2801void OpenACCClauseProfiler::VisitTileClause(const OpenACCTileClause &Clause) {
2802 for (auto *E : Clause.getSizeExprs())
2803 Profiler.VisitStmt(E);
2804}
2805
2806void OpenACCClauseProfiler::VisitNumWorkersClause(
2807 const OpenACCNumWorkersClause &Clause) {
2808 assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr");
2809 Profiler.VisitStmt(Clause.getIntExpr());
2810}
2811
2812void OpenACCClauseProfiler::VisitCollapseClause(
2813 const OpenACCCollapseClause &Clause) {
2814 assert(Clause.getLoopCount() && "collapse clause requires a valid int expr");
2815 Profiler.VisitStmt(Clause.getLoopCount());
2816}
2817
2818void OpenACCClauseProfiler::VisitPrivateClause(
2819 const OpenACCPrivateClause &Clause) {
2820 VisitClauseWithVarList(Clause);
2821
2822 for (auto &Recipe : Clause.getInitRecipes()) {
2823 Profiler.VisitDecl(Recipe.AllocaDecl);
2824 }
2825}
2826
2827void OpenACCClauseProfiler::VisitFirstPrivateClause(
2828 const OpenACCFirstPrivateClause &Clause) {
2829 VisitClauseWithVarList(Clause);
2830
2831 for (auto &Recipe : Clause.getInitRecipes()) {
2832 Profiler.VisitDecl(Recipe.AllocaDecl);
2833 Profiler.VisitDecl(Recipe.InitFromTemporary);
2834 }
2835}
2836
2837void OpenACCClauseProfiler::VisitAttachClause(
2838 const OpenACCAttachClause &Clause) {
2839 VisitClauseWithVarList(Clause);
2840}
2841
2842void OpenACCClauseProfiler::VisitDetachClause(
2843 const OpenACCDetachClause &Clause) {
2844 VisitClauseWithVarList(Clause);
2845}
2846
2847void OpenACCClauseProfiler::VisitDeleteClause(
2848 const OpenACCDeleteClause &Clause) {
2849 VisitClauseWithVarList(Clause);
2850}
2851
2852void OpenACCClauseProfiler::VisitDevicePtrClause(
2853 const OpenACCDevicePtrClause &Clause) {
2854 VisitClauseWithVarList(Clause);
2855}
2856
2857void OpenACCClauseProfiler::VisitNoCreateClause(
2858 const OpenACCNoCreateClause &Clause) {
2859 VisitClauseWithVarList(Clause);
2860}
2861
2862void OpenACCClauseProfiler::VisitPresentClause(
2863 const OpenACCPresentClause &Clause) {
2864 VisitClauseWithVarList(Clause);
2865}
2866
2867void OpenACCClauseProfiler::VisitUseDeviceClause(
2868 const OpenACCUseDeviceClause &Clause) {
2869 VisitClauseWithVarList(Clause);
2870}
2871
2872void OpenACCClauseProfiler::VisitVectorLengthClause(
2873 const OpenACCVectorLengthClause &Clause) {
2874 assert(Clause.hasIntExpr() &&
2875 "vector_length clause requires a valid int expr");
2876 Profiler.VisitStmt(Clause.getIntExpr());
2877}
2878
2879void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
2880 if (Clause.hasIntExpr())
2881 Profiler.VisitStmt(Clause.getIntExpr());
2882}
2883
2884void OpenACCClauseProfiler::VisitDeviceNumClause(
2885 const OpenACCDeviceNumClause &Clause) {
2886 Profiler.VisitStmt(Clause.getIntExpr());
2887}
2888
2889void OpenACCClauseProfiler::VisitDefaultAsyncClause(
2890 const OpenACCDefaultAsyncClause &Clause) {
2891 Profiler.VisitStmt(Clause.getIntExpr());
2892}
2893
2894void OpenACCClauseProfiler::VisitWorkerClause(
2895 const OpenACCWorkerClause &Clause) {
2896 if (Clause.hasIntExpr())
2897 Profiler.VisitStmt(Clause.getIntExpr());
2898}
2899
2900void OpenACCClauseProfiler::VisitVectorClause(
2901 const OpenACCVectorClause &Clause) {
2902 if (Clause.hasIntExpr())
2903 Profiler.VisitStmt(Clause.getIntExpr());
2904}
2905
2906void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
2907 if (Clause.hasDevNumExpr())
2908 Profiler.VisitStmt(Clause.getDevNumExpr());
2909 for (auto *E : Clause.getQueueIdExprs())
2910 Profiler.VisitStmt(E);
2911}
2912
2913/// Nothing to do here, there are no sub-statements.
2914void OpenACCClauseProfiler::VisitDeviceTypeClause(
2915 const OpenACCDeviceTypeClause &Clause) {}
2916
2917void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}
2918
2919void OpenACCClauseProfiler::VisitIndependentClause(
2920 const OpenACCIndependentClause &Clause) {}
2921
2922void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}
2923void OpenACCClauseProfiler::VisitNoHostClause(
2924 const OpenACCNoHostClause &Clause) {}
2925
2926void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) {
2927 for (unsigned I = 0; I < Clause.getNumExprs(); ++I) {
2928 Profiler.VisitStmt(Clause.getExpr(I).second);
2929 }
2930}
2931
2932void OpenACCClauseProfiler::VisitReductionClause(
2933 const OpenACCReductionClause &Clause) {
2934 VisitClauseWithVarList(Clause);
2935
2936 for (auto &Recipe : Clause.getRecipes()) {
2937 Profiler.VisitDecl(Recipe.AllocaDecl);
2938
2939 // TODO: OpenACC: Make sure we remember to update this when we figure out
2940 // what we're adding for the operation recipe, in the meantime, a static
2941 // assert will make sure we don't add something.
2942 static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) ==
2943 3 * sizeof(int *));
2944 for (auto &CombinerRecipe : Recipe.CombinerRecipes) {
2945 if (CombinerRecipe.Op) {
2946 Profiler.VisitDecl(CombinerRecipe.LHS);
2947 Profiler.VisitDecl(CombinerRecipe.RHS);
2948 Profiler.VisitStmt(CombinerRecipe.Op);
2949 }
2950 }
2951 }
2952}
2953
2954void OpenACCClauseProfiler::VisitBindClause(const OpenACCBindClause &Clause) {
2955 assert(false && "not implemented... what can we do about our expr?");
2956}
2957} // namespace
2958
2959void StmtProfiler::VisitOpenACCComputeConstruct(
2960 const OpenACCComputeConstruct *S) {
2961 // VisitStmt handles children, so the AssociatedStmt is handled.
2962 VisitStmt(S);
2963
2964 OpenACCClauseProfiler P{*this};
2965 P.VisitOpenACCClauseList(S->clauses());
2966}
2967
2968void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2969 // VisitStmt handles children, so the Loop is handled.
2970 VisitStmt(S);
2971
2972 OpenACCClauseProfiler P{*this};
2973 P.VisitOpenACCClauseList(S->clauses());
2974}
2975
2976void StmtProfiler::VisitOpenACCCombinedConstruct(
2977 const OpenACCCombinedConstruct *S) {
2978 // VisitStmt handles children, so the Loop is handled.
2979 VisitStmt(S);
2980
2981 OpenACCClauseProfiler P{*this};
2982 P.VisitOpenACCClauseList(S->clauses());
2983}
2984
2985void StmtProfiler::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) {
2986 VisitStmt(S);
2987
2988 OpenACCClauseProfiler P{*this};
2989 P.VisitOpenACCClauseList(S->clauses());
2990}
2991
2992void StmtProfiler::VisitOpenACCEnterDataConstruct(
2993 const OpenACCEnterDataConstruct *S) {
2994 VisitStmt(S);
2995
2996 OpenACCClauseProfiler P{*this};
2997 P.VisitOpenACCClauseList(S->clauses());
2998}
2999
3000void StmtProfiler::VisitOpenACCExitDataConstruct(
3001 const OpenACCExitDataConstruct *S) {
3002 VisitStmt(S);
3003
3004 OpenACCClauseProfiler P{*this};
3005 P.VisitOpenACCClauseList(S->clauses());
3006}
3007
3008void StmtProfiler::VisitOpenACCHostDataConstruct(
3009 const OpenACCHostDataConstruct *S) {
3010 VisitStmt(S);
3011
3012 OpenACCClauseProfiler P{*this};
3013 P.VisitOpenACCClauseList(S->clauses());
3014}
3015
3016void StmtProfiler::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
3017 // VisitStmt covers 'children', so the exprs inside of it are covered.
3018 VisitStmt(S);
3019
3020 OpenACCClauseProfiler P{*this};
3021 P.VisitOpenACCClauseList(S->clauses());
3022}
3023
3024void StmtProfiler::VisitOpenACCCacheConstruct(const OpenACCCacheConstruct *S) {
3025 // VisitStmt covers 'children', so the exprs inside of it are covered.
3026 VisitStmt(S);
3027}
3028
3029void StmtProfiler::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
3030 VisitStmt(S);
3031 OpenACCClauseProfiler P{*this};
3032 P.VisitOpenACCClauseList(S->clauses());
3033}
3034
3035void StmtProfiler::VisitOpenACCShutdownConstruct(
3036 const OpenACCShutdownConstruct *S) {
3037 VisitStmt(S);
3038 OpenACCClauseProfiler P{*this};
3039 P.VisitOpenACCClauseList(S->clauses());
3040}
3041
3042void StmtProfiler::VisitOpenACCSetConstruct(const OpenACCSetConstruct *S) {
3043 VisitStmt(S);
3044 OpenACCClauseProfiler P{*this};
3045 P.VisitOpenACCClauseList(S->clauses());
3046}
3047
3048void StmtProfiler::VisitOpenACCUpdateConstruct(
3049 const OpenACCUpdateConstruct *S) {
3050 VisitStmt(S);
3051 OpenACCClauseProfiler P{*this};
3052 P.VisitOpenACCClauseList(S->clauses());
3053}
3054
3055void StmtProfiler::VisitOpenACCAtomicConstruct(
3056 const OpenACCAtomicConstruct *S) {
3057 VisitStmt(S);
3058 OpenACCClauseProfiler P{*this};
3059 P.VisitOpenACCClauseList(S->clauses());
3060}
3061
3062void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) {
3063 VisitStmt(S);
3064}
3065
3066void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3067 bool Canonical, bool ProfileLambdaExpr) const {
3068 StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr);
3069 Profiler.Visit(this);
3070}
3071
3072void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
3073 class ODRHash &Hash) const {
3074 StmtProfilerWithoutPointers Profiler(ID, Hash);
3075 Profiler.Visit(this);
3076}
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:585
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
LabelDecl * getLabel() const
Definition Expr.h:4621
ArrayTypeTrait getTrait() const
Definition ExprCXX.h:3051
QualType getQueriedType() const
Definition ExprCXX.h:3055
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:7045
Opcode getOpcode() const
Definition Expr.h:4131
const BlockDecl * getBlockDecl() const
Definition Expr.h:6738
CXXTemporary * getTemporary()
Definition ExprCXX.h:1516
bool getValue() const
Definition ExprCXX.h:745
QualType getCaughtType() const
Definition StmtCXX.cpp:20
bool isElidable() const
Whether this construction is elidable.
Definition ExprCXX.h:1622
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1616
const ParmVarDecl * getParam() const
Definition ExprCXX.h:1317
FieldDecl * getField()
Get the field whose initializer will be used.
Definition ExprCXX.h:1416
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2670
bool isArrayForm() const
Definition ExprCXX.h:2657
bool isGlobalDelete() const
Definition ExprCXX.h:2656
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4023
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the member name.
Definition ExprCXX.h:4031
unsigned getNumTemplateArgs() const
Retrieve the number of template arguments provided as part of this template-id.
Definition ExprCXX.h:4118
const TemplateArgumentLoc * getTemplateArgs() const
Retrieve the template arguments provided as part of this template-id.
Definition ExprCXX.h:4109
bool hasExplicitTemplateArgs() const
Determines whether this member expression actually had a C++ template argument list explicitly specif...
Definition ExprCXX.h:4097
DeclarationName getMember() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4062
bool isImplicitAccess() const
True if this is an implicit access, i.e.
Definition ExprCXX.h:4006
bool shouldApplyLifetimeExtensionToPreamble() const
Definition StmtCXX.h:1077
Expr * getRHS() const
Definition ExprCXX.h:5112
Expr * getLHS() const
Definition ExprCXX.h:5111
BinaryOperatorKind getOperator() const
Definition ExprCXX.h:5131
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Definition ExprCXX.h:1793
bool isArray() const
Definition ExprCXX.h:2469
QualType getAllocatedType() const
Definition ExprCXX.h:2439
CXXNewInitializationStyle getInitializationStyle() const
The kind of initializer this new-expression has.
Definition ExprCXX.h:2532
FunctionDecl * getOperatorDelete() const
Definition ExprCXX.h:2466
unsigned getNumPlacementArgs() const
Definition ExprCXX.h:2499
bool isParenTypeId() const
Definition ExprCXX.h:2520
FunctionDecl * getOperatorNew() const
Definition ExprCXX.h:2464
bool isGlobalNew() const
Definition ExprCXX.h:2526
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:86
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Definition ExprCXX.h:116
TypeSourceInfo * getDestroyedTypeInfo() const
Retrieve the source location information for the type being destroyed.
Definition ExprCXX.h:2844
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
Definition ExprCXX.h:2814
TypeSourceInfo * getScopeTypeInfo() const
Retrieve the scope type in a qualified pseudo-destructor expression.
Definition ExprCXX.h:2828
QualType getDestroyedType() const
Retrieve the type being destroyed.
Definition ExprCXX.cpp:392
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition ExprCXX.h:2808
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:2851
capture_const_range captures() const
Definition DeclCXX.h:1107
ReflectionKind getKind() const
Definition ExprCXX.h:5599
const TypeSourceInfo * getTypeSourceInfo() const
Definition ExprCXX.h:5601
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Definition ExprCXX.h:309
bool isReversed() const
Determine whether this expression was rewritten in reverse form.
Definition ExprCXX.h:327
const CXXDestructorDecl * getDestructor() const
Definition ExprCXX.h:1475
bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const
Definition ExprCXX.h:1185
bool isImplicit() const
Definition ExprCXX.h:1182
bool isTypeOperand() const
Definition ExprCXX.h:889
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:896
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition ExprCXX.h:3853
QualType getTypeAsWritten() const
Retrieve the type that is being constructed, as specified in the source code.
Definition ExprCXX.h:3832
bool isTypeOperand() const
Definition ExprCXX.h:1103
TypeSourceInfo * getTypeOperandSourceInfo() const
Retrieve source information for the type operand.
Definition ExprCXX.h:1110
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3195
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3182
unsigned getValue() const
Definition Expr.h:1653
CharacterLiteralKind getKind() const
Definition Expr.h:1646
bool isFileScope() const
Definition Expr.h:3685
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:2417
unsigned getNumTemplateArgs() const
Retrieve the number of template arguments provided as part of this template-id.
Definition Expr.h:1469
bool hasExplicitTemplateArgs() const
Determines whether this declaration reference was followed by an explicit template argument list.
Definition Expr.h:1449
NestedNameSpecifier getQualifier() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name.
Definition Expr.h:1395
ValueDecl * getDecl()
Definition Expr.h:1362
const TemplateArgumentLoc * getTemplateArgs() const
Retrieve the template arguments provided as part of this template-id.
Definition Expr.h:1461
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:3648
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies this declaration.
Definition ExprCXX.h:3616
unsigned getNumTemplateArgs() const
Definition ExprCXX.h:3665
DeclarationName getDeclName() const
Retrieve the name that this expression refers to.
Definition ExprCXX.h:3603
TemplateArgumentLoc const * getTemplateArgs() const
Definition ExprCXX.h:3658
ArrayRef< TemplateArgumentLoc > template_arguments() const
Definition ExprCXX.h:3525
TemplateName getTemplateName() const
Definition ExprCXX.h:3508
unsigned getNumTemplateArgs() const
Definition ExprCXX.h:3523
bool usesGNUSyntax() const
Determines whether this designated initializer used the deprecated GNU syntax for designated initiali...
Definition Expr.h:5869
MutableArrayRef< Designator > designators()
Definition Expr.h:5838
IdentifierInfo & getAccessor() const
Definition Expr.h:6639
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition Expr.h:3998
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition Expr.h:4003
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:3123
ExpressionTrait getTrait() const
Definition ExprCXX.h:3119
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
Definition Expr.h:1599
llvm::APFloat getValue() const
Definition Expr.h:1690
bool isExact() const
Definition Expr.h:1723
const Expr * getSubExpr() const
Definition Expr.h:1086
ValueDecl *const * iterator
Iterators over the parameters which the parameter pack expanded into.
Definition ExprCXX.h:4928
ValueDecl * getParameterPack() const
Get the parameter pack which this expression refers to.
Definition ExprCXX.h:4921
iterator end() const
Definition ExprCXX.h:4930
unsigned getNumExpansions() const
Get the number of parameters in this parameter pack.
Definition ExprCXX.h:4933
iterator begin() const
Definition ExprCXX.h:4929
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:6569
AssociationTy< true > ConstAssociation
Definition Expr.h:6470
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:5526
LabelDecl * getDecl() const
Definition Stmt.h:2176
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Definition ExprCXX.cpp:1432
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:994
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
Definition Expr.h:3523
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition Expr.h:3495
bool isArrow() const
Definition Expr.h:3596
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:5607
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:2622
TypeSourceInfo * getTypeSourceInfo() const
Definition Expr.h:2615
unsigned getNumComponents() const
Definition Expr.h:2630
const IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1725
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition Expr.h:2533
@ Array
An index into an array.
Definition Expr.h:2474
@ Identifier
A field in a dependent type, known only by its name.
Definition Expr.h:2478
@ Field
A field.
Definition Expr.h:2476
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition Expr.h:2481
Kind getKind() const
Determine what kind of offsetof node this is.
Definition Expr.h:2523
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:3295
NestedNameSpecifier getQualifier() const
Fetches the nested-name qualifier, if one was given.
Definition ExprCXX.h:3259
decls_iterator decls_begin() const
Definition ExprCXX.h:3236
unsigned getNumDecls() const
Gets the number of declarations in the unresolved set.
Definition ExprCXX.h:3247
TemplateArgumentLoc const * getTemplateArgs() const
Definition ExprCXX.h:3307
unsigned getNumTemplateArgs() const
Definition ExprCXX.h:3313
DeclarationName getName() const
Gets the name looked up.
Definition ExprCXX.h:3253
Expr * getIndexExpr() const
Definition ExprCXX.h:4682
ArrayRef< Expr * > getExpressions() const
Return the trailing expressions, regardless of the expansion.
Definition ExprCXX.h:4700
bool expandsToEmptyPack() const
Determine if the expression was expanded to empty.
Definition ExprCXX.h:4661
Expr * getPackIdExpression() const
Definition ExprCXX.h:4678
PredefinedIdentKind getIdentKind() const
Definition Expr.h:2088
semantics_iterator semantics_end()
Definition Expr.h:6923
semantics_iterator semantics_begin()
Definition Expr.h:6919
const Expr *const * const_semantics_iterator
Definition Expr.h:6918
A (possibly-)qualified type.
Definition TypeBase.h:938
ArrayRef< concepts::Requirement * > getRequirements() const
ArrayRef< ParmVarDecl * > getLocalParameters() const
TypeSourceInfo * getTypeSourceInfo()
Definition Expr.h:2191
bool isPartiallySubstituted() const
Determine whether this represents a partially-substituted sizeof... expression, such as is produced f...
Definition ExprCXX.h:4580
ArrayRef< TemplateArgument > getPartialArguments() const
Get.
Definition ExprCXX.h:4585
NamedDecl * getPack() const
Retrieve the parameter pack.
Definition ExprCXX.h:4563
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:1952
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Definition Expr.h:1899
TemplateArgument getArgumentPack() const
Retrieve the template argument pack containing the substituted template arguments.
Definition ExprCXX.cpp:1815
NonTypeTemplateParmDecl * getParameterPack() const
Retrieve the non-type template parameter pack being substituted.
Definition ExprCXX.cpp:1810
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:8428
TypeSourceInfo * getArg(unsigned I) const
Retrieve the Ith argument.
Definition ExprCXX.h:2976
unsigned getNumArgs() const
Determine the number of arguments to this type trait.
Definition ExprCXX.h:2973
TypeTrait getTrait() const
Determine which type trait this expression uses.
Definition ExprCXX.h:2950
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9366
TypeClass getTypeClass() const
Definition TypeBase.h:2449
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9299
QualType getArgumentType() const
Definition Expr.h:2716
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2705
Opcode getOpcode() const
Definition Expr.h:2328
DeclarationName getMemberName() const
Retrieve the name of the member that this expression refers to.
Definition ExprCXX.h:4288
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4272
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:1675
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
bool isTypeAliasAsReflectionName(QualType QT)
[expr.reflect] p5, if a reflect-expression R matches the form ^^reflection-name it is interpreted as ...
Definition Reflection.h:58
#define false
Definition stdbool.h:26
Expr * AllocatorTraits
Allocator traits.
DeclarationName getName() const
getName - Returns the embedded declaration name.