llvm-project

Форк
0
/
StmtProfile.cpp 
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"
25
using namespace clang;
26

27
namespace {
28
  class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
29
  protected:
30
    llvm::FoldingSetNodeID &ID;
31
    bool Canonical;
32
    bool ProfileLambdaExpr;
33

34
  public:
35
    StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical,
36
                 bool ProfileLambdaExpr)
37
        : ID(ID), Canonical(Canonical), ProfileLambdaExpr(ProfileLambdaExpr) {}
38

39
    virtual ~StmtProfiler() {}
40

41
    void VisitStmt(const Stmt *S);
42

43
    void VisitStmtNoChildren(const Stmt *S) {
44
      HandleStmtClass(S->getStmtClass());
45
    }
46

47
    virtual void HandleStmtClass(Stmt::StmtClass SC) = 0;
48

49
#define STMT(Node, Base) void Visit##Node(const Node *S);
50
#include "clang/AST/StmtNodes.inc"
51

52
    /// Visit a declaration that is referenced within an expression
53
    /// or statement.
54
    virtual void VisitDecl(const Decl *D) = 0;
55

56
    /// Visit a type that is referenced within an expression or
57
    /// statement.
58
    virtual void VisitType(QualType T) = 0;
59

60
    /// Visit a name that occurs within an expression or statement.
61
    virtual void VisitName(DeclarationName Name, bool TreatAsDecl = false) = 0;
62

63
    /// Visit identifiers that are not in Decl's or Type's.
64
    virtual void VisitIdentifierInfo(const IdentifierInfo *II) = 0;
65

66
    /// Visit a nested-name-specifier that occurs within an expression
67
    /// or statement.
68
    virtual void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) = 0;
69

70
    /// Visit a template name that occurs within an expression or
71
    /// statement.
72
    virtual void VisitTemplateName(TemplateName Name) = 0;
73

74
    /// Visit template arguments that occur within an expression or
75
    /// statement.
76
    void VisitTemplateArguments(const TemplateArgumentLoc *Args,
77
                                unsigned NumArgs);
78

79
    /// Visit a single template argument.
80
    void VisitTemplateArgument(const TemplateArgument &Arg);
81
  };
82

83
  class StmtProfilerWithPointers : public StmtProfiler {
84
    const ASTContext &Context;
85

86
  public:
87
    StmtProfilerWithPointers(llvm::FoldingSetNodeID &ID,
88
                             const ASTContext &Context, bool Canonical,
89
                             bool ProfileLambdaExpr)
90
        : StmtProfiler(ID, Canonical, ProfileLambdaExpr), Context(Context) {}
91

92
  private:
93
    void HandleStmtClass(Stmt::StmtClass SC) override {
94
      ID.AddInteger(SC);
95
    }
96

97
    void VisitDecl(const Decl *D) override {
98
      ID.AddInteger(D ? D->getKind() : 0);
99

100
      if (Canonical && D) {
101
        if (const NonTypeTemplateParmDecl *NTTP =
102
                dyn_cast<NonTypeTemplateParmDecl>(D)) {
103
          ID.AddInteger(NTTP->getDepth());
104
          ID.AddInteger(NTTP->getIndex());
105
          ID.AddBoolean(NTTP->isParameterPack());
106
          // C++20 [temp.over.link]p6:
107
          //   Two template-parameters are equivalent under the following
108
          //   conditions: [...] if they declare non-type template parameters,
109
          //   they have equivalent types ignoring the use of type-constraints
110
          //   for placeholder types
111
          //
112
          // TODO: Why do we need to include the type in the profile? It's not
113
          // part of the mangling.
114
          VisitType(Context.getUnconstrainedType(NTTP->getType()));
115
          return;
116
        }
117

118
        if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
119
          // The Itanium C++ ABI uses the type, scope depth, and scope
120
          // index of a parameter when mangling expressions that involve
121
          // function parameters, so we will use the parameter's type for
122
          // establishing function parameter identity. That way, our
123
          // definition of "equivalent" (per C++ [temp.over.link]) is at
124
          // least as strong as the definition of "equivalent" used for
125
          // name mangling.
126
          //
127
          // TODO: The Itanium C++ ABI only uses the top-level cv-qualifiers,
128
          // not the entirety of the type.
129
          VisitType(Parm->getType());
130
          ID.AddInteger(Parm->getFunctionScopeDepth());
131
          ID.AddInteger(Parm->getFunctionScopeIndex());
132
          return;
133
        }
134

135
        if (const TemplateTypeParmDecl *TTP =
136
                dyn_cast<TemplateTypeParmDecl>(D)) {
137
          ID.AddInteger(TTP->getDepth());
138
          ID.AddInteger(TTP->getIndex());
139
          ID.AddBoolean(TTP->isParameterPack());
140
          return;
141
        }
142

143
        if (const TemplateTemplateParmDecl *TTP =
144
                dyn_cast<TemplateTemplateParmDecl>(D)) {
145
          ID.AddInteger(TTP->getDepth());
146
          ID.AddInteger(TTP->getIndex());
147
          ID.AddBoolean(TTP->isParameterPack());
148
          return;
149
        }
150
      }
151

152
      ID.AddPointer(D ? D->getCanonicalDecl() : nullptr);
153
    }
154

155
    void VisitType(QualType T) override {
156
      if (Canonical && !T.isNull())
157
        T = Context.getCanonicalType(T);
158

159
      ID.AddPointer(T.getAsOpaquePtr());
160
    }
161

162
    void VisitName(DeclarationName Name, bool /*TreatAsDecl*/) override {
163
      ID.AddPointer(Name.getAsOpaquePtr());
164
    }
165

166
    void VisitIdentifierInfo(const IdentifierInfo *II) override {
167
      ID.AddPointer(II);
168
    }
169

170
    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
171
      if (Canonical)
172
        NNS = Context.getCanonicalNestedNameSpecifier(NNS);
173
      ID.AddPointer(NNS);
174
    }
175

176
    void VisitTemplateName(TemplateName Name) override {
177
      if (Canonical)
178
        Name = Context.getCanonicalTemplateName(Name);
179

180
      Name.Profile(ID);
181
    }
182
  };
183

184
  class StmtProfilerWithoutPointers : public StmtProfiler {
185
    ODRHash &Hash;
186
  public:
187
    StmtProfilerWithoutPointers(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
188
        : StmtProfiler(ID, /*Canonical=*/false, /*ProfileLambdaExpr=*/false),
189
          Hash(Hash) {}
190

191
  private:
192
    void HandleStmtClass(Stmt::StmtClass SC) override {
193
      if (SC == Stmt::UnresolvedLookupExprClass) {
194
        // Pretend that the name looked up is a Decl due to how templates
195
        // handle some Decl lookups.
196
        ID.AddInteger(Stmt::DeclRefExprClass);
197
      } else {
198
        ID.AddInteger(SC);
199
      }
200
    }
201

202
    void VisitType(QualType T) override {
203
      Hash.AddQualType(T);
204
    }
205

206
    void VisitName(DeclarationName Name, bool TreatAsDecl) override {
207
      if (TreatAsDecl) {
208
        // A Decl can be null, so each Decl is preceded by a boolean to
209
        // store its nullness.  Add a boolean here to match.
210
        ID.AddBoolean(true);
211
      }
212
      Hash.AddDeclarationName(Name, TreatAsDecl);
213
    }
214
    void VisitIdentifierInfo(const IdentifierInfo *II) override {
215
      ID.AddBoolean(II);
216
      if (II) {
217
        Hash.AddIdentifierInfo(II);
218
      }
219
    }
220
    void VisitDecl(const Decl *D) override {
221
      ID.AddBoolean(D);
222
      if (D) {
223
        Hash.AddDecl(D);
224
      }
225
    }
226
    void VisitTemplateName(TemplateName Name) override {
227
      Hash.AddTemplateName(Name);
228
    }
229
    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
230
      ID.AddBoolean(NNS);
231
      if (NNS) {
232
        Hash.AddNestedNameSpecifier(NNS);
233
      }
234
    }
235
  };
236
}
237

238
void StmtProfiler::VisitStmt(const Stmt *S) {
239
  assert(S && "Requires non-null Stmt pointer");
240

241
  VisitStmtNoChildren(S);
242

243
  for (const Stmt *SubStmt : S->children()) {
244
    if (SubStmt)
245
      Visit(SubStmt);
246
    else
247
      ID.AddInteger(0);
248
  }
249
}
250

251
void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
252
  VisitStmt(S);
253
  for (const auto *D : S->decls())
254
    VisitDecl(D);
255
}
256

257
void StmtProfiler::VisitNullStmt(const NullStmt *S) {
258
  VisitStmt(S);
259
}
260

261
void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
262
  VisitStmt(S);
263
}
264

265
void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
266
  VisitStmt(S);
267
}
268

269
void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
270
  VisitStmt(S);
271
}
272

273
void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
274
  VisitStmt(S);
275
  VisitDecl(S->getDecl());
276
}
277

278
void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
279
  VisitStmt(S);
280
  // TODO: maybe visit attributes?
281
}
282

283
void StmtProfiler::VisitIfStmt(const IfStmt *S) {
284
  VisitStmt(S);
285
  VisitDecl(S->getConditionVariable());
286
}
287

288
void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
289
  VisitStmt(S);
290
  VisitDecl(S->getConditionVariable());
291
}
292

293
void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
294
  VisitStmt(S);
295
  VisitDecl(S->getConditionVariable());
296
}
297

298
void StmtProfiler::VisitDoStmt(const DoStmt *S) {
299
  VisitStmt(S);
300
}
301

302
void StmtProfiler::VisitForStmt(const ForStmt *S) {
303
  VisitStmt(S);
304
}
305

306
void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
307
  VisitStmt(S);
308
  VisitDecl(S->getLabel());
309
}
310

311
void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
312
  VisitStmt(S);
313
}
314

315
void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
316
  VisitStmt(S);
317
}
318

319
void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
320
  VisitStmt(S);
321
}
322

323
void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
324
  VisitStmt(S);
325
}
326

327
void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
328
  VisitStmt(S);
329
  ID.AddBoolean(S->isVolatile());
330
  ID.AddBoolean(S->isSimple());
331
  VisitStringLiteral(S->getAsmString());
332
  ID.AddInteger(S->getNumOutputs());
333
  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
334
    ID.AddString(S->getOutputName(I));
335
    VisitStringLiteral(S->getOutputConstraintLiteral(I));
336
  }
337
  ID.AddInteger(S->getNumInputs());
338
  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
339
    ID.AddString(S->getInputName(I));
340
    VisitStringLiteral(S->getInputConstraintLiteral(I));
341
  }
342
  ID.AddInteger(S->getNumClobbers());
343
  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
344
    VisitStringLiteral(S->getClobberStringLiteral(I));
345
  ID.AddInteger(S->getNumLabels());
346
  for (auto *L : S->labels())
347
    VisitDecl(L->getLabel());
348
}
349

350
void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) {
351
  // FIXME: Implement MS style inline asm statement profiler.
352
  VisitStmt(S);
353
}
354

355
void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
356
  VisitStmt(S);
357
  VisitType(S->getCaughtType());
358
}
359

360
void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
361
  VisitStmt(S);
362
}
363

364
void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
365
  VisitStmt(S);
366
}
367

368
void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
369
  VisitStmt(S);
370
  ID.AddBoolean(S->isIfExists());
371
  VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
372
  VisitName(S->getNameInfo().getName());
373
}
374

375
void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
376
  VisitStmt(S);
377
}
378

379
void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
380
  VisitStmt(S);
381
}
382

383
void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
384
  VisitStmt(S);
385
}
386

387
void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
388
  VisitStmt(S);
389
}
390

391
void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
392
  VisitStmt(S);
393
}
394

395
void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
396
  VisitStmt(S);
397
}
398

399
void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
400
  VisitStmt(S);
401
  ID.AddBoolean(S->hasEllipsis());
402
  if (S->getCatchParamDecl())
403
    VisitType(S->getCatchParamDecl()->getType());
404
}
405

406
void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
407
  VisitStmt(S);
408
}
409

410
void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
411
  VisitStmt(S);
412
}
413

414
void
415
StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
416
  VisitStmt(S);
417
}
418

419
void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
420
  VisitStmt(S);
421
}
422

423
void
424
StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
425
  VisitStmt(S);
426
}
427

428
namespace {
429
class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
430
  StmtProfiler *Profiler;
431
  /// Process clauses with list of variables.
432
  template <typename T>
433
  void VisitOMPClauseList(T *Node);
434

435
public:
436
  OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
437
#define GEN_CLANG_CLAUSE_CLASS
438
#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
439
#include "llvm/Frontend/OpenMP/OMP.inc"
440
  void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
441
  void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
442
};
443

444
void OMPClauseProfiler::VistOMPClauseWithPreInit(
445
    const OMPClauseWithPreInit *C) {
446
  if (auto *S = C->getPreInitStmt())
447
    Profiler->VisitStmt(S);
448
}
449

450
void OMPClauseProfiler::VistOMPClauseWithPostUpdate(
451
    const OMPClauseWithPostUpdate *C) {
452
  VistOMPClauseWithPreInit(C);
453
  if (auto *E = C->getPostUpdateExpr())
454
    Profiler->VisitStmt(E);
455
}
456

457
void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
458
  VistOMPClauseWithPreInit(C);
459
  if (C->getCondition())
460
    Profiler->VisitStmt(C->getCondition());
461
}
462

463
void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
464
  VistOMPClauseWithPreInit(C);
465
  if (C->getCondition())
466
    Profiler->VisitStmt(C->getCondition());
467
}
468

469
void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
470
  VistOMPClauseWithPreInit(C);
471
  if (C->getNumThreads())
472
    Profiler->VisitStmt(C->getNumThreads());
473
}
474

475
void OMPClauseProfiler::VisitOMPAlignClause(const OMPAlignClause *C) {
476
  if (C->getAlignment())
477
    Profiler->VisitStmt(C->getAlignment());
478
}
479

480
void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
481
  if (C->getSafelen())
482
    Profiler->VisitStmt(C->getSafelen());
483
}
484

485
void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
486
  if (C->getSimdlen())
487
    Profiler->VisitStmt(C->getSimdlen());
488
}
489

490
void OMPClauseProfiler::VisitOMPSizesClause(const OMPSizesClause *C) {
491
  for (auto *E : C->getSizesRefs())
492
    if (E)
493
      Profiler->VisitExpr(E);
494
}
495

496
void OMPClauseProfiler::VisitOMPFullClause(const OMPFullClause *C) {}
497

498
void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause *C) {
499
  if (const Expr *Factor = C->getFactor())
500
    Profiler->VisitExpr(Factor);
501
}
502

503
void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
504
  if (C->getAllocator())
505
    Profiler->VisitStmt(C->getAllocator());
506
}
507

508
void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
509
  if (C->getNumForLoops())
510
    Profiler->VisitStmt(C->getNumForLoops());
511
}
512

513
void OMPClauseProfiler::VisitOMPDetachClause(const OMPDetachClause *C) {
514
  if (Expr *Evt = C->getEventHandler())
515
    Profiler->VisitStmt(Evt);
516
}
517

518
void OMPClauseProfiler::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
519
  VistOMPClauseWithPreInit(C);
520
  if (C->getCondition())
521
    Profiler->VisitStmt(C->getCondition());
522
}
523

524
void OMPClauseProfiler::VisitOMPNocontextClause(const OMPNocontextClause *C) {
525
  VistOMPClauseWithPreInit(C);
526
  if (C->getCondition())
527
    Profiler->VisitStmt(C->getCondition());
528
}
529

530
void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
531

532
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
533

534
void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
535
    const OMPUnifiedAddressClause *C) {}
536

537
void OMPClauseProfiler::VisitOMPUnifiedSharedMemoryClause(
538
    const OMPUnifiedSharedMemoryClause *C) {}
539

540
void OMPClauseProfiler::VisitOMPReverseOffloadClause(
541
    const OMPReverseOffloadClause *C) {}
542

543
void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause(
544
    const OMPDynamicAllocatorsClause *C) {}
545

546
void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
547
    const OMPAtomicDefaultMemOrderClause *C) {}
548

549
void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
550

551
void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {}
552

553
void OMPClauseProfiler::VisitOMPMessageClause(const OMPMessageClause *C) {
554
  if (C->getMessageString())
555
    Profiler->VisitStmt(C->getMessageString());
556
}
557

558
void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
559
  VistOMPClauseWithPreInit(C);
560
  if (auto *S = C->getChunkSize())
561
    Profiler->VisitStmt(S);
562
}
563

564
void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) {
565
  if (auto *Num = C->getNumForLoops())
566
    Profiler->VisitStmt(Num);
567
}
568

569
void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
570

571
void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
572

573
void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
574

575
void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}
576

577
void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {}
578

579
void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
580

581
void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
582

583
void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
584

585
void OMPClauseProfiler::VisitOMPFailClause(const OMPFailClause *) {}
586

587
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
588

589
void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
590

591
void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause *) {}
592

593
void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause *) {}
594

595
void OMPClauseProfiler::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
596

597
void OMPClauseProfiler::VisitOMPWeakClause(const OMPWeakClause *) {}
598

599
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
600

601
void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
602

603
void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {}
604

605
void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) {
606
  VisitOMPClauseList(C);
607
}
608

609
void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause *C) {
610
  if (C->getInteropVar())
611
    Profiler->VisitStmt(C->getInteropVar());
612
}
613

614
void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *C) {
615
  if (C->getInteropVar())
616
    Profiler->VisitStmt(C->getInteropVar());
617
}
618

619
void OMPClauseProfiler::VisitOMPFilterClause(const OMPFilterClause *C) {
620
  VistOMPClauseWithPreInit(C);
621
  if (C->getThreadID())
622
    Profiler->VisitStmt(C->getThreadID());
623
}
624

625
template<typename T>
626
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
627
  for (auto *E : Node->varlists()) {
628
    if (E)
629
      Profiler->VisitStmt(E);
630
  }
631
}
632

633
void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
634
  VisitOMPClauseList(C);
635
  for (auto *E : C->private_copies()) {
636
    if (E)
637
      Profiler->VisitStmt(E);
638
  }
639
}
640
void
641
OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
642
  VisitOMPClauseList(C);
643
  VistOMPClauseWithPreInit(C);
644
  for (auto *E : C->private_copies()) {
645
    if (E)
646
      Profiler->VisitStmt(E);
647
  }
648
  for (auto *E : C->inits()) {
649
    if (E)
650
      Profiler->VisitStmt(E);
651
  }
652
}
653
void
654
OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
655
  VisitOMPClauseList(C);
656
  VistOMPClauseWithPostUpdate(C);
657
  for (auto *E : C->source_exprs()) {
658
    if (E)
659
      Profiler->VisitStmt(E);
660
  }
661
  for (auto *E : C->destination_exprs()) {
662
    if (E)
663
      Profiler->VisitStmt(E);
664
  }
665
  for (auto *E : C->assignment_ops()) {
666
    if (E)
667
      Profiler->VisitStmt(E);
668
  }
669
}
670
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
671
  VisitOMPClauseList(C);
672
}
673
void OMPClauseProfiler::VisitOMPReductionClause(
674
                                         const OMPReductionClause *C) {
675
  Profiler->VisitNestedNameSpecifier(
676
      C->getQualifierLoc().getNestedNameSpecifier());
677
  Profiler->VisitName(C->getNameInfo().getName());
678
  VisitOMPClauseList(C);
679
  VistOMPClauseWithPostUpdate(C);
680
  for (auto *E : C->privates()) {
681
    if (E)
682
      Profiler->VisitStmt(E);
683
  }
684
  for (auto *E : C->lhs_exprs()) {
685
    if (E)
686
      Profiler->VisitStmt(E);
687
  }
688
  for (auto *E : C->rhs_exprs()) {
689
    if (E)
690
      Profiler->VisitStmt(E);
691
  }
692
  for (auto *E : C->reduction_ops()) {
693
    if (E)
694
      Profiler->VisitStmt(E);
695
  }
696
  if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
697
    for (auto *E : C->copy_ops()) {
698
      if (E)
699
        Profiler->VisitStmt(E);
700
    }
701
    for (auto *E : C->copy_array_temps()) {
702
      if (E)
703
        Profiler->VisitStmt(E);
704
    }
705
    for (auto *E : C->copy_array_elems()) {
706
      if (E)
707
        Profiler->VisitStmt(E);
708
    }
709
  }
710
}
711
void OMPClauseProfiler::VisitOMPTaskReductionClause(
712
    const OMPTaskReductionClause *C) {
713
  Profiler->VisitNestedNameSpecifier(
714
      C->getQualifierLoc().getNestedNameSpecifier());
715
  Profiler->VisitName(C->getNameInfo().getName());
716
  VisitOMPClauseList(C);
717
  VistOMPClauseWithPostUpdate(C);
718
  for (auto *E : C->privates()) {
719
    if (E)
720
      Profiler->VisitStmt(E);
721
  }
722
  for (auto *E : C->lhs_exprs()) {
723
    if (E)
724
      Profiler->VisitStmt(E);
725
  }
726
  for (auto *E : C->rhs_exprs()) {
727
    if (E)
728
      Profiler->VisitStmt(E);
729
  }
730
  for (auto *E : C->reduction_ops()) {
731
    if (E)
732
      Profiler->VisitStmt(E);
733
  }
734
}
735
void OMPClauseProfiler::VisitOMPInReductionClause(
736
    const OMPInReductionClause *C) {
737
  Profiler->VisitNestedNameSpecifier(
738
      C->getQualifierLoc().getNestedNameSpecifier());
739
  Profiler->VisitName(C->getNameInfo().getName());
740
  VisitOMPClauseList(C);
741
  VistOMPClauseWithPostUpdate(C);
742
  for (auto *E : C->privates()) {
743
    if (E)
744
      Profiler->VisitStmt(E);
745
  }
746
  for (auto *E : C->lhs_exprs()) {
747
    if (E)
748
      Profiler->VisitStmt(E);
749
  }
750
  for (auto *E : C->rhs_exprs()) {
751
    if (E)
752
      Profiler->VisitStmt(E);
753
  }
754
  for (auto *E : C->reduction_ops()) {
755
    if (E)
756
      Profiler->VisitStmt(E);
757
  }
758
  for (auto *E : C->taskgroup_descriptors()) {
759
    if (E)
760
      Profiler->VisitStmt(E);
761
  }
762
}
763
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
764
  VisitOMPClauseList(C);
765
  VistOMPClauseWithPostUpdate(C);
766
  for (auto *E : C->privates()) {
767
    if (E)
768
      Profiler->VisitStmt(E);
769
  }
770
  for (auto *E : C->inits()) {
771
    if (E)
772
      Profiler->VisitStmt(E);
773
  }
774
  for (auto *E : C->updates()) {
775
    if (E)
776
      Profiler->VisitStmt(E);
777
  }
778
  for (auto *E : C->finals()) {
779
    if (E)
780
      Profiler->VisitStmt(E);
781
  }
782
  if (C->getStep())
783
    Profiler->VisitStmt(C->getStep());
784
  if (C->getCalcStep())
785
    Profiler->VisitStmt(C->getCalcStep());
786
}
787
void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
788
  VisitOMPClauseList(C);
789
  if (C->getAlignment())
790
    Profiler->VisitStmt(C->getAlignment());
791
}
792
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
793
  VisitOMPClauseList(C);
794
  for (auto *E : C->source_exprs()) {
795
    if (E)
796
      Profiler->VisitStmt(E);
797
  }
798
  for (auto *E : C->destination_exprs()) {
799
    if (E)
800
      Profiler->VisitStmt(E);
801
  }
802
  for (auto *E : C->assignment_ops()) {
803
    if (E)
804
      Profiler->VisitStmt(E);
805
  }
806
}
807
void
808
OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
809
  VisitOMPClauseList(C);
810
  for (auto *E : C->source_exprs()) {
811
    if (E)
812
      Profiler->VisitStmt(E);
813
  }
814
  for (auto *E : C->destination_exprs()) {
815
    if (E)
816
      Profiler->VisitStmt(E);
817
  }
818
  for (auto *E : C->assignment_ops()) {
819
    if (E)
820
      Profiler->VisitStmt(E);
821
  }
822
}
823
void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
824
  VisitOMPClauseList(C);
825
}
826
void OMPClauseProfiler::VisitOMPDepobjClause(const OMPDepobjClause *C) {
827
  if (const Expr *Depobj = C->getDepobj())
828
    Profiler->VisitStmt(Depobj);
829
}
830
void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) {
831
  VisitOMPClauseList(C);
832
}
833
void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) {
834
  if (C->getDevice())
835
    Profiler->VisitStmt(C->getDevice());
836
}
837
void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) {
838
  VisitOMPClauseList(C);
839
}
840
void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) {
841
  if (Expr *Allocator = C->getAllocator())
842
    Profiler->VisitStmt(Allocator);
843
  VisitOMPClauseList(C);
844
}
845
void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
846
  VistOMPClauseWithPreInit(C);
847
  if (C->getNumTeams())
848
    Profiler->VisitStmt(C->getNumTeams());
849
}
850
void OMPClauseProfiler::VisitOMPThreadLimitClause(
851
    const OMPThreadLimitClause *C) {
852
  VistOMPClauseWithPreInit(C);
853
  if (C->getThreadLimit())
854
    Profiler->VisitStmt(C->getThreadLimit());
855
}
856
void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) {
857
  VistOMPClauseWithPreInit(C);
858
  if (C->getPriority())
859
    Profiler->VisitStmt(C->getPriority());
860
}
861
void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
862
  VistOMPClauseWithPreInit(C);
863
  if (C->getGrainsize())
864
    Profiler->VisitStmt(C->getGrainsize());
865
}
866
void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
867
  VistOMPClauseWithPreInit(C);
868
  if (C->getNumTasks())
869
    Profiler->VisitStmt(C->getNumTasks());
870
}
871
void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
872
  if (C->getHint())
873
    Profiler->VisitStmt(C->getHint());
874
}
875
void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) {
876
  VisitOMPClauseList(C);
877
}
878
void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) {
879
  VisitOMPClauseList(C);
880
}
881
void OMPClauseProfiler::VisitOMPUseDevicePtrClause(
882
    const OMPUseDevicePtrClause *C) {
883
  VisitOMPClauseList(C);
884
}
885
void OMPClauseProfiler::VisitOMPUseDeviceAddrClause(
886
    const OMPUseDeviceAddrClause *C) {
887
  VisitOMPClauseList(C);
888
}
889
void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
890
    const OMPIsDevicePtrClause *C) {
891
  VisitOMPClauseList(C);
892
}
893
void OMPClauseProfiler::VisitOMPHasDeviceAddrClause(
894
    const OMPHasDeviceAddrClause *C) {
895
  VisitOMPClauseList(C);
896
}
897
void OMPClauseProfiler::VisitOMPNontemporalClause(
898
    const OMPNontemporalClause *C) {
899
  VisitOMPClauseList(C);
900
  for (auto *E : C->private_refs())
901
    Profiler->VisitStmt(E);
902
}
903
void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
904
  VisitOMPClauseList(C);
905
}
906
void OMPClauseProfiler::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
907
  VisitOMPClauseList(C);
908
}
909
void OMPClauseProfiler::VisitOMPUsesAllocatorsClause(
910
    const OMPUsesAllocatorsClause *C) {
911
  for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
912
    OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
913
    Profiler->VisitStmt(D.Allocator);
914
    if (D.AllocatorTraits)
915
      Profiler->VisitStmt(D.AllocatorTraits);
916
  }
917
}
918
void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
919
  if (const Expr *Modifier = C->getModifier())
920
    Profiler->VisitStmt(Modifier);
921
  for (const Expr *E : C->varlists())
922
    Profiler->VisitStmt(E);
923
}
924
void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
925
void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause *C) {}
926
void OMPClauseProfiler::VisitOMPXDynCGroupMemClause(
927
    const OMPXDynCGroupMemClause *C) {
928
  VistOMPClauseWithPreInit(C);
929
  if (Expr *Size = C->getSize())
930
    Profiler->VisitStmt(Size);
931
}
932
void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {
933
  VisitOMPClauseList(C);
934
}
935
void OMPClauseProfiler::VisitOMPXAttributeClause(const OMPXAttributeClause *C) {
936
}
937
void OMPClauseProfiler::VisitOMPXBareClause(const OMPXBareClause *C) {}
938
} // namespace
939

940
void
941
StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
942
  VisitStmt(S);
943
  OMPClauseProfiler P(this);
944
  ArrayRef<OMPClause *> Clauses = S->clauses();
945
  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
946
       I != E; ++I)
947
    if (*I)
948
      P.Visit(*I);
949
}
950

951
void StmtProfiler::VisitOMPCanonicalLoop(const OMPCanonicalLoop *L) {
952
  VisitStmt(L);
953
}
954

955
void StmtProfiler::VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *S) {
956
  VisitOMPExecutableDirective(S);
957
}
958

959
void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
960
  VisitOMPLoopBasedDirective(S);
961
}
962

963
void StmtProfiler::VisitOMPMetaDirective(const OMPMetaDirective *S) {
964
  VisitOMPExecutableDirective(S);
965
}
966

967
void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
968
  VisitOMPExecutableDirective(S);
969
}
970

971
void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
972
  VisitOMPLoopDirective(S);
973
}
974

975
void StmtProfiler::VisitOMPLoopTransformationDirective(
976
    const OMPLoopTransformationDirective *S) {
977
  VisitOMPLoopBasedDirective(S);
978
}
979

980
void StmtProfiler::VisitOMPTileDirective(const OMPTileDirective *S) {
981
  VisitOMPLoopTransformationDirective(S);
982
}
983

984
void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) {
985
  VisitOMPLoopTransformationDirective(S);
986
}
987

988
void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
989
  VisitOMPLoopDirective(S);
990
}
991

992
void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
993
  VisitOMPLoopDirective(S);
994
}
995

996
void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
997
  VisitOMPExecutableDirective(S);
998
}
999

1000
void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
1001
  VisitOMPExecutableDirective(S);
1002
}
1003

1004
void StmtProfiler::VisitOMPScopeDirective(const OMPScopeDirective *S) {
1005
  VisitOMPExecutableDirective(S);
1006
}
1007

1008
void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
1009
  VisitOMPExecutableDirective(S);
1010
}
1011

1012
void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
1013
  VisitOMPExecutableDirective(S);
1014
}
1015

1016
void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
1017
  VisitOMPExecutableDirective(S);
1018
  VisitName(S->getDirectiveName().getName());
1019
}
1020

1021
void
1022
StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
1023
  VisitOMPLoopDirective(S);
1024
}
1025

1026
void StmtProfiler::VisitOMPParallelForSimdDirective(
1027
    const OMPParallelForSimdDirective *S) {
1028
  VisitOMPLoopDirective(S);
1029
}
1030

1031
void StmtProfiler::VisitOMPParallelMasterDirective(
1032
    const OMPParallelMasterDirective *S) {
1033
  VisitOMPExecutableDirective(S);
1034
}
1035

1036
void StmtProfiler::VisitOMPParallelMaskedDirective(
1037
    const OMPParallelMaskedDirective *S) {
1038
  VisitOMPExecutableDirective(S);
1039
}
1040

1041
void StmtProfiler::VisitOMPParallelSectionsDirective(
1042
    const OMPParallelSectionsDirective *S) {
1043
  VisitOMPExecutableDirective(S);
1044
}
1045

1046
void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
1047
  VisitOMPExecutableDirective(S);
1048
}
1049

1050
void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
1051
  VisitOMPExecutableDirective(S);
1052
}
1053

1054
void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
1055
  VisitOMPExecutableDirective(S);
1056
}
1057

1058
void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
1059
  VisitOMPExecutableDirective(S);
1060
}
1061

1062
void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) {
1063
  VisitOMPExecutableDirective(S);
1064
}
1065
void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
1066
  VisitOMPExecutableDirective(S);
1067
  if (const Expr *E = S->getReductionRef())
1068
    VisitStmt(E);
1069
}
1070

1071
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
1072
  VisitOMPExecutableDirective(S);
1073
}
1074

1075
void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective *S) {
1076
  VisitOMPExecutableDirective(S);
1077
}
1078

1079
void StmtProfiler::VisitOMPScanDirective(const OMPScanDirective *S) {
1080
  VisitOMPExecutableDirective(S);
1081
}
1082

1083
void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
1084
  VisitOMPExecutableDirective(S);
1085
}
1086

1087
void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
1088
  VisitOMPExecutableDirective(S);
1089
}
1090

1091
void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
1092
  VisitOMPExecutableDirective(S);
1093
}
1094

1095
void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) {
1096
  VisitOMPExecutableDirective(S);
1097
}
1098

1099
void StmtProfiler::VisitOMPTargetEnterDataDirective(
1100
    const OMPTargetEnterDataDirective *S) {
1101
  VisitOMPExecutableDirective(S);
1102
}
1103

1104
void StmtProfiler::VisitOMPTargetExitDataDirective(
1105
    const OMPTargetExitDataDirective *S) {
1106
  VisitOMPExecutableDirective(S);
1107
}
1108

1109
void StmtProfiler::VisitOMPTargetParallelDirective(
1110
    const OMPTargetParallelDirective *S) {
1111
  VisitOMPExecutableDirective(S);
1112
}
1113

1114
void StmtProfiler::VisitOMPTargetParallelForDirective(
1115
    const OMPTargetParallelForDirective *S) {
1116
  VisitOMPExecutableDirective(S);
1117
}
1118

1119
void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
1120
  VisitOMPExecutableDirective(S);
1121
}
1122

1123
void StmtProfiler::VisitOMPCancellationPointDirective(
1124
    const OMPCancellationPointDirective *S) {
1125
  VisitOMPExecutableDirective(S);
1126
}
1127

1128
void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) {
1129
  VisitOMPExecutableDirective(S);
1130
}
1131

1132
void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) {
1133
  VisitOMPLoopDirective(S);
1134
}
1135

1136
void StmtProfiler::VisitOMPTaskLoopSimdDirective(
1137
    const OMPTaskLoopSimdDirective *S) {
1138
  VisitOMPLoopDirective(S);
1139
}
1140

1141
void StmtProfiler::VisitOMPMasterTaskLoopDirective(
1142
    const OMPMasterTaskLoopDirective *S) {
1143
  VisitOMPLoopDirective(S);
1144
}
1145

1146
void StmtProfiler::VisitOMPMaskedTaskLoopDirective(
1147
    const OMPMaskedTaskLoopDirective *S) {
1148
  VisitOMPLoopDirective(S);
1149
}
1150

1151
void StmtProfiler::VisitOMPMasterTaskLoopSimdDirective(
1152
    const OMPMasterTaskLoopSimdDirective *S) {
1153
  VisitOMPLoopDirective(S);
1154
}
1155

1156
void StmtProfiler::VisitOMPMaskedTaskLoopSimdDirective(
1157
    const OMPMaskedTaskLoopSimdDirective *S) {
1158
  VisitOMPLoopDirective(S);
1159
}
1160

1161
void StmtProfiler::VisitOMPParallelMasterTaskLoopDirective(
1162
    const OMPParallelMasterTaskLoopDirective *S) {
1163
  VisitOMPLoopDirective(S);
1164
}
1165

1166
void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective(
1167
    const OMPParallelMaskedTaskLoopDirective *S) {
1168
  VisitOMPLoopDirective(S);
1169
}
1170

1171
void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective(
1172
    const OMPParallelMasterTaskLoopSimdDirective *S) {
1173
  VisitOMPLoopDirective(S);
1174
}
1175

1176
void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective(
1177
    const OMPParallelMaskedTaskLoopSimdDirective *S) {
1178
  VisitOMPLoopDirective(S);
1179
}
1180

1181
void StmtProfiler::VisitOMPDistributeDirective(
1182
    const OMPDistributeDirective *S) {
1183
  VisitOMPLoopDirective(S);
1184
}
1185

1186
void OMPClauseProfiler::VisitOMPDistScheduleClause(
1187
    const OMPDistScheduleClause *C) {
1188
  VistOMPClauseWithPreInit(C);
1189
  if (auto *S = C->getChunkSize())
1190
    Profiler->VisitStmt(S);
1191
}
1192

1193
void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {}
1194

1195
void StmtProfiler::VisitOMPTargetUpdateDirective(
1196
    const OMPTargetUpdateDirective *S) {
1197
  VisitOMPExecutableDirective(S);
1198
}
1199

1200
void StmtProfiler::VisitOMPDistributeParallelForDirective(
1201
    const OMPDistributeParallelForDirective *S) {
1202
  VisitOMPLoopDirective(S);
1203
}
1204

1205
void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
1206
    const OMPDistributeParallelForSimdDirective *S) {
1207
  VisitOMPLoopDirective(S);
1208
}
1209

1210
void StmtProfiler::VisitOMPDistributeSimdDirective(
1211
    const OMPDistributeSimdDirective *S) {
1212
  VisitOMPLoopDirective(S);
1213
}
1214

1215
void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
1216
    const OMPTargetParallelForSimdDirective *S) {
1217
  VisitOMPLoopDirective(S);
1218
}
1219

1220
void StmtProfiler::VisitOMPTargetSimdDirective(
1221
    const OMPTargetSimdDirective *S) {
1222
  VisitOMPLoopDirective(S);
1223
}
1224

1225
void StmtProfiler::VisitOMPTeamsDistributeDirective(
1226
    const OMPTeamsDistributeDirective *S) {
1227
  VisitOMPLoopDirective(S);
1228
}
1229

1230
void StmtProfiler::VisitOMPTeamsDistributeSimdDirective(
1231
    const OMPTeamsDistributeSimdDirective *S) {
1232
  VisitOMPLoopDirective(S);
1233
}
1234

1235
void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
1236
    const OMPTeamsDistributeParallelForSimdDirective *S) {
1237
  VisitOMPLoopDirective(S);
1238
}
1239

1240
void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
1241
    const OMPTeamsDistributeParallelForDirective *S) {
1242
  VisitOMPLoopDirective(S);
1243
}
1244

1245
void StmtProfiler::VisitOMPTargetTeamsDirective(
1246
    const OMPTargetTeamsDirective *S) {
1247
  VisitOMPExecutableDirective(S);
1248
}
1249

1250
void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
1251
    const OMPTargetTeamsDistributeDirective *S) {
1252
  VisitOMPLoopDirective(S);
1253
}
1254

1255
void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
1256
    const OMPTargetTeamsDistributeParallelForDirective *S) {
1257
  VisitOMPLoopDirective(S);
1258
}
1259

1260
void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1261
    const OMPTargetTeamsDistributeParallelForSimdDirective *S) {
1262
  VisitOMPLoopDirective(S);
1263
}
1264

1265
void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
1266
    const OMPTargetTeamsDistributeSimdDirective *S) {
1267
  VisitOMPLoopDirective(S);
1268
}
1269

1270
void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective *S) {
1271
  VisitOMPExecutableDirective(S);
1272
}
1273

1274
void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective *S) {
1275
  VisitOMPExecutableDirective(S);
1276
}
1277

1278
void StmtProfiler::VisitOMPMaskedDirective(const OMPMaskedDirective *S) {
1279
  VisitOMPExecutableDirective(S);
1280
}
1281

1282
void StmtProfiler::VisitOMPGenericLoopDirective(
1283
    const OMPGenericLoopDirective *S) {
1284
  VisitOMPLoopDirective(S);
1285
}
1286

1287
void StmtProfiler::VisitOMPTeamsGenericLoopDirective(
1288
    const OMPTeamsGenericLoopDirective *S) {
1289
  VisitOMPLoopDirective(S);
1290
}
1291

1292
void StmtProfiler::VisitOMPTargetTeamsGenericLoopDirective(
1293
    const OMPTargetTeamsGenericLoopDirective *S) {
1294
  VisitOMPLoopDirective(S);
1295
}
1296

1297
void StmtProfiler::VisitOMPParallelGenericLoopDirective(
1298
    const OMPParallelGenericLoopDirective *S) {
1299
  VisitOMPLoopDirective(S);
1300
}
1301

1302
void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective(
1303
    const OMPTargetParallelGenericLoopDirective *S) {
1304
  VisitOMPLoopDirective(S);
1305
}
1306

1307
void StmtProfiler::VisitExpr(const Expr *S) {
1308
  VisitStmt(S);
1309
}
1310

1311
void StmtProfiler::VisitConstantExpr(const ConstantExpr *S) {
1312
  VisitExpr(S);
1313
}
1314

1315
void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
1316
  VisitExpr(S);
1317
  if (!Canonical)
1318
    VisitNestedNameSpecifier(S->getQualifier());
1319
  VisitDecl(S->getDecl());
1320
  if (!Canonical) {
1321
    ID.AddBoolean(S->hasExplicitTemplateArgs());
1322
    if (S->hasExplicitTemplateArgs())
1323
      VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
1324
  }
1325
}
1326

1327
void StmtProfiler::VisitSYCLUniqueStableNameExpr(
1328
    const SYCLUniqueStableNameExpr *S) {
1329
  VisitExpr(S);
1330
  VisitType(S->getTypeSourceInfo()->getType());
1331
}
1332

1333
void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
1334
  VisitExpr(S);
1335
  ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
1336
}
1337

1338
void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
1339
  VisitExpr(S);
1340
  S->getValue().Profile(ID);
1341

1342
  QualType T = S->getType();
1343
  if (Canonical)
1344
    T = T.getCanonicalType();
1345
  ID.AddInteger(T->getTypeClass());
1346
  if (auto BitIntT = T->getAs<BitIntType>())
1347
    BitIntT->Profile(ID);
1348
  else
1349
    ID.AddInteger(T->castAs<BuiltinType>()->getKind());
1350
}
1351

1352
void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
1353
  VisitExpr(S);
1354
  S->getValue().Profile(ID);
1355
  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1356
}
1357

1358
void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
1359
  VisitExpr(S);
1360
  ID.AddInteger(llvm::to_underlying(S->getKind()));
1361
  ID.AddInteger(S->getValue());
1362
}
1363

1364
void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
1365
  VisitExpr(S);
1366
  S->getValue().Profile(ID);
1367
  ID.AddBoolean(S->isExact());
1368
  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1369
}
1370

1371
void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
1372
  VisitExpr(S);
1373
}
1374

1375
void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
1376
  VisitExpr(S);
1377
  ID.AddString(S->getBytes());
1378
  ID.AddInteger(llvm::to_underlying(S->getKind()));
1379
}
1380

1381
void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
1382
  VisitExpr(S);
1383
}
1384

1385
void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
1386
  VisitExpr(S);
1387
}
1388

1389
void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
1390
  VisitExpr(S);
1391
  ID.AddInteger(S->getOpcode());
1392
}
1393

1394
void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
1395
  VisitType(S->getTypeSourceInfo()->getType());
1396
  unsigned n = S->getNumComponents();
1397
  for (unsigned i = 0; i < n; ++i) {
1398
    const OffsetOfNode &ON = S->getComponent(i);
1399
    ID.AddInteger(ON.getKind());
1400
    switch (ON.getKind()) {
1401
    case OffsetOfNode::Array:
1402
      // Expressions handled below.
1403
      break;
1404

1405
    case OffsetOfNode::Field:
1406
      VisitDecl(ON.getField());
1407
      break;
1408

1409
    case OffsetOfNode::Identifier:
1410
      VisitIdentifierInfo(ON.getFieldName());
1411
      break;
1412

1413
    case OffsetOfNode::Base:
1414
      // These nodes are implicit, and therefore don't need profiling.
1415
      break;
1416
    }
1417
  }
1418

1419
  VisitExpr(S);
1420
}
1421

1422
void
1423
StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
1424
  VisitExpr(S);
1425
  ID.AddInteger(S->getKind());
1426
  if (S->isArgumentType())
1427
    VisitType(S->getArgumentType());
1428
}
1429

1430
void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
1431
  VisitExpr(S);
1432
}
1433

1434
void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) {
1435
  VisitExpr(S);
1436
}
1437

1438
void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) {
1439
  VisitExpr(S);
1440
}
1441

1442
void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
1443
  VisitExpr(S);
1444
}
1445

1446
void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) {
1447
  VisitExpr(S);
1448
  for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I)
1449
    VisitDecl(S->getIteratorDecl(I));
1450
}
1451

1452
void StmtProfiler::VisitCallExpr(const CallExpr *S) {
1453
  VisitExpr(S);
1454
}
1455

1456
void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
1457
  VisitExpr(S);
1458
  VisitDecl(S->getMemberDecl());
1459
  if (!Canonical)
1460
    VisitNestedNameSpecifier(S->getQualifier());
1461
  ID.AddBoolean(S->isArrow());
1462
}
1463

1464
void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
1465
  VisitExpr(S);
1466
  ID.AddBoolean(S->isFileScope());
1467
}
1468

1469
void StmtProfiler::VisitCastExpr(const CastExpr *S) {
1470
  VisitExpr(S);
1471
}
1472

1473
void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
1474
  VisitCastExpr(S);
1475
  ID.AddInteger(S->getValueKind());
1476
}
1477

1478
void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
1479
  VisitCastExpr(S);
1480
  VisitType(S->getTypeAsWritten());
1481
}
1482

1483
void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
1484
  VisitExplicitCastExpr(S);
1485
}
1486

1487
void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
1488
  VisitExpr(S);
1489
  ID.AddInteger(S->getOpcode());
1490
}
1491

1492
void
1493
StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
1494
  VisitBinaryOperator(S);
1495
}
1496

1497
void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
1498
  VisitExpr(S);
1499
}
1500

1501
void StmtProfiler::VisitBinaryConditionalOperator(
1502
    const BinaryConditionalOperator *S) {
1503
  VisitExpr(S);
1504
}
1505

1506
void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
1507
  VisitExpr(S);
1508
  VisitDecl(S->getLabel());
1509
}
1510

1511
void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
1512
  VisitExpr(S);
1513
}
1514

1515
void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
1516
  VisitExpr(S);
1517
}
1518

1519
void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
1520
  VisitExpr(S);
1521
}
1522

1523
void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
1524
  VisitExpr(S);
1525
}
1526

1527
void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
1528
  VisitExpr(S);
1529
}
1530

1531
void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
1532
  VisitExpr(S);
1533
}
1534

1535
void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
1536
  if (S->getSyntacticForm()) {
1537
    VisitInitListExpr(S->getSyntacticForm());
1538
    return;
1539
  }
1540

1541
  VisitExpr(S);
1542
}
1543

1544
void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
1545
  VisitExpr(S);
1546
  ID.AddBoolean(S->usesGNUSyntax());
1547
  for (const DesignatedInitExpr::Designator &D : S->designators()) {
1548
    if (D.isFieldDesignator()) {
1549
      ID.AddInteger(0);
1550
      VisitName(D.getFieldName());
1551
      continue;
1552
    }
1553

1554
    if (D.isArrayDesignator()) {
1555
      ID.AddInteger(1);
1556
    } else {
1557
      assert(D.isArrayRangeDesignator());
1558
      ID.AddInteger(2);
1559
    }
1560
    ID.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.
1566
void StmtProfiler::VisitDesignatedInitUpdateExpr(
1567
    const DesignatedInitUpdateExpr *S) {
1568
  llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
1569
                   "initializer");
1570
}
1571

1572
void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
1573
  VisitExpr(S);
1574
}
1575

1576
void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
1577
  VisitExpr(S);
1578
}
1579

1580
void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
1581
  llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
1582
}
1583

1584
void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
1585
  VisitExpr(S);
1586
}
1587

1588
void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
1589
  VisitExpr(S);
1590
  VisitName(&S->getAccessor());
1591
}
1592

1593
void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
1594
  VisitExpr(S);
1595
  VisitDecl(S->getBlockDecl());
1596
}
1597

1598
void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
1599
  VisitExpr(S);
1600
  for (const GenericSelectionExpr::ConstAssociation Assoc :
1601
       S->associations()) {
1602
    QualType T = Assoc.getType();
1603
    if (T.isNull())
1604
      ID.AddPointer(nullptr);
1605
    else
1606
      VisitType(T);
1607
    VisitExpr(Assoc.getAssociationExpr());
1608
  }
1609
}
1610

1611
void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
1612
  VisitExpr(S);
1613
  for (PseudoObjectExpr::const_semantics_iterator
1614
         i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
1615
    // Normally, we would not profile the source expressions of OVEs.
1616
    if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
1617
      Visit(OVE->getSourceExpr());
1618
}
1619

1620
void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
1621
  VisitExpr(S);
1622
  ID.AddInteger(S->getOp());
1623
}
1624

1625
void StmtProfiler::VisitConceptSpecializationExpr(
1626
                                           const ConceptSpecializationExpr *S) {
1627
  VisitExpr(S);
1628
  VisitDecl(S->getNamedConcept());
1629
  for (const TemplateArgument &Arg : S->getTemplateArguments())
1630
    VisitTemplateArgument(Arg);
1631
}
1632

1633
void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
1634
  VisitExpr(S);
1635
  ID.AddInteger(S->getLocalParameters().size());
1636
  for (ParmVarDecl *LocalParam : S->getLocalParameters())
1637
    VisitDecl(LocalParam);
1638
  ID.AddInteger(S->getRequirements().size());
1639
  for (concepts::Requirement *Req : S->getRequirements()) {
1640
    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
1641
      ID.AddInteger(concepts::Requirement::RK_Type);
1642
      ID.AddBoolean(TypeReq->isSubstitutionFailure());
1643
      if (!TypeReq->isSubstitutionFailure())
1644
        VisitType(TypeReq->getType()->getType());
1645
    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
1646
      ID.AddInteger(concepts::Requirement::RK_Compound);
1647
      ID.AddBoolean(ExprReq->isExprSubstitutionFailure());
1648
      if (!ExprReq->isExprSubstitutionFailure())
1649
        Visit(ExprReq->getExpr());
1650
      // C++2a [expr.prim.req.compound]p1 Example:
1651
      //    [...] The compound-requirement in C1 requires that x++ is a valid
1652
      //    expression. It is equivalent to the simple-requirement x++; [...]
1653
      // We therefore do not profile isSimple() here.
1654
      ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());
1655
      const concepts::ExprRequirement::ReturnTypeRequirement &RetReq =
1656
          ExprReq->getReturnTypeRequirement();
1657
      if (RetReq.isEmpty()) {
1658
        ID.AddInteger(0);
1659
      } else if (RetReq.isTypeConstraint()) {
1660
        ID.AddInteger(1);
1661
        Visit(RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint());
1662
      } else {
1663
        assert(RetReq.isSubstitutionFailure());
1664
        ID.AddInteger(2);
1665
      }
1666
    } else {
1667
      ID.AddInteger(concepts::Requirement::RK_Nested);
1668
      auto *NestedReq = cast<concepts::NestedRequirement>(Req);
1669
      ID.AddBoolean(NestedReq->hasInvalidConstraint());
1670
      if (!NestedReq->hasInvalidConstraint())
1671
        Visit(NestedReq->getConstraintExpr());
1672
    }
1673
  }
1674
}
1675

1676
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
1677
                                          UnaryOperatorKind &UnaryOp,
1678
                                          BinaryOperatorKind &BinaryOp,
1679
                                          unsigned &NumArgs) {
1680
  switch (S->getOperator()) {
1681
  case OO_None:
1682
  case OO_New:
1683
  case OO_Delete:
1684
  case OO_Array_New:
1685
  case OO_Array_Delete:
1686
  case OO_Arrow:
1687
  case OO_Conditional:
1688
  case NUM_OVERLOADED_OPERATORS:
1689
    llvm_unreachable("Invalid operator call kind");
1690

1691
  case OO_Plus:
1692
    if (NumArgs == 1) {
1693
      UnaryOp = UO_Plus;
1694
      return Stmt::UnaryOperatorClass;
1695
    }
1696

1697
    BinaryOp = BO_Add;
1698
    return Stmt::BinaryOperatorClass;
1699

1700
  case OO_Minus:
1701
    if (NumArgs == 1) {
1702
      UnaryOp = UO_Minus;
1703
      return Stmt::UnaryOperatorClass;
1704
    }
1705

1706
    BinaryOp = BO_Sub;
1707
    return Stmt::BinaryOperatorClass;
1708

1709
  case OO_Star:
1710
    if (NumArgs == 1) {
1711
      UnaryOp = UO_Deref;
1712
      return Stmt::UnaryOperatorClass;
1713
    }
1714

1715
    BinaryOp = BO_Mul;
1716
    return Stmt::BinaryOperatorClass;
1717

1718
  case OO_Slash:
1719
    BinaryOp = BO_Div;
1720
    return Stmt::BinaryOperatorClass;
1721

1722
  case OO_Percent:
1723
    BinaryOp = BO_Rem;
1724
    return Stmt::BinaryOperatorClass;
1725

1726
  case OO_Caret:
1727
    BinaryOp = BO_Xor;
1728
    return Stmt::BinaryOperatorClass;
1729

1730
  case OO_Amp:
1731
    if (NumArgs == 1) {
1732
      UnaryOp = UO_AddrOf;
1733
      return Stmt::UnaryOperatorClass;
1734
    }
1735

1736
    BinaryOp = BO_And;
1737
    return Stmt::BinaryOperatorClass;
1738

1739
  case OO_Pipe:
1740
    BinaryOp = BO_Or;
1741
    return Stmt::BinaryOperatorClass;
1742

1743
  case OO_Tilde:
1744
    UnaryOp = UO_Not;
1745
    return Stmt::UnaryOperatorClass;
1746

1747
  case OO_Exclaim:
1748
    UnaryOp = UO_LNot;
1749
    return Stmt::UnaryOperatorClass;
1750

1751
  case OO_Equal:
1752
    BinaryOp = BO_Assign;
1753
    return Stmt::BinaryOperatorClass;
1754

1755
  case OO_Less:
1756
    BinaryOp = BO_LT;
1757
    return Stmt::BinaryOperatorClass;
1758

1759
  case OO_Greater:
1760
    BinaryOp = BO_GT;
1761
    return Stmt::BinaryOperatorClass;
1762

1763
  case OO_PlusEqual:
1764
    BinaryOp = BO_AddAssign;
1765
    return Stmt::CompoundAssignOperatorClass;
1766

1767
  case OO_MinusEqual:
1768
    BinaryOp = BO_SubAssign;
1769
    return Stmt::CompoundAssignOperatorClass;
1770

1771
  case OO_StarEqual:
1772
    BinaryOp = BO_MulAssign;
1773
    return Stmt::CompoundAssignOperatorClass;
1774

1775
  case OO_SlashEqual:
1776
    BinaryOp = BO_DivAssign;
1777
    return Stmt::CompoundAssignOperatorClass;
1778

1779
  case OO_PercentEqual:
1780
    BinaryOp = BO_RemAssign;
1781
    return Stmt::CompoundAssignOperatorClass;
1782

1783
  case OO_CaretEqual:
1784
    BinaryOp = BO_XorAssign;
1785
    return Stmt::CompoundAssignOperatorClass;
1786

1787
  case OO_AmpEqual:
1788
    BinaryOp = BO_AndAssign;
1789
    return Stmt::CompoundAssignOperatorClass;
1790

1791
  case OO_PipeEqual:
1792
    BinaryOp = BO_OrAssign;
1793
    return Stmt::CompoundAssignOperatorClass;
1794

1795
  case OO_LessLess:
1796
    BinaryOp = BO_Shl;
1797
    return Stmt::BinaryOperatorClass;
1798

1799
  case OO_GreaterGreater:
1800
    BinaryOp = BO_Shr;
1801
    return Stmt::BinaryOperatorClass;
1802

1803
  case OO_LessLessEqual:
1804
    BinaryOp = BO_ShlAssign;
1805
    return Stmt::CompoundAssignOperatorClass;
1806

1807
  case OO_GreaterGreaterEqual:
1808
    BinaryOp = BO_ShrAssign;
1809
    return Stmt::CompoundAssignOperatorClass;
1810

1811
  case OO_EqualEqual:
1812
    BinaryOp = BO_EQ;
1813
    return Stmt::BinaryOperatorClass;
1814

1815
  case OO_ExclaimEqual:
1816
    BinaryOp = BO_NE;
1817
    return Stmt::BinaryOperatorClass;
1818

1819
  case OO_LessEqual:
1820
    BinaryOp = BO_LE;
1821
    return Stmt::BinaryOperatorClass;
1822

1823
  case OO_GreaterEqual:
1824
    BinaryOp = BO_GE;
1825
    return Stmt::BinaryOperatorClass;
1826

1827
  case OO_Spaceship:
1828
    BinaryOp = BO_Cmp;
1829
    return Stmt::BinaryOperatorClass;
1830

1831
  case OO_AmpAmp:
1832
    BinaryOp = BO_LAnd;
1833
    return Stmt::BinaryOperatorClass;
1834

1835
  case OO_PipePipe:
1836
    BinaryOp = BO_LOr;
1837
    return Stmt::BinaryOperatorClass;
1838

1839
  case OO_PlusPlus:
1840
    UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc;
1841
    NumArgs = 1;
1842
    return Stmt::UnaryOperatorClass;
1843

1844
  case OO_MinusMinus:
1845
    UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec;
1846
    NumArgs = 1;
1847
    return Stmt::UnaryOperatorClass;
1848

1849
  case OO_Comma:
1850
    BinaryOp = BO_Comma;
1851
    return Stmt::BinaryOperatorClass;
1852

1853
  case OO_ArrowStar:
1854
    BinaryOp = BO_PtrMemI;
1855
    return Stmt::BinaryOperatorClass;
1856

1857
  case OO_Subscript:
1858
    return Stmt::ArraySubscriptExprClass;
1859

1860
  case OO_Call:
1861
    return Stmt::CallExprClass;
1862

1863
  case OO_Coawait:
1864
    UnaryOp = UO_Coawait;
1865
    return Stmt::UnaryOperatorClass;
1866
  }
1867

1868
  llvm_unreachable("Invalid overloaded operator expression");
1869
}
1870

1871
#if defined(_MSC_VER) && !defined(__clang__)
1872
#if _MSC_VER == 1911
1873
// 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
#endif
1878
#endif
1879

1880
void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
1881
  if (S->isTypeDependent()) {
1882
    // Type-dependent operator calls are profiled like their underlying
1883
    // syntactic operator.
1884
    //
1885
    // An operator call to operator-> is always implicit, so just skip it. The
1886
    // enclosing MemberExpr will profile the actual member access.
1887
    if (S->getOperator() == OO_Arrow)
1888
      return Visit(S->getArg(0));
1889

1890
    UnaryOperatorKind UnaryOp = UO_Extension;
1891
    BinaryOperatorKind BinaryOp = BO_Comma;
1892
    unsigned NumArgs = S->getNumArgs();
1893
    Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs);
1894

1895
    ID.AddInteger(SC);
1896
    for (unsigned I = 0; I != NumArgs; ++I)
1897
      Visit(S->getArg(I));
1898
    if (SC == Stmt::UnaryOperatorClass)
1899
      ID.AddInteger(UnaryOp);
1900
    else if (SC == Stmt::BinaryOperatorClass ||
1901
             SC == Stmt::CompoundAssignOperatorClass)
1902
      ID.AddInteger(BinaryOp);
1903
    else
1904
      assert(SC == Stmt::ArraySubscriptExprClass || SC == Stmt::CallExprClass);
1905

1906
    return;
1907
  }
1908

1909
  VisitCallExpr(S);
1910
  ID.AddInteger(S->getOperator());
1911
}
1912

1913
void StmtProfiler::VisitCXXRewrittenBinaryOperator(
1914
    const CXXRewrittenBinaryOperator *S) {
1915
  // If a rewritten operator were ever to be type-dependent, we should profile
1916
  // it following its syntactic operator.
1917
  assert(!S->isTypeDependent() &&
1918
         "resolved rewritten operator should never be type-dependent");
1919
  ID.AddBoolean(S->isReversed());
1920
  VisitExpr(S->getSemanticForm());
1921
}
1922

1923
#if defined(_MSC_VER) && !defined(__clang__)
1924
#if _MSC_VER == 1911
1925
#pragma optimize("", on)
1926
#endif
1927
#endif
1928

1929
void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
1930
  VisitCallExpr(S);
1931
}
1932

1933
void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
1934
  VisitCallExpr(S);
1935
}
1936

1937
void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
1938
  VisitExpr(S);
1939
}
1940

1941
void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
1942
  VisitExplicitCastExpr(S);
1943
}
1944

1945
void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
1946
  VisitCXXNamedCastExpr(S);
1947
}
1948

1949
void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
1950
  VisitCXXNamedCastExpr(S);
1951
}
1952

1953
void
1954
StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
1955
  VisitCXXNamedCastExpr(S);
1956
}
1957

1958
void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
1959
  VisitCXXNamedCastExpr(S);
1960
}
1961

1962
void StmtProfiler::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *S) {
1963
  VisitExpr(S);
1964
  VisitType(S->getTypeInfoAsWritten()->getType());
1965
}
1966

1967
void StmtProfiler::VisitCXXAddrspaceCastExpr(const CXXAddrspaceCastExpr *S) {
1968
  VisitCXXNamedCastExpr(S);
1969
}
1970

1971
void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
1972
  VisitCallExpr(S);
1973
}
1974

1975
void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
1976
  VisitExpr(S);
1977
  ID.AddBoolean(S->getValue());
1978
}
1979

1980
void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
1981
  VisitExpr(S);
1982
}
1983

1984
void StmtProfiler::VisitCXXStdInitializerListExpr(
1985
    const CXXStdInitializerListExpr *S) {
1986
  VisitExpr(S);
1987
}
1988

1989
void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
1990
  VisitExpr(S);
1991
  if (S->isTypeOperand())
1992
    VisitType(S->getTypeOperandSourceInfo()->getType());
1993
}
1994

1995
void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
1996
  VisitExpr(S);
1997
  if (S->isTypeOperand())
1998
    VisitType(S->getTypeOperandSourceInfo()->getType());
1999
}
2000

2001
void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
2002
  VisitExpr(S);
2003
  VisitDecl(S->getPropertyDecl());
2004
}
2005

2006
void StmtProfiler::VisitMSPropertySubscriptExpr(
2007
    const MSPropertySubscriptExpr *S) {
2008
  VisitExpr(S);
2009
}
2010

2011
void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
2012
  VisitExpr(S);
2013
  ID.AddBoolean(S->isImplicit());
2014
  ID.AddBoolean(S->isCapturedByCopyInLambdaWithExplicitObjectParameter());
2015
}
2016

2017
void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
2018
  VisitExpr(S);
2019
}
2020

2021
void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
2022
  VisitExpr(S);
2023
  VisitDecl(S->getParam());
2024
}
2025

2026
void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
2027
  VisitExpr(S);
2028
  VisitDecl(S->getField());
2029
}
2030

2031
void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
2032
  VisitExpr(S);
2033
  VisitDecl(
2034
         const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
2035
}
2036

2037
void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
2038
  VisitExpr(S);
2039
  VisitDecl(S->getConstructor());
2040
  ID.AddBoolean(S->isElidable());
2041
}
2042

2043
void StmtProfiler::VisitCXXInheritedCtorInitExpr(
2044
    const CXXInheritedCtorInitExpr *S) {
2045
  VisitExpr(S);
2046
  VisitDecl(S->getConstructor());
2047
}
2048

2049
void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
2050
  VisitExplicitCastExpr(S);
2051
}
2052

2053
void
2054
StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
2055
  VisitCXXConstructExpr(S);
2056
}
2057

2058
void
2059
StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
2060
  if (!ProfileLambdaExpr) {
2061
    // Do not recursively visit the children of this expression. Profiling the
2062
    // body would result in unnecessary work, and is not safe to do during
2063
    // deserialization.
2064
    VisitStmtNoChildren(S);
2065

2066
    // C++20 [temp.over.link]p5:
2067
    //   Two lambda-expressions are never considered equivalent.
2068
    VisitDecl(S->getLambdaClass());
2069

2070
    return;
2071
  }
2072

2073
  CXXRecordDecl *Lambda = S->getLambdaClass();
2074
  for (const auto &Capture : Lambda->captures()) {
2075
    ID.AddInteger(Capture.getCaptureKind());
2076
    if (Capture.capturesVariable())
2077
      VisitDecl(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.
2082
  ODRHash Hasher;
2083
  // FIXME: We can't get the operator call easily by
2084
  // `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization.
2085
  // So we have to do something raw here.
2086
  for (auto *SubDecl : Lambda->decls()) {
2087
    FunctionDecl *Call = nullptr;
2088
    if (auto *FTD = dyn_cast<FunctionTemplateDecl>(SubDecl))
2089
      Call = FTD->getTemplatedDecl();
2090
    else if (auto *FD = dyn_cast<FunctionDecl>(SubDecl))
2091
      Call = FD;
2092

2093
    if (!Call)
2094
      continue;
2095

2096
    Hasher.AddFunctionDecl(Call, /*SkipBody=*/true);
2097
  }
2098
  ID.AddInteger(Hasher.CalculateHash());
2099
}
2100

2101
void
2102
StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
2103
  VisitExpr(S);
2104
}
2105

2106
void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
2107
  VisitExpr(S);
2108
  ID.AddBoolean(S->isGlobalDelete());
2109
  ID.AddBoolean(S->isArrayForm());
2110
  VisitDecl(S->getOperatorDelete());
2111
}
2112

2113
void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
2114
  VisitExpr(S);
2115
  VisitType(S->getAllocatedType());
2116
  VisitDecl(S->getOperatorNew());
2117
  VisitDecl(S->getOperatorDelete());
2118
  ID.AddBoolean(S->isArray());
2119
  ID.AddInteger(S->getNumPlacementArgs());
2120
  ID.AddBoolean(S->isGlobalNew());
2121
  ID.AddBoolean(S->isParenTypeId());
2122
  ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
2123
}
2124

2125
void
2126
StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
2127
  VisitExpr(S);
2128
  ID.AddBoolean(S->isArrow());
2129
  VisitNestedNameSpecifier(S->getQualifier());
2130
  ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
2131
  if (S->getScopeTypeInfo())
2132
    VisitType(S->getScopeTypeInfo()->getType());
2133
  ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
2134
  if (S->getDestroyedTypeInfo())
2135
    VisitType(S->getDestroyedType());
2136
  else
2137
    VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
2138
}
2139

2140
void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
2141
  VisitExpr(S);
2142
  VisitNestedNameSpecifier(S->getQualifier());
2143
  VisitName(S->getName(), /*TreatAsDecl*/ true);
2144
  ID.AddBoolean(S->hasExplicitTemplateArgs());
2145
  if (S->hasExplicitTemplateArgs())
2146
    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2147
}
2148

2149
void
2150
StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
2151
  VisitOverloadExpr(S);
2152
}
2153

2154
void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
2155
  VisitExpr(S);
2156
  ID.AddInteger(S->getTrait());
2157
  ID.AddInteger(S->getNumArgs());
2158
  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2159
    VisitType(S->getArg(I)->getType());
2160
}
2161

2162
void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
2163
  VisitExpr(S);
2164
  ID.AddInteger(S->getTrait());
2165
  VisitType(S->getQueriedType());
2166
}
2167

2168
void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
2169
  VisitExpr(S);
2170
  ID.AddInteger(S->getTrait());
2171
  VisitExpr(S->getQueriedExpression());
2172
}
2173

2174
void StmtProfiler::VisitDependentScopeDeclRefExpr(
2175
    const DependentScopeDeclRefExpr *S) {
2176
  VisitExpr(S);
2177
  VisitName(S->getDeclName());
2178
  VisitNestedNameSpecifier(S->getQualifier());
2179
  ID.AddBoolean(S->hasExplicitTemplateArgs());
2180
  if (S->hasExplicitTemplateArgs())
2181
    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2182
}
2183

2184
void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
2185
  VisitExpr(S);
2186
}
2187

2188
void StmtProfiler::VisitCXXUnresolvedConstructExpr(
2189
    const CXXUnresolvedConstructExpr *S) {
2190
  VisitExpr(S);
2191
  VisitType(S->getTypeAsWritten());
2192
  ID.AddInteger(S->isListInitialization());
2193
}
2194

2195
void StmtProfiler::VisitCXXDependentScopeMemberExpr(
2196
    const CXXDependentScopeMemberExpr *S) {
2197
  ID.AddBoolean(S->isImplicitAccess());
2198
  if (!S->isImplicitAccess()) {
2199
    VisitExpr(S);
2200
    ID.AddBoolean(S->isArrow());
2201
  }
2202
  VisitNestedNameSpecifier(S->getQualifier());
2203
  VisitName(S->getMember());
2204
  ID.AddBoolean(S->hasExplicitTemplateArgs());
2205
  if (S->hasExplicitTemplateArgs())
2206
    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2207
}
2208

2209
void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
2210
  ID.AddBoolean(S->isImplicitAccess());
2211
  if (!S->isImplicitAccess()) {
2212
    VisitExpr(S);
2213
    ID.AddBoolean(S->isArrow());
2214
  }
2215
  VisitNestedNameSpecifier(S->getQualifier());
2216
  VisitName(S->getMemberName());
2217
  ID.AddBoolean(S->hasExplicitTemplateArgs());
2218
  if (S->hasExplicitTemplateArgs())
2219
    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2220
}
2221

2222
void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
2223
  VisitExpr(S);
2224
}
2225

2226
void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
2227
  VisitExpr(S);
2228
}
2229

2230
void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
2231
  VisitExpr(S);
2232
  VisitDecl(S->getPack());
2233
  if (S->isPartiallySubstituted()) {
2234
    auto Args = S->getPartialArguments();
2235
    ID.AddInteger(Args.size());
2236
    for (const auto &TA : Args)
2237
      VisitTemplateArgument(TA);
2238
  } else {
2239
    ID.AddInteger(0);
2240
  }
2241
}
2242

2243
void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
2244
  VisitExpr(E);
2245
  VisitExpr(E->getPackIdExpression());
2246
  VisitExpr(E->getIndexExpr());
2247
}
2248

2249
void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
2250
    const SubstNonTypeTemplateParmPackExpr *S) {
2251
  VisitExpr(S);
2252
  VisitDecl(S->getParameterPack());
2253
  VisitTemplateArgument(S->getArgumentPack());
2254
}
2255

2256
void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
2257
    const SubstNonTypeTemplateParmExpr *E) {
2258
  // Profile exactly as the replacement expression.
2259
  Visit(E->getReplacement());
2260
}
2261

2262
void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
2263
  VisitExpr(S);
2264
  VisitDecl(S->getParameterPack());
2265
  ID.AddInteger(S->getNumExpansions());
2266
  for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
2267
    VisitDecl(*I);
2268
}
2269

2270
void StmtProfiler::VisitMaterializeTemporaryExpr(
2271
                                           const MaterializeTemporaryExpr *S) {
2272
  VisitExpr(S);
2273
}
2274

2275
void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
2276
  VisitExpr(S);
2277
  ID.AddInteger(S->getOperator());
2278
}
2279

2280
void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
2281
  VisitExpr(S);
2282
}
2283

2284
void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
2285
  VisitStmt(S);
2286
}
2287

2288
void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
2289
  VisitStmt(S);
2290
}
2291

2292
void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
2293
  VisitExpr(S);
2294
}
2295

2296
void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
2297
  VisitExpr(S);
2298
}
2299

2300
void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
2301
  VisitExpr(S);
2302
}
2303

2304
void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2305
  VisitExpr(E);
2306
}
2307

2308
void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
2309
  VisitExpr(E);
2310
}
2311

2312
void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
2313
  VisitExpr(E);
2314
}
2315

2316
void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); }
2317

2318
void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
2319

2320
void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
2321
  VisitExpr(S);
2322
}
2323

2324
void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
2325
  VisitExpr(E);
2326
}
2327

2328
void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
2329
  VisitExpr(E);
2330
}
2331

2332
void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
2333
  VisitExpr(E);
2334
}
2335

2336
void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
2337
  VisitExpr(S);
2338
  VisitType(S->getEncodedType());
2339
}
2340

2341
void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
2342
  VisitExpr(S);
2343
  VisitName(S->getSelector());
2344
}
2345

2346
void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
2347
  VisitExpr(S);
2348
  VisitDecl(S->getProtocol());
2349
}
2350

2351
void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
2352
  VisitExpr(S);
2353
  VisitDecl(S->getDecl());
2354
  ID.AddBoolean(S->isArrow());
2355
  ID.AddBoolean(S->isFreeIvar());
2356
}
2357

2358
void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
2359
  VisitExpr(S);
2360
  if (S->isImplicitProperty()) {
2361
    VisitDecl(S->getImplicitPropertyGetter());
2362
    VisitDecl(S->getImplicitPropertySetter());
2363
  } else {
2364
    VisitDecl(S->getExplicitProperty());
2365
  }
2366
  if (S->isSuperReceiver()) {
2367
    ID.AddBoolean(S->isSuperReceiver());
2368
    VisitType(S->getSuperReceiverType());
2369
  }
2370
}
2371

2372
void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
2373
  VisitExpr(S);
2374
  VisitDecl(S->getAtIndexMethodDecl());
2375
  VisitDecl(S->setAtIndexMethodDecl());
2376
}
2377

2378
void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
2379
  VisitExpr(S);
2380
  VisitName(S->getSelector());
2381
  VisitDecl(S->getMethodDecl());
2382
}
2383

2384
void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
2385
  VisitExpr(S);
2386
  ID.AddBoolean(S->isArrow());
2387
}
2388

2389
void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
2390
  VisitExpr(S);
2391
  ID.AddBoolean(S->getValue());
2392
}
2393

2394
void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
2395
    const ObjCIndirectCopyRestoreExpr *S) {
2396
  VisitExpr(S);
2397
  ID.AddBoolean(S->shouldCopy());
2398
}
2399

2400
void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
2401
  VisitExplicitCastExpr(S);
2402
  ID.AddBoolean(S->getBridgeKind());
2403
}
2404

2405
void StmtProfiler::VisitObjCAvailabilityCheckExpr(
2406
    const ObjCAvailabilityCheckExpr *S) {
2407
  VisitExpr(S);
2408
}
2409

2410
void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
2411
                                          unsigned NumArgs) {
2412
  ID.AddInteger(NumArgs);
2413
  for (unsigned I = 0; I != NumArgs; ++I)
2414
    VisitTemplateArgument(Args[I].getArgument());
2415
}
2416

2417
void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
2418
  // Mostly repetitive with TemplateArgument::Profile!
2419
  ID.AddInteger(Arg.getKind());
2420
  switch (Arg.getKind()) {
2421
  case TemplateArgument::Null:
2422
    break;
2423

2424
  case TemplateArgument::Type:
2425
    VisitType(Arg.getAsType());
2426
    break;
2427

2428
  case TemplateArgument::Template:
2429
  case TemplateArgument::TemplateExpansion:
2430
    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
2431
    break;
2432

2433
  case TemplateArgument::Declaration:
2434
    VisitType(Arg.getParamTypeForDecl());
2435
    // FIXME: Do we need to recursively decompose template parameter objects?
2436
    VisitDecl(Arg.getAsDecl());
2437
    break;
2438

2439
  case TemplateArgument::NullPtr:
2440
    VisitType(Arg.getNullPtrType());
2441
    break;
2442

2443
  case TemplateArgument::Integral:
2444
    VisitType(Arg.getIntegralType());
2445
    Arg.getAsIntegral().Profile(ID);
2446
    break;
2447

2448
  case TemplateArgument::StructuralValue:
2449
    VisitType(Arg.getStructuralValueType());
2450
    // FIXME: Do we need to recursively decompose this ourselves?
2451
    Arg.getAsStructuralValue().Profile(ID);
2452
    break;
2453

2454
  case TemplateArgument::Expression:
2455
    Visit(Arg.getAsExpr());
2456
    break;
2457

2458
  case TemplateArgument::Pack:
2459
    for (const auto &P : Arg.pack_elements())
2460
      VisitTemplateArgument(P);
2461
    break;
2462
  }
2463
}
2464

2465
namespace {
2466
class OpenACCClauseProfiler
2467
    : public OpenACCClauseVisitor<OpenACCClauseProfiler> {
2468
  StmtProfiler &Profiler;
2469

2470
public:
2471
  OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {}
2472

2473
  void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) {
2474
    for (const OpenACCClause *Clause : Clauses) {
2475
      // TODO OpenACC: When we have clauses with expressions, we should
2476
      // profile them too.
2477
      Visit(Clause);
2478
    }
2479
  }
2480

2481
#define VISIT_CLAUSE(CLAUSE_NAME)                                              \
2482
  void 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.
2488
void OpenACCClauseProfiler::VisitDefaultClause(
2489
    const OpenACCDefaultClause &Clause) {}
2490

2491
void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
2492
  assert(Clause.hasConditionExpr() &&
2493
         "if clause requires a valid condition expr");
2494
  Profiler.VisitStmt(Clause.getConditionExpr());
2495
}
2496

2497
void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
2498
  for (auto *E : Clause.getVarList())
2499
    Profiler.VisitStmt(E);
2500
}
2501
void OpenACCClauseProfiler::VisitCopyInClause(
2502
    const OpenACCCopyInClause &Clause) {
2503
  for (auto *E : Clause.getVarList())
2504
    Profiler.VisitStmt(E);
2505
}
2506

2507
void OpenACCClauseProfiler::VisitCopyOutClause(
2508
    const OpenACCCopyOutClause &Clause) {
2509
  for (auto *E : Clause.getVarList())
2510
    Profiler.VisitStmt(E);
2511
}
2512

2513
void OpenACCClauseProfiler::VisitCreateClause(
2514
    const OpenACCCreateClause &Clause) {
2515
  for (auto *E : Clause.getVarList())
2516
    Profiler.VisitStmt(E);
2517
}
2518

2519
void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
2520
  if (Clause.hasConditionExpr())
2521
    Profiler.VisitStmt(Clause.getConditionExpr());
2522
}
2523

2524
void OpenACCClauseProfiler::VisitNumGangsClause(
2525
    const OpenACCNumGangsClause &Clause) {
2526
  for (auto *E : Clause.getIntExprs())
2527
    Profiler.VisitStmt(E);
2528
}
2529

2530
void OpenACCClauseProfiler::VisitNumWorkersClause(
2531
    const OpenACCNumWorkersClause &Clause) {
2532
  assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr");
2533
  Profiler.VisitStmt(Clause.getIntExpr());
2534
}
2535

2536
void OpenACCClauseProfiler::VisitPrivateClause(
2537
    const OpenACCPrivateClause &Clause) {
2538
  for (auto *E : Clause.getVarList())
2539
    Profiler.VisitStmt(E);
2540
}
2541

2542
void OpenACCClauseProfiler::VisitFirstPrivateClause(
2543
    const OpenACCFirstPrivateClause &Clause) {
2544
  for (auto *E : Clause.getVarList())
2545
    Profiler.VisitStmt(E);
2546
}
2547

2548
void OpenACCClauseProfiler::VisitAttachClause(
2549
    const OpenACCAttachClause &Clause) {
2550
  for (auto *E : Clause.getVarList())
2551
    Profiler.VisitStmt(E);
2552
}
2553

2554
void OpenACCClauseProfiler::VisitDevicePtrClause(
2555
    const OpenACCDevicePtrClause &Clause) {
2556
  for (auto *E : Clause.getVarList())
2557
    Profiler.VisitStmt(E);
2558
}
2559

2560
void OpenACCClauseProfiler::VisitNoCreateClause(
2561
    const OpenACCNoCreateClause &Clause) {
2562
  for (auto *E : Clause.getVarList())
2563
    Profiler.VisitStmt(E);
2564
}
2565

2566
void OpenACCClauseProfiler::VisitPresentClause(
2567
    const OpenACCPresentClause &Clause) {
2568
  for (auto *E : Clause.getVarList())
2569
    Profiler.VisitStmt(E);
2570
}
2571

2572
void OpenACCClauseProfiler::VisitVectorLengthClause(
2573
    const OpenACCVectorLengthClause &Clause) {
2574
  assert(Clause.hasIntExpr() &&
2575
         "vector_length clause requires a valid int expr");
2576
  Profiler.VisitStmt(Clause.getIntExpr());
2577
}
2578

2579
void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
2580
  if (Clause.hasIntExpr())
2581
    Profiler.VisitStmt(Clause.getIntExpr());
2582
}
2583

2584
void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
2585
  if (Clause.hasDevNumExpr())
2586
    Profiler.VisitStmt(Clause.getDevNumExpr());
2587
  for (auto *E : Clause.getQueueIdExprs())
2588
    Profiler.VisitStmt(E);
2589
}
2590
/// Nothing to do here, there are no sub-statements.
2591
void OpenACCClauseProfiler::VisitDeviceTypeClause(
2592
    const OpenACCDeviceTypeClause &Clause) {}
2593

2594
void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}
2595

2596
void OpenACCClauseProfiler::VisitIndependentClause(
2597
    const OpenACCIndependentClause &Clause) {}
2598

2599
void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}
2600

2601
void OpenACCClauseProfiler::VisitReductionClause(
2602
    const OpenACCReductionClause &Clause) {
2603
  for (auto *E : Clause.getVarList())
2604
    Profiler.VisitStmt(E);
2605
}
2606
} // namespace
2607

2608
void StmtProfiler::VisitOpenACCComputeConstruct(
2609
    const OpenACCComputeConstruct *S) {
2610
  // VisitStmt handles children, so the AssociatedStmt is handled.
2611
  VisitStmt(S);
2612

2613
  OpenACCClauseProfiler P{*this};
2614
  P.VisitOpenACCClauseList(S->clauses());
2615
}
2616

2617
void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2618
  // VisitStmt handles children, so the Loop is handled.
2619
  VisitStmt(S);
2620

2621
  OpenACCClauseProfiler P{*this};
2622
  P.VisitOpenACCClauseList(S->clauses());
2623
}
2624

2625
void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2626
                   bool Canonical, bool ProfileLambdaExpr) const {
2627
  StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr);
2628
  Profiler.Visit(this);
2629
}
2630

2631
void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
2632
                          class ODRHash &Hash) const {
2633
  StmtProfilerWithoutPointers Profiler(ID, Hash);
2634
  Profiler.Visit(this);
2635
}
2636

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.