1 //===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the Stmt::Profile method, which builds a unique bit
10 // representation that identifies a statement/expression.
12 //===----------------------------------------------------------------------===//
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclObjC.h"
16 #include "clang/AST/DeclTemplate.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/ExprCXX.h"
19 #include "clang/AST/ExprObjC.h"
20 #include "clang/AST/ExprOpenMP.h"
21 #include "clang/AST/ODRHash.h"
22 #include "clang/AST/OpenMPClause.h"
23 #include "clang/AST/StmtVisitor.h"
24 #include "llvm/ADT/FoldingSet.h"
25 using namespace clang
;
28 class StmtProfiler
: public ConstStmtVisitor
<StmtProfiler
> {
30 llvm::FoldingSetNodeID
&ID
;
34 StmtProfiler(llvm::FoldingSetNodeID
&ID
, bool Canonical
)
35 : ID(ID
), Canonical(Canonical
) {}
37 virtual ~StmtProfiler() {}
39 void VisitStmt(const Stmt
*S
);
41 void VisitStmtNoChildren(const Stmt
*S
) {
42 HandleStmtClass(S
->getStmtClass());
45 virtual void HandleStmtClass(Stmt::StmtClass SC
) = 0;
47 #define STMT(Node, Base) void Visit##Node(const Node *S);
48 #include "clang/AST/StmtNodes.inc"
50 /// Visit a declaration that is referenced within an expression
52 virtual void VisitDecl(const Decl
*D
) = 0;
54 /// Visit a type that is referenced within an expression or
56 virtual void VisitType(QualType T
) = 0;
58 /// Visit a name that occurs within an expression or statement.
59 virtual void VisitName(DeclarationName Name
, bool TreatAsDecl
= false) = 0;
61 /// Visit identifiers that are not in Decl's or Type's.
62 virtual void VisitIdentifierInfo(IdentifierInfo
*II
) = 0;
64 /// Visit a nested-name-specifier that occurs within an expression
66 virtual void VisitNestedNameSpecifier(NestedNameSpecifier
*NNS
) = 0;
68 /// Visit a template name that occurs within an expression or
70 virtual void VisitTemplateName(TemplateName Name
) = 0;
72 /// Visit template arguments that occur within an expression or
74 void VisitTemplateArguments(const TemplateArgumentLoc
*Args
,
77 /// Visit a single template argument.
78 void VisitTemplateArgument(const TemplateArgument
&Arg
);
81 class StmtProfilerWithPointers
: public StmtProfiler
{
82 const ASTContext
&Context
;
85 StmtProfilerWithPointers(llvm::FoldingSetNodeID
&ID
,
86 const ASTContext
&Context
, bool Canonical
)
87 : StmtProfiler(ID
, Canonical
), Context(Context
) {}
89 void HandleStmtClass(Stmt::StmtClass SC
) override
{
93 void VisitDecl(const Decl
*D
) override
{
94 ID
.AddInteger(D
? D
->getKind() : 0);
97 if (const NonTypeTemplateParmDecl
*NTTP
=
98 dyn_cast
<NonTypeTemplateParmDecl
>(D
)) {
99 ID
.AddInteger(NTTP
->getDepth());
100 ID
.AddInteger(NTTP
->getIndex());
101 ID
.AddBoolean(NTTP
->isParameterPack());
102 VisitType(NTTP
->getType());
106 if (const ParmVarDecl
*Parm
= dyn_cast
<ParmVarDecl
>(D
)) {
107 // The Itanium C++ ABI uses the type, scope depth, and scope
108 // index of a parameter when mangling expressions that involve
109 // function parameters, so we will use the parameter's type for
110 // establishing function parameter identity. That way, our
111 // definition of "equivalent" (per C++ [temp.over.link]) is at
112 // least as strong as the definition of "equivalent" used for
114 VisitType(Parm
->getType());
115 ID
.AddInteger(Parm
->getFunctionScopeDepth());
116 ID
.AddInteger(Parm
->getFunctionScopeIndex());
120 if (const TemplateTypeParmDecl
*TTP
=
121 dyn_cast
<TemplateTypeParmDecl
>(D
)) {
122 ID
.AddInteger(TTP
->getDepth());
123 ID
.AddInteger(TTP
->getIndex());
124 ID
.AddBoolean(TTP
->isParameterPack());
128 if (const TemplateTemplateParmDecl
*TTP
=
129 dyn_cast
<TemplateTemplateParmDecl
>(D
)) {
130 ID
.AddInteger(TTP
->getDepth());
131 ID
.AddInteger(TTP
->getIndex());
132 ID
.AddBoolean(TTP
->isParameterPack());
137 ID
.AddPointer(D
? D
->getCanonicalDecl() : nullptr);
140 void VisitType(QualType T
) override
{
141 if (Canonical
&& !T
.isNull())
142 T
= Context
.getCanonicalType(T
);
144 ID
.AddPointer(T
.getAsOpaquePtr());
147 void VisitName(DeclarationName Name
, bool /*TreatAsDecl*/) override
{
148 ID
.AddPointer(Name
.getAsOpaquePtr());
151 void VisitIdentifierInfo(IdentifierInfo
*II
) override
{
155 void VisitNestedNameSpecifier(NestedNameSpecifier
*NNS
) override
{
157 NNS
= Context
.getCanonicalNestedNameSpecifier(NNS
);
161 void VisitTemplateName(TemplateName Name
) override
{
163 Name
= Context
.getCanonicalTemplateName(Name
);
169 class StmtProfilerWithoutPointers
: public StmtProfiler
{
172 StmtProfilerWithoutPointers(llvm::FoldingSetNodeID
&ID
, ODRHash
&Hash
)
173 : StmtProfiler(ID
, false), Hash(Hash
) {}
176 void HandleStmtClass(Stmt::StmtClass SC
) override
{
177 if (SC
== Stmt::UnresolvedLookupExprClass
) {
178 // Pretend that the name looked up is a Decl due to how templates
179 // handle some Decl lookups.
180 ID
.AddInteger(Stmt::DeclRefExprClass
);
186 void VisitType(QualType T
) override
{
190 void VisitName(DeclarationName Name
, bool TreatAsDecl
) override
{
192 // A Decl can be null, so each Decl is preceded by a boolean to
193 // store its nullness. Add a boolean here to match.
196 Hash
.AddDeclarationName(Name
, TreatAsDecl
);
198 void VisitIdentifierInfo(IdentifierInfo
*II
) override
{
201 Hash
.AddIdentifierInfo(II
);
204 void VisitDecl(const Decl
*D
) override
{
210 void VisitTemplateName(TemplateName Name
) override
{
211 Hash
.AddTemplateName(Name
);
213 void VisitNestedNameSpecifier(NestedNameSpecifier
*NNS
) override
{
216 Hash
.AddNestedNameSpecifier(NNS
);
222 void StmtProfiler::VisitStmt(const Stmt
*S
) {
223 assert(S
&& "Requires non-null Stmt pointer");
225 VisitStmtNoChildren(S
);
227 for (const Stmt
*SubStmt
: S
->children()) {
235 void StmtProfiler::VisitDeclStmt(const DeclStmt
*S
) {
237 for (const auto *D
: S
->decls())
241 void StmtProfiler::VisitNullStmt(const NullStmt
*S
) {
245 void StmtProfiler::VisitCompoundStmt(const CompoundStmt
*S
) {
249 void StmtProfiler::VisitCaseStmt(const CaseStmt
*S
) {
253 void StmtProfiler::VisitDefaultStmt(const DefaultStmt
*S
) {
257 void StmtProfiler::VisitLabelStmt(const LabelStmt
*S
) {
259 VisitDecl(S
->getDecl());
262 void StmtProfiler::VisitAttributedStmt(const AttributedStmt
*S
) {
264 // TODO: maybe visit attributes?
267 void StmtProfiler::VisitIfStmt(const IfStmt
*S
) {
269 VisitDecl(S
->getConditionVariable());
272 void StmtProfiler::VisitSwitchStmt(const SwitchStmt
*S
) {
274 VisitDecl(S
->getConditionVariable());
277 void StmtProfiler::VisitWhileStmt(const WhileStmt
*S
) {
279 VisitDecl(S
->getConditionVariable());
282 void StmtProfiler::VisitDoStmt(const DoStmt
*S
) {
286 void StmtProfiler::VisitForStmt(const ForStmt
*S
) {
290 void StmtProfiler::VisitGotoStmt(const GotoStmt
*S
) {
292 VisitDecl(S
->getLabel());
295 void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt
*S
) {
299 void StmtProfiler::VisitContinueStmt(const ContinueStmt
*S
) {
303 void StmtProfiler::VisitBreakStmt(const BreakStmt
*S
) {
307 void StmtProfiler::VisitReturnStmt(const ReturnStmt
*S
) {
311 void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt
*S
) {
313 ID
.AddBoolean(S
->isVolatile());
314 ID
.AddBoolean(S
->isSimple());
315 VisitStringLiteral(S
->getAsmString());
316 ID
.AddInteger(S
->getNumOutputs());
317 for (unsigned I
= 0, N
= S
->getNumOutputs(); I
!= N
; ++I
) {
318 ID
.AddString(S
->getOutputName(I
));
319 VisitStringLiteral(S
->getOutputConstraintLiteral(I
));
321 ID
.AddInteger(S
->getNumInputs());
322 for (unsigned I
= 0, N
= S
->getNumInputs(); I
!= N
; ++I
) {
323 ID
.AddString(S
->getInputName(I
));
324 VisitStringLiteral(S
->getInputConstraintLiteral(I
));
326 ID
.AddInteger(S
->getNumClobbers());
327 for (unsigned I
= 0, N
= S
->getNumClobbers(); I
!= N
; ++I
)
328 VisitStringLiteral(S
->getClobberStringLiteral(I
));
329 ID
.AddInteger(S
->getNumLabels());
330 for (auto *L
: S
->labels())
331 VisitDecl(L
->getLabel());
334 void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt
*S
) {
335 // FIXME: Implement MS style inline asm statement profiler.
339 void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt
*S
) {
341 VisitType(S
->getCaughtType());
344 void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt
*S
) {
348 void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt
*S
) {
352 void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt
*S
) {
354 ID
.AddBoolean(S
->isIfExists());
355 VisitNestedNameSpecifier(S
->getQualifierLoc().getNestedNameSpecifier());
356 VisitName(S
->getNameInfo().getName());
359 void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt
*S
) {
363 void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt
*S
) {
367 void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt
*S
) {
371 void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt
*S
) {
375 void StmtProfiler::VisitCapturedStmt(const CapturedStmt
*S
) {
379 void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt
*S
) {
383 void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt
*S
) {
385 ID
.AddBoolean(S
->hasEllipsis());
386 if (S
->getCatchParamDecl())
387 VisitType(S
->getCatchParamDecl()->getType());
390 void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt
*S
) {
394 void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt
*S
) {
399 StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt
*S
) {
403 void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt
*S
) {
408 StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt
*S
) {
413 class OMPClauseProfiler
: public ConstOMPClauseVisitor
<OMPClauseProfiler
> {
414 StmtProfiler
*Profiler
;
415 /// Process clauses with list of variables.
416 template <typename T
>
417 void VisitOMPClauseList(T
*Node
);
420 OMPClauseProfiler(StmtProfiler
*P
) : Profiler(P
) { }
421 #define GEN_CLANG_CLAUSE_CLASS
422 #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
423 #include "llvm/Frontend/OpenMP/OMP.inc"
424 void VistOMPClauseWithPreInit(const OMPClauseWithPreInit
*C
);
425 void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate
*C
);
428 void OMPClauseProfiler::VistOMPClauseWithPreInit(
429 const OMPClauseWithPreInit
*C
) {
430 if (auto *S
= C
->getPreInitStmt())
431 Profiler
->VisitStmt(S
);
434 void OMPClauseProfiler::VistOMPClauseWithPostUpdate(
435 const OMPClauseWithPostUpdate
*C
) {
436 VistOMPClauseWithPreInit(C
);
437 if (auto *E
= C
->getPostUpdateExpr())
438 Profiler
->VisitStmt(E
);
441 void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause
*C
) {
442 VistOMPClauseWithPreInit(C
);
443 if (C
->getCondition())
444 Profiler
->VisitStmt(C
->getCondition());
447 void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause
*C
) {
448 VistOMPClauseWithPreInit(C
);
449 if (C
->getCondition())
450 Profiler
->VisitStmt(C
->getCondition());
453 void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause
*C
) {
454 VistOMPClauseWithPreInit(C
);
455 if (C
->getNumThreads())
456 Profiler
->VisitStmt(C
->getNumThreads());
459 void OMPClauseProfiler::VisitOMPAlignClause(const OMPAlignClause
*C
) {
460 if (C
->getAlignment())
461 Profiler
->VisitStmt(C
->getAlignment());
464 void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause
*C
) {
466 Profiler
->VisitStmt(C
->getSafelen());
469 void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause
*C
) {
471 Profiler
->VisitStmt(C
->getSimdlen());
474 void OMPClauseProfiler::VisitOMPSizesClause(const OMPSizesClause
*C
) {
475 for (auto *E
: C
->getSizesRefs())
477 Profiler
->VisitExpr(E
);
480 void OMPClauseProfiler::VisitOMPFullClause(const OMPFullClause
*C
) {}
482 void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause
*C
) {
483 if (const Expr
*Factor
= C
->getFactor())
484 Profiler
->VisitExpr(Factor
);
487 void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause
*C
) {
488 if (C
->getAllocator())
489 Profiler
->VisitStmt(C
->getAllocator());
492 void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause
*C
) {
493 if (C
->getNumForLoops())
494 Profiler
->VisitStmt(C
->getNumForLoops());
497 void OMPClauseProfiler::VisitOMPDetachClause(const OMPDetachClause
*C
) {
498 if (Expr
*Evt
= C
->getEventHandler())
499 Profiler
->VisitStmt(Evt
);
502 void OMPClauseProfiler::VisitOMPNovariantsClause(const OMPNovariantsClause
*C
) {
503 VistOMPClauseWithPreInit(C
);
504 if (C
->getCondition())
505 Profiler
->VisitStmt(C
->getCondition());
508 void OMPClauseProfiler::VisitOMPNocontextClause(const OMPNocontextClause
*C
) {
509 VistOMPClauseWithPreInit(C
);
510 if (C
->getCondition())
511 Profiler
->VisitStmt(C
->getCondition());
514 void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause
*C
) { }
516 void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause
*C
) { }
518 void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
519 const OMPUnifiedAddressClause
*C
) {}
521 void OMPClauseProfiler::VisitOMPUnifiedSharedMemoryClause(
522 const OMPUnifiedSharedMemoryClause
*C
) {}
524 void OMPClauseProfiler::VisitOMPReverseOffloadClause(
525 const OMPReverseOffloadClause
*C
) {}
527 void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause(
528 const OMPDynamicAllocatorsClause
*C
) {}
530 void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
531 const OMPAtomicDefaultMemOrderClause
*C
) {}
533 void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause
*C
) {}
535 void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause
*C
) {}
537 void OMPClauseProfiler::VisitOMPMessageClause(const OMPMessageClause
*C
) {
538 if (C
->getMessageString())
539 Profiler
->VisitStmt(C
->getMessageString());
542 void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause
*C
) {
543 VistOMPClauseWithPreInit(C
);
544 if (auto *S
= C
->getChunkSize())
545 Profiler
->VisitStmt(S
);
548 void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause
*C
) {
549 if (auto *Num
= C
->getNumForLoops())
550 Profiler
->VisitStmt(Num
);
553 void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause
*) {}
555 void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause
*) {}
557 void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause
*) {}
559 void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause
*) {}
561 void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause
*) {}
563 void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause
*) {}
565 void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause
*) {}
567 void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause
*) {}
569 void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause
*) {}
571 void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause
*) {}
573 void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause
*) {}
575 void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause
*) {}
577 void OMPClauseProfiler::VisitOMPRelaxedClause(const OMPRelaxedClause
*) {}
579 void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause
*) {}
581 void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause
*) {}
583 void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause
*) {}
585 void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause
*C
) {
586 VisitOMPClauseList(C
);
589 void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause
*C
) {
590 if (C
->getInteropVar())
591 Profiler
->VisitStmt(C
->getInteropVar());
594 void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause
*C
) {
595 if (C
->getInteropVar())
596 Profiler
->VisitStmt(C
->getInteropVar());
599 void OMPClauseProfiler::VisitOMPFilterClause(const OMPFilterClause
*C
) {
600 VistOMPClauseWithPreInit(C
);
601 if (C
->getThreadID())
602 Profiler
->VisitStmt(C
->getThreadID());
606 void OMPClauseProfiler::VisitOMPClauseList(T
*Node
) {
607 for (auto *E
: Node
->varlists()) {
609 Profiler
->VisitStmt(E
);
613 void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause
*C
) {
614 VisitOMPClauseList(C
);
615 for (auto *E
: C
->private_copies()) {
617 Profiler
->VisitStmt(E
);
621 OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause
*C
) {
622 VisitOMPClauseList(C
);
623 VistOMPClauseWithPreInit(C
);
624 for (auto *E
: C
->private_copies()) {
626 Profiler
->VisitStmt(E
);
628 for (auto *E
: C
->inits()) {
630 Profiler
->VisitStmt(E
);
634 OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause
*C
) {
635 VisitOMPClauseList(C
);
636 VistOMPClauseWithPostUpdate(C
);
637 for (auto *E
: C
->source_exprs()) {
639 Profiler
->VisitStmt(E
);
641 for (auto *E
: C
->destination_exprs()) {
643 Profiler
->VisitStmt(E
);
645 for (auto *E
: C
->assignment_ops()) {
647 Profiler
->VisitStmt(E
);
650 void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause
*C
) {
651 VisitOMPClauseList(C
);
653 void OMPClauseProfiler::VisitOMPReductionClause(
654 const OMPReductionClause
*C
) {
655 Profiler
->VisitNestedNameSpecifier(
656 C
->getQualifierLoc().getNestedNameSpecifier());
657 Profiler
->VisitName(C
->getNameInfo().getName());
658 VisitOMPClauseList(C
);
659 VistOMPClauseWithPostUpdate(C
);
660 for (auto *E
: C
->privates()) {
662 Profiler
->VisitStmt(E
);
664 for (auto *E
: C
->lhs_exprs()) {
666 Profiler
->VisitStmt(E
);
668 for (auto *E
: C
->rhs_exprs()) {
670 Profiler
->VisitStmt(E
);
672 for (auto *E
: C
->reduction_ops()) {
674 Profiler
->VisitStmt(E
);
676 if (C
->getModifier() == clang::OMPC_REDUCTION_inscan
) {
677 for (auto *E
: C
->copy_ops()) {
679 Profiler
->VisitStmt(E
);
681 for (auto *E
: C
->copy_array_temps()) {
683 Profiler
->VisitStmt(E
);
685 for (auto *E
: C
->copy_array_elems()) {
687 Profiler
->VisitStmt(E
);
691 void OMPClauseProfiler::VisitOMPTaskReductionClause(
692 const OMPTaskReductionClause
*C
) {
693 Profiler
->VisitNestedNameSpecifier(
694 C
->getQualifierLoc().getNestedNameSpecifier());
695 Profiler
->VisitName(C
->getNameInfo().getName());
696 VisitOMPClauseList(C
);
697 VistOMPClauseWithPostUpdate(C
);
698 for (auto *E
: C
->privates()) {
700 Profiler
->VisitStmt(E
);
702 for (auto *E
: C
->lhs_exprs()) {
704 Profiler
->VisitStmt(E
);
706 for (auto *E
: C
->rhs_exprs()) {
708 Profiler
->VisitStmt(E
);
710 for (auto *E
: C
->reduction_ops()) {
712 Profiler
->VisitStmt(E
);
715 void OMPClauseProfiler::VisitOMPInReductionClause(
716 const OMPInReductionClause
*C
) {
717 Profiler
->VisitNestedNameSpecifier(
718 C
->getQualifierLoc().getNestedNameSpecifier());
719 Profiler
->VisitName(C
->getNameInfo().getName());
720 VisitOMPClauseList(C
);
721 VistOMPClauseWithPostUpdate(C
);
722 for (auto *E
: C
->privates()) {
724 Profiler
->VisitStmt(E
);
726 for (auto *E
: C
->lhs_exprs()) {
728 Profiler
->VisitStmt(E
);
730 for (auto *E
: C
->rhs_exprs()) {
732 Profiler
->VisitStmt(E
);
734 for (auto *E
: C
->reduction_ops()) {
736 Profiler
->VisitStmt(E
);
738 for (auto *E
: C
->taskgroup_descriptors()) {
740 Profiler
->VisitStmt(E
);
743 void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause
*C
) {
744 VisitOMPClauseList(C
);
745 VistOMPClauseWithPostUpdate(C
);
746 for (auto *E
: C
->privates()) {
748 Profiler
->VisitStmt(E
);
750 for (auto *E
: C
->inits()) {
752 Profiler
->VisitStmt(E
);
754 for (auto *E
: C
->updates()) {
756 Profiler
->VisitStmt(E
);
758 for (auto *E
: C
->finals()) {
760 Profiler
->VisitStmt(E
);
763 Profiler
->VisitStmt(C
->getStep());
764 if (C
->getCalcStep())
765 Profiler
->VisitStmt(C
->getCalcStep());
767 void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause
*C
) {
768 VisitOMPClauseList(C
);
769 if (C
->getAlignment())
770 Profiler
->VisitStmt(C
->getAlignment());
772 void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause
*C
) {
773 VisitOMPClauseList(C
);
774 for (auto *E
: C
->source_exprs()) {
776 Profiler
->VisitStmt(E
);
778 for (auto *E
: C
->destination_exprs()) {
780 Profiler
->VisitStmt(E
);
782 for (auto *E
: C
->assignment_ops()) {
784 Profiler
->VisitStmt(E
);
788 OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause
*C
) {
789 VisitOMPClauseList(C
);
790 for (auto *E
: C
->source_exprs()) {
792 Profiler
->VisitStmt(E
);
794 for (auto *E
: C
->destination_exprs()) {
796 Profiler
->VisitStmt(E
);
798 for (auto *E
: C
->assignment_ops()) {
800 Profiler
->VisitStmt(E
);
803 void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause
*C
) {
804 VisitOMPClauseList(C
);
806 void OMPClauseProfiler::VisitOMPDepobjClause(const OMPDepobjClause
*C
) {
807 if (const Expr
*Depobj
= C
->getDepobj())
808 Profiler
->VisitStmt(Depobj
);
810 void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause
*C
) {
811 VisitOMPClauseList(C
);
813 void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause
*C
) {
815 Profiler
->VisitStmt(C
->getDevice());
817 void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause
*C
) {
818 VisitOMPClauseList(C
);
820 void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause
*C
) {
821 if (Expr
*Allocator
= C
->getAllocator())
822 Profiler
->VisitStmt(Allocator
);
823 VisitOMPClauseList(C
);
825 void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause
*C
) {
826 VistOMPClauseWithPreInit(C
);
827 if (C
->getNumTeams())
828 Profiler
->VisitStmt(C
->getNumTeams());
830 void OMPClauseProfiler::VisitOMPThreadLimitClause(
831 const OMPThreadLimitClause
*C
) {
832 VistOMPClauseWithPreInit(C
);
833 if (C
->getThreadLimit())
834 Profiler
->VisitStmt(C
->getThreadLimit());
836 void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause
*C
) {
837 VistOMPClauseWithPreInit(C
);
838 if (C
->getPriority())
839 Profiler
->VisitStmt(C
->getPriority());
841 void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause
*C
) {
842 VistOMPClauseWithPreInit(C
);
843 if (C
->getGrainsize())
844 Profiler
->VisitStmt(C
->getGrainsize());
846 void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause
*C
) {
847 VistOMPClauseWithPreInit(C
);
848 if (C
->getNumTasks())
849 Profiler
->VisitStmt(C
->getNumTasks());
851 void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause
*C
) {
853 Profiler
->VisitStmt(C
->getHint());
855 void OMPClauseProfiler::VisitOMPToClause(const OMPToClause
*C
) {
856 VisitOMPClauseList(C
);
858 void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause
*C
) {
859 VisitOMPClauseList(C
);
861 void OMPClauseProfiler::VisitOMPUseDevicePtrClause(
862 const OMPUseDevicePtrClause
*C
) {
863 VisitOMPClauseList(C
);
865 void OMPClauseProfiler::VisitOMPUseDeviceAddrClause(
866 const OMPUseDeviceAddrClause
*C
) {
867 VisitOMPClauseList(C
);
869 void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
870 const OMPIsDevicePtrClause
*C
) {
871 VisitOMPClauseList(C
);
873 void OMPClauseProfiler::VisitOMPHasDeviceAddrClause(
874 const OMPHasDeviceAddrClause
*C
) {
875 VisitOMPClauseList(C
);
877 void OMPClauseProfiler::VisitOMPNontemporalClause(
878 const OMPNontemporalClause
*C
) {
879 VisitOMPClauseList(C
);
880 for (auto *E
: C
->private_refs())
881 Profiler
->VisitStmt(E
);
883 void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause
*C
) {
884 VisitOMPClauseList(C
);
886 void OMPClauseProfiler::VisitOMPExclusiveClause(const OMPExclusiveClause
*C
) {
887 VisitOMPClauseList(C
);
889 void OMPClauseProfiler::VisitOMPUsesAllocatorsClause(
890 const OMPUsesAllocatorsClause
*C
) {
891 for (unsigned I
= 0, E
= C
->getNumberOfAllocators(); I
< E
; ++I
) {
892 OMPUsesAllocatorsClause::Data D
= C
->getAllocatorData(I
);
893 Profiler
->VisitStmt(D
.Allocator
);
894 if (D
.AllocatorTraits
)
895 Profiler
->VisitStmt(D
.AllocatorTraits
);
898 void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause
*C
) {
899 if (const Expr
*Modifier
= C
->getModifier())
900 Profiler
->VisitStmt(Modifier
);
901 for (const Expr
*E
: C
->varlists())
902 Profiler
->VisitStmt(E
);
904 void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause
*C
) {}
905 void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause
*C
) {}
906 void OMPClauseProfiler::VisitOMPXDynCGroupMemClause(
907 const OMPXDynCGroupMemClause
*C
) {
908 VistOMPClauseWithPreInit(C
);
909 if (Expr
*Size
= C
->getSize())
910 Profiler
->VisitStmt(Size
);
915 StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective
*S
) {
917 OMPClauseProfiler
P(this);
918 ArrayRef
<OMPClause
*> Clauses
= S
->clauses();
919 for (ArrayRef
<OMPClause
*>::iterator I
= Clauses
.begin(), E
= Clauses
.end();
925 void StmtProfiler::VisitOMPCanonicalLoop(const OMPCanonicalLoop
*L
) {
929 void StmtProfiler::VisitOMPLoopBasedDirective(const OMPLoopBasedDirective
*S
) {
930 VisitOMPExecutableDirective(S
);
933 void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective
*S
) {
934 VisitOMPLoopBasedDirective(S
);
937 void StmtProfiler::VisitOMPMetaDirective(const OMPMetaDirective
*S
) {
938 VisitOMPExecutableDirective(S
);
941 void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective
*S
) {
942 VisitOMPExecutableDirective(S
);
945 void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective
*S
) {
946 VisitOMPLoopDirective(S
);
949 void StmtProfiler::VisitOMPLoopTransformationDirective(
950 const OMPLoopTransformationDirective
*S
) {
951 VisitOMPLoopBasedDirective(S
);
954 void StmtProfiler::VisitOMPTileDirective(const OMPTileDirective
*S
) {
955 VisitOMPLoopTransformationDirective(S
);
958 void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective
*S
) {
959 VisitOMPLoopTransformationDirective(S
);
962 void StmtProfiler::VisitOMPForDirective(const OMPForDirective
*S
) {
963 VisitOMPLoopDirective(S
);
966 void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective
*S
) {
967 VisitOMPLoopDirective(S
);
970 void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective
*S
) {
971 VisitOMPExecutableDirective(S
);
974 void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective
*S
) {
975 VisitOMPExecutableDirective(S
);
978 void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective
*S
) {
979 VisitOMPExecutableDirective(S
);
982 void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective
*S
) {
983 VisitOMPExecutableDirective(S
);
986 void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective
*S
) {
987 VisitOMPExecutableDirective(S
);
988 VisitName(S
->getDirectiveName().getName());
992 StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective
*S
) {
993 VisitOMPLoopDirective(S
);
996 void StmtProfiler::VisitOMPParallelForSimdDirective(
997 const OMPParallelForSimdDirective
*S
) {
998 VisitOMPLoopDirective(S
);
1001 void StmtProfiler::VisitOMPParallelMasterDirective(
1002 const OMPParallelMasterDirective
*S
) {
1003 VisitOMPExecutableDirective(S
);
1006 void StmtProfiler::VisitOMPParallelMaskedDirective(
1007 const OMPParallelMaskedDirective
*S
) {
1008 VisitOMPExecutableDirective(S
);
1011 void StmtProfiler::VisitOMPParallelSectionsDirective(
1012 const OMPParallelSectionsDirective
*S
) {
1013 VisitOMPExecutableDirective(S
);
1016 void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective
*S
) {
1017 VisitOMPExecutableDirective(S
);
1020 void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective
*S
) {
1021 VisitOMPExecutableDirective(S
);
1024 void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective
*S
) {
1025 VisitOMPExecutableDirective(S
);
1028 void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective
*S
) {
1029 VisitOMPExecutableDirective(S
);
1032 void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective
*S
) {
1033 VisitOMPExecutableDirective(S
);
1035 void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective
*S
) {
1036 VisitOMPExecutableDirective(S
);
1037 if (const Expr
*E
= S
->getReductionRef())
1041 void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective
*S
) {
1042 VisitOMPExecutableDirective(S
);
1045 void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective
*S
) {
1046 VisitOMPExecutableDirective(S
);
1049 void StmtProfiler::VisitOMPScanDirective(const OMPScanDirective
*S
) {
1050 VisitOMPExecutableDirective(S
);
1053 void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective
*S
) {
1054 VisitOMPExecutableDirective(S
);
1057 void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective
*S
) {
1058 VisitOMPExecutableDirective(S
);
1061 void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective
*S
) {
1062 VisitOMPExecutableDirective(S
);
1065 void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective
*S
) {
1066 VisitOMPExecutableDirective(S
);
1069 void StmtProfiler::VisitOMPTargetEnterDataDirective(
1070 const OMPTargetEnterDataDirective
*S
) {
1071 VisitOMPExecutableDirective(S
);
1074 void StmtProfiler::VisitOMPTargetExitDataDirective(
1075 const OMPTargetExitDataDirective
*S
) {
1076 VisitOMPExecutableDirective(S
);
1079 void StmtProfiler::VisitOMPTargetParallelDirective(
1080 const OMPTargetParallelDirective
*S
) {
1081 VisitOMPExecutableDirective(S
);
1084 void StmtProfiler::VisitOMPTargetParallelForDirective(
1085 const OMPTargetParallelForDirective
*S
) {
1086 VisitOMPExecutableDirective(S
);
1089 void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective
*S
) {
1090 VisitOMPExecutableDirective(S
);
1093 void StmtProfiler::VisitOMPCancellationPointDirective(
1094 const OMPCancellationPointDirective
*S
) {
1095 VisitOMPExecutableDirective(S
);
1098 void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective
*S
) {
1099 VisitOMPExecutableDirective(S
);
1102 void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective
*S
) {
1103 VisitOMPLoopDirective(S
);
1106 void StmtProfiler::VisitOMPTaskLoopSimdDirective(
1107 const OMPTaskLoopSimdDirective
*S
) {
1108 VisitOMPLoopDirective(S
);
1111 void StmtProfiler::VisitOMPMasterTaskLoopDirective(
1112 const OMPMasterTaskLoopDirective
*S
) {
1113 VisitOMPLoopDirective(S
);
1116 void StmtProfiler::VisitOMPMaskedTaskLoopDirective(
1117 const OMPMaskedTaskLoopDirective
*S
) {
1118 VisitOMPLoopDirective(S
);
1121 void StmtProfiler::VisitOMPMasterTaskLoopSimdDirective(
1122 const OMPMasterTaskLoopSimdDirective
*S
) {
1123 VisitOMPLoopDirective(S
);
1126 void StmtProfiler::VisitOMPMaskedTaskLoopSimdDirective(
1127 const OMPMaskedTaskLoopSimdDirective
*S
) {
1128 VisitOMPLoopDirective(S
);
1131 void StmtProfiler::VisitOMPParallelMasterTaskLoopDirective(
1132 const OMPParallelMasterTaskLoopDirective
*S
) {
1133 VisitOMPLoopDirective(S
);
1136 void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective(
1137 const OMPParallelMaskedTaskLoopDirective
*S
) {
1138 VisitOMPLoopDirective(S
);
1141 void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective(
1142 const OMPParallelMasterTaskLoopSimdDirective
*S
) {
1143 VisitOMPLoopDirective(S
);
1146 void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective(
1147 const OMPParallelMaskedTaskLoopSimdDirective
*S
) {
1148 VisitOMPLoopDirective(S
);
1151 void StmtProfiler::VisitOMPDistributeDirective(
1152 const OMPDistributeDirective
*S
) {
1153 VisitOMPLoopDirective(S
);
1156 void OMPClauseProfiler::VisitOMPDistScheduleClause(
1157 const OMPDistScheduleClause
*C
) {
1158 VistOMPClauseWithPreInit(C
);
1159 if (auto *S
= C
->getChunkSize())
1160 Profiler
->VisitStmt(S
);
1163 void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause
*) {}
1165 void StmtProfiler::VisitOMPTargetUpdateDirective(
1166 const OMPTargetUpdateDirective
*S
) {
1167 VisitOMPExecutableDirective(S
);
1170 void StmtProfiler::VisitOMPDistributeParallelForDirective(
1171 const OMPDistributeParallelForDirective
*S
) {
1172 VisitOMPLoopDirective(S
);
1175 void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
1176 const OMPDistributeParallelForSimdDirective
*S
) {
1177 VisitOMPLoopDirective(S
);
1180 void StmtProfiler::VisitOMPDistributeSimdDirective(
1181 const OMPDistributeSimdDirective
*S
) {
1182 VisitOMPLoopDirective(S
);
1185 void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
1186 const OMPTargetParallelForSimdDirective
*S
) {
1187 VisitOMPLoopDirective(S
);
1190 void StmtProfiler::VisitOMPTargetSimdDirective(
1191 const OMPTargetSimdDirective
*S
) {
1192 VisitOMPLoopDirective(S
);
1195 void StmtProfiler::VisitOMPTeamsDistributeDirective(
1196 const OMPTeamsDistributeDirective
*S
) {
1197 VisitOMPLoopDirective(S
);
1200 void StmtProfiler::VisitOMPTeamsDistributeSimdDirective(
1201 const OMPTeamsDistributeSimdDirective
*S
) {
1202 VisitOMPLoopDirective(S
);
1205 void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
1206 const OMPTeamsDistributeParallelForSimdDirective
*S
) {
1207 VisitOMPLoopDirective(S
);
1210 void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
1211 const OMPTeamsDistributeParallelForDirective
*S
) {
1212 VisitOMPLoopDirective(S
);
1215 void StmtProfiler::VisitOMPTargetTeamsDirective(
1216 const OMPTargetTeamsDirective
*S
) {
1217 VisitOMPExecutableDirective(S
);
1220 void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
1221 const OMPTargetTeamsDistributeDirective
*S
) {
1222 VisitOMPLoopDirective(S
);
1225 void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
1226 const OMPTargetTeamsDistributeParallelForDirective
*S
) {
1227 VisitOMPLoopDirective(S
);
1230 void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1231 const OMPTargetTeamsDistributeParallelForSimdDirective
*S
) {
1232 VisitOMPLoopDirective(S
);
1235 void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
1236 const OMPTargetTeamsDistributeSimdDirective
*S
) {
1237 VisitOMPLoopDirective(S
);
1240 void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective
*S
) {
1241 VisitOMPExecutableDirective(S
);
1244 void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective
*S
) {
1245 VisitOMPExecutableDirective(S
);
1248 void StmtProfiler::VisitOMPMaskedDirective(const OMPMaskedDirective
*S
) {
1249 VisitOMPExecutableDirective(S
);
1252 void StmtProfiler::VisitOMPGenericLoopDirective(
1253 const OMPGenericLoopDirective
*S
) {
1254 VisitOMPLoopDirective(S
);
1257 void StmtProfiler::VisitOMPTeamsGenericLoopDirective(
1258 const OMPTeamsGenericLoopDirective
*S
) {
1259 VisitOMPLoopDirective(S
);
1262 void StmtProfiler::VisitOMPTargetTeamsGenericLoopDirective(
1263 const OMPTargetTeamsGenericLoopDirective
*S
) {
1264 VisitOMPLoopDirective(S
);
1267 void StmtProfiler::VisitOMPParallelGenericLoopDirective(
1268 const OMPParallelGenericLoopDirective
*S
) {
1269 VisitOMPLoopDirective(S
);
1272 void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective(
1273 const OMPTargetParallelGenericLoopDirective
*S
) {
1274 VisitOMPLoopDirective(S
);
1277 void StmtProfiler::VisitExpr(const Expr
*S
) {
1281 void StmtProfiler::VisitConstantExpr(const ConstantExpr
*S
) {
1285 void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr
*S
) {
1288 VisitNestedNameSpecifier(S
->getQualifier());
1289 VisitDecl(S
->getDecl());
1291 ID
.AddBoolean(S
->hasExplicitTemplateArgs());
1292 if (S
->hasExplicitTemplateArgs())
1293 VisitTemplateArguments(S
->getTemplateArgs(), S
->getNumTemplateArgs());
1297 void StmtProfiler::VisitSYCLUniqueStableNameExpr(
1298 const SYCLUniqueStableNameExpr
*S
) {
1300 VisitType(S
->getTypeSourceInfo()->getType());
1303 void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr
*S
) {
1305 ID
.AddInteger(S
->getIdentKind());
1308 void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral
*S
) {
1310 S
->getValue().Profile(ID
);
1311 ID
.AddInteger(S
->getType()->castAs
<BuiltinType
>()->getKind());
1314 void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral
*S
) {
1316 S
->getValue().Profile(ID
);
1317 ID
.AddInteger(S
->getType()->castAs
<BuiltinType
>()->getKind());
1320 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral
*S
) {
1322 ID
.AddInteger(S
->getKind());
1323 ID
.AddInteger(S
->getValue());
1326 void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral
*S
) {
1328 S
->getValue().Profile(ID
);
1329 ID
.AddBoolean(S
->isExact());
1330 ID
.AddInteger(S
->getType()->castAs
<BuiltinType
>()->getKind());
1333 void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral
*S
) {
1337 void StmtProfiler::VisitStringLiteral(const StringLiteral
*S
) {
1339 ID
.AddString(S
->getBytes());
1340 ID
.AddInteger(S
->getKind());
1343 void StmtProfiler::VisitParenExpr(const ParenExpr
*S
) {
1347 void StmtProfiler::VisitParenListExpr(const ParenListExpr
*S
) {
1351 void StmtProfiler::VisitUnaryOperator(const UnaryOperator
*S
) {
1353 ID
.AddInteger(S
->getOpcode());
1356 void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr
*S
) {
1357 VisitType(S
->getTypeSourceInfo()->getType());
1358 unsigned n
= S
->getNumComponents();
1359 for (unsigned i
= 0; i
< n
; ++i
) {
1360 const OffsetOfNode
&ON
= S
->getComponent(i
);
1361 ID
.AddInteger(ON
.getKind());
1362 switch (ON
.getKind()) {
1363 case OffsetOfNode::Array
:
1364 // Expressions handled below.
1367 case OffsetOfNode::Field
:
1368 VisitDecl(ON
.getField());
1371 case OffsetOfNode::Identifier
:
1372 VisitIdentifierInfo(ON
.getFieldName());
1375 case OffsetOfNode::Base
:
1376 // These nodes are implicit, and therefore don't need profiling.
1385 StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr
*S
) {
1387 ID
.AddInteger(S
->getKind());
1388 if (S
->isArgumentType())
1389 VisitType(S
->getArgumentType());
1392 void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr
*S
) {
1396 void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr
*S
) {
1400 void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr
*S
) {
1404 void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr
*S
) {
1408 void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr
*S
) {
1410 for (unsigned I
= 0, E
= S
->numOfIterators(); I
< E
; ++I
)
1411 VisitDecl(S
->getIteratorDecl(I
));
1414 void StmtProfiler::VisitCallExpr(const CallExpr
*S
) {
1418 void StmtProfiler::VisitMemberExpr(const MemberExpr
*S
) {
1420 VisitDecl(S
->getMemberDecl());
1422 VisitNestedNameSpecifier(S
->getQualifier());
1423 ID
.AddBoolean(S
->isArrow());
1426 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr
*S
) {
1428 ID
.AddBoolean(S
->isFileScope());
1431 void StmtProfiler::VisitCastExpr(const CastExpr
*S
) {
1435 void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr
*S
) {
1437 ID
.AddInteger(S
->getValueKind());
1440 void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr
*S
) {
1442 VisitType(S
->getTypeAsWritten());
1445 void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr
*S
) {
1446 VisitExplicitCastExpr(S
);
1449 void StmtProfiler::VisitBinaryOperator(const BinaryOperator
*S
) {
1451 ID
.AddInteger(S
->getOpcode());
1455 StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator
*S
) {
1456 VisitBinaryOperator(S
);
1459 void StmtProfiler::VisitConditionalOperator(const ConditionalOperator
*S
) {
1463 void StmtProfiler::VisitBinaryConditionalOperator(
1464 const BinaryConditionalOperator
*S
) {
1468 void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr
*S
) {
1470 VisitDecl(S
->getLabel());
1473 void StmtProfiler::VisitStmtExpr(const StmtExpr
*S
) {
1477 void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr
*S
) {
1481 void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr
*S
) {
1485 void StmtProfiler::VisitChooseExpr(const ChooseExpr
*S
) {
1489 void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr
*S
) {
1493 void StmtProfiler::VisitVAArgExpr(const VAArgExpr
*S
) {
1497 void StmtProfiler::VisitInitListExpr(const InitListExpr
*S
) {
1498 if (S
->getSyntacticForm()) {
1499 VisitInitListExpr(S
->getSyntacticForm());
1506 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr
*S
) {
1508 ID
.AddBoolean(S
->usesGNUSyntax());
1509 for (const Designator
&D
: S
->designators()) {
1510 if (D
.isFieldDesignator()) {
1512 VisitName(D
.getFieldName());
1516 if (D
.isArrayDesignator()) {
1519 assert(D
.isArrayRangeDesignator());
1522 ID
.AddInteger(D
.getFirstExprIndex());
1526 // Seems that if VisitInitListExpr() only works on the syntactic form of an
1527 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
1528 void StmtProfiler::VisitDesignatedInitUpdateExpr(
1529 const DesignatedInitUpdateExpr
*S
) {
1530 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
1534 void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr
*S
) {
1538 void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr
*S
) {
1542 void StmtProfiler::VisitNoInitExpr(const NoInitExpr
*S
) {
1543 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
1546 void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr
*S
) {
1550 void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr
*S
) {
1552 VisitName(&S
->getAccessor());
1555 void StmtProfiler::VisitBlockExpr(const BlockExpr
*S
) {
1557 VisitDecl(S
->getBlockDecl());
1560 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr
*S
) {
1562 for (const GenericSelectionExpr::ConstAssociation Assoc
:
1563 S
->associations()) {
1564 QualType T
= Assoc
.getType();
1566 ID
.AddPointer(nullptr);
1569 VisitExpr(Assoc
.getAssociationExpr());
1573 void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr
*S
) {
1575 for (PseudoObjectExpr::const_semantics_iterator
1576 i
= S
->semantics_begin(), e
= S
->semantics_end(); i
!= e
; ++i
)
1577 // Normally, we would not profile the source expressions of OVEs.
1578 if (const OpaqueValueExpr
*OVE
= dyn_cast
<OpaqueValueExpr
>(*i
))
1579 Visit(OVE
->getSourceExpr());
1582 void StmtProfiler::VisitAtomicExpr(const AtomicExpr
*S
) {
1584 ID
.AddInteger(S
->getOp());
1587 void StmtProfiler::VisitConceptSpecializationExpr(
1588 const ConceptSpecializationExpr
*S
) {
1590 VisitDecl(S
->getNamedConcept());
1591 for (const TemplateArgument
&Arg
: S
->getTemplateArguments())
1592 VisitTemplateArgument(Arg
);
1595 void StmtProfiler::VisitRequiresExpr(const RequiresExpr
*S
) {
1597 ID
.AddInteger(S
->getLocalParameters().size());
1598 for (ParmVarDecl
*LocalParam
: S
->getLocalParameters())
1599 VisitDecl(LocalParam
);
1600 ID
.AddInteger(S
->getRequirements().size());
1601 for (concepts::Requirement
*Req
: S
->getRequirements()) {
1602 if (auto *TypeReq
= dyn_cast
<concepts::TypeRequirement
>(Req
)) {
1603 ID
.AddInteger(concepts::Requirement::RK_Type
);
1604 ID
.AddBoolean(TypeReq
->isSubstitutionFailure());
1605 if (!TypeReq
->isSubstitutionFailure())
1606 VisitType(TypeReq
->getType()->getType());
1607 } else if (auto *ExprReq
= dyn_cast
<concepts::ExprRequirement
>(Req
)) {
1608 ID
.AddInteger(concepts::Requirement::RK_Compound
);
1609 ID
.AddBoolean(ExprReq
->isExprSubstitutionFailure());
1610 if (!ExprReq
->isExprSubstitutionFailure())
1611 Visit(ExprReq
->getExpr());
1612 // C++2a [expr.prim.req.compound]p1 Example:
1613 // [...] The compound-requirement in C1 requires that x++ is a valid
1614 // expression. It is equivalent to the simple-requirement x++; [...]
1615 // We therefore do not profile isSimple() here.
1616 ID
.AddBoolean(ExprReq
->getNoexceptLoc().isValid());
1617 const concepts::ExprRequirement::ReturnTypeRequirement
&RetReq
=
1618 ExprReq
->getReturnTypeRequirement();
1619 if (RetReq
.isEmpty()) {
1621 } else if (RetReq
.isTypeConstraint()) {
1623 Visit(RetReq
.getTypeConstraint()->getImmediatelyDeclaredConstraint());
1625 assert(RetReq
.isSubstitutionFailure());
1629 ID
.AddInteger(concepts::Requirement::RK_Nested
);
1630 auto *NestedReq
= cast
<concepts::NestedRequirement
>(Req
);
1631 ID
.AddBoolean(NestedReq
->hasInvalidConstraint());
1632 if (!NestedReq
->hasInvalidConstraint())
1633 Visit(NestedReq
->getConstraintExpr());
1638 static Stmt::StmtClass
DecodeOperatorCall(const CXXOperatorCallExpr
*S
,
1639 UnaryOperatorKind
&UnaryOp
,
1640 BinaryOperatorKind
&BinaryOp
) {
1641 switch (S
->getOperator()) {
1646 case OO_Array_Delete
:
1648 case OO_Conditional
:
1649 case NUM_OVERLOADED_OPERATORS
:
1650 llvm_unreachable("Invalid operator call kind");
1653 if (S
->getNumArgs() == 1) {
1655 return Stmt::UnaryOperatorClass
;
1659 return Stmt::BinaryOperatorClass
;
1662 if (S
->getNumArgs() == 1) {
1664 return Stmt::UnaryOperatorClass
;
1668 return Stmt::BinaryOperatorClass
;
1671 if (S
->getNumArgs() == 1) {
1673 return Stmt::UnaryOperatorClass
;
1677 return Stmt::BinaryOperatorClass
;
1681 return Stmt::BinaryOperatorClass
;
1685 return Stmt::BinaryOperatorClass
;
1689 return Stmt::BinaryOperatorClass
;
1692 if (S
->getNumArgs() == 1) {
1693 UnaryOp
= UO_AddrOf
;
1694 return Stmt::UnaryOperatorClass
;
1698 return Stmt::BinaryOperatorClass
;
1702 return Stmt::BinaryOperatorClass
;
1706 return Stmt::UnaryOperatorClass
;
1710 return Stmt::UnaryOperatorClass
;
1713 BinaryOp
= BO_Assign
;
1714 return Stmt::BinaryOperatorClass
;
1718 return Stmt::BinaryOperatorClass
;
1722 return Stmt::BinaryOperatorClass
;
1725 BinaryOp
= BO_AddAssign
;
1726 return Stmt::CompoundAssignOperatorClass
;
1729 BinaryOp
= BO_SubAssign
;
1730 return Stmt::CompoundAssignOperatorClass
;
1733 BinaryOp
= BO_MulAssign
;
1734 return Stmt::CompoundAssignOperatorClass
;
1737 BinaryOp
= BO_DivAssign
;
1738 return Stmt::CompoundAssignOperatorClass
;
1740 case OO_PercentEqual
:
1741 BinaryOp
= BO_RemAssign
;
1742 return Stmt::CompoundAssignOperatorClass
;
1745 BinaryOp
= BO_XorAssign
;
1746 return Stmt::CompoundAssignOperatorClass
;
1749 BinaryOp
= BO_AndAssign
;
1750 return Stmt::CompoundAssignOperatorClass
;
1753 BinaryOp
= BO_OrAssign
;
1754 return Stmt::CompoundAssignOperatorClass
;
1758 return Stmt::BinaryOperatorClass
;
1760 case OO_GreaterGreater
:
1762 return Stmt::BinaryOperatorClass
;
1764 case OO_LessLessEqual
:
1765 BinaryOp
= BO_ShlAssign
;
1766 return Stmt::CompoundAssignOperatorClass
;
1768 case OO_GreaterGreaterEqual
:
1769 BinaryOp
= BO_ShrAssign
;
1770 return Stmt::CompoundAssignOperatorClass
;
1774 return Stmt::BinaryOperatorClass
;
1776 case OO_ExclaimEqual
:
1778 return Stmt::BinaryOperatorClass
;
1782 return Stmt::BinaryOperatorClass
;
1784 case OO_GreaterEqual
:
1786 return Stmt::BinaryOperatorClass
;
1790 return Stmt::BinaryOperatorClass
;
1794 return Stmt::BinaryOperatorClass
;
1798 return Stmt::BinaryOperatorClass
;
1801 UnaryOp
= S
->getNumArgs() == 1? UO_PreInc
1803 return Stmt::UnaryOperatorClass
;
1806 UnaryOp
= S
->getNumArgs() == 1? UO_PreDec
1808 return Stmt::UnaryOperatorClass
;
1811 BinaryOp
= BO_Comma
;
1812 return Stmt::BinaryOperatorClass
;
1815 BinaryOp
= BO_PtrMemI
;
1816 return Stmt::BinaryOperatorClass
;
1819 return Stmt::ArraySubscriptExprClass
;
1822 return Stmt::CallExprClass
;
1825 UnaryOp
= UO_Coawait
;
1826 return Stmt::UnaryOperatorClass
;
1829 llvm_unreachable("Invalid overloaded operator expression");
1832 #if defined(_MSC_VER) && !defined(__clang__)
1833 #if _MSC_VER == 1911
1834 // Work around https://developercommunity.visualstudio.com/content/problem/84002/clang-cl-when-built-with-vc-2017-crashes-cause-vc.html
1835 // MSVC 2017 update 3 miscompiles this function, and a clang built with it
1836 // will crash in stage 2 of a bootstrap build.
1837 #pragma optimize("", off)
1841 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr
*S
) {
1842 if (S
->isTypeDependent()) {
1843 // Type-dependent operator calls are profiled like their underlying
1844 // syntactic operator.
1846 // An operator call to operator-> is always implicit, so just skip it. The
1847 // enclosing MemberExpr will profile the actual member access.
1848 if (S
->getOperator() == OO_Arrow
)
1849 return Visit(S
->getArg(0));
1851 UnaryOperatorKind UnaryOp
= UO_Extension
;
1852 BinaryOperatorKind BinaryOp
= BO_Comma
;
1853 Stmt::StmtClass SC
= DecodeOperatorCall(S
, UnaryOp
, BinaryOp
);
1856 for (unsigned I
= 0, N
= S
->getNumArgs(); I
!= N
; ++I
)
1857 Visit(S
->getArg(I
));
1858 if (SC
== Stmt::UnaryOperatorClass
)
1859 ID
.AddInteger(UnaryOp
);
1860 else if (SC
== Stmt::BinaryOperatorClass
||
1861 SC
== Stmt::CompoundAssignOperatorClass
)
1862 ID
.AddInteger(BinaryOp
);
1864 assert(SC
== Stmt::ArraySubscriptExprClass
|| SC
== Stmt::CallExprClass
);
1870 ID
.AddInteger(S
->getOperator());
1873 void StmtProfiler::VisitCXXRewrittenBinaryOperator(
1874 const CXXRewrittenBinaryOperator
*S
) {
1875 // If a rewritten operator were ever to be type-dependent, we should profile
1876 // it following its syntactic operator.
1877 assert(!S
->isTypeDependent() &&
1878 "resolved rewritten operator should never be type-dependent");
1879 ID
.AddBoolean(S
->isReversed());
1880 VisitExpr(S
->getSemanticForm());
1883 #if defined(_MSC_VER) && !defined(__clang__)
1884 #if _MSC_VER == 1911
1885 #pragma optimize("", on)
1889 void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr
*S
) {
1893 void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr
*S
) {
1897 void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr
*S
) {
1901 void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr
*S
) {
1902 VisitExplicitCastExpr(S
);
1905 void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr
*S
) {
1906 VisitCXXNamedCastExpr(S
);
1909 void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr
*S
) {
1910 VisitCXXNamedCastExpr(S
);
1914 StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr
*S
) {
1915 VisitCXXNamedCastExpr(S
);
1918 void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr
*S
) {
1919 VisitCXXNamedCastExpr(S
);
1922 void StmtProfiler::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr
*S
) {
1924 VisitType(S
->getTypeInfoAsWritten()->getType());
1927 void StmtProfiler::VisitCXXAddrspaceCastExpr(const CXXAddrspaceCastExpr
*S
) {
1928 VisitCXXNamedCastExpr(S
);
1931 void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral
*S
) {
1935 void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr
*S
) {
1937 ID
.AddBoolean(S
->getValue());
1940 void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr
*S
) {
1944 void StmtProfiler::VisitCXXStdInitializerListExpr(
1945 const CXXStdInitializerListExpr
*S
) {
1949 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr
*S
) {
1951 if (S
->isTypeOperand())
1952 VisitType(S
->getTypeOperandSourceInfo()->getType());
1955 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr
*S
) {
1957 if (S
->isTypeOperand())
1958 VisitType(S
->getTypeOperandSourceInfo()->getType());
1961 void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr
*S
) {
1963 VisitDecl(S
->getPropertyDecl());
1966 void StmtProfiler::VisitMSPropertySubscriptExpr(
1967 const MSPropertySubscriptExpr
*S
) {
1971 void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr
*S
) {
1973 ID
.AddBoolean(S
->isImplicit());
1976 void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr
*S
) {
1980 void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr
*S
) {
1982 VisitDecl(S
->getParam());
1985 void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr
*S
) {
1987 VisitDecl(S
->getField());
1990 void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr
*S
) {
1993 const_cast<CXXDestructorDecl
*>(S
->getTemporary()->getDestructor()));
1996 void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr
*S
) {
1998 VisitDecl(S
->getConstructor());
1999 ID
.AddBoolean(S
->isElidable());
2002 void StmtProfiler::VisitCXXInheritedCtorInitExpr(
2003 const CXXInheritedCtorInitExpr
*S
) {
2005 VisitDecl(S
->getConstructor());
2008 void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr
*S
) {
2009 VisitExplicitCastExpr(S
);
2013 StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr
*S
) {
2014 VisitCXXConstructExpr(S
);
2018 StmtProfiler::VisitLambdaExpr(const LambdaExpr
*S
) {
2019 // Do not recursively visit the children of this expression. Profiling the
2020 // body would result in unnecessary work, and is not safe to do during
2022 VisitStmtNoChildren(S
);
2024 // C++20 [temp.over.link]p5:
2025 // Two lambda-expressions are never considered equivalent.
2026 VisitDecl(S
->getLambdaClass());
2030 StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr
*S
) {
2034 void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr
*S
) {
2036 ID
.AddBoolean(S
->isGlobalDelete());
2037 ID
.AddBoolean(S
->isArrayForm());
2038 VisitDecl(S
->getOperatorDelete());
2041 void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr
*S
) {
2043 VisitType(S
->getAllocatedType());
2044 VisitDecl(S
->getOperatorNew());
2045 VisitDecl(S
->getOperatorDelete());
2046 ID
.AddBoolean(S
->isArray());
2047 ID
.AddInteger(S
->getNumPlacementArgs());
2048 ID
.AddBoolean(S
->isGlobalNew());
2049 ID
.AddBoolean(S
->isParenTypeId());
2050 ID
.AddInteger(S
->getInitializationStyle());
2054 StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr
*S
) {
2056 ID
.AddBoolean(S
->isArrow());
2057 VisitNestedNameSpecifier(S
->getQualifier());
2058 ID
.AddBoolean(S
->getScopeTypeInfo() != nullptr);
2059 if (S
->getScopeTypeInfo())
2060 VisitType(S
->getScopeTypeInfo()->getType());
2061 ID
.AddBoolean(S
->getDestroyedTypeInfo() != nullptr);
2062 if (S
->getDestroyedTypeInfo())
2063 VisitType(S
->getDestroyedType());
2065 VisitIdentifierInfo(S
->getDestroyedTypeIdentifier());
2068 void StmtProfiler::VisitOverloadExpr(const OverloadExpr
*S
) {
2070 VisitNestedNameSpecifier(S
->getQualifier());
2071 VisitName(S
->getName(), /*TreatAsDecl*/ true);
2072 ID
.AddBoolean(S
->hasExplicitTemplateArgs());
2073 if (S
->hasExplicitTemplateArgs())
2074 VisitTemplateArguments(S
->getTemplateArgs(), S
->getNumTemplateArgs());
2078 StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr
*S
) {
2079 VisitOverloadExpr(S
);
2082 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr
*S
) {
2084 ID
.AddInteger(S
->getTrait());
2085 ID
.AddInteger(S
->getNumArgs());
2086 for (unsigned I
= 0, N
= S
->getNumArgs(); I
!= N
; ++I
)
2087 VisitType(S
->getArg(I
)->getType());
2090 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr
*S
) {
2092 ID
.AddInteger(S
->getTrait());
2093 VisitType(S
->getQueriedType());
2096 void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr
*S
) {
2098 ID
.AddInteger(S
->getTrait());
2099 VisitExpr(S
->getQueriedExpression());
2102 void StmtProfiler::VisitDependentScopeDeclRefExpr(
2103 const DependentScopeDeclRefExpr
*S
) {
2105 VisitName(S
->getDeclName());
2106 VisitNestedNameSpecifier(S
->getQualifier());
2107 ID
.AddBoolean(S
->hasExplicitTemplateArgs());
2108 if (S
->hasExplicitTemplateArgs())
2109 VisitTemplateArguments(S
->getTemplateArgs(), S
->getNumTemplateArgs());
2112 void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups
*S
) {
2116 void StmtProfiler::VisitCXXUnresolvedConstructExpr(
2117 const CXXUnresolvedConstructExpr
*S
) {
2119 VisitType(S
->getTypeAsWritten());
2120 ID
.AddInteger(S
->isListInitialization());
2123 void StmtProfiler::VisitCXXDependentScopeMemberExpr(
2124 const CXXDependentScopeMemberExpr
*S
) {
2125 ID
.AddBoolean(S
->isImplicitAccess());
2126 if (!S
->isImplicitAccess()) {
2128 ID
.AddBoolean(S
->isArrow());
2130 VisitNestedNameSpecifier(S
->getQualifier());
2131 VisitName(S
->getMember());
2132 ID
.AddBoolean(S
->hasExplicitTemplateArgs());
2133 if (S
->hasExplicitTemplateArgs())
2134 VisitTemplateArguments(S
->getTemplateArgs(), S
->getNumTemplateArgs());
2137 void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr
*S
) {
2138 ID
.AddBoolean(S
->isImplicitAccess());
2139 if (!S
->isImplicitAccess()) {
2141 ID
.AddBoolean(S
->isArrow());
2143 VisitNestedNameSpecifier(S
->getQualifier());
2144 VisitName(S
->getMemberName());
2145 ID
.AddBoolean(S
->hasExplicitTemplateArgs());
2146 if (S
->hasExplicitTemplateArgs())
2147 VisitTemplateArguments(S
->getTemplateArgs(), S
->getNumTemplateArgs());
2150 void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr
*S
) {
2154 void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr
*S
) {
2158 void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr
*S
) {
2160 VisitDecl(S
->getPack());
2161 if (S
->isPartiallySubstituted()) {
2162 auto Args
= S
->getPartialArguments();
2163 ID
.AddInteger(Args
.size());
2164 for (const auto &TA
: Args
)
2165 VisitTemplateArgument(TA
);
2171 void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
2172 const SubstNonTypeTemplateParmPackExpr
*S
) {
2174 VisitDecl(S
->getParameterPack());
2175 VisitTemplateArgument(S
->getArgumentPack());
2178 void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
2179 const SubstNonTypeTemplateParmExpr
*E
) {
2180 // Profile exactly as the replacement expression.
2181 Visit(E
->getReplacement());
2184 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr
*S
) {
2186 VisitDecl(S
->getParameterPack());
2187 ID
.AddInteger(S
->getNumExpansions());
2188 for (FunctionParmPackExpr::iterator I
= S
->begin(), E
= S
->end(); I
!= E
; ++I
)
2192 void StmtProfiler::VisitMaterializeTemporaryExpr(
2193 const MaterializeTemporaryExpr
*S
) {
2197 void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr
*S
) {
2199 ID
.AddInteger(S
->getOperator());
2202 void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr
*S
) {
2206 void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt
*S
) {
2210 void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt
*S
) {
2214 void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr
*S
) {
2218 void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr
*S
) {
2222 void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr
*S
) {
2226 void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr
*E
) {
2230 void StmtProfiler::VisitTypoExpr(const TypoExpr
*E
) {
2234 void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr
*E
) {
2238 void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr
*E
) { VisitExpr(E
); }
2240 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral
*S
) {
2244 void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr
*E
) {
2248 void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral
*E
) {
2252 void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral
*E
) {
2256 void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr
*S
) {
2258 VisitType(S
->getEncodedType());
2261 void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr
*S
) {
2263 VisitName(S
->getSelector());
2266 void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr
*S
) {
2268 VisitDecl(S
->getProtocol());
2271 void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*S
) {
2273 VisitDecl(S
->getDecl());
2274 ID
.AddBoolean(S
->isArrow());
2275 ID
.AddBoolean(S
->isFreeIvar());
2278 void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*S
) {
2280 if (S
->isImplicitProperty()) {
2281 VisitDecl(S
->getImplicitPropertyGetter());
2282 VisitDecl(S
->getImplicitPropertySetter());
2284 VisitDecl(S
->getExplicitProperty());
2286 if (S
->isSuperReceiver()) {
2287 ID
.AddBoolean(S
->isSuperReceiver());
2288 VisitType(S
->getSuperReceiverType());
2292 void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr
*S
) {
2294 VisitDecl(S
->getAtIndexMethodDecl());
2295 VisitDecl(S
->setAtIndexMethodDecl());
2298 void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr
*S
) {
2300 VisitName(S
->getSelector());
2301 VisitDecl(S
->getMethodDecl());
2304 void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr
*S
) {
2306 ID
.AddBoolean(S
->isArrow());
2309 void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr
*S
) {
2311 ID
.AddBoolean(S
->getValue());
2314 void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
2315 const ObjCIndirectCopyRestoreExpr
*S
) {
2317 ID
.AddBoolean(S
->shouldCopy());
2320 void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr
*S
) {
2321 VisitExplicitCastExpr(S
);
2322 ID
.AddBoolean(S
->getBridgeKind());
2325 void StmtProfiler::VisitObjCAvailabilityCheckExpr(
2326 const ObjCAvailabilityCheckExpr
*S
) {
2330 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc
*Args
,
2332 ID
.AddInteger(NumArgs
);
2333 for (unsigned I
= 0; I
!= NumArgs
; ++I
)
2334 VisitTemplateArgument(Args
[I
].getArgument());
2337 void StmtProfiler::VisitTemplateArgument(const TemplateArgument
&Arg
) {
2338 // Mostly repetitive with TemplateArgument::Profile!
2339 ID
.AddInteger(Arg
.getKind());
2340 switch (Arg
.getKind()) {
2341 case TemplateArgument::Null
:
2344 case TemplateArgument::Type
:
2345 VisitType(Arg
.getAsType());
2348 case TemplateArgument::Template
:
2349 case TemplateArgument::TemplateExpansion
:
2350 VisitTemplateName(Arg
.getAsTemplateOrTemplatePattern());
2353 case TemplateArgument::Declaration
:
2354 VisitType(Arg
.getParamTypeForDecl());
2355 // FIXME: Do we need to recursively decompose template parameter objects?
2356 VisitDecl(Arg
.getAsDecl());
2359 case TemplateArgument::NullPtr
:
2360 VisitType(Arg
.getNullPtrType());
2363 case TemplateArgument::Integral
:
2364 VisitType(Arg
.getIntegralType());
2365 Arg
.getAsIntegral().Profile(ID
);
2368 case TemplateArgument::Expression
:
2369 Visit(Arg
.getAsExpr());
2372 case TemplateArgument::Pack
:
2373 for (const auto &P
: Arg
.pack_elements())
2374 VisitTemplateArgument(P
);
2379 void Stmt::Profile(llvm::FoldingSetNodeID
&ID
, const ASTContext
&Context
,
2380 bool Canonical
) const {
2381 StmtProfilerWithPointers
Profiler(ID
, Context
, Canonical
);
2382 Profiler
.Visit(this);
2385 void Stmt::ProcessODRHash(llvm::FoldingSetNodeID
&ID
,
2386 class ODRHash
&Hash
) const {
2387 StmtProfilerWithoutPointers
Profiler(ID
, Hash
);
2388 Profiler
.Visit(this);