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