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