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