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