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