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