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