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 Profiler->VisitInteger(C->getModifier());
916 if (const Expr *Modifier = C->getModifierExpr())
917 Profiler->VisitStmt(Modifier);
918 VisitOMPClauseList(C);
919 VisitOMPClauseWithPreInit(C);
920}
921void OMPClauseProfiler::VisitOMPThreadLimitClause(
922 const OMPThreadLimitClause *C) {
923 VisitOMPClauseList(C);
924 VisitOMPClauseWithPreInit(C);
925}
926void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) {
927 VisitOMPClauseWithPreInit(C);
928 if (C->getPriority())
929 Profiler->VisitStmt(C->getPriority());
930}
931void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
932 VisitOMPClauseWithPreInit(C);
933 if (C->getGrainsize())
934 Profiler->VisitStmt(C->getGrainsize());
935}
936void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
937 VisitOMPClauseWithPreInit(C);
938 if (C->getNumTasks())
939 Profiler->VisitStmt(C->getNumTasks());
940}
941void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
942 if (C->getHint())
943 Profiler->VisitStmt(C->getHint());
944}
945void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) {
946 VisitOMPClauseList(C);
947}
948void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) {
949 VisitOMPClauseList(C);
950}
951void OMPClauseProfiler::VisitOMPUseDevicePtrClause(
952 const OMPUseDevicePtrClause *C) {
953 VisitOMPClauseList(C);
954}
955void OMPClauseProfiler::VisitOMPUseDeviceAddrClause(
956 const OMPUseDeviceAddrClause *C) {
957 VisitOMPClauseList(C);
958}
959void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
960 const OMPIsDevicePtrClause *C) {
961 VisitOMPClauseList(C);
962}
963void OMPClauseProfiler::VisitOMPHasDeviceAddrClause(
964 const OMPHasDeviceAddrClause *C) {
965 VisitOMPClauseList(C);
966}
967void OMPClauseProfiler::VisitOMPNontemporalClause(
968 const OMPNontemporalClause *C) {
969 VisitOMPClauseList(C);
970 for (auto *E : C->private_refs())
971 Profiler->VisitStmt(E);
972}
973void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
974 VisitOMPClauseList(C);
975}
976void OMPClauseProfiler::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
977 VisitOMPClauseList(C);
978}
979void OMPClauseProfiler::VisitOMPUsesAllocatorsClause(
980 const OMPUsesAllocatorsClause *C) {
981 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
982 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
983 Profiler->VisitStmt(D.Allocator);
984 if (D.AllocatorTraits)
985 Profiler->VisitStmt(D.AllocatorTraits);
986 }
987}
988void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
989 if (const Expr *Modifier = C->getModifier())
990 Profiler->VisitStmt(Modifier);
991 for (const Expr *E : C->varlist())
992 Profiler->VisitStmt(E);
993}
994void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
995void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause *C) {}
996void OMPClauseProfiler::VisitOMPXDynCGroupMemClause(
997 const OMPXDynCGroupMemClause *C) {
998 VisitOMPClauseWithPreInit(C);
999 if (Expr *Size = C->getSize())
1000 Profiler->VisitStmt(Size);
1001}
1002void OMPClauseProfiler::VisitOMPDynGroupprivateClause(
1003 const OMPDynGroupprivateClause *C) {
1004 VisitOMPClauseWithPreInit(C);
1005 if (auto *Size = C->getSize())
1006 Profiler->VisitStmt(Size);
1007}
1008void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {
1009 VisitOMPClauseList(C);
1010}
1011void OMPClauseProfiler::VisitOMPXAttributeClause(const OMPXAttributeClause *C) {
1012}
1013void OMPClauseProfiler::VisitOMPXBareClause(const OMPXBareClause *C) {}
1014} // namespace
1015
1016void
1017StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
1018 VisitStmt(S);
1019 OMPClauseProfiler P(this);
1020 ArrayRef<OMPClause *> Clauses = S->clauses();
1021 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
1022 I != E; ++I)
1023 if (*I)
1024 P.Visit(*I);
1025}
1026
1027void StmtProfiler::VisitOMPCanonicalLoop(const OMPCanonicalLoop *L) {
1028 VisitStmt(L);
1029}
1030
1031void StmtProfiler::VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *S) {
1032 VisitOMPExecutableDirective(S);
1033}
1034
1035void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
1036 VisitOMPLoopBasedDirective(S);
1037}
1038
1039void StmtProfiler::VisitOMPMetaDirective(const OMPMetaDirective *S) {
1040 VisitOMPExecutableDirective(S);
1041}
1042
1043void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
1044 VisitOMPExecutableDirective(S);
1045}
1046
1047void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
1048 VisitOMPLoopDirective(S);
1049}
1050
1051void StmtProfiler::VisitOMPCanonicalLoopNestTransformationDirective(
1052 const OMPCanonicalLoopNestTransformationDirective *S) {
1053 VisitOMPLoopBasedDirective(S);
1054}
1055
1056void StmtProfiler::VisitOMPTileDirective(const OMPTileDirective *S) {
1057 VisitOMPCanonicalLoopNestTransformationDirective(S);
1058}
1059
1060void StmtProfiler::VisitOMPStripeDirective(const OMPStripeDirective *S) {
1061 VisitOMPCanonicalLoopNestTransformationDirective(S);
1062}
1063
1064void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) {
1065 VisitOMPCanonicalLoopNestTransformationDirective(S);
1066}
1067
1068void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) {
1069 VisitOMPCanonicalLoopNestTransformationDirective(S);
1070}
1071
1072void StmtProfiler::VisitOMPInterchangeDirective(
1073 const OMPInterchangeDirective *S) {
1074 VisitOMPCanonicalLoopNestTransformationDirective(S);
1075}
1076
1077void StmtProfiler::VisitOMPSplitDirective(const OMPSplitDirective *S) {
1078 VisitOMPCanonicalLoopNestTransformationDirective(S);
1079}
1080
1081void StmtProfiler::VisitOMPCanonicalLoopSequenceTransformationDirective(
1082 const OMPCanonicalLoopSequenceTransformationDirective *S) {
1083 VisitOMPExecutableDirective(S);
1084}
1085
1086void StmtProfiler::VisitOMPFuseDirective(const OMPFuseDirective *S) {
1087 VisitOMPCanonicalLoopSequenceTransformationDirective(S);
1088}
1089
1090void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
1091 VisitOMPLoopDirective(S);
1092}
1093
1094void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
1095 VisitOMPLoopDirective(S);
1096}
1097
1098void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
1099 VisitOMPExecutableDirective(S);
1100}
1101
1102void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
1103 VisitOMPExecutableDirective(S);
1104}
1105
1106void StmtProfiler::VisitOMPScopeDirective(const OMPScopeDirective *S) {
1107 VisitOMPExecutableDirective(S);
1108}
1109
1110void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
1111 VisitOMPExecutableDirective(S);
1112}
1113
1114void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
1115 VisitOMPExecutableDirective(S);
1116}
1117
1118void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
1119 VisitOMPExecutableDirective(S);
1120 VisitName(S->getDirectiveName().getName());
1121}
1122
1123void
1124StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
1125 VisitOMPLoopDirective(S);
1126}
1127
1128void StmtProfiler::VisitOMPParallelForSimdDirective(
1129 const OMPParallelForSimdDirective *S) {
1130 VisitOMPLoopDirective(S);
1131}
1132
1133void StmtProfiler::VisitOMPParallelMasterDirective(
1134 const OMPParallelMasterDirective *S) {
1135 VisitOMPExecutableDirective(S);
1136}
1137
1138void StmtProfiler::VisitOMPParallelMaskedDirective(
1139 const OMPParallelMaskedDirective *S) {
1140 VisitOMPExecutableDirective(S);
1141}
1142
1143void StmtProfiler::VisitOMPParallelSectionsDirective(
1144 const OMPParallelSectionsDirective *S) {
1145 VisitOMPExecutableDirective(S);
1146}
1147
1148void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
1149 VisitOMPExecutableDirective(S);
1150}
1151
1152void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
1153 VisitOMPExecutableDirective(S);
1154}
1155
1156void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
1157 VisitOMPExecutableDirective(S);
1158}
1159
1160void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
1161 VisitOMPExecutableDirective(S);
1162}
1163
1164void StmtProfiler::VisitOMPAssumeDirective(const OMPAssumeDirective *S) {
1165 VisitOMPExecutableDirective(S);
1166}
1167
1168void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) {
1169 VisitOMPExecutableDirective(S);
1170}
1171void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
1172 VisitOMPExecutableDirective(S);
1173 if (const Expr *E = S->getReductionRef())
1174 VisitStmt(E);
1175}
1176
1177void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
1178 VisitOMPExecutableDirective(S);
1179}
1180
1181void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective *S) {
1182 VisitOMPExecutableDirective(S);
1183}
1184
1185void StmtProfiler::VisitOMPScanDirective(const OMPScanDirective *S) {
1186 VisitOMPExecutableDirective(S);
1187}
1188
1189void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
1190 VisitOMPExecutableDirective(S);
1191}
1192
1193void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
1194 VisitOMPExecutableDirective(S);
1195}
1196
1197void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
1198 VisitOMPExecutableDirective(S);
1199}
1200
1201void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) {
1202 VisitOMPExecutableDirective(S);
1203}
1204
1205void StmtProfiler::VisitOMPTargetEnterDataDirective(
1206 const OMPTargetEnterDataDirective *S) {
1207 VisitOMPExecutableDirective(S);
1208}
1209
1210void StmtProfiler::VisitOMPTargetExitDataDirective(
1211 const OMPTargetExitDataDirective *S) {
1212 VisitOMPExecutableDirective(S);
1213}
1214
1215void StmtProfiler::VisitOMPTargetParallelDirective(
1216 const OMPTargetParallelDirective *S) {
1217 VisitOMPExecutableDirective(S);
1218}
1219
1220void StmtProfiler::VisitOMPTargetParallelForDirective(
1221 const OMPTargetParallelForDirective *S) {
1222 VisitOMPExecutableDirective(S);
1223}
1224
1225void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
1226 VisitOMPExecutableDirective(S);
1227}
1228
1229void StmtProfiler::VisitOMPCancellationPointDirective(
1230 const OMPCancellationPointDirective *S) {
1231 VisitOMPExecutableDirective(S);
1232}
1233
1234void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) {
1235 VisitOMPExecutableDirective(S);
1236}
1237
1238void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) {
1239 VisitOMPLoopDirective(S);
1240}
1241
1242void StmtProfiler::VisitOMPTaskLoopSimdDirective(
1243 const OMPTaskLoopSimdDirective *S) {
1244 VisitOMPLoopDirective(S);
1245}
1246
1247void StmtProfiler::VisitOMPMasterTaskLoopDirective(
1248 const OMPMasterTaskLoopDirective *S) {
1249 VisitOMPLoopDirective(S);
1250}
1251
1252void StmtProfiler::VisitOMPMaskedTaskLoopDirective(
1253 const OMPMaskedTaskLoopDirective *S) {
1254 VisitOMPLoopDirective(S);
1255}
1256
1257void StmtProfiler::VisitOMPMasterTaskLoopSimdDirective(
1258 const OMPMasterTaskLoopSimdDirective *S) {
1259 VisitOMPLoopDirective(S);
1260}
1261
1262void StmtProfiler::VisitOMPMaskedTaskLoopSimdDirective(
1263 const OMPMaskedTaskLoopSimdDirective *S) {
1264 VisitOMPLoopDirective(S);
1265}
1266
1267void StmtProfiler::VisitOMPParallelMasterTaskLoopDirective(
1268 const OMPParallelMasterTaskLoopDirective *S) {
1269 VisitOMPLoopDirective(S);
1270}
1271
1272void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective(
1273 const OMPParallelMaskedTaskLoopDirective *S) {
1274 VisitOMPLoopDirective(S);
1275}
1276
1277void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective(
1278 const OMPParallelMasterTaskLoopSimdDirective *S) {
1279 VisitOMPLoopDirective(S);
1280}
1281
1282void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective(
1283 const OMPParallelMaskedTaskLoopSimdDirective *S) {
1284 VisitOMPLoopDirective(S);
1285}
1286
1287void StmtProfiler::VisitOMPDistributeDirective(
1288 const OMPDistributeDirective *S) {
1289 VisitOMPLoopDirective(S);
1290}
1291
1292void OMPClauseProfiler::VisitOMPDistScheduleClause(
1293 const OMPDistScheduleClause *C) {
1294 VisitOMPClauseWithPreInit(C);
1295 if (auto *S = C->getChunkSize())
1296 Profiler->VisitStmt(S);
1297}
1298
1299void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {}
1300
1301void StmtProfiler::VisitOMPTargetUpdateDirective(
1302 const OMPTargetUpdateDirective *S) {
1303 VisitOMPExecutableDirective(S);
1304}
1305
1306void StmtProfiler::VisitOMPDistributeParallelForDirective(
1307 const OMPDistributeParallelForDirective *S) {
1308 VisitOMPLoopDirective(S);
1309}
1310
1311void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
1312 const OMPDistributeParallelForSimdDirective *S) {
1313 VisitOMPLoopDirective(S);
1314}
1315
1316void StmtProfiler::VisitOMPDistributeSimdDirective(
1317 const OMPDistributeSimdDirective *S) {
1318 VisitOMPLoopDirective(S);
1319}
1320
1321void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
1322 const OMPTargetParallelForSimdDirective *S) {
1323 VisitOMPLoopDirective(S);
1324}
1325
1326void StmtProfiler::VisitOMPTargetSimdDirective(
1327 const OMPTargetSimdDirective *S) {
1328 VisitOMPLoopDirective(S);
1329}
1330
1331void StmtProfiler::VisitOMPTeamsDistributeDirective(
1332 const OMPTeamsDistributeDirective *S) {
1333 VisitOMPLoopDirective(S);
1334}
1335
1336void StmtProfiler::VisitOMPTeamsDistributeSimdDirective(
1337 const OMPTeamsDistributeSimdDirective *S) {
1338 VisitOMPLoopDirective(S);
1339}
1340
1341void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
1342 const OMPTeamsDistributeParallelForSimdDirective *S) {
1343 VisitOMPLoopDirective(S);
1344}
1345
1346void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
1347 const OMPTeamsDistributeParallelForDirective *S) {
1348 VisitOMPLoopDirective(S);
1349}
1350
1351void StmtProfiler::VisitOMPTargetTeamsDirective(
1352 const OMPTargetTeamsDirective *S) {
1353 VisitOMPExecutableDirective(S);
1354}
1355
1356void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
1357 const OMPTargetTeamsDistributeDirective *S) {
1358 VisitOMPLoopDirective(S);
1359}
1360
1361void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
1362 const OMPTargetTeamsDistributeParallelForDirective *S) {
1363 VisitOMPLoopDirective(S);
1364}
1365
1366void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1367 const OMPTargetTeamsDistributeParallelForSimdDirective *S) {
1368 VisitOMPLoopDirective(S);
1369}
1370
1371void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
1372 const OMPTargetTeamsDistributeSimdDirective *S) {
1373 VisitOMPLoopDirective(S);
1374}
1375
1376void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective *S) {
1377 VisitOMPExecutableDirective(S);
1378}
1379
1380void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective *S) {
1381 VisitOMPExecutableDirective(S);
1382}
1383
1384void StmtProfiler::VisitOMPMaskedDirective(const OMPMaskedDirective *S) {
1385 VisitOMPExecutableDirective(S);
1386}
1387
1388void StmtProfiler::VisitOMPGenericLoopDirective(
1389 const OMPGenericLoopDirective *S) {
1390 VisitOMPLoopDirective(S);
1391}
1392
1393void StmtProfiler::VisitOMPTeamsGenericLoopDirective(
1394 const OMPTeamsGenericLoopDirective *S) {
1395 VisitOMPLoopDirective(S);
1396}
1397
1398void StmtProfiler::VisitOMPTargetTeamsGenericLoopDirective(
1399 const OMPTargetTeamsGenericLoopDirective *S) {
1400 VisitOMPLoopDirective(S);
1401}
1402
1403void StmtProfiler::VisitOMPParallelGenericLoopDirective(
1404 const OMPParallelGenericLoopDirective *S) {
1405 VisitOMPLoopDirective(S);
1406}
1407
1408void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective(
1409 const OMPTargetParallelGenericLoopDirective *S) {
1410 VisitOMPLoopDirective(S);
1411}
1412
1413void StmtProfiler::VisitExpr(const Expr *S) {
1414 VisitStmt(S);
1415}
1416
1417void StmtProfiler::VisitConstantExpr(const ConstantExpr *S) {
1418 // Profile exactly as the sub-expression.
1419 Visit(S->getSubExpr());
1420}
1421
1422void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
1423 VisitExpr(S);
1424 if (!Canonical)
1425 VisitNestedNameSpecifier(S->getQualifier());
1426 VisitDecl(S->getDecl());
1427 if (!Canonical) {
1428 ID.AddBoolean(S->hasExplicitTemplateArgs());
1429 if (S->hasExplicitTemplateArgs())
1430 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
1431 }
1432}
1433
1434void StmtProfiler::VisitSYCLUniqueStableNameExpr(
1435 const SYCLUniqueStableNameExpr *S) {
1436 VisitExpr(S);
1437 VisitType(S->getTypeSourceInfo()->getType());
1438}
1439
1440void StmtProfiler::VisitUnresolvedSYCLKernelCallStmt(
1441 const UnresolvedSYCLKernelCallStmt *S) {
1442 VisitStmt(S);
1443}
1444
1445void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
1446 VisitExpr(S);
1447 ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
1448}
1449
1450void StmtProfiler::VisitOpenACCAsteriskSizeExpr(
1451 const OpenACCAsteriskSizeExpr *S) {
1452 VisitExpr(S);
1453}
1454
1455void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
1456 VisitExpr(S);
1457 S->getValue().Profile(ID);
1458
1459 QualType T = S->getType();
1460 if (Canonical)
1461 T = T.getCanonicalType();
1462 ID.AddInteger(T->getTypeClass());
1463 if (auto BitIntT = T->getAs<BitIntType>())
1464 BitIntT->Profile(ID);
1465 else
1466 ID.AddInteger(T->castAs<BuiltinType>()->getKind());
1467}
1468
1469void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
1470 VisitExpr(S);
1471 S->getValue().Profile(ID);
1472 ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1473}
1474
1475void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
1476 VisitExpr(S);
1477 ID.AddInteger(llvm::to_underlying(S->getKind()));
1478 ID.AddInteger(S->getValue());
1479}
1480
1481void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
1482 VisitExpr(S);
1483 S->getValue().Profile(ID);
1484 ID.AddBoolean(S->isExact());
1485 ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1486}
1487
1488void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
1489 VisitExpr(S);
1490}
1491
1492void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
1493 VisitExpr(S);
1494 ID.AddString(S->getBytes());
1495 ID.AddInteger(llvm::to_underlying(S->getKind()));
1496}
1497
1498void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
1499 VisitExpr(S);
1500}
1501
1502void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
1503 VisitExpr(S);
1504}
1505
1506void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
1507 VisitExpr(S);
1508 ID.AddInteger(S->getOpcode());
1509}
1510
1511void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
1512 VisitType(S->getTypeSourceInfo()->getType());
1513 unsigned n = S->getNumComponents();
1514 for (unsigned i = 0; i < n; ++i) {
1515 const OffsetOfNode &ON = S->getComponent(i);
1516 ID.AddInteger(ON.getKind());
1517 switch (ON.getKind()) {
1519 // Expressions handled below.
1520 break;
1521
1523 VisitDecl(ON.getField());
1524 break;
1525
1527 VisitIdentifierInfo(ON.getFieldName());
1528 break;
1529
1530 case OffsetOfNode::Base:
1531 // These nodes are implicit, and therefore don't need profiling.
1532 break;
1533 }
1534 }
1535
1536 VisitExpr(S);
1537}
1538
1539void
1540StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
1541 VisitExpr(S);
1542 ID.AddInteger(S->getKind());
1543 if (S->isArgumentType())
1544 VisitType(S->getArgumentType());
1545}
1546
1547void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
1548 VisitExpr(S);
1549}
1550
1551void StmtProfiler::VisitMatrixSingleSubscriptExpr(
1552 const MatrixSingleSubscriptExpr *S) {
1553 VisitExpr(S);
1554}
1555
1556void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) {
1557 VisitExpr(S);
1558}
1559
1560void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) {
1561 VisitExpr(S);
1562}
1563
1564void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
1565 VisitExpr(S);
1566}
1567
1568void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) {
1569 VisitExpr(S);
1570 for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I)
1571 VisitDecl(S->getIteratorDecl(I));
1572}
1573
1574void StmtProfiler::VisitCallExpr(const CallExpr *S) {
1575 VisitExpr(S);
1576}
1577
1578void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
1579 VisitExpr(S);
1580 VisitDecl(S->getMemberDecl());
1581 if (!Canonical)
1582 VisitNestedNameSpecifier(S->getQualifier());
1583 ID.AddBoolean(S->isArrow());
1584}
1585
1586void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
1587 VisitExpr(S);
1588 ID.AddBoolean(S->isFileScope());
1589}
1590
1591void StmtProfiler::VisitCastExpr(const CastExpr *S) {
1592 VisitExpr(S);
1593}
1594
1595void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
1596 VisitCastExpr(S);
1597 ID.AddInteger(S->getValueKind());
1598}
1599
1600void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
1601 VisitCastExpr(S);
1602 VisitType(S->getTypeAsWritten());
1603}
1604
1605void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
1606 VisitExplicitCastExpr(S);
1607}
1608
1609void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
1610 VisitExpr(S);
1611 ID.AddInteger(S->getOpcode());
1612}
1613
1614void
1615StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
1616 VisitBinaryOperator(S);
1617}
1618
1619void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
1620 VisitExpr(S);
1621}
1622
1623void StmtProfiler::VisitBinaryConditionalOperator(
1624 const BinaryConditionalOperator *S) {
1625 VisitExpr(S);
1626}
1627
1628void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
1629 VisitExpr(S);
1630 VisitDecl(S->getLabel());
1631}
1632
1633void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
1634 VisitExpr(S);
1635}
1636
1637void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
1638 VisitExpr(S);
1639}
1640
1641void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
1642 VisitExpr(S);
1643}
1644
1645void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
1646 VisitExpr(S);
1647}
1648
1649void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
1650 VisitExpr(S);
1651}
1652
1653void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
1654 VisitExpr(S);
1655}
1656
1657void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
1658 if (S->getSyntacticForm()) {
1659 VisitInitListExpr(S->getSyntacticForm());
1660 return;
1661 }
1662
1663 VisitExpr(S);
1664}
1665
1666void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
1667 VisitExpr(S);
1668 ID.AddBoolean(S->usesGNUSyntax());
1669 for (const DesignatedInitExpr::Designator &D : S->designators()) {
1670 if (D.isFieldDesignator()) {
1671 ID.AddInteger(0);
1672 VisitName(D.getFieldName());
1673 continue;
1674 }
1675
1676 if (D.isArrayDesignator()) {
1677 ID.AddInteger(1);
1678 } else {
1679 assert(D.isArrayRangeDesignator());
1680 ID.AddInteger(2);
1681 }
1682 ID.AddInteger(D.getArrayIndex());
1683 }
1684}
1685
1686// Seems that if VisitInitListExpr() only works on the syntactic form of an
1687// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
1688void StmtProfiler::VisitDesignatedInitUpdateExpr(
1689 const DesignatedInitUpdateExpr *S) {
1690 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
1691 "initializer");
1692}
1693
1694void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
1695 VisitExpr(S);
1696}
1697
1698void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
1699 VisitExpr(S);
1700}
1701
1702void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
1703 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
1704}
1705
1706void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
1707 VisitExpr(S);
1708}
1709
1710void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
1711 VisitExpr(S);
1712 VisitName(&S->getAccessor());
1713}
1714
1715void StmtProfiler::VisitMatrixElementExpr(const MatrixElementExpr *S) {
1716 VisitExpr(S);
1717 VisitName(&S->getAccessor());
1718}
1719
1720void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
1721 VisitExpr(S);
1722 VisitDecl(S->getBlockDecl());
1723}
1724
1725void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
1726 VisitExpr(S);
1728 S->associations()) {
1729 QualType T = Assoc.getType();
1730 if (T.isNull())
1731 ID.AddPointer(nullptr);
1732 else
1733 VisitType(T);
1734 VisitExpr(Assoc.getAssociationExpr());
1735 }
1736}
1737
1738void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
1739 VisitExpr(S);
1741 i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
1742 // Normally, we would not profile the source expressions of OVEs.
1743 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
1744 Visit(OVE->getSourceExpr());
1745}
1746
1747void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
1748 VisitExpr(S);
1749 ID.AddInteger(S->getOp());
1750}
1751
1752void StmtProfiler::VisitConceptSpecializationExpr(
1753 const ConceptSpecializationExpr *S) {
1754 VisitExpr(S);
1755 VisitDecl(S->getNamedConcept());
1756 for (const TemplateArgument &Arg : S->getTemplateArguments())
1757 VisitTemplateArgument(Arg);
1758}
1759
1760void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
1761 VisitExpr(S);
1762 ID.AddInteger(S->getLocalParameters().size());
1763 for (ParmVarDecl *LocalParam : S->getLocalParameters())
1764 VisitDecl(LocalParam);
1765 ID.AddInteger(S->getRequirements().size());
1766 for (concepts::Requirement *Req : S->getRequirements()) {
1767 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
1769 ID.AddBoolean(TypeReq->isSubstitutionFailure());
1770 if (!TypeReq->isSubstitutionFailure())
1771 VisitType(TypeReq->getType()->getType());
1772 } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
1774 ID.AddBoolean(ExprReq->isExprSubstitutionFailure());
1775 if (!ExprReq->isExprSubstitutionFailure())
1776 Visit(ExprReq->getExpr());
1777 // C++2a [expr.prim.req.compound]p1 Example:
1778 // [...] The compound-requirement in C1 requires that x++ is a valid
1779 // expression. It is equivalent to the simple-requirement x++; [...]
1780 // We therefore do not profile isSimple() here.
1781 ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());
1782 const concepts::ExprRequirement::ReturnTypeRequirement &RetReq =
1783 ExprReq->getReturnTypeRequirement();
1784 if (RetReq.isEmpty()) {
1785 ID.AddInteger(0);
1786 } else if (RetReq.isTypeConstraint()) {
1787 ID.AddInteger(1);
1789 } else {
1790 assert(RetReq.isSubstitutionFailure());
1791 ID.AddInteger(2);
1792 }
1793 } else {
1795 auto *NestedReq = cast<concepts::NestedRequirement>(Req);
1796 ID.AddBoolean(NestedReq->hasInvalidConstraint());
1797 if (!NestedReq->hasInvalidConstraint())
1798 Visit(NestedReq->getConstraintExpr());
1799 }
1800 }
1801}
1802
1804 UnaryOperatorKind &UnaryOp,
1805 BinaryOperatorKind &BinaryOp,
1806 unsigned &NumArgs) {
1807 switch (S->getOperator()) {
1808 case OO_None:
1809 case OO_New:
1810 case OO_Delete:
1811 case OO_Array_New:
1812 case OO_Array_Delete:
1813 case OO_Arrow:
1814 case OO_Conditional:
1816 llvm_unreachable("Invalid operator call kind");
1817
1818 case OO_Plus:
1819 if (NumArgs == 1) {
1820 UnaryOp = UO_Plus;
1821 return Stmt::UnaryOperatorClass;
1822 }
1823
1824 BinaryOp = BO_Add;
1825 return Stmt::BinaryOperatorClass;
1826
1827 case OO_Minus:
1828 if (NumArgs == 1) {
1829 UnaryOp = UO_Minus;
1830 return Stmt::UnaryOperatorClass;
1831 }
1832
1833 BinaryOp = BO_Sub;
1834 return Stmt::BinaryOperatorClass;
1835
1836 case OO_Star:
1837 if (NumArgs == 1) {
1838 UnaryOp = UO_Deref;
1839 return Stmt::UnaryOperatorClass;
1840 }
1841
1842 BinaryOp = BO_Mul;
1843 return Stmt::BinaryOperatorClass;
1844
1845 case OO_Slash:
1846 BinaryOp = BO_Div;
1847 return Stmt::BinaryOperatorClass;
1848
1849 case OO_Percent:
1850 BinaryOp = BO_Rem;
1851 return Stmt::BinaryOperatorClass;
1852
1853 case OO_Caret:
1854 BinaryOp = BO_Xor;
1855 return Stmt::BinaryOperatorClass;
1856
1857 case OO_Amp:
1858 if (NumArgs == 1) {
1859 UnaryOp = UO_AddrOf;
1860 return Stmt::UnaryOperatorClass;
1861 }
1862
1863 BinaryOp = BO_And;
1864 return Stmt::BinaryOperatorClass;
1865
1866 case OO_Pipe:
1867 BinaryOp = BO_Or;
1868 return Stmt::BinaryOperatorClass;
1869
1870 case OO_Tilde:
1871 UnaryOp = UO_Not;
1872 return Stmt::UnaryOperatorClass;
1873
1874 case OO_Exclaim:
1875 UnaryOp = UO_LNot;
1876 return Stmt::UnaryOperatorClass;
1877
1878 case OO_Equal:
1879 BinaryOp = BO_Assign;
1880 return Stmt::BinaryOperatorClass;
1881
1882 case OO_Less:
1883 BinaryOp = BO_LT;
1884 return Stmt::BinaryOperatorClass;
1885
1886 case OO_Greater:
1887 BinaryOp = BO_GT;
1888 return Stmt::BinaryOperatorClass;
1889
1890 case OO_PlusEqual:
1891 BinaryOp = BO_AddAssign;
1892 return Stmt::CompoundAssignOperatorClass;
1893
1894 case OO_MinusEqual:
1895 BinaryOp = BO_SubAssign;
1896 return Stmt::CompoundAssignOperatorClass;
1897
1898 case OO_StarEqual:
1899 BinaryOp = BO_MulAssign;
1900 return Stmt::CompoundAssignOperatorClass;
1901
1902 case OO_SlashEqual:
1903 BinaryOp = BO_DivAssign;
1904 return Stmt::CompoundAssignOperatorClass;
1905
1906 case OO_PercentEqual:
1907 BinaryOp = BO_RemAssign;
1908 return Stmt::CompoundAssignOperatorClass;
1909
1910 case OO_CaretEqual:
1911 BinaryOp = BO_XorAssign;
1912 return Stmt::CompoundAssignOperatorClass;
1913
1914 case OO_AmpEqual:
1915 BinaryOp = BO_AndAssign;
1916 return Stmt::CompoundAssignOperatorClass;
1917
1918 case OO_PipeEqual:
1919 BinaryOp = BO_OrAssign;
1920 return Stmt::CompoundAssignOperatorClass;
1921
1922 case OO_LessLess:
1923 BinaryOp = BO_Shl;
1924 return Stmt::BinaryOperatorClass;
1925
1926 case OO_GreaterGreater:
1927 BinaryOp = BO_Shr;
1928 return Stmt::BinaryOperatorClass;
1929
1930 case OO_LessLessEqual:
1931 BinaryOp = BO_ShlAssign;
1932 return Stmt::CompoundAssignOperatorClass;
1933
1934 case OO_GreaterGreaterEqual:
1935 BinaryOp = BO_ShrAssign;
1936 return Stmt::CompoundAssignOperatorClass;
1937
1938 case OO_EqualEqual:
1939 BinaryOp = BO_EQ;
1940 return Stmt::BinaryOperatorClass;
1941
1942 case OO_ExclaimEqual:
1943 BinaryOp = BO_NE;
1944 return Stmt::BinaryOperatorClass;
1945
1946 case OO_LessEqual:
1947 BinaryOp = BO_LE;
1948 return Stmt::BinaryOperatorClass;
1949
1950 case OO_GreaterEqual:
1951 BinaryOp = BO_GE;
1952 return Stmt::BinaryOperatorClass;
1953
1954 case OO_Spaceship:
1955 BinaryOp = BO_Cmp;
1956 return Stmt::BinaryOperatorClass;
1957
1958 case OO_AmpAmp:
1959 BinaryOp = BO_LAnd;
1960 return Stmt::BinaryOperatorClass;
1961
1962 case OO_PipePipe:
1963 BinaryOp = BO_LOr;
1964 return Stmt::BinaryOperatorClass;
1965
1966 case OO_PlusPlus:
1967 UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc;
1968 NumArgs = 1;
1969 return Stmt::UnaryOperatorClass;
1970
1971 case OO_MinusMinus:
1972 UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec;
1973 NumArgs = 1;
1974 return Stmt::UnaryOperatorClass;
1975
1976 case OO_Comma:
1977 BinaryOp = BO_Comma;
1978 return Stmt::BinaryOperatorClass;
1979
1980 case OO_ArrowStar:
1981 BinaryOp = BO_PtrMemI;
1982 return Stmt::BinaryOperatorClass;
1983
1984 case OO_Subscript:
1985 return Stmt::ArraySubscriptExprClass;
1986
1987 case OO_Call:
1988 return Stmt::CallExprClass;
1989
1990 case OO_Coawait:
1991 UnaryOp = UO_Coawait;
1992 return Stmt::UnaryOperatorClass;
1993 }
1994
1995 llvm_unreachable("Invalid overloaded operator expression");
1996}
1997
1998#if defined(_MSC_VER) && !defined(__clang__)
1999#if _MSC_VER == 1911
2000// Work around https://developercommunity.visualstudio.com/content/problem/84002/clang-cl-when-built-with-vc-2017-crashes-cause-vc.html
2001// MSVC 2017 update 3 miscompiles this function, and a clang built with it
2002// will crash in stage 2 of a bootstrap build.
2003#pragma optimize("", off)
2004#endif
2005#endif
2006
2007void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
2008 if (S->isTypeDependent()) {
2009 // Type-dependent operator calls are profiled like their underlying
2010 // syntactic operator.
2011 //
2012 // An operator call to operator-> is always implicit, so just skip it. The
2013 // enclosing MemberExpr will profile the actual member access.
2014 if (S->getOperator() == OO_Arrow)
2015 return Visit(S->getArg(0));
2016
2017 UnaryOperatorKind UnaryOp = UO_Extension;
2018 BinaryOperatorKind BinaryOp = BO_Comma;
2019 unsigned NumArgs = S->getNumArgs();
2020 Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs);
2021
2022 ID.AddInteger(SC);
2023 for (unsigned I = 0; I != NumArgs; ++I)
2024 Visit(S->getArg(I));
2025 if (SC == Stmt::UnaryOperatorClass)
2026 ID.AddInteger(UnaryOp);
2027 else if (SC == Stmt::BinaryOperatorClass ||
2028 SC == Stmt::CompoundAssignOperatorClass)
2029 ID.AddInteger(BinaryOp);
2030 else
2031 assert(SC == Stmt::ArraySubscriptExprClass || SC == Stmt::CallExprClass);
2032
2033 return;
2034 }
2035
2036 VisitCallExpr(S);
2037 ID.AddInteger(S->getOperator());
2038}
2039
2040void StmtProfiler::VisitCXXRewrittenBinaryOperator(
2041 const CXXRewrittenBinaryOperator *S) {
2042 // If a rewritten operator were ever to be type-dependent, we should profile
2043 // it following its syntactic operator.
2044 assert(!S->isTypeDependent() &&
2045 "resolved rewritten operator should never be type-dependent");
2046 ID.AddBoolean(S->isReversed());
2047 VisitExpr(S->getSemanticForm());
2048}
2049
2050#if defined(_MSC_VER) && !defined(__clang__)
2051#if _MSC_VER == 1911
2052#pragma optimize("", on)
2053#endif
2054#endif
2055
2056void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
2057 VisitCallExpr(S);
2058}
2059
2060void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
2061 VisitCallExpr(S);
2062}
2063
2064void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
2065 VisitExpr(S);
2066}
2067
2068void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
2069 VisitExplicitCastExpr(S);
2070}
2071
2072void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
2073 VisitCXXNamedCastExpr(S);
2074}
2075
2076void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
2077 VisitCXXNamedCastExpr(S);
2078}
2079
2080void
2081StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
2082 VisitCXXNamedCastExpr(S);
2083}
2084
2085void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
2086 VisitCXXNamedCastExpr(S);
2087}
2088
2089void StmtProfiler::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *S) {
2090 VisitExpr(S);
2091 VisitType(S->getTypeInfoAsWritten()->getType());
2092}
2093
2094void StmtProfiler::VisitCXXAddrspaceCastExpr(const CXXAddrspaceCastExpr *S) {
2095 VisitCXXNamedCastExpr(S);
2096}
2097
2098void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
2099 VisitCallExpr(S);
2100}
2101
2102void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
2103 VisitExpr(S);
2104 ID.AddBoolean(S->getValue());
2105}
2106
2107void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
2108 VisitExpr(S);
2109}
2110
2111void StmtProfiler::VisitCXXStdInitializerListExpr(
2112 const CXXStdInitializerListExpr *S) {
2113 VisitExpr(S);
2114}
2115
2116void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
2117 VisitExpr(S);
2118 if (S->isTypeOperand())
2119 VisitType(S->getTypeOperandSourceInfo()->getType());
2120}
2121
2122void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
2123 VisitExpr(S);
2124 if (S->isTypeOperand())
2125 VisitType(S->getTypeOperandSourceInfo()->getType());
2126}
2127
2128void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
2129 VisitExpr(S);
2130 VisitDecl(S->getPropertyDecl());
2131}
2132
2133void StmtProfiler::VisitMSPropertySubscriptExpr(
2134 const MSPropertySubscriptExpr *S) {
2135 VisitExpr(S);
2136}
2137
2138void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
2139 VisitExpr(S);
2140 ID.AddBoolean(S->isImplicit());
2142}
2143
2144void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
2145 VisitExpr(S);
2146}
2147
2148void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
2149 VisitExpr(S);
2150 VisitDecl(S->getParam());
2151}
2152
2153void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
2154 VisitExpr(S);
2155 VisitDecl(S->getField());
2156}
2157
2158void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
2159 VisitExpr(S);
2160 VisitDecl(
2161 const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
2162}
2163
2164void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
2165 VisitExpr(S);
2166 VisitDecl(S->getConstructor());
2167 ID.AddBoolean(S->isElidable());
2168}
2169
2170void StmtProfiler::VisitCXXInheritedCtorInitExpr(
2171 const CXXInheritedCtorInitExpr *S) {
2172 VisitExpr(S);
2173 VisitDecl(S->getConstructor());
2174}
2175
2176void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
2177 VisitExplicitCastExpr(S);
2178}
2179
2180void
2181StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
2182 VisitCXXConstructExpr(S);
2183}
2184
2185void
2186StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
2187 if (!ProfileLambdaExpr) {
2188 // Do not recursively visit the children of this expression. Profiling the
2189 // body would result in unnecessary work, and is not safe to do during
2190 // deserialization.
2191 VisitStmtNoChildren(S);
2192
2193 // C++20 [temp.over.link]p5:
2194 // Two lambda-expressions are never considered equivalent.
2195 VisitDecl(S->getLambdaClass());
2196
2197 return;
2198 }
2199
2200 CXXRecordDecl *Lambda = S->getLambdaClass();
2201 for (const auto &Capture : Lambda->captures()) {
2202 ID.AddInteger(Capture.getCaptureKind());
2203 if (Capture.capturesVariable())
2204 VisitDecl(Capture.getCapturedVar());
2205 }
2206
2207 // Profiling the body of the lambda may be dangerous during deserialization.
2208 // So we'd like only to profile the signature here.
2209 ODRHash Hasher;
2210 // FIXME: We can't get the operator call easily by
2211 // `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization.
2212 // So we have to do something raw here.
2213 for (auto *SubDecl : Lambda->decls()) {
2214 FunctionDecl *Call = nullptr;
2215 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(SubDecl))
2216 Call = FTD->getTemplatedDecl();
2217 else if (auto *FD = dyn_cast<FunctionDecl>(SubDecl))
2218 Call = FD;
2219
2220 if (!Call)
2221 continue;
2222
2223 Hasher.AddFunctionDecl(Call, /*SkipBody=*/true);
2224 }
2225 ID.AddInteger(Hasher.CalculateHash());
2226}
2227
2228void StmtProfiler::VisitCXXReflectExpr(const CXXReflectExpr *E) {
2229 // TODO(Reflection): Implement this.
2230 assert(false && "not implemented yet");
2231}
2232
2233void
2234StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
2235 VisitExpr(S);
2236}
2237
2238void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
2239 VisitExpr(S);
2240 ID.AddBoolean(S->isGlobalDelete());
2241 ID.AddBoolean(S->isArrayForm());
2242 VisitDecl(S->getOperatorDelete());
2243}
2244
2245void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
2246 VisitExpr(S);
2247 VisitType(S->getAllocatedType());
2248 VisitDecl(S->getOperatorNew());
2249 VisitDecl(S->getOperatorDelete());
2250 ID.AddBoolean(S->isArray());
2251 ID.AddInteger(S->getNumPlacementArgs());
2252 ID.AddBoolean(S->isGlobalNew());
2253 ID.AddBoolean(S->isParenTypeId());
2254 ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
2255}
2256
2257void
2258StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
2259 VisitExpr(S);
2260 ID.AddBoolean(S->isArrow());
2261 VisitNestedNameSpecifier(S->getQualifier());
2262 ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
2263 if (S->getScopeTypeInfo())
2264 VisitType(S->getScopeTypeInfo()->getType());
2265 ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
2266 if (S->getDestroyedTypeInfo())
2267 VisitType(S->getDestroyedType());
2268 else
2269 VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
2270}
2271
2272void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
2273 VisitExpr(S);
2274 bool DescribingDependentVarTemplate =
2275 S->getNumDecls() == 1 && isa<VarTemplateDecl>(*S->decls_begin());
2276 if (DescribingDependentVarTemplate) {
2277 VisitDecl(*S->decls_begin());
2278 } else {
2279 VisitNestedNameSpecifier(S->getQualifier());
2280 VisitName(S->getName(), /*TreatAsDecl*/ true);
2281 }
2282 ID.AddBoolean(S->hasExplicitTemplateArgs());
2283 if (S->hasExplicitTemplateArgs())
2284 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2285}
2286
2287void
2288StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
2289 VisitOverloadExpr(S);
2290}
2291
2292void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
2293 VisitExpr(S);
2294 ID.AddInteger(S->getTrait());
2295 ID.AddInteger(S->getNumArgs());
2296 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2297 VisitType(S->getArg(I)->getType());
2298}
2299
2300void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
2301 VisitExpr(S);
2302 ID.AddInteger(S->getTrait());
2303 VisitType(S->getQueriedType());
2304}
2305
2306void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
2307 VisitExpr(S);
2308 ID.AddInteger(S->getTrait());
2309 VisitExpr(S->getQueriedExpression());
2310}
2311
2312void StmtProfiler::VisitDependentScopeDeclRefExpr(
2313 const DependentScopeDeclRefExpr *S) {
2314 VisitExpr(S);
2315 VisitName(S->getDeclName());
2316 VisitNestedNameSpecifier(S->getQualifier());
2317 ID.AddBoolean(S->hasExplicitTemplateArgs());
2318 if (S->hasExplicitTemplateArgs())
2319 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2320}
2321
2322void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
2323 VisitExpr(S);
2324}
2325
2326void StmtProfiler::VisitCXXUnresolvedConstructExpr(
2327 const CXXUnresolvedConstructExpr *S) {
2328 VisitExpr(S);
2329 VisitType(S->getTypeAsWritten());
2330 ID.AddInteger(S->isListInitialization());
2331}
2332
2333void StmtProfiler::VisitCXXDependentScopeMemberExpr(
2334 const CXXDependentScopeMemberExpr *S) {
2335 ID.AddBoolean(S->isImplicitAccess());
2336 if (!S->isImplicitAccess()) {
2337 VisitExpr(S);
2338 ID.AddBoolean(S->isArrow());
2339 }
2340 VisitNestedNameSpecifier(S->getQualifier());
2341 VisitName(S->getMember());
2342 ID.AddBoolean(S->hasExplicitTemplateArgs());
2343 if (S->hasExplicitTemplateArgs())
2344 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2345}
2346
2347void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
2348 ID.AddBoolean(S->isImplicitAccess());
2349 if (!S->isImplicitAccess()) {
2350 VisitExpr(S);
2351 ID.AddBoolean(S->isArrow());
2352 }
2353 VisitNestedNameSpecifier(S->getQualifier());
2354 VisitName(S->getMemberName());
2355 ID.AddBoolean(S->hasExplicitTemplateArgs());
2356 if (S->hasExplicitTemplateArgs())
2357 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2358}
2359
2360void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
2361 VisitExpr(S);
2362}
2363
2364void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
2365 VisitExpr(S);
2366}
2367
2368void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
2369 VisitExpr(S);
2370 if (S->isPartiallySubstituted()) {
2371 auto Args = S->getPartialArguments();
2372 ID.AddInteger(Args.size());
2373 for (const auto &TA : Args)
2374 VisitTemplateArgument(TA);
2375 } else {
2376 VisitDecl(S->getPack());
2377 ID.AddInteger(0);
2378 }
2379}
2380
2381void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
2382 VisitStmtNoChildren(E);
2383 Visit(E->getIndexExpr());
2384 if (E->expandsToEmptyPack() || E->getExpressions().size() != 0) {
2385 ID.AddInteger(E->getExpressions().size());
2386 for (const Expr *Sub : E->getExpressions())
2387 Visit(Sub);
2388 } else {
2389 Visit(E->getPackIdExpression());
2390 }
2391}
2392
2393void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
2394 const SubstNonTypeTemplateParmPackExpr *S) {
2395 VisitExpr(S);
2396 VisitDecl(S->getParameterPack());
2397 VisitTemplateArgument(S->getArgumentPack());
2398}
2399
2400void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
2401 const SubstNonTypeTemplateParmExpr *E) {
2402 // Profile exactly as the replacement expression.
2403 Visit(E->getReplacement());
2404}
2405
2406void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
2407 VisitExpr(S);
2408 VisitDecl(S->getParameterPack());
2409 ID.AddInteger(S->getNumExpansions());
2410 for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
2411 VisitDecl(*I);
2412}
2413
2414void StmtProfiler::VisitMaterializeTemporaryExpr(
2415 const MaterializeTemporaryExpr *S) {
2416 VisitExpr(S);
2417}
2418
2419void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
2420 VisitStmtNoChildren(S);
2421 // The callee sub-expression is not part of how the expression is written,
2422 // so it's not added to the profile.
2423 //
2424 // Example:
2425 // template <typename... T> requires ((sizeof(T) > 0) && ...) void f() {}
2426 // class A;
2427 // void operator&&(A, A);
2428 // template <typename... T> requires ((sizeof(T) > 0) && ...) void f() {}
2429 //
2430 // Both definitions have identically written fold expressions, but semantic
2431 // analysis adds the overloaded operator to the second one.
2432 if (S->getLHS())
2433 Visit(S->getLHS());
2434 else
2435 ID.AddInteger(0);
2436 if (S->getRHS())
2437 Visit(S->getRHS());
2438 else
2439 ID.AddInteger(0);
2440 ID.AddInteger(S->getOperator());
2441}
2442
2443void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
2444 VisitExpr(S);
2445}
2446
2447void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
2448 VisitStmt(S);
2449}
2450
2451void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
2452 VisitStmt(S);
2453}
2454
2455void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
2456 VisitExpr(S);
2457}
2458
2459void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
2460 VisitExpr(S);
2461}
2462
2463void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
2464 VisitExpr(S);
2465}
2466
2467void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2468 VisitExpr(E);
2469}
2470
2471void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
2472 VisitExpr(E);
2473}
2474
2475void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); }
2476
2477void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
2478
2479void StmtProfiler::VisitObjCObjectLiteral(const ObjCObjectLiteral *E) {
2480 VisitExpr(E);
2481}
2482
2483void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
2484 VisitObjCObjectLiteral(S);
2485}
2486
2487void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
2488 VisitObjCObjectLiteral(E);
2489}
2490
2491void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
2492 VisitObjCObjectLiteral(E);
2493}
2494
2495void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
2496 VisitObjCObjectLiteral(E);
2497}
2498
2499void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
2500 VisitExpr(S);
2501 VisitType(S->getEncodedType());
2502}
2503
2504void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
2505 VisitExpr(S);
2506 VisitName(S->getSelector());
2507}
2508
2509void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
2510 VisitExpr(S);
2511 VisitDecl(S->getProtocol());
2512}
2513
2514void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
2515 VisitExpr(S);
2516 VisitDecl(S->getDecl());
2517 ID.AddBoolean(S->isArrow());
2518 ID.AddBoolean(S->isFreeIvar());
2519}
2520
2521void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
2522 VisitExpr(S);
2523 if (S->isImplicitProperty()) {
2524 VisitDecl(S->getImplicitPropertyGetter());
2525 VisitDecl(S->getImplicitPropertySetter());
2526 } else {
2527 VisitDecl(S->getExplicitProperty());
2528 }
2529 if (S->isSuperReceiver()) {
2530 ID.AddBoolean(S->isSuperReceiver());
2531 VisitType(S->getSuperReceiverType());
2532 }
2533}
2534
2535void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
2536 VisitExpr(S);
2537 VisitDecl(S->getAtIndexMethodDecl());
2538 VisitDecl(S->setAtIndexMethodDecl());
2539}
2540
2541void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
2542 VisitExpr(S);
2543 VisitName(S->getSelector());
2544 VisitDecl(S->getMethodDecl());
2545}
2546
2547void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
2548 VisitExpr(S);
2549 ID.AddBoolean(S->isArrow());
2550}
2551
2552void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
2553 VisitExpr(S);
2554 ID.AddBoolean(S->getValue());
2555}
2556
2557void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
2558 const ObjCIndirectCopyRestoreExpr *S) {
2559 VisitExpr(S);
2560 ID.AddBoolean(S->shouldCopy());
2561}
2562
2563void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
2564 VisitExplicitCastExpr(S);
2565 ID.AddBoolean(S->getBridgeKind());
2566}
2567
2568void StmtProfiler::VisitObjCAvailabilityCheckExpr(
2569 const ObjCAvailabilityCheckExpr *S) {
2570 VisitExpr(S);
2571}
2572
2573void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
2574 unsigned NumArgs) {
2575 ID.AddInteger(NumArgs);
2576 for (unsigned I = 0; I != NumArgs; ++I)
2577 VisitTemplateArgument(Args[I].getArgument());
2578}
2579
2580void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
2581 // Mostly repetitive with TemplateArgument::Profile!
2582 ID.AddInteger(Arg.getKind());
2583 switch (Arg.getKind()) {
2585 break;
2586
2588 VisitType(Arg.getAsType());
2589 break;
2590
2593 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
2594 break;
2595
2597 VisitType(Arg.getParamTypeForDecl());
2598 // FIXME: Do we need to recursively decompose template parameter objects?
2599 VisitDecl(Arg.getAsDecl());
2600 break;
2601
2603 VisitType(Arg.getNullPtrType());
2604 break;
2605
2607 VisitType(Arg.getIntegralType());
2608 Arg.getAsIntegral().Profile(ID);
2609 break;
2610
2612 VisitType(Arg.getStructuralValueType());
2613 // FIXME: Do we need to recursively decompose this ourselves?
2614 Arg.getAsStructuralValue().Profile(ID);
2615 break;
2616
2618 Visit(Arg.getAsExpr());
2619 break;
2620
2622 for (const auto &P : Arg.pack_elements())
2623 VisitTemplateArgument(P);
2624 break;
2625 }
2626}
2627
2628namespace {
2629class OpenACCClauseProfiler
2630 : public OpenACCClauseVisitor<OpenACCClauseProfiler> {
2631 StmtProfiler &Profiler;
2632
2633public:
2634 OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {}
2635
2636 void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) {
2637 for (const OpenACCClause *Clause : Clauses) {
2638 // TODO OpenACC: When we have clauses with expressions, we should
2639 // profile them too.
2640 Visit(Clause);
2641 }
2642 }
2643
2644 void VisitClauseWithVarList(const OpenACCClauseWithVarList &Clause) {
2645 for (auto *E : Clause.getVarList())
2646 Profiler.VisitStmt(E);
2647 }
2648
2649#define VISIT_CLAUSE(CLAUSE_NAME) \
2650 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
2651
2652#include "clang/Basic/OpenACCClauses.def"
2653};
2654
2655/// Nothing to do here, there are no sub-statements.
2656void OpenACCClauseProfiler::VisitDefaultClause(
2657 const OpenACCDefaultClause &Clause) {}
2658
2659void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
2660 assert(Clause.hasConditionExpr() &&
2661 "if clause requires a valid condition expr");
2662 Profiler.VisitStmt(Clause.getConditionExpr());
2663}
2664
2665void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
2666 VisitClauseWithVarList(Clause);
2667}
2668
2669void OpenACCClauseProfiler::VisitLinkClause(const OpenACCLinkClause &Clause) {
2670 VisitClauseWithVarList(Clause);
2671}
2672
2673void OpenACCClauseProfiler::VisitDeviceResidentClause(
2674 const OpenACCDeviceResidentClause &Clause) {
2675 VisitClauseWithVarList(Clause);
2676}
2677
2678void OpenACCClauseProfiler::VisitCopyInClause(
2679 const OpenACCCopyInClause &Clause) {
2680 VisitClauseWithVarList(Clause);
2681}
2682
2683void OpenACCClauseProfiler::VisitCopyOutClause(
2684 const OpenACCCopyOutClause &Clause) {
2685 VisitClauseWithVarList(Clause);
2686}
2687
2688void OpenACCClauseProfiler::VisitCreateClause(
2689 const OpenACCCreateClause &Clause) {
2690 VisitClauseWithVarList(Clause);
2691}
2692
2693void OpenACCClauseProfiler::VisitHostClause(const OpenACCHostClause &Clause) {
2694 VisitClauseWithVarList(Clause);
2695}
2696
2697void OpenACCClauseProfiler::VisitDeviceClause(
2698 const OpenACCDeviceClause &Clause) {
2699 VisitClauseWithVarList(Clause);
2700}
2701
2702void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
2703 if (Clause.isConditionExprClause()) {
2704 if (Clause.hasConditionExpr())
2705 Profiler.VisitStmt(Clause.getConditionExpr());
2706 } else {
2707 for (auto *E : Clause.getVarList())
2708 Profiler.VisitStmt(E);
2709 }
2710}
2711
2712void OpenACCClauseProfiler::VisitFinalizeClause(
2713 const OpenACCFinalizeClause &Clause) {}
2714
2715void OpenACCClauseProfiler::VisitIfPresentClause(
2716 const OpenACCIfPresentClause &Clause) {}
2717
2718void OpenACCClauseProfiler::VisitNumGangsClause(
2719 const OpenACCNumGangsClause &Clause) {
2720 for (auto *E : Clause.getIntExprs())
2721 Profiler.VisitStmt(E);
2722}
2723
2724void OpenACCClauseProfiler::VisitTileClause(const OpenACCTileClause &Clause) {
2725 for (auto *E : Clause.getSizeExprs())
2726 Profiler.VisitStmt(E);
2727}
2728
2729void OpenACCClauseProfiler::VisitNumWorkersClause(
2730 const OpenACCNumWorkersClause &Clause) {
2731 assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr");
2732 Profiler.VisitStmt(Clause.getIntExpr());
2733}
2734
2735void OpenACCClauseProfiler::VisitCollapseClause(
2736 const OpenACCCollapseClause &Clause) {
2737 assert(Clause.getLoopCount() && "collapse clause requires a valid int expr");
2738 Profiler.VisitStmt(Clause.getLoopCount());
2739}
2740
2741void OpenACCClauseProfiler::VisitPrivateClause(
2742 const OpenACCPrivateClause &Clause) {
2743 VisitClauseWithVarList(Clause);
2744
2745 for (auto &Recipe : Clause.getInitRecipes()) {
2746 Profiler.VisitDecl(Recipe.AllocaDecl);
2747 }
2748}
2749
2750void OpenACCClauseProfiler::VisitFirstPrivateClause(
2751 const OpenACCFirstPrivateClause &Clause) {
2752 VisitClauseWithVarList(Clause);
2753
2754 for (auto &Recipe : Clause.getInitRecipes()) {
2755 Profiler.VisitDecl(Recipe.AllocaDecl);
2756 Profiler.VisitDecl(Recipe.InitFromTemporary);
2757 }
2758}
2759
2760void OpenACCClauseProfiler::VisitAttachClause(
2761 const OpenACCAttachClause &Clause) {
2762 VisitClauseWithVarList(Clause);
2763}
2764
2765void OpenACCClauseProfiler::VisitDetachClause(
2766 const OpenACCDetachClause &Clause) {
2767 VisitClauseWithVarList(Clause);
2768}
2769
2770void OpenACCClauseProfiler::VisitDeleteClause(
2771 const OpenACCDeleteClause &Clause) {
2772 VisitClauseWithVarList(Clause);
2773}
2774
2775void OpenACCClauseProfiler::VisitDevicePtrClause(
2776 const OpenACCDevicePtrClause &Clause) {
2777 VisitClauseWithVarList(Clause);
2778}
2779
2780void OpenACCClauseProfiler::VisitNoCreateClause(
2781 const OpenACCNoCreateClause &Clause) {
2782 VisitClauseWithVarList(Clause);
2783}
2784
2785void OpenACCClauseProfiler::VisitPresentClause(
2786 const OpenACCPresentClause &Clause) {
2787 VisitClauseWithVarList(Clause);
2788}
2789
2790void OpenACCClauseProfiler::VisitUseDeviceClause(
2791 const OpenACCUseDeviceClause &Clause) {
2792 VisitClauseWithVarList(Clause);
2793}
2794
2795void OpenACCClauseProfiler::VisitVectorLengthClause(
2796 const OpenACCVectorLengthClause &Clause) {
2797 assert(Clause.hasIntExpr() &&
2798 "vector_length clause requires a valid int expr");
2799 Profiler.VisitStmt(Clause.getIntExpr());
2800}
2801
2802void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
2803 if (Clause.hasIntExpr())
2804 Profiler.VisitStmt(Clause.getIntExpr());
2805}
2806
2807void OpenACCClauseProfiler::VisitDeviceNumClause(
2808 const OpenACCDeviceNumClause &Clause) {
2809 Profiler.VisitStmt(Clause.getIntExpr());
2810}
2811
2812void OpenACCClauseProfiler::VisitDefaultAsyncClause(
2813 const OpenACCDefaultAsyncClause &Clause) {
2814 Profiler.VisitStmt(Clause.getIntExpr());
2815}
2816
2817void OpenACCClauseProfiler::VisitWorkerClause(
2818 const OpenACCWorkerClause &Clause) {
2819 if (Clause.hasIntExpr())
2820 Profiler.VisitStmt(Clause.getIntExpr());
2821}
2822
2823void OpenACCClauseProfiler::VisitVectorClause(
2824 const OpenACCVectorClause &Clause) {
2825 if (Clause.hasIntExpr())
2826 Profiler.VisitStmt(Clause.getIntExpr());
2827}
2828
2829void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
2830 if (Clause.hasDevNumExpr())
2831 Profiler.VisitStmt(Clause.getDevNumExpr());
2832 for (auto *E : Clause.getQueueIdExprs())
2833 Profiler.VisitStmt(E);
2834}
2835
2836/// Nothing to do here, there are no sub-statements.
2837void OpenACCClauseProfiler::VisitDeviceTypeClause(
2838 const OpenACCDeviceTypeClause &Clause) {}
2839
2840void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}
2841
2842void OpenACCClauseProfiler::VisitIndependentClause(
2843 const OpenACCIndependentClause &Clause) {}
2844
2845void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}
2846void OpenACCClauseProfiler::VisitNoHostClause(
2847 const OpenACCNoHostClause &Clause) {}
2848
2849void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) {
2850 for (unsigned I = 0; I < Clause.getNumExprs(); ++I) {
2851 Profiler.VisitStmt(Clause.getExpr(I).second);
2852 }
2853}
2854
2855void OpenACCClauseProfiler::VisitReductionClause(
2856 const OpenACCReductionClause &Clause) {
2857 VisitClauseWithVarList(Clause);
2858
2859 for (auto &Recipe : Clause.getRecipes()) {
2860 Profiler.VisitDecl(Recipe.AllocaDecl);
2861
2862 // TODO: OpenACC: Make sure we remember to update this when we figure out
2863 // what we're adding for the operation recipe, in the meantime, a static
2864 // assert will make sure we don't add something.
2865 static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) ==
2866 3 * sizeof(int *));
2867 for (auto &CombinerRecipe : Recipe.CombinerRecipes) {
2868 if (CombinerRecipe.Op) {
2869 Profiler.VisitDecl(CombinerRecipe.LHS);
2870 Profiler.VisitDecl(CombinerRecipe.RHS);
2871 Profiler.VisitStmt(CombinerRecipe.Op);
2872 }
2873 }
2874 }
2875}
2876
2877void OpenACCClauseProfiler::VisitBindClause(const OpenACCBindClause &Clause) {
2878 assert(false && "not implemented... what can we do about our expr?");
2879}
2880} // namespace
2881
2882void StmtProfiler::VisitOpenACCComputeConstruct(
2883 const OpenACCComputeConstruct *S) {
2884 // VisitStmt handles children, so the AssociatedStmt is handled.
2885 VisitStmt(S);
2886
2887 OpenACCClauseProfiler P{*this};
2888 P.VisitOpenACCClauseList(S->clauses());
2889}
2890
2891void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2892 // VisitStmt handles children, so the Loop is handled.
2893 VisitStmt(S);
2894
2895 OpenACCClauseProfiler P{*this};
2896 P.VisitOpenACCClauseList(S->clauses());
2897}
2898
2899void StmtProfiler::VisitOpenACCCombinedConstruct(
2900 const OpenACCCombinedConstruct *S) {
2901 // VisitStmt handles children, so the Loop is handled.
2902 VisitStmt(S);
2903
2904 OpenACCClauseProfiler P{*this};
2905 P.VisitOpenACCClauseList(S->clauses());
2906}
2907
2908void StmtProfiler::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) {
2909 VisitStmt(S);
2910
2911 OpenACCClauseProfiler P{*this};
2912 P.VisitOpenACCClauseList(S->clauses());
2913}
2914
2915void StmtProfiler::VisitOpenACCEnterDataConstruct(
2916 const OpenACCEnterDataConstruct *S) {
2917 VisitStmt(S);
2918
2919 OpenACCClauseProfiler P{*this};
2920 P.VisitOpenACCClauseList(S->clauses());
2921}
2922
2923void StmtProfiler::VisitOpenACCExitDataConstruct(
2924 const OpenACCExitDataConstruct *S) {
2925 VisitStmt(S);
2926
2927 OpenACCClauseProfiler P{*this};
2928 P.VisitOpenACCClauseList(S->clauses());
2929}
2930
2931void StmtProfiler::VisitOpenACCHostDataConstruct(
2932 const OpenACCHostDataConstruct *S) {
2933 VisitStmt(S);
2934
2935 OpenACCClauseProfiler P{*this};
2936 P.VisitOpenACCClauseList(S->clauses());
2937}
2938
2939void StmtProfiler::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
2940 // VisitStmt covers 'children', so the exprs inside of it are covered.
2941 VisitStmt(S);
2942
2943 OpenACCClauseProfiler P{*this};
2944 P.VisitOpenACCClauseList(S->clauses());
2945}
2946
2947void StmtProfiler::VisitOpenACCCacheConstruct(const OpenACCCacheConstruct *S) {
2948 // VisitStmt covers 'children', so the exprs inside of it are covered.
2949 VisitStmt(S);
2950}
2951
2952void StmtProfiler::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
2953 VisitStmt(S);
2954 OpenACCClauseProfiler P{*this};
2955 P.VisitOpenACCClauseList(S->clauses());
2956}
2957
2958void StmtProfiler::VisitOpenACCShutdownConstruct(
2959 const OpenACCShutdownConstruct *S) {
2960 VisitStmt(S);
2961 OpenACCClauseProfiler P{*this};
2962 P.VisitOpenACCClauseList(S->clauses());
2963}
2964
2965void StmtProfiler::VisitOpenACCSetConstruct(const OpenACCSetConstruct *S) {
2966 VisitStmt(S);
2967 OpenACCClauseProfiler P{*this};
2968 P.VisitOpenACCClauseList(S->clauses());
2969}
2970
2971void StmtProfiler::VisitOpenACCUpdateConstruct(
2972 const OpenACCUpdateConstruct *S) {
2973 VisitStmt(S);
2974 OpenACCClauseProfiler P{*this};
2975 P.VisitOpenACCClauseList(S->clauses());
2976}
2977
2978void StmtProfiler::VisitOpenACCAtomicConstruct(
2979 const OpenACCAtomicConstruct *S) {
2980 VisitStmt(S);
2981 OpenACCClauseProfiler P{*this};
2982 P.VisitOpenACCClauseList(S->clauses());
2983}
2984
2985void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) {
2986 VisitStmt(S);
2987}
2988
2989void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2990 bool Canonical, bool ProfileLambdaExpr) const {
2991 StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr);
2992 Profiler.Visit(this);
2993}
2994
2995void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
2996 class ODRHash &Hash) const {
2997 StmtProfilerWithoutPointers Profiler(ID, Hash);
2998 Profiler.Visit(this);
2999}
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:2390
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:995
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:5567
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
const IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition Expr.cpp:1694
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition Expr.h:2491
@ 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.