clang  19.0.0git
StmtProfile.cpp
Go to the documentation of this file.
1 //===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Stmt::Profile method, which builds a unique bit
10 // representation that identifies a statement/expression.
11 //
12 //===----------------------------------------------------------------------===//
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(
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(
1163  VisitOMPLoopDirective(S);
1164 }
1165 
1166 void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective(
1168  VisitOMPLoopDirective(S);
1169 }
1170 
1171 void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective(
1173  VisitOMPLoopDirective(S);
1174 }
1175 
1176 void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective(
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(
1202  VisitOMPLoopDirective(S);
1203 }
1204 
1205 void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
1207  VisitOMPLoopDirective(S);
1208 }
1209 
1210 void StmtProfiler::VisitOMPDistributeSimdDirective(
1211  const OMPDistributeSimdDirective *S) {
1212  VisitOMPLoopDirective(S);
1213 }
1214 
1215 void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
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(
1232  VisitOMPLoopDirective(S);
1233 }
1234 
1235 void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
1237  VisitOMPLoopDirective(S);
1238 }
1239 
1240 void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
1242  VisitOMPLoopDirective(S);
1243 }
1244 
1245 void StmtProfiler::VisitOMPTargetTeamsDirective(
1246  const OMPTargetTeamsDirective *S) {
1247  VisitOMPExecutableDirective(S);
1248 }
1249 
1250 void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
1252  VisitOMPLoopDirective(S);
1253 }
1254 
1255 void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
1257  VisitOMPLoopDirective(S);
1258 }
1259 
1260 void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1262  VisitOMPLoopDirective(S);
1263 }
1264 
1265 void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
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(
1294  VisitOMPLoopDirective(S);
1295 }
1296 
1297 void StmtProfiler::VisitOMPParallelGenericLoopDirective(
1299  VisitOMPLoopDirective(S);
1300 }
1301 
1302 void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective(
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::VisitSYCLUniqueStableIdExpr(
1334  const SYCLUniqueStableIdExpr *S) {
1335  VisitExpr(S);
1336 }
1337 
1338 void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
1339  VisitExpr(S);
1340  ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
1341 }
1342 
1343 void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
1344  VisitExpr(S);
1345  S->getValue().Profile(ID);
1346 
1347  QualType T = S->getType();
1348  if (Canonical)
1349  T = T.getCanonicalType();
1350  ID.AddInteger(T->getTypeClass());
1351  if (auto BitIntT = T->getAs<BitIntType>())
1352  BitIntT->Profile(ID);
1353  else
1354  ID.AddInteger(T->castAs<BuiltinType>()->getKind());
1355 }
1356 
1357 void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
1358  VisitExpr(S);
1359  S->getValue().Profile(ID);
1360  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1361 }
1362 
1363 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
1364  VisitExpr(S);
1365  ID.AddInteger(llvm::to_underlying(S->getKind()));
1366  ID.AddInteger(S->getValue());
1367 }
1368 
1369 void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
1370  VisitExpr(S);
1371  S->getValue().Profile(ID);
1372  ID.AddBoolean(S->isExact());
1373  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
1374 }
1375 
1376 void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
1377  VisitExpr(S);
1378 }
1379 
1380 void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
1381  VisitExpr(S);
1382  ID.AddString(S->getBytes());
1383  ID.AddInteger(llvm::to_underlying(S->getKind()));
1384 }
1385 
1386 void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
1387  VisitExpr(S);
1388 }
1389 
1390 void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
1391  VisitExpr(S);
1392 }
1393 
1394 void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
1395  VisitExpr(S);
1396  ID.AddInteger(S->getOpcode());
1397 }
1398 
1399 void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
1400  VisitType(S->getTypeSourceInfo()->getType());
1401  unsigned n = S->getNumComponents();
1402  for (unsigned i = 0; i < n; ++i) {
1403  const OffsetOfNode &ON = S->getComponent(i);
1404  ID.AddInteger(ON.getKind());
1405  switch (ON.getKind()) {
1406  case OffsetOfNode::Array:
1407  // Expressions handled below.
1408  break;
1409 
1410  case OffsetOfNode::Field:
1411  VisitDecl(ON.getField());
1412  break;
1413 
1415  VisitIdentifierInfo(ON.getFieldName());
1416  break;
1417 
1418  case OffsetOfNode::Base:
1419  // These nodes are implicit, and therefore don't need profiling.
1420  break;
1421  }
1422  }
1423 
1424  VisitExpr(S);
1425 }
1426 
1427 void
1428 StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
1429  VisitExpr(S);
1430  ID.AddInteger(S->getKind());
1431  if (S->isArgumentType())
1432  VisitType(S->getArgumentType());
1433 }
1434 
1435 void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
1436  VisitExpr(S);
1437 }
1438 
1439 void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) {
1440  VisitExpr(S);
1441 }
1442 
1443 void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) {
1444  VisitExpr(S);
1445 }
1446 
1447 void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
1448  VisitExpr(S);
1449 }
1450 
1451 void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) {
1452  VisitExpr(S);
1453  for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I)
1454  VisitDecl(S->getIteratorDecl(I));
1455 }
1456 
1457 void StmtProfiler::VisitCallExpr(const CallExpr *S) {
1458  VisitExpr(S);
1459 }
1460 
1461 void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
1462  VisitExpr(S);
1463  VisitDecl(S->getMemberDecl());
1464  if (!Canonical)
1465  VisitNestedNameSpecifier(S->getQualifier());
1466  ID.AddBoolean(S->isArrow());
1467 }
1468 
1469 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
1470  VisitExpr(S);
1471  ID.AddBoolean(S->isFileScope());
1472 }
1473 
1474 void StmtProfiler::VisitCastExpr(const CastExpr *S) {
1475  VisitExpr(S);
1476 }
1477 
1478 void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
1479  VisitCastExpr(S);
1480  ID.AddInteger(S->getValueKind());
1481 }
1482 
1483 void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
1484  VisitCastExpr(S);
1485  VisitType(S->getTypeAsWritten());
1486 }
1487 
1488 void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
1489  VisitExplicitCastExpr(S);
1490 }
1491 
1492 void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
1493  VisitExpr(S);
1494  ID.AddInteger(S->getOpcode());
1495 }
1496 
1497 void
1498 StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
1499  VisitBinaryOperator(S);
1500 }
1501 
1502 void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
1503  VisitExpr(S);
1504 }
1505 
1506 void StmtProfiler::VisitBinaryConditionalOperator(
1507  const BinaryConditionalOperator *S) {
1508  VisitExpr(S);
1509 }
1510 
1511 void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
1512  VisitExpr(S);
1513  VisitDecl(S->getLabel());
1514 }
1515 
1516 void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
1517  VisitExpr(S);
1518 }
1519 
1520 void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
1521  VisitExpr(S);
1522 }
1523 
1524 void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
1525  VisitExpr(S);
1526 }
1527 
1528 void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
1529  VisitExpr(S);
1530 }
1531 
1532 void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
1533  VisitExpr(S);
1534 }
1535 
1536 void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
1537  VisitExpr(S);
1538 }
1539 
1540 void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
1541  if (S->getSyntacticForm()) {
1542  VisitInitListExpr(S->getSyntacticForm());
1543  return;
1544  }
1545 
1546  VisitExpr(S);
1547 }
1548 
1549 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
1550  VisitExpr(S);
1551  ID.AddBoolean(S->usesGNUSyntax());
1552  for (const DesignatedInitExpr::Designator &D : S->designators()) {
1553  if (D.isFieldDesignator()) {
1554  ID.AddInteger(0);
1555  VisitName(D.getFieldName());
1556  continue;
1557  }
1558 
1559  if (D.isArrayDesignator()) {
1560  ID.AddInteger(1);
1561  } else {
1562  assert(D.isArrayRangeDesignator());
1563  ID.AddInteger(2);
1564  }
1565  ID.AddInteger(D.getArrayIndex());
1566  }
1567 }
1568 
1569 // Seems that if VisitInitListExpr() only works on the syntactic form of an
1570 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
1571 void StmtProfiler::VisitDesignatedInitUpdateExpr(
1572  const DesignatedInitUpdateExpr *S) {
1573  llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
1574  "initializer");
1575 }
1576 
1577 void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
1578  VisitExpr(S);
1579 }
1580 
1581 void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
1582  VisitExpr(S);
1583 }
1584 
1585 void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
1586  llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
1587 }
1588 
1589 void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
1590  VisitExpr(S);
1591 }
1592 
1593 void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
1594  VisitExpr(S);
1595  VisitName(&S->getAccessor());
1596 }
1597 
1598 void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
1599  VisitExpr(S);
1600  VisitDecl(S->getBlockDecl());
1601 }
1602 
1603 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
1604  VisitExpr(S);
1605  for (const GenericSelectionExpr::ConstAssociation Assoc :
1606  S->associations()) {
1607  QualType T = Assoc.getType();
1608  if (T.isNull())
1609  ID.AddPointer(nullptr);
1610  else
1611  VisitType(T);
1612  VisitExpr(Assoc.getAssociationExpr());
1613  }
1614 }
1615 
1616 void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
1617  VisitExpr(S);
1619  i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
1620  // Normally, we would not profile the source expressions of OVEs.
1621  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
1622  Visit(OVE->getSourceExpr());
1623 }
1624 
1625 void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
1626  VisitExpr(S);
1627  ID.AddInteger(S->getOp());
1628 }
1629 
1630 void StmtProfiler::VisitConceptSpecializationExpr(
1631  const ConceptSpecializationExpr *S) {
1632  VisitExpr(S);
1633  VisitDecl(S->getNamedConcept());
1634  for (const TemplateArgument &Arg : S->getTemplateArguments())
1635  VisitTemplateArgument(Arg);
1636 }
1637 
1638 void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
1639  VisitExpr(S);
1640  ID.AddInteger(S->getLocalParameters().size());
1641  for (ParmVarDecl *LocalParam : S->getLocalParameters())
1642  VisitDecl(LocalParam);
1643  ID.AddInteger(S->getRequirements().size());
1644  for (concepts::Requirement *Req : S->getRequirements()) {
1645  if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
1646  ID.AddInteger(concepts::Requirement::RK_Type);
1647  ID.AddBoolean(TypeReq->isSubstitutionFailure());
1648  if (!TypeReq->isSubstitutionFailure())
1649  VisitType(TypeReq->getType()->getType());
1650  } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
1652  ID.AddBoolean(ExprReq->isExprSubstitutionFailure());
1653  if (!ExprReq->isExprSubstitutionFailure())
1654  Visit(ExprReq->getExpr());
1655  // C++2a [expr.prim.req.compound]p1 Example:
1656  // [...] The compound-requirement in C1 requires that x++ is a valid
1657  // expression. It is equivalent to the simple-requirement x++; [...]
1658  // We therefore do not profile isSimple() here.
1659  ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());
1661  ExprReq->getReturnTypeRequirement();
1662  if (RetReq.isEmpty()) {
1663  ID.AddInteger(0);
1664  } else if (RetReq.isTypeConstraint()) {
1665  ID.AddInteger(1);
1667  } else {
1668  assert(RetReq.isSubstitutionFailure());
1669  ID.AddInteger(2);
1670  }
1671  } else {
1673  auto *NestedReq = cast<concepts::NestedRequirement>(Req);
1674  ID.AddBoolean(NestedReq->hasInvalidConstraint());
1675  if (!NestedReq->hasInvalidConstraint())
1676  Visit(NestedReq->getConstraintExpr());
1677  }
1678  }
1679 }
1680 
1682  UnaryOperatorKind &UnaryOp,
1683  BinaryOperatorKind &BinaryOp,
1684  unsigned &NumArgs) {
1685  switch (S->getOperator()) {
1686  case OO_None:
1687  case OO_New:
1688  case OO_Delete:
1689  case OO_Array_New:
1690  case OO_Array_Delete:
1691  case OO_Arrow:
1692  case OO_Conditional:
1694  llvm_unreachable("Invalid operator call kind");
1695 
1696  case OO_Plus:
1697  if (NumArgs == 1) {
1698  UnaryOp = UO_Plus;
1699  return Stmt::UnaryOperatorClass;
1700  }
1701 
1702  BinaryOp = BO_Add;
1703  return Stmt::BinaryOperatorClass;
1704 
1705  case OO_Minus:
1706  if (NumArgs == 1) {
1707  UnaryOp = UO_Minus;
1708  return Stmt::UnaryOperatorClass;
1709  }
1710 
1711  BinaryOp = BO_Sub;
1712  return Stmt::BinaryOperatorClass;
1713 
1714  case OO_Star:
1715  if (NumArgs == 1) {
1716  UnaryOp = UO_Deref;
1717  return Stmt::UnaryOperatorClass;
1718  }
1719 
1720  BinaryOp = BO_Mul;
1721  return Stmt::BinaryOperatorClass;
1722 
1723  case OO_Slash:
1724  BinaryOp = BO_Div;
1725  return Stmt::BinaryOperatorClass;
1726 
1727  case OO_Percent:
1728  BinaryOp = BO_Rem;
1729  return Stmt::BinaryOperatorClass;
1730 
1731  case OO_Caret:
1732  BinaryOp = BO_Xor;
1733  return Stmt::BinaryOperatorClass;
1734 
1735  case OO_Amp:
1736  if (NumArgs == 1) {
1737  UnaryOp = UO_AddrOf;
1738  return Stmt::UnaryOperatorClass;
1739  }
1740 
1741  BinaryOp = BO_And;
1742  return Stmt::BinaryOperatorClass;
1743 
1744  case OO_Pipe:
1745  BinaryOp = BO_Or;
1746  return Stmt::BinaryOperatorClass;
1747 
1748  case OO_Tilde:
1749  UnaryOp = UO_Not;
1750  return Stmt::UnaryOperatorClass;
1751 
1752  case OO_Exclaim:
1753  UnaryOp = UO_LNot;
1754  return Stmt::UnaryOperatorClass;
1755 
1756  case OO_Equal:
1757  BinaryOp = BO_Assign;
1758  return Stmt::BinaryOperatorClass;
1759 
1760  case OO_Less:
1761  BinaryOp = BO_LT;
1762  return Stmt::BinaryOperatorClass;
1763 
1764  case OO_Greater:
1765  BinaryOp = BO_GT;
1766  return Stmt::BinaryOperatorClass;
1767 
1768  case OO_PlusEqual:
1769  BinaryOp = BO_AddAssign;
1770  return Stmt::CompoundAssignOperatorClass;
1771 
1772  case OO_MinusEqual:
1773  BinaryOp = BO_SubAssign;
1774  return Stmt::CompoundAssignOperatorClass;
1775 
1776  case OO_StarEqual:
1777  BinaryOp = BO_MulAssign;
1778  return Stmt::CompoundAssignOperatorClass;
1779 
1780  case OO_SlashEqual:
1781  BinaryOp = BO_DivAssign;
1782  return Stmt::CompoundAssignOperatorClass;
1783 
1784  case OO_PercentEqual:
1785  BinaryOp = BO_RemAssign;
1786  return Stmt::CompoundAssignOperatorClass;
1787 
1788  case OO_CaretEqual:
1789  BinaryOp = BO_XorAssign;
1790  return Stmt::CompoundAssignOperatorClass;
1791 
1792  case OO_AmpEqual:
1793  BinaryOp = BO_AndAssign;
1794  return Stmt::CompoundAssignOperatorClass;
1795 
1796  case OO_PipeEqual:
1797  BinaryOp = BO_OrAssign;
1798  return Stmt::CompoundAssignOperatorClass;
1799 
1800  case OO_LessLess:
1801  BinaryOp = BO_Shl;
1802  return Stmt::BinaryOperatorClass;
1803 
1804  case OO_GreaterGreater:
1805  BinaryOp = BO_Shr;
1806  return Stmt::BinaryOperatorClass;
1807 
1808  case OO_LessLessEqual:
1809  BinaryOp = BO_ShlAssign;
1810  return Stmt::CompoundAssignOperatorClass;
1811 
1812  case OO_GreaterGreaterEqual:
1813  BinaryOp = BO_ShrAssign;
1814  return Stmt::CompoundAssignOperatorClass;
1815 
1816  case OO_EqualEqual:
1817  BinaryOp = BO_EQ;
1818  return Stmt::BinaryOperatorClass;
1819 
1820  case OO_ExclaimEqual:
1821  BinaryOp = BO_NE;
1822  return Stmt::BinaryOperatorClass;
1823 
1824  case OO_LessEqual:
1825  BinaryOp = BO_LE;
1826  return Stmt::BinaryOperatorClass;
1827 
1828  case OO_GreaterEqual:
1829  BinaryOp = BO_GE;
1830  return Stmt::BinaryOperatorClass;
1831 
1832  case OO_Spaceship:
1833  BinaryOp = BO_Cmp;
1834  return Stmt::BinaryOperatorClass;
1835 
1836  case OO_AmpAmp:
1837  BinaryOp = BO_LAnd;
1838  return Stmt::BinaryOperatorClass;
1839 
1840  case OO_PipePipe:
1841  BinaryOp = BO_LOr;
1842  return Stmt::BinaryOperatorClass;
1843 
1844  case OO_PlusPlus:
1845  UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc;
1846  NumArgs = 1;
1847  return Stmt::UnaryOperatorClass;
1848 
1849  case OO_MinusMinus:
1850  UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec;
1851  NumArgs = 1;
1852  return Stmt::UnaryOperatorClass;
1853 
1854  case OO_Comma:
1855  BinaryOp = BO_Comma;
1856  return Stmt::BinaryOperatorClass;
1857 
1858  case OO_ArrowStar:
1859  BinaryOp = BO_PtrMemI;
1860  return Stmt::BinaryOperatorClass;
1861 
1862  case OO_Subscript:
1863  return Stmt::ArraySubscriptExprClass;
1864 
1865  case OO_Call:
1866  return Stmt::CallExprClass;
1867 
1868  case OO_Coawait:
1869  UnaryOp = UO_Coawait;
1870  return Stmt::UnaryOperatorClass;
1871  }
1872 
1873  llvm_unreachable("Invalid overloaded operator expression");
1874 }
1875 
1876 #if defined(_MSC_VER) && !defined(__clang__)
1877 #if _MSC_VER == 1911
1878 // Work around https://developercommunity.visualstudio.com/content/problem/84002/clang-cl-when-built-with-vc-2017-crashes-cause-vc.html
1879 // MSVC 2017 update 3 miscompiles this function, and a clang built with it
1880 // will crash in stage 2 of a bootstrap build.
1881 #pragma optimize("", off)
1882 #endif
1883 #endif
1884 
1885 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
1886  if (S->isTypeDependent()) {
1887  // Type-dependent operator calls are profiled like their underlying
1888  // syntactic operator.
1889  //
1890  // An operator call to operator-> is always implicit, so just skip it. The
1891  // enclosing MemberExpr will profile the actual member access.
1892  if (S->getOperator() == OO_Arrow)
1893  return Visit(S->getArg(0));
1894 
1895  UnaryOperatorKind UnaryOp = UO_Extension;
1896  BinaryOperatorKind BinaryOp = BO_Comma;
1897  unsigned NumArgs = S->getNumArgs();
1898  Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs);
1899 
1900  ID.AddInteger(SC);
1901  for (unsigned I = 0; I != NumArgs; ++I)
1902  Visit(S->getArg(I));
1903  if (SC == Stmt::UnaryOperatorClass)
1904  ID.AddInteger(UnaryOp);
1905  else if (SC == Stmt::BinaryOperatorClass ||
1906  SC == Stmt::CompoundAssignOperatorClass)
1907  ID.AddInteger(BinaryOp);
1908  else
1909  assert(SC == Stmt::ArraySubscriptExprClass || SC == Stmt::CallExprClass);
1910 
1911  return;
1912  }
1913 
1914  VisitCallExpr(S);
1915  ID.AddInteger(S->getOperator());
1916 }
1917 
1918 void StmtProfiler::VisitCXXRewrittenBinaryOperator(
1919  const CXXRewrittenBinaryOperator *S) {
1920  // If a rewritten operator were ever to be type-dependent, we should profile
1921  // it following its syntactic operator.
1922  assert(!S->isTypeDependent() &&
1923  "resolved rewritten operator should never be type-dependent");
1924  ID.AddBoolean(S->isReversed());
1925  VisitExpr(S->getSemanticForm());
1926 }
1927 
1928 #if defined(_MSC_VER) && !defined(__clang__)
1929 #if _MSC_VER == 1911
1930 #pragma optimize("", on)
1931 #endif
1932 #endif
1933 
1934 void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
1935  VisitCallExpr(S);
1936 }
1937 
1938 void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
1939  VisitCallExpr(S);
1940 }
1941 
1942 void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
1943  VisitExpr(S);
1944 }
1945 
1946 void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
1947  VisitExplicitCastExpr(S);
1948 }
1949 
1950 void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
1951  VisitCXXNamedCastExpr(S);
1952 }
1953 
1954 void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
1955  VisitCXXNamedCastExpr(S);
1956 }
1957 
1958 void
1959 StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
1960  VisitCXXNamedCastExpr(S);
1961 }
1962 
1963 void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
1964  VisitCXXNamedCastExpr(S);
1965 }
1966 
1967 void StmtProfiler::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *S) {
1968  VisitExpr(S);
1969  VisitType(S->getTypeInfoAsWritten()->getType());
1970 }
1971 
1972 void StmtProfiler::VisitSYCLBuiltinNumFieldsExpr(
1973  const SYCLBuiltinNumFieldsExpr *E) {
1974  VisitType(E->getSourceType());
1975 }
1976 
1977 void StmtProfiler::VisitSYCLBuiltinFieldTypeExpr(
1978  const SYCLBuiltinFieldTypeExpr *E) {
1979  VisitType(E->getSourceType());
1980  VisitExpr(E->getIndex());
1981 }
1982 
1983 void StmtProfiler::VisitSYCLBuiltinNumBasesExpr(
1984  const SYCLBuiltinNumBasesExpr *E) {
1985  VisitType(E->getSourceType());
1986 }
1987 
1988 void StmtProfiler::VisitSYCLBuiltinBaseTypeExpr(
1989  const SYCLBuiltinBaseTypeExpr *E) {
1990  VisitType(E->getSourceType());
1991  VisitExpr(E->getIndex());
1992 }
1993 
1994 void StmtProfiler::VisitCXXAddrspaceCastExpr(const CXXAddrspaceCastExpr *S) {
1995  VisitCXXNamedCastExpr(S);
1996 }
1997 
1998 void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
1999  VisitCallExpr(S);
2000 }
2001 
2002 void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
2003  VisitExpr(S);
2004  ID.AddBoolean(S->getValue());
2005 }
2006 
2007 void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
2008  VisitExpr(S);
2009 }
2010 
2011 void StmtProfiler::VisitCXXStdInitializerListExpr(
2012  const CXXStdInitializerListExpr *S) {
2013  VisitExpr(S);
2014 }
2015 
2016 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
2017  VisitExpr(S);
2018  if (S->isTypeOperand())
2019  VisitType(S->getTypeOperandSourceInfo()->getType());
2020 }
2021 
2022 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
2023  VisitExpr(S);
2024  if (S->isTypeOperand())
2025  VisitType(S->getTypeOperandSourceInfo()->getType());
2026 }
2027 
2028 void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
2029  VisitExpr(S);
2030  VisitDecl(S->getPropertyDecl());
2031 }
2032 
2033 void StmtProfiler::VisitMSPropertySubscriptExpr(
2034  const MSPropertySubscriptExpr *S) {
2035  VisitExpr(S);
2036 }
2037 
2038 void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
2039  VisitExpr(S);
2040  ID.AddBoolean(S->isImplicit());
2041  ID.AddBoolean(S->isCapturedByCopyInLambdaWithExplicitObjectParameter());
2042 }
2043 
2044 void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
2045  VisitExpr(S);
2046 }
2047 
2048 void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
2049  VisitExpr(S);
2050  VisitDecl(S->getParam());
2051 }
2052 
2053 void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
2054  VisitExpr(S);
2055  VisitDecl(S->getField());
2056 }
2057 
2058 void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
2059  VisitExpr(S);
2060  VisitDecl(
2061  const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
2062 }
2063 
2064 void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
2065  VisitExpr(S);
2066  VisitDecl(S->getConstructor());
2067  ID.AddBoolean(S->isElidable());
2068 }
2069 
2070 void StmtProfiler::VisitCXXInheritedCtorInitExpr(
2071  const CXXInheritedCtorInitExpr *S) {
2072  VisitExpr(S);
2073  VisitDecl(S->getConstructor());
2074 }
2075 
2076 void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
2077  VisitExplicitCastExpr(S);
2078 }
2079 
2080 void
2081 StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
2082  VisitCXXConstructExpr(S);
2083 }
2084 
2085 void
2086 StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
2087  if (!ProfileLambdaExpr) {
2088  // Do not recursively visit the children of this expression. Profiling the
2089  // body would result in unnecessary work, and is not safe to do during
2090  // deserialization.
2091  VisitStmtNoChildren(S);
2092 
2093  // C++20 [temp.over.link]p5:
2094  // Two lambda-expressions are never considered equivalent.
2095  VisitDecl(S->getLambdaClass());
2096 
2097  return;
2098  }
2099 
2100  CXXRecordDecl *Lambda = S->getLambdaClass();
2101  for (const auto &Capture : Lambda->captures()) {
2102  ID.AddInteger(Capture.getCaptureKind());
2103  if (Capture.capturesVariable())
2104  VisitDecl(Capture.getCapturedVar());
2105  }
2106 
2107  // Profiling the body of the lambda may be dangerous during deserialization.
2108  // So we'd like only to profile the signature here.
2109  ODRHash Hasher;
2110  // FIXME: We can't get the operator call easily by
2111  // `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization.
2112  // So we have to do something raw here.
2113  for (auto *SubDecl : Lambda->decls()) {
2114  FunctionDecl *Call = nullptr;
2115  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(SubDecl))
2116  Call = FTD->getTemplatedDecl();
2117  else if (auto *FD = dyn_cast<FunctionDecl>(SubDecl))
2118  Call = FD;
2119 
2120  if (!Call)
2121  continue;
2122 
2123  Hasher.AddFunctionDecl(Call, /*SkipBody=*/true);
2124  }
2125  ID.AddInteger(Hasher.CalculateHash());
2126 }
2127 
2128 void
2129 StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
2130  VisitExpr(S);
2131 }
2132 
2133 void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
2134  VisitExpr(S);
2135  ID.AddBoolean(S->isGlobalDelete());
2136  ID.AddBoolean(S->isArrayForm());
2137  VisitDecl(S->getOperatorDelete());
2138 }
2139 
2140 void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
2141  VisitExpr(S);
2142  VisitType(S->getAllocatedType());
2143  VisitDecl(S->getOperatorNew());
2144  VisitDecl(S->getOperatorDelete());
2145  ID.AddBoolean(S->isArray());
2146  ID.AddInteger(S->getNumPlacementArgs());
2147  ID.AddBoolean(S->isGlobalNew());
2148  ID.AddBoolean(S->isParenTypeId());
2149  ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
2150 }
2151 
2152 void
2153 StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
2154  VisitExpr(S);
2155  ID.AddBoolean(S->isArrow());
2156  VisitNestedNameSpecifier(S->getQualifier());
2157  ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
2158  if (S->getScopeTypeInfo())
2159  VisitType(S->getScopeTypeInfo()->getType());
2160  ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
2161  if (S->getDestroyedTypeInfo())
2162  VisitType(S->getDestroyedType());
2163  else
2164  VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
2165 }
2166 
2167 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
2168  VisitExpr(S);
2169  VisitNestedNameSpecifier(S->getQualifier());
2170  VisitName(S->getName(), /*TreatAsDecl*/ true);
2171  ID.AddBoolean(S->hasExplicitTemplateArgs());
2172  if (S->hasExplicitTemplateArgs())
2173  VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2174 }
2175 
2176 void
2177 StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
2178  VisitOverloadExpr(S);
2179 }
2180 
2181 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
2182  VisitExpr(S);
2183  ID.AddInteger(S->getTrait());
2184  ID.AddInteger(S->getNumArgs());
2185  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2186  VisitType(S->getArg(I)->getType());
2187 }
2188 
2189 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
2190  VisitExpr(S);
2191  ID.AddInteger(S->getTrait());
2192  VisitType(S->getQueriedType());
2193 }
2194 
2195 void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
2196  VisitExpr(S);
2197  ID.AddInteger(S->getTrait());
2198  VisitExpr(S->getQueriedExpression());
2199 }
2200 
2201 void StmtProfiler::VisitDependentScopeDeclRefExpr(
2202  const DependentScopeDeclRefExpr *S) {
2203  VisitExpr(S);
2204  VisitName(S->getDeclName());
2205  VisitNestedNameSpecifier(S->getQualifier());
2206  ID.AddBoolean(S->hasExplicitTemplateArgs());
2207  if (S->hasExplicitTemplateArgs())
2208  VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2209 }
2210 
2211 void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
2212  VisitExpr(S);
2213 }
2214 
2215 void StmtProfiler::VisitCXXUnresolvedConstructExpr(
2216  const CXXUnresolvedConstructExpr *S) {
2217  VisitExpr(S);
2218  VisitType(S->getTypeAsWritten());
2219  ID.AddInteger(S->isListInitialization());
2220 }
2221 
2222 void StmtProfiler::VisitCXXDependentScopeMemberExpr(
2223  const CXXDependentScopeMemberExpr *S) {
2224  ID.AddBoolean(S->isImplicitAccess());
2225  if (!S->isImplicitAccess()) {
2226  VisitExpr(S);
2227  ID.AddBoolean(S->isArrow());
2228  }
2229  VisitNestedNameSpecifier(S->getQualifier());
2230  VisitName(S->getMember());
2231  ID.AddBoolean(S->hasExplicitTemplateArgs());
2232  if (S->hasExplicitTemplateArgs())
2233  VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2234 }
2235 
2236 void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
2237  ID.AddBoolean(S->isImplicitAccess());
2238  if (!S->isImplicitAccess()) {
2239  VisitExpr(S);
2240  ID.AddBoolean(S->isArrow());
2241  }
2242  VisitNestedNameSpecifier(S->getQualifier());
2243  VisitName(S->getMemberName());
2244  ID.AddBoolean(S->hasExplicitTemplateArgs());
2245  if (S->hasExplicitTemplateArgs())
2246  VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
2247 }
2248 
2249 void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
2250  VisitExpr(S);
2251 }
2252 
2253 void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
2254  VisitExpr(S);
2255 }
2256 
2257 void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
2258  VisitExpr(S);
2259  VisitDecl(S->getPack());
2260  if (S->isPartiallySubstituted()) {
2261  auto Args = S->getPartialArguments();
2262  ID.AddInteger(Args.size());
2263  for (const auto &TA : Args)
2264  VisitTemplateArgument(TA);
2265  } else {
2266  ID.AddInteger(0);
2267  }
2268 }
2269 
2270 void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
2271  VisitExpr(E);
2272  VisitExpr(E->getPackIdExpression());
2273  VisitExpr(E->getIndexExpr());
2274 }
2275 
2276 void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
2278  VisitExpr(S);
2279  VisitDecl(S->getParameterPack());
2280  VisitTemplateArgument(S->getArgumentPack());
2281 }
2282 
2283 void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
2284  const SubstNonTypeTemplateParmExpr *E) {
2285  // Profile exactly as the replacement expression.
2286  Visit(E->getReplacement());
2287 }
2288 
2289 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
2290  VisitExpr(S);
2291  VisitDecl(S->getParameterPack());
2292  ID.AddInteger(S->getNumExpansions());
2293  for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
2294  VisitDecl(*I);
2295 }
2296 
2297 void StmtProfiler::VisitMaterializeTemporaryExpr(
2298  const MaterializeTemporaryExpr *S) {
2299  VisitExpr(S);
2300 }
2301 
2302 void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
2303  VisitExpr(S);
2304  ID.AddInteger(S->getOperator());
2305 }
2306 
2307 void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
2308  VisitExpr(S);
2309 }
2310 
2311 void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
2312  VisitStmt(S);
2313 }
2314 
2315 void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
2316  VisitStmt(S);
2317 }
2318 
2319 void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
2320  VisitExpr(S);
2321 }
2322 
2323 void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
2324  VisitExpr(S);
2325 }
2326 
2327 void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
2328  VisitExpr(S);
2329 }
2330 
2331 void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2332  VisitExpr(E);
2333 }
2334 
2335 void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
2336  VisitExpr(E);
2337 }
2338 
2339 void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
2340  VisitExpr(E);
2341 }
2342 
2343 void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
2344 
2345 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
2346  VisitExpr(S);
2347 }
2348 
2349 void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
2350  VisitExpr(E);
2351 }
2352 
2353 void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
2354  VisitExpr(E);
2355 }
2356 
2357 void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
2358  VisitExpr(E);
2359 }
2360 
2361 void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
2362  VisitExpr(S);
2363  VisitType(S->getEncodedType());
2364 }
2365 
2366 void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
2367  VisitExpr(S);
2368  VisitName(S->getSelector());
2369 }
2370 
2371 void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
2372  VisitExpr(S);
2373  VisitDecl(S->getProtocol());
2374 }
2375 
2376 void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
2377  VisitExpr(S);
2378  VisitDecl(S->getDecl());
2379  ID.AddBoolean(S->isArrow());
2380  ID.AddBoolean(S->isFreeIvar());
2381 }
2382 
2383 void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
2384  VisitExpr(S);
2385  if (S->isImplicitProperty()) {
2386  VisitDecl(S->getImplicitPropertyGetter());
2387  VisitDecl(S->getImplicitPropertySetter());
2388  } else {
2389  VisitDecl(S->getExplicitProperty());
2390  }
2391  if (S->isSuperReceiver()) {
2392  ID.AddBoolean(S->isSuperReceiver());
2393  VisitType(S->getSuperReceiverType());
2394  }
2395 }
2396 
2397 void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
2398  VisitExpr(S);
2399  VisitDecl(S->getAtIndexMethodDecl());
2400  VisitDecl(S->setAtIndexMethodDecl());
2401 }
2402 
2403 void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
2404  VisitExpr(S);
2405  VisitName(S->getSelector());
2406  VisitDecl(S->getMethodDecl());
2407 }
2408 
2409 void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
2410  VisitExpr(S);
2411  ID.AddBoolean(S->isArrow());
2412 }
2413 
2414 void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
2415  VisitExpr(S);
2416  ID.AddBoolean(S->getValue());
2417 }
2418 
2419 void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
2420  const ObjCIndirectCopyRestoreExpr *S) {
2421  VisitExpr(S);
2422  ID.AddBoolean(S->shouldCopy());
2423 }
2424 
2425 void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
2426  VisitExplicitCastExpr(S);
2427  ID.AddBoolean(S->getBridgeKind());
2428 }
2429 
2430 void StmtProfiler::VisitObjCAvailabilityCheckExpr(
2431  const ObjCAvailabilityCheckExpr *S) {
2432  VisitExpr(S);
2433 }
2434 
2435 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
2436  unsigned NumArgs) {
2437  ID.AddInteger(NumArgs);
2438  for (unsigned I = 0; I != NumArgs; ++I)
2439  VisitTemplateArgument(Args[I].getArgument());
2440 }
2441 
2442 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
2443  // Mostly repetitive with TemplateArgument::Profile!
2444  ID.AddInteger(Arg.getKind());
2445  switch (Arg.getKind()) {
2447  break;
2448 
2450  VisitType(Arg.getAsType());
2451  break;
2452 
2455  VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
2456  break;
2457 
2459  VisitType(Arg.getParamTypeForDecl());
2460  // FIXME: Do we need to recursively decompose template parameter objects?
2461  VisitDecl(Arg.getAsDecl());
2462  break;
2463 
2465  VisitType(Arg.getNullPtrType());
2466  break;
2467 
2469  VisitType(Arg.getIntegralType());
2470  Arg.getAsIntegral().Profile(ID);
2471  break;
2472 
2474  VisitType(Arg.getStructuralValueType());
2475  // FIXME: Do we need to recursively decompose this ourselves?
2477  break;
2478 
2480  Visit(Arg.getAsExpr());
2481  break;
2482 
2484  for (const auto &P : Arg.pack_elements())
2485  VisitTemplateArgument(P);
2486  break;
2487  }
2488 }
2489 
2490 namespace {
2491 class OpenACCClauseProfiler
2492  : public OpenACCClauseVisitor<OpenACCClauseProfiler> {
2493  StmtProfiler &Profiler;
2494 
2495 public:
2496  OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {}
2497 
2498  void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) {
2499  for (const OpenACCClause *Clause : Clauses) {
2500  // TODO OpenACC: When we have clauses with expressions, we should
2501  // profile them too.
2502  Visit(Clause);
2503  }
2504  }
2505 
2506 #define VISIT_CLAUSE(CLAUSE_NAME) \
2507  void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
2508 
2509 #include "clang/Basic/OpenACCClauses.def"
2510 };
2511 
2512 /// Nothing to do here, there are no sub-statements.
2513 void OpenACCClauseProfiler::VisitDefaultClause(
2514  const OpenACCDefaultClause &Clause) {}
2515 
2516 void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
2517  assert(Clause.hasConditionExpr() &&
2518  "if clause requires a valid condition expr");
2519  Profiler.VisitStmt(Clause.getConditionExpr());
2520 }
2521 
2522 void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
2523  for (auto *E : Clause.getVarList())
2524  Profiler.VisitStmt(E);
2525 }
2526 void OpenACCClauseProfiler::VisitCopyInClause(
2527  const OpenACCCopyInClause &Clause) {
2528  for (auto *E : Clause.getVarList())
2529  Profiler.VisitStmt(E);
2530 }
2531 
2532 void OpenACCClauseProfiler::VisitCopyOutClause(
2533  const OpenACCCopyOutClause &Clause) {
2534  for (auto *E : Clause.getVarList())
2535  Profiler.VisitStmt(E);
2536 }
2537 
2538 void OpenACCClauseProfiler::VisitCreateClause(
2539  const OpenACCCreateClause &Clause) {
2540  for (auto *E : Clause.getVarList())
2541  Profiler.VisitStmt(E);
2542 }
2543 
2544 void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
2545  if (Clause.hasConditionExpr())
2546  Profiler.VisitStmt(Clause.getConditionExpr());
2547 }
2548 
2549 void OpenACCClauseProfiler::VisitNumGangsClause(
2550  const OpenACCNumGangsClause &Clause) {
2551  for (auto *E : Clause.getIntExprs())
2552  Profiler.VisitStmt(E);
2553 }
2554 
2555 void OpenACCClauseProfiler::VisitNumWorkersClause(
2556  const OpenACCNumWorkersClause &Clause) {
2557  assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr");
2558  Profiler.VisitStmt(Clause.getIntExpr());
2559 }
2560 
2561 void OpenACCClauseProfiler::VisitPrivateClause(
2562  const OpenACCPrivateClause &Clause) {
2563  for (auto *E : Clause.getVarList())
2564  Profiler.VisitStmt(E);
2565 }
2566 
2567 void OpenACCClauseProfiler::VisitFirstPrivateClause(
2568  const OpenACCFirstPrivateClause &Clause) {
2569  for (auto *E : Clause.getVarList())
2570  Profiler.VisitStmt(E);
2571 }
2572 
2573 void OpenACCClauseProfiler::VisitAttachClause(
2574  const OpenACCAttachClause &Clause) {
2575  for (auto *E : Clause.getVarList())
2576  Profiler.VisitStmt(E);
2577 }
2578 
2579 void OpenACCClauseProfiler::VisitDevicePtrClause(
2580  const OpenACCDevicePtrClause &Clause) {
2581  for (auto *E : Clause.getVarList())
2582  Profiler.VisitStmt(E);
2583 }
2584 
2585 void OpenACCClauseProfiler::VisitNoCreateClause(
2586  const OpenACCNoCreateClause &Clause) {
2587  for (auto *E : Clause.getVarList())
2588  Profiler.VisitStmt(E);
2589 }
2590 
2591 void OpenACCClauseProfiler::VisitPresentClause(
2592  const OpenACCPresentClause &Clause) {
2593  for (auto *E : Clause.getVarList())
2594  Profiler.VisitStmt(E);
2595 }
2596 
2597 void OpenACCClauseProfiler::VisitVectorLengthClause(
2598  const OpenACCVectorLengthClause &Clause) {
2599  assert(Clause.hasIntExpr() &&
2600  "vector_length clause requires a valid int expr");
2601  Profiler.VisitStmt(Clause.getIntExpr());
2602 }
2603 
2604 void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
2605  if (Clause.hasIntExpr())
2606  Profiler.VisitStmt(Clause.getIntExpr());
2607 }
2608 
2609 void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
2610  if (Clause.hasDevNumExpr())
2611  Profiler.VisitStmt(Clause.getDevNumExpr());
2612  for (auto *E : Clause.getQueueIdExprs())
2613  Profiler.VisitStmt(E);
2614 }
2615 /// Nothing to do here, there are no sub-statements.
2616 void OpenACCClauseProfiler::VisitDeviceTypeClause(
2617  const OpenACCDeviceTypeClause &Clause) {}
2618 
2619 void OpenACCClauseProfiler::VisitReductionClause(
2620  const OpenACCReductionClause &Clause) {
2621  for (auto *E : Clause.getVarList())
2622  Profiler.VisitStmt(E);
2623 }
2624 } // namespace
2625 
2626 void StmtProfiler::VisitOpenACCComputeConstruct(
2627  const OpenACCComputeConstruct *S) {
2628  // VisitStmt handles children, so the AssociatedStmt is handled.
2629  VisitStmt(S);
2630 
2631  OpenACCClauseProfiler P{*this};
2632  P.VisitOpenACCClauseList(S->clauses());
2633 }
2634 
2635 void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2636  bool Canonical, bool ProfileLambdaExpr) const {
2637  StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr);
2638  Profiler.Visit(this);
2639 }
2640 
2641 void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
2642  class ODRHash &Hash) const {
2643  StmtProfilerWithoutPointers Profiler(ID, Hash);
2644  Profiler.Visit(this);
2645 }
Defines the clang::ASTContext interface.
DynTypedNode Node
StringRef P
static char ID
Definition: Arena.cpp:183
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
This file defines OpenMP AST classes for clauses.
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, UnaryOperatorKind &UnaryOp, BinaryOperatorKind &BinaryOp, unsigned &NumArgs)
static const TemplateArgument & getArgument(const TemplateArgument &A)
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
Definition: APValue.cpp:479
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
TemplateName getCanonicalTemplateName(const TemplateName &Name) const
Retrieves the "canonical" template name that refers to a given template.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2589
QualType getUnconstrainedType(QualType T) const
Remove any type constraints from a template parameter type, for equivalence comparison of template pa...
NestedNameSpecifier * getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const
Retrieves the "canonical" nested name specifier for a given nested name specifier.
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4390
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition: Expr.h:5605
Represents a loop initializing the elements of an array.
Definition: Expr.h:5552
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition: Expr.h:6775
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2716
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2848
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition: Expr.h:6275
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6478
Represents an attribute applied to a statement.
Definition: Stmt.h:2080
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4293
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3892
A fixed int type of a specified bitwidth.
Definition: Type.h:7254
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6214
BreakStmt - This represents a break.
Definition: Stmt.h:2980
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5293
This class is used for builtin types like 'int'.
Definition: Type.h:2989
Kind getKind() const
Definition: Type.h:3035
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition: Expr.h:3823
Represents a call to a CUDA kernel function.
Definition: ExprCXX.h:231
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition: ExprCXX.h:601
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1487
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
A C++ const_cast expression (C++ [expr.const.cast]).
Definition: ExprCXX.h:563
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1542
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1264
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1371
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2493
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition: ExprCXX.h:3676
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2799
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition: ExprCXX.h:478
Represents a folding of a pack over an operator.
Definition: ExprCXX.h:4833
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Definition: ExprCXX.h:1813
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1733
Represents a call to a member function that may be written either with member call syntax (e....
Definition: ExprCXX.h:176
Abstract class common to all of the C++ "named"/"keyword" casts.
Definition: ExprCXX.h:372
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2236
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4119
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:81
Represents a list-initialization with parenthesis.
Definition: ExprCXX.h:4955
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition: ExprCXX.h:2612
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
capture_const_range captures() const
Definition: DeclCXX.h:1101
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition: ExprCXX.h:523
A rewritten comparison expression that was originally written using operator syntax.
Definition: ExprCXX.h:283
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2177
A C++ static_cast expression (C++ [expr.static.cast]).
Definition: ExprCXX.h:433
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition: ExprCXX.h:797
Represents a C++ functional cast expression that builds a temporary object.
Definition: ExprCXX.h:1881
Represents the this expression in C++.
Definition: ExprCXX.h:1148
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1202
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:69
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:845
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition: ExprCXX.h:3550
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition: ExprCXX.h:1062
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2872
This captures a statement into a function.
Definition: Stmt.h:3757
CaseStmt - Represent a case statement.
Definition: Stmt.h:1801
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3535
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4610
Represents a 'co_await' expression.
Definition: ExprCXX.h:5186
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4140
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3465
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1606
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:42
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4231
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:195
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1072
ContinueStmt - This represents a continue.
Definition: Stmt.h:2950
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition: Expr.h:4551
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition: StmtCXX.h:473
Represents the body of a coroutine.
Definition: StmtCXX.h:320
Represents a 'co_yield' expression.
Definition: ExprCXX.h:5267
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2322
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1497
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:968
Kind getKind() const
Definition: DeclBase.h:448
The name of a declaration.
Represents a 'co_await' expression while the type of the promise is dependent.
Definition: ExprCXX.h:5218
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3316
Represents a single C99 designator.
Definition: Expr.h:5176
Represents a C99 designated initializer expression.
Definition: Expr.h:5133
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2725
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3782
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3467
This represents one expression.
Definition: Expr.h:110
An expression trait intrinsic.
Definition: ExprCXX.h:2919
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition: Expr.h:6154
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2781
Represents a function declaration or definition.
Definition: Decl.h:1972
Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...
Definition: ExprCXX.h:4641
VarDecl *const * iterator
Iterators over the parameters which the parameter pack expanded into.
Definition: ExprCXX.h:4675
This represents a GCC inline-assembly statement extension.
Definition: Stmt.h:3259
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4685
Represents a C11 generic selection.
Definition: Expr.h:5766
AssociationTy< true > ConstAssociation
Definition: Expr.h:5998
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2862
One of these records is kept for each identifier that is lexed.
IfStmt - This represents an if/then/else.
Definition: Stmt.h:2138
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1712
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3707
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5641
IndirectGotoStmt - This represents an indirect goto.
Definition: Stmt.h:2901
Describes an C or C++ initializer list.
Definition: Expr.h:4888
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2031
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1950
This represents a Microsoft inline-assembly statement extension.
Definition: Stmt.h:3482
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Definition: StmtCXX.h:253
A member reference to an MSPropertyDecl.
Definition: ExprCXX.h:929
MS property subscript expression.
Definition: ExprCXX.h:1000
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4721
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition: Expr.h:2794
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3224
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Represents a place-holder for an object not to be initialized by anything.
Definition: Expr.h:5461
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition: Stmt.h:1569
void AddDecl(const Decl *D)
Definition: ODRHash.cpp:799
void AddIdentifierInfo(const IdentifierInfo *II)
Definition: ODRHash.cpp:29
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl=false)
Definition: ODRHash.cpp:34
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS)
Definition: ODRHash.cpp:112
void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody=false)
Definition: ODRHash.cpp:653
void AddTemplateName(TemplateName Name)
Definition: ODRHash.cpp:141
void AddQualType(QualType T)
Definition: ODRHash.cpp:1254
unsigned CalculateHash()
Definition: ODRHash.cpp:218
This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.
This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.
This represents clause 'affinity' in the '#pragma omp task'-based directives.
This represents the 'align' clause in the '#pragma omp allocate' directive.
Definition: OpenMPClause.h:388
This represents clause 'aligned' in the '#pragma omp ...' directives.
This represents clause 'allocate' in the '#pragma omp ...' directives.
Definition: OpenMPClause.h:432
This represents 'allocator' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:354
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition: ExprOpenMP.h:24
This represents 'at' clause in the '#pragma omp error' directive.
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
This represents '#pragma omp atomic' directive.
Definition: StmtOpenMP.h:2963
This represents '#pragma omp barrier' directive.
Definition: StmtOpenMP.h:2641
This represents 'bind' clause in the '#pragma omp ...' directives.
This represents '#pragma omp cancel' directive.
Definition: StmtOpenMP.h:3671
This represents '#pragma omp cancellation point' directive.
Definition: StmtOpenMP.h:3613
Representation of an OpenMP canonical loop.
Definition: StmtOpenMP.h:142
This represents 'capture' clause in the '#pragma omp atomic' directive.
Class that handles post-update expression for some clauses, like 'lastprivate', 'reduction' etc.
Definition: OpenMPClause.h:233
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc.
Definition: OpenMPClause.h:195
This represents 'collapse' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:977
This represents 'compare' clause in the '#pragma omp atomic' directive.
This represents clause 'copyin' in the '#pragma omp ...' directives.
This represents clause 'copyprivate' in the '#pragma omp ...' directives.
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:2092
This represents 'default' clause in the '#pragma omp ...' directive.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
This represents implicit clause 'depobj' for the '#pragma omp depobj' directive.
This represents '#pragma omp depobj' directive.
Definition: StmtOpenMP.h:2857
This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...
This represents 'detach' clause in the '#pragma omp task' directive.
This represents 'device' clause in the '#pragma omp ...' directive.
This represents '#pragma omp dispatch' directive.
Definition: StmtOpenMP.h:5827
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
This represents '#pragma omp distribute' directive.
Definition: StmtOpenMP.h:4441
This represents '#pragma omp distribute parallel for' composite directive.
Definition: StmtOpenMP.h:4564
This represents '#pragma omp distribute parallel for simd' composite directive.
Definition: StmtOpenMP.h:4660
This represents '#pragma omp distribute simd' composite directive.
Definition: StmtOpenMP.h:4725
This represents the 'doacross' clause for the '#pragma omp ordered' directive.
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
This represents '#pragma omp error' directive.
Definition: StmtOpenMP.h:6311
This represents clause 'exclusive' in the '#pragma omp scan' directive.
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
This represents 'fail' clause in the '#pragma omp atomic' directive.
This represents 'filter' clause in the '#pragma omp ...' directive.
This represents 'final' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:630
This represents clause 'firstprivate' in the '#pragma omp ...' directives.
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
This represents '#pragma omp flush' directive.
Definition: StmtOpenMP.h:2805
This represents '#pragma omp for' directive.
Definition: StmtOpenMP.h:1649
This represents '#pragma omp for simd' directive.
Definition: StmtOpenMP.h:1740
This represents clause 'from' in the '#pragma omp ...' directives.
Representation of the 'full' clause of the '#pragma omp unroll' directive.
Definition: OpenMPClause.h:879
This represents '#pragma omp loop' directive.
Definition: StmtOpenMP.h:5982
This represents 'grainsize' clause in the '#pragma omp ...' directive.
This represents clause 'has_device_ptr' in the '#pragma omp ...' directives.
This represents 'hint' clause in the '#pragma omp ...' directive.
This represents 'if' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:527
This represents clause 'in_reduction' in the '#pragma omp task' directives.
This represents clause 'inclusive' in the '#pragma omp scan' directive.
This represents the 'init' clause in '#pragma omp ...' directives.
This represents '#pragma omp interop' directive.
Definition: StmtOpenMP.h:5774
This represents clause 'is_device_ptr' in the '#pragma omp ...' directives.
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition: ExprOpenMP.h:151
This represents clause 'lastprivate' in the '#pragma omp ...' directives.
This represents clause 'linear' in the '#pragma omp ...' directives.
The base class for all loop-based directives, including loop transformation directives.
Definition: StmtOpenMP.h:698
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc....
Definition: StmtOpenMP.h:1018
The base class for all loop transformation directives.
Definition: StmtOpenMP.h:975
This represents clause 'map' in the '#pragma omp ...' directives.
This represents '#pragma omp masked' directive.
Definition: StmtOpenMP.h:5892
This represents '#pragma omp masked taskloop' directive.
Definition: StmtOpenMP.h:3946
This represents '#pragma omp masked taskloop simd' directive.
Definition: StmtOpenMP.h:4087
This represents '#pragma omp master' directive.
Definition: StmtOpenMP.h:2044
This represents '#pragma omp master taskloop' directive.
Definition: StmtOpenMP.h:3870
This represents '#pragma omp master taskloop simd' directive.
Definition: StmtOpenMP.h:4022
This represents 'mergeable' clause in the '#pragma omp ...' directive.
This represents 'message' clause in the '#pragma omp error' directive.
This represents '#pragma omp metadirective' directive.
Definition: StmtOpenMP.h:5943
This represents 'nocontext' clause in the '#pragma omp ...' directive.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
This represents clause 'nontemporal' in the '#pragma omp ...' directives.
This represents 'novariants' clause in the '#pragma omp ...' directive.
This represents 'nowait' clause in the '#pragma omp ...' directive.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:676
This represents 'order' clause in the '#pragma omp ...' directive.
This represents 'ordered' clause in the '#pragma omp ...' directive.
This represents '#pragma omp ordered' directive.
Definition: StmtOpenMP.h:2909
This represents '#pragma omp parallel' directive.
Definition: StmtOpenMP.h:627
This represents '#pragma omp parallel for' directive.
Definition: StmtOpenMP.h:2163
This represents '#pragma omp parallel for simd' directive.
Definition: StmtOpenMP.h:2260
This represents '#pragma omp parallel loop' directive.
Definition: StmtOpenMP.h:6184
This represents '#pragma omp parallel masked' directive.
Definition: StmtOpenMP.h:2388
This represents '#pragma omp parallel masked taskloop' directive.
Definition: StmtOpenMP.h:4231
This represents '#pragma omp parallel masked taskloop simd' directive.
Definition: StmtOpenMP.h:4376
This represents '#pragma omp parallel master' directive.
Definition: StmtOpenMP.h:2325
This represents '#pragma omp parallel master taskloop' directive.
Definition: StmtOpenMP.h:4153
This represents '#pragma omp parallel master taskloop simd' directive.
Definition: StmtOpenMP.h:4309
This represents '#pragma omp parallel sections' directive.
Definition: StmtOpenMP.h:2452
Representation of the 'partial' clause of the '#pragma omp unroll' directive.
Definition: OpenMPClause.h:907
This represents 'priority' clause in the '#pragma omp ...' directive.
This represents clause 'private' in the '#pragma omp ...' directives.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'read' clause in the '#pragma omp atomic' directive.
This represents clause 'reduction' in the '#pragma omp ...' directives.
This represents 'relaxed' clause in the '#pragma omp atomic' directives.
This represents 'release' clause in the '#pragma omp atomic|flush' directives.
This represents 'reverse_offload' clause in the '#pragma omp requires' directive.
This represents 'simd' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:721
This represents '#pragma omp scan' directive.
Definition: StmtOpenMP.h:5721
This represents 'schedule' clause in the '#pragma omp ...' directive.
This represents '#pragma omp scope' directive.
Definition: StmtOpenMP.h:1941
This represents '#pragma omp section' directive.
Definition: StmtOpenMP.h:1880
This represents '#pragma omp sections' directive.
Definition: StmtOpenMP.h:1803
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'severity' clause in the '#pragma omp error' directive.
This represents clause 'shared' in the '#pragma omp ...' directives.
This represents '#pragma omp simd' directive.
Definition: StmtOpenMP.h:1585
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:756
This represents '#pragma omp single' directive.
Definition: StmtOpenMP.h:1993
This represents the 'sizes' clause in the '#pragma omp tile' directive.
Definition: OpenMPClause.h:788
This represents '#pragma omp target data' directive.
Definition: StmtOpenMP.h:3222
This represents '#pragma omp target' directive.
Definition: StmtOpenMP.h:3168
This represents '#pragma omp target enter data' directive.
Definition: StmtOpenMP.h:3276
This represents '#pragma omp target exit data' directive.
Definition: StmtOpenMP.h:3331
This represents '#pragma omp target parallel' directive.
Definition: StmtOpenMP.h:3385
This represents '#pragma omp target parallel for' directive.
Definition: StmtOpenMP.h:3465
This represents '#pragma omp target parallel for simd' directive.
Definition: StmtOpenMP.h:4791
This represents '#pragma omp target parallel loop' directive.
Definition: StmtOpenMP.h:6249
This represents '#pragma omp target simd' directive.
Definition: StmtOpenMP.h:4858
This represents '#pragma omp target teams' directive.
Definition: StmtOpenMP.h:5216
This represents '#pragma omp target teams distribute' combined directive.
Definition: StmtOpenMP.h:5272
This represents '#pragma omp target teams distribute parallel for' combined directive.
Definition: StmtOpenMP.h:5339
This represents '#pragma omp target teams distribute parallel for simd' combined directive.
Definition: StmtOpenMP.h:5437
This represents '#pragma omp target teams distribute simd' combined directive.
Definition: StmtOpenMP.h:5507
This represents '#pragma omp target teams loop' directive.
Definition: StmtOpenMP.h:6109
This represents '#pragma omp target update' directive.
Definition: StmtOpenMP.h:4508
This represents '#pragma omp task' directive.
Definition: StmtOpenMP.h:2533
This represents '#pragma omp taskloop' directive.
Definition: StmtOpenMP.h:3731
This represents '#pragma omp taskloop simd' directive.
Definition: StmtOpenMP.h:3804
This represents clause 'task_reduction' in the '#pragma omp taskgroup' directives.
This represents '#pragma omp taskgroup' directive.
Definition: StmtOpenMP.h:2738
This represents '#pragma omp taskwait' directive.
Definition: StmtOpenMP.h:2687
This represents '#pragma omp taskyield' directive.
Definition: StmtOpenMP.h:2595
This represents '#pragma omp teams' directive.
Definition: StmtOpenMP.h:3560
This represents '#pragma omp teams distribute' directive.
Definition: StmtOpenMP.h:4923
This represents '#pragma omp teams distribute parallel for' composite directive.
Definition: StmtOpenMP.h:5123
This represents '#pragma omp teams distribute parallel for simd' composite directive.
Definition: StmtOpenMP.h:5057
This represents '#pragma omp teams distribute simd' combined directive.
Definition: StmtOpenMP.h:4989
This represents '#pragma omp teams loop' directive.
Definition: StmtOpenMP.h:6044
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
This represents 'threads' clause in the '#pragma omp ...' directive.
This represents the '#pragma omp tile' loop transformation directive.
Definition: StmtOpenMP.h:5565
This represents clause 'to' in the '#pragma omp ...' directives.
This represents 'unified_address' clause in the '#pragma omp requires' directive.
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
This represents the '#pragma omp unroll' loop transformation directive.
Definition: StmtOpenMP.h:5647
This represents 'untied' clause in the '#pragma omp ...' directive.
This represents 'update' clause in the '#pragma omp atomic' directive.
This represents the 'use' clause in '#pragma omp ...' directives.
This represents clause 'use_device_addr' in the '#pragma omp ...' directives.
This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.
This represents clause 'uses_allocators' in the '#pragma omp target'-based directives.
This represents 'weak' clause in the '#pragma omp atomic' directives.
This represents 'write' clause in the '#pragma omp atomic' directive.
This represents 'ompx_attribute' clause in a directive that might generate an outlined function.
This represents 'ompx_bare' clause in the '#pragma omp target teams ...' directive.
This represents 'ompx_dyn_cgroup_mem' clause in the '#pragma omp target ...' directive.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:191
Represents Objective-C's @catch statement.
Definition: StmtObjC.h:77
Represents Objective-C's @finally statement.
Definition: StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition: StmtObjC.h:303
Represents Objective-C's @throw statement.
Definition: StmtObjC.h:358
Represents Objective-C's @try ... @catch ... @finally statement.
Definition: StmtObjC.h:167
Represents Objective-C's @autoreleasepool Statement.
Definition: StmtObjC.h:394
A runtime availability query.
Definition: ExprObjC.h:1696
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:87
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:127
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition: ExprObjC.h:1636
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:309
ObjCEncodeExpr, used for @encode in Objective-C.
Definition: ExprObjC.h:410
Represents Objective-C's collection statement.
Definition: StmtObjC.h:23
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition: ExprObjC.h:1575
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition: ExprObjC.h:1491
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:549
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:945
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:617
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition: ExprObjC.h:505
ObjCSelectorExpr used for @selector in Objective-C.
Definition: ExprObjC.h:455
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:51
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition: ExprObjC.h:844
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2517
Helper class for OffsetOfExpr.
Definition: Expr.h:2411
IdentifierInfo * getFieldName() const
For a field or identifier offsetof node, returns the name of the field.
Definition: Expr.cpp:1747
FieldDecl * getField() const
For a field offsetof node, returns the field.
Definition: Expr.h:2475
@ Array
An index into an array.
Definition: Expr.h:2416
@ Identifier
A field in a dependent type, known only by its name.
Definition: Expr.h:2420
@ Field
A field.
Definition: Expr.h:2418
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2423
Kind getKind() const
Determine what kind of offsetof node this is.
Definition: Expr.h:2465
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1168
const Expr * getConditionExpr() const
ArrayRef< Expr * > getVarList()
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:24
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Definition: StmtOpenACC.h:124
A 'default' clause, has the optional 'none' or 'present' argument.
A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.
Definition: OpenACCClause.h:86
An 'if' clause, which has a required condition expression.
llvm::ArrayRef< Expr * > getIntExprs()
A 'self' clause, which has an optional condition expression.
Expr * getDevNumExpr() const
llvm::ArrayRef< Expr * > getQueueIdExprs()
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2978
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4173
Expr * getPackIdExpression() const
Definition: ExprCXX.h:4437
Expr * getIndexExpr() const
Definition: ExprCXX.h:4441
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2182
Represents a parameter to a function.
Definition: Decl.h:1762
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1986
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6346
const Expr *const * const_semantics_iterator
Definition: Expr.h:6411
A (possibly-)qualified type.
Definition: Type.h:940
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition: Expr.h:6950
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:510
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3019
Represents a __leave statement.
Definition: Stmt.h:3718
Represents a __builtin_base_type expression.
Definition: ExprCXX.h:5459
QualType getSourceType() const
Definition: ExprCXX.h:5477
const Expr * getIndex() const
Definition: ExprCXX.h:5479
Represents a __builtin_field_type expression.
Definition: ExprCXX.h:5372
QualType getSourceType() const
Definition: ExprCXX.h:5390
const Expr * getIndex() const
Definition: ExprCXX.h:5392
Represents a __builtin_num_bases expression.
Definition: ExprCXX.h:5413
QualType getSourceType() const
Definition: ExprCXX.h:5429
Represents a __builtin_num_fields expression.
Definition: ExprCXX.h:5320
QualType getSourceType() const
Definition: ExprCXX.h:5337
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition: Expr.h:4483
Represents an expression that computes the length of a parameter pack.
Definition: ExprCXX.h:4251
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition: Expr.h:4779
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4435
Stmt - This represents one statement.
Definition: Stmt.h:84
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash &Hash) const
Calculate a unique representation for a statement that is stable across compiler invocations.
StmtClass
Definition: Stmt.h:86
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1773
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4477
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition: ExprCXX.h:4562
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2388
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
Represents a template argument.
Definition: TemplateBase.h:61
QualType getStructuralValueType() const
Get the type of a StructuralValue.
Definition: TemplateBase.h:399
QualType getParamTypeForDecl() const
Definition: TemplateBase.h:331
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
Definition: TemplateBase.h:337
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:396
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:326
QualType getIntegralType() const
Retrieve the type of the integral value.
Definition: TemplateBase.h:377
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:432
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:350
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:246
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition: ExprCXX.h:2763
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8227
TypeClass getTypeClass() const
Definition: Type.h:2300
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
Definition: Expr.h:6626
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2620
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2235
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3197
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3936
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
Definition: ExprCXX.h:637
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4719
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2584
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
Definition: Interp.h:2179
The JSON file list parser is used to communicate input to InstallAPI.
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
@ NUM_OVERLOADED_OPERATORS
Definition: OperatorKinds.h:26
BinaryOperatorKind
UnaryOperatorKind
const FunctionProtoType * T
#define false
Definition: stdbool.h:26
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.