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