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