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