1//===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Stmt::Profile method, which builds a unique bit
11// representation that identifies a statement/expression.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/DeclObjC.h"
17#include "clang/AST/DeclTemplate.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/ExprCXX.h"
20#include "clang/AST/ExprObjC.h"
21#include "clang/AST/StmtVisitor.h"
22#include "llvm/ADT/FoldingSet.h"
23using namespace clang;
24
25namespace {
26  class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
27    llvm::FoldingSetNodeID &ID;
28    const ASTContext &Context;
29    bool Canonical;
30
31  public:
32    StmtProfiler(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
33                 bool Canonical)
34      : ID(ID), Context(Context), Canonical(Canonical) { }
35
36    void VisitStmt(const Stmt *S);
37
38#define STMT(Node, Base) void Visit##Node(const Node *S);
39#include "clang/AST/StmtNodes.inc"
40
41    /// \brief Visit a declaration that is referenced within an expression
42    /// or statement.
43    void VisitDecl(const Decl *D);
44
45    /// \brief Visit a type that is referenced within an expression or
46    /// statement.
47    void VisitType(QualType T);
48
49    /// \brief Visit a name that occurs within an expression or statement.
50    void VisitName(DeclarationName Name);
51
52    /// \brief Visit a nested-name-specifier that occurs within an expression
53    /// or statement.
54    void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
55
56    /// \brief Visit a template name that occurs within an expression or
57    /// statement.
58    void VisitTemplateName(TemplateName Name);
59
60    /// \brief Visit template arguments that occur within an expression or
61    /// statement.
62    void VisitTemplateArguments(const TemplateArgumentLoc *Args,
63                                unsigned NumArgs);
64
65    /// \brief Visit a single template argument.
66    void VisitTemplateArgument(const TemplateArgument &Arg);
67  };
68}
69
70void StmtProfiler::VisitStmt(const Stmt *S) {
71  ID.AddInteger(S->getStmtClass());
72  for (Stmt::const_child_range C = S->children(); C; ++C) {
73    if (*C)
74      Visit(*C);
75    else
76      ID.AddInteger(0);
77  }
78}
79
80void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
81  VisitStmt(S);
82  for (const auto *D : S->decls())
83    VisitDecl(D);
84}
85
86void StmtProfiler::VisitNullStmt(const NullStmt *S) {
87  VisitStmt(S);
88}
89
90void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
91  VisitStmt(S);
92}
93
94void StmtProfiler::VisitSwitchCase(const SwitchCase *S) {
95  VisitStmt(S);
96}
97
98void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
99  VisitStmt(S);
100}
101
102void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
103  VisitStmt(S);
104}
105
106void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
107  VisitStmt(S);
108  VisitDecl(S->getDecl());
109}
110
111void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
112  VisitStmt(S);
113  // TODO: maybe visit attributes?
114}
115
116void StmtProfiler::VisitIfStmt(const IfStmt *S) {
117  VisitStmt(S);
118  VisitDecl(S->getConditionVariable());
119}
120
121void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
122  VisitStmt(S);
123  VisitDecl(S->getConditionVariable());
124}
125
126void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
127  VisitStmt(S);
128  VisitDecl(S->getConditionVariable());
129}
130
131void StmtProfiler::VisitDoStmt(const DoStmt *S) {
132  VisitStmt(S);
133}
134
135void StmtProfiler::VisitForStmt(const ForStmt *S) {
136  VisitStmt(S);
137}
138
139void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
140  VisitStmt(S);
141  VisitDecl(S->getLabel());
142}
143
144void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
145  VisitStmt(S);
146}
147
148void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
149  VisitStmt(S);
150}
151
152void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
153  VisitStmt(S);
154}
155
156void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
157  VisitStmt(S);
158}
159
160void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
161  VisitStmt(S);
162  ID.AddBoolean(S->isVolatile());
163  ID.AddBoolean(S->isSimple());
164  VisitStringLiteral(S->getAsmString());
165  ID.AddInteger(S->getNumOutputs());
166  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
167    ID.AddString(S->getOutputName(I));
168    VisitStringLiteral(S->getOutputConstraintLiteral(I));
169  }
170  ID.AddInteger(S->getNumInputs());
171  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
172    ID.AddString(S->getInputName(I));
173    VisitStringLiteral(S->getInputConstraintLiteral(I));
174  }
175  ID.AddInteger(S->getNumClobbers());
176  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
177    VisitStringLiteral(S->getClobberStringLiteral(I));
178}
179
180void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) {
181  // FIXME: Implement MS style inline asm statement profiler.
182  VisitStmt(S);
183}
184
185void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
186  VisitStmt(S);
187  VisitType(S->getCaughtType());
188}
189
190void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
191  VisitStmt(S);
192}
193
194void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
195  VisitStmt(S);
196}
197
198void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
199  VisitStmt(S);
200  ID.AddBoolean(S->isIfExists());
201  VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
202  VisitName(S->getNameInfo().getName());
203}
204
205void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
206  VisitStmt(S);
207}
208
209void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
210  VisitStmt(S);
211}
212
213void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
214  VisitStmt(S);
215}
216
217void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
218  VisitStmt(S);
219}
220
221void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
222  VisitStmt(S);
223}
224
225void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
226  VisitStmt(S);
227}
228
229void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
230  VisitStmt(S);
231  ID.AddBoolean(S->hasEllipsis());
232  if (S->getCatchParamDecl())
233    VisitType(S->getCatchParamDecl()->getType());
234}
235
236void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
237  VisitStmt(S);
238}
239
240void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
241  VisitStmt(S);
242}
243
244void
245StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
246  VisitStmt(S);
247}
248
249void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
250  VisitStmt(S);
251}
252
253void
254StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
255  VisitStmt(S);
256}
257
258namespace {
259class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
260  StmtProfiler *Profiler;
261  /// \brief Process clauses with list of variables.
262  template <typename T>
263  void VisitOMPClauseList(T *Node);
264public:
265  OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
266#define OPENMP_CLAUSE(Name, Class)                                             \
267  void Visit##Class(const Class *C);
268#include "clang/Basic/OpenMPKinds.def"
269};
270
271void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
272  if (C->getCondition())
273    Profiler->VisitStmt(C->getCondition());
274}
275
276void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
277  if (C->getCondition())
278    Profiler->VisitStmt(C->getCondition());
279}
280
281void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
282  if (C->getNumThreads())
283    Profiler->VisitStmt(C->getNumThreads());
284}
285
286void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
287  if (C->getSafelen())
288    Profiler->VisitStmt(C->getSafelen());
289}
290
291void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
292  if (C->getNumForLoops())
293    Profiler->VisitStmt(C->getNumForLoops());
294}
295
296void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
297
298void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
299
300void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
301  if (C->getChunkSize())
302    Profiler->VisitStmt(C->getChunkSize());
303}
304
305void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {}
306
307void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
308
309void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
310
311void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
312
313void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}
314
315void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {}
316
317void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
318
319void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
320
321void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
322
323template<typename T>
324void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
325  for (auto *E : Node->varlists()) {
326    Profiler->VisitStmt(E);
327  }
328}
329
330void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
331  VisitOMPClauseList(C);
332  for (auto *E : C->private_copies()) {
333    Profiler->VisitStmt(E);
334  }
335}
336void
337OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
338  VisitOMPClauseList(C);
339  for (auto *E : C->private_copies()) {
340    Profiler->VisitStmt(E);
341  }
342  for (auto *E : C->inits()) {
343    Profiler->VisitStmt(E);
344  }
345}
346void
347OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
348  VisitOMPClauseList(C);
349  for (auto *E : C->source_exprs()) {
350    Profiler->VisitStmt(E);
351  }
352  for (auto *E : C->destination_exprs()) {
353    Profiler->VisitStmt(E);
354  }
355  for (auto *E : C->assignment_ops()) {
356    Profiler->VisitStmt(E);
357  }
358}
359void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
360  VisitOMPClauseList(C);
361}
362void OMPClauseProfiler::VisitOMPReductionClause(
363                                         const OMPReductionClause *C) {
364  Profiler->VisitNestedNameSpecifier(
365      C->getQualifierLoc().getNestedNameSpecifier());
366  Profiler->VisitName(C->getNameInfo().getName());
367  VisitOMPClauseList(C);
368  for (auto *E : C->lhs_exprs()) {
369    Profiler->VisitStmt(E);
370  }
371  for (auto *E : C->rhs_exprs()) {
372    Profiler->VisitStmt(E);
373  }
374  for (auto *E : C->reduction_ops()) {
375    Profiler->VisitStmt(E);
376  }
377}
378void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
379  VisitOMPClauseList(C);
380  for (auto *E : C->inits()) {
381    Profiler->VisitStmt(E);
382  }
383  for (auto *E : C->updates()) {
384    Profiler->VisitStmt(E);
385  }
386  for (auto *E : C->finals()) {
387    Profiler->VisitStmt(E);
388  }
389  Profiler->VisitStmt(C->getStep());
390  Profiler->VisitStmt(C->getCalcStep());
391}
392void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
393  VisitOMPClauseList(C);
394  Profiler->VisitStmt(C->getAlignment());
395}
396void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
397  VisitOMPClauseList(C);
398  for (auto *E : C->source_exprs()) {
399    Profiler->VisitStmt(E);
400  }
401  for (auto *E : C->destination_exprs()) {
402    Profiler->VisitStmt(E);
403  }
404  for (auto *E : C->assignment_ops()) {
405    Profiler->VisitStmt(E);
406  }
407}
408void
409OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
410  VisitOMPClauseList(C);
411  for (auto *E : C->source_exprs()) {
412    Profiler->VisitStmt(E);
413  }
414  for (auto *E : C->destination_exprs()) {
415    Profiler->VisitStmt(E);
416  }
417  for (auto *E : C->assignment_ops()) {
418    Profiler->VisitStmt(E);
419  }
420}
421void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
422  VisitOMPClauseList(C);
423}
424}
425
426void
427StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
428  VisitStmt(S);
429  OMPClauseProfiler P(this);
430  ArrayRef<OMPClause *> Clauses = S->clauses();
431  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
432       I != E; ++I)
433    if (*I)
434      P.Visit(*I);
435}
436
437void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
438  VisitOMPExecutableDirective(S);
439}
440
441void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
442  VisitOMPExecutableDirective(S);
443}
444
445void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
446  VisitOMPLoopDirective(S);
447}
448
449void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
450  VisitOMPLoopDirective(S);
451}
452
453void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
454  VisitOMPLoopDirective(S);
455}
456
457void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
458  VisitOMPExecutableDirective(S);
459}
460
461void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
462  VisitOMPExecutableDirective(S);
463}
464
465void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
466  VisitOMPExecutableDirective(S);
467}
468
469void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
470  VisitOMPExecutableDirective(S);
471}
472
473void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
474  VisitOMPExecutableDirective(S);
475  VisitName(S->getDirectiveName().getName());
476}
477
478void
479StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
480  VisitOMPLoopDirective(S);
481}
482
483void StmtProfiler::VisitOMPParallelForSimdDirective(
484    const OMPParallelForSimdDirective *S) {
485  VisitOMPLoopDirective(S);
486}
487
488void StmtProfiler::VisitOMPParallelSectionsDirective(
489    const OMPParallelSectionsDirective *S) {
490  VisitOMPExecutableDirective(S);
491}
492
493void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
494  VisitOMPExecutableDirective(S);
495}
496
497void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
498  VisitOMPExecutableDirective(S);
499}
500
501void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
502  VisitOMPExecutableDirective(S);
503}
504
505void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
506  VisitOMPExecutableDirective(S);
507}
508
509void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
510  VisitOMPExecutableDirective(S);
511}
512
513void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
514  VisitOMPExecutableDirective(S);
515}
516
517void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
518  VisitOMPExecutableDirective(S);
519}
520
521void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
522  VisitOMPExecutableDirective(S);
523}
524
525void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
526  VisitOMPExecutableDirective(S);
527}
528
529void StmtProfiler::VisitExpr(const Expr *S) {
530  VisitStmt(S);
531}
532
533void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
534  VisitExpr(S);
535  if (!Canonical)
536    VisitNestedNameSpecifier(S->getQualifier());
537  VisitDecl(S->getDecl());
538  if (!Canonical)
539    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
540}
541
542void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
543  VisitExpr(S);
544  ID.AddInteger(S->getIdentType());
545}
546
547void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
548  VisitExpr(S);
549  S->getValue().Profile(ID);
550  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
551}
552
553void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
554  VisitExpr(S);
555  ID.AddInteger(S->getKind());
556  ID.AddInteger(S->getValue());
557}
558
559void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
560  VisitExpr(S);
561  S->getValue().Profile(ID);
562  ID.AddBoolean(S->isExact());
563  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
564}
565
566void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
567  VisitExpr(S);
568}
569
570void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
571  VisitExpr(S);
572  ID.AddString(S->getBytes());
573  ID.AddInteger(S->getKind());
574}
575
576void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
577  VisitExpr(S);
578}
579
580void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
581  VisitExpr(S);
582}
583
584void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
585  VisitExpr(S);
586  ID.AddInteger(S->getOpcode());
587}
588
589void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
590  VisitType(S->getTypeSourceInfo()->getType());
591  unsigned n = S->getNumComponents();
592  for (unsigned i = 0; i < n; ++i) {
593    const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
594    ID.AddInteger(ON.getKind());
595    switch (ON.getKind()) {
596    case OffsetOfExpr::OffsetOfNode::Array:
597      // Expressions handled below.
598      break;
599
600    case OffsetOfExpr::OffsetOfNode::Field:
601      VisitDecl(ON.getField());
602      break;
603
604    case OffsetOfExpr::OffsetOfNode::Identifier:
605      ID.AddPointer(ON.getFieldName());
606      break;
607
608    case OffsetOfExpr::OffsetOfNode::Base:
609      // These nodes are implicit, and therefore don't need profiling.
610      break;
611    }
612  }
613
614  VisitExpr(S);
615}
616
617void
618StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
619  VisitExpr(S);
620  ID.AddInteger(S->getKind());
621  if (S->isArgumentType())
622    VisitType(S->getArgumentType());
623}
624
625void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
626  VisitExpr(S);
627}
628
629void StmtProfiler::VisitCallExpr(const CallExpr *S) {
630  VisitExpr(S);
631}
632
633void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
634  VisitExpr(S);
635  VisitDecl(S->getMemberDecl());
636  if (!Canonical)
637    VisitNestedNameSpecifier(S->getQualifier());
638  ID.AddBoolean(S->isArrow());
639}
640
641void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
642  VisitExpr(S);
643  ID.AddBoolean(S->isFileScope());
644}
645
646void StmtProfiler::VisitCastExpr(const CastExpr *S) {
647  VisitExpr(S);
648}
649
650void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
651  VisitCastExpr(S);
652  ID.AddInteger(S->getValueKind());
653}
654
655void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
656  VisitCastExpr(S);
657  VisitType(S->getTypeAsWritten());
658}
659
660void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
661  VisitExplicitCastExpr(S);
662}
663
664void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
665  VisitExpr(S);
666  ID.AddInteger(S->getOpcode());
667}
668
669void
670StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
671  VisitBinaryOperator(S);
672}
673
674void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
675  VisitExpr(S);
676}
677
678void StmtProfiler::VisitBinaryConditionalOperator(
679    const BinaryConditionalOperator *S) {
680  VisitExpr(S);
681}
682
683void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
684  VisitExpr(S);
685  VisitDecl(S->getLabel());
686}
687
688void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
689  VisitExpr(S);
690}
691
692void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
693  VisitExpr(S);
694}
695
696void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
697  VisitExpr(S);
698}
699
700void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
701  VisitExpr(S);
702}
703
704void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
705  VisitExpr(S);
706}
707
708void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
709  VisitExpr(S);
710}
711
712void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
713  if (S->getSyntacticForm()) {
714    VisitInitListExpr(S->getSyntacticForm());
715    return;
716  }
717
718  VisitExpr(S);
719}
720
721void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
722  VisitExpr(S);
723  ID.AddBoolean(S->usesGNUSyntax());
724  for (DesignatedInitExpr::const_designators_iterator D =
725         S->designators_begin(), DEnd = S->designators_end();
726       D != DEnd; ++D) {
727    if (D->isFieldDesignator()) {
728      ID.AddInteger(0);
729      VisitName(D->getFieldName());
730      continue;
731    }
732
733    if (D->isArrayDesignator()) {
734      ID.AddInteger(1);
735    } else {
736      assert(D->isArrayRangeDesignator());
737      ID.AddInteger(2);
738    }
739    ID.AddInteger(D->getFirstExprIndex());
740  }
741}
742
743void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
744  VisitExpr(S);
745}
746
747void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
748  VisitExpr(S);
749  VisitName(&S->getAccessor());
750}
751
752void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
753  VisitExpr(S);
754  VisitDecl(S->getBlockDecl());
755}
756
757void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
758  VisitExpr(S);
759  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
760    QualType T = S->getAssocType(i);
761    if (T.isNull())
762      ID.AddPointer(nullptr);
763    else
764      VisitType(T);
765    VisitExpr(S->getAssocExpr(i));
766  }
767}
768
769void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
770  VisitExpr(S);
771  for (PseudoObjectExpr::const_semantics_iterator
772         i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
773    // Normally, we would not profile the source expressions of OVEs.
774    if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
775      Visit(OVE->getSourceExpr());
776}
777
778void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
779  VisitExpr(S);
780  ID.AddInteger(S->getOp());
781}
782
783static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
784                                          UnaryOperatorKind &UnaryOp,
785                                          BinaryOperatorKind &BinaryOp) {
786  switch (S->getOperator()) {
787  case OO_None:
788  case OO_New:
789  case OO_Delete:
790  case OO_Array_New:
791  case OO_Array_Delete:
792  case OO_Arrow:
793  case OO_Call:
794  case OO_Conditional:
795  case NUM_OVERLOADED_OPERATORS:
796    llvm_unreachable("Invalid operator call kind");
797
798  case OO_Plus:
799    if (S->getNumArgs() == 1) {
800      UnaryOp = UO_Plus;
801      return Stmt::UnaryOperatorClass;
802    }
803
804    BinaryOp = BO_Add;
805    return Stmt::BinaryOperatorClass;
806
807  case OO_Minus:
808    if (S->getNumArgs() == 1) {
809      UnaryOp = UO_Minus;
810      return Stmt::UnaryOperatorClass;
811    }
812
813    BinaryOp = BO_Sub;
814    return Stmt::BinaryOperatorClass;
815
816  case OO_Star:
817    if (S->getNumArgs() == 1) {
818      UnaryOp = UO_Deref;
819      return Stmt::UnaryOperatorClass;
820    }
821
822    BinaryOp = BO_Mul;
823    return Stmt::BinaryOperatorClass;
824
825  case OO_Slash:
826    BinaryOp = BO_Div;
827    return Stmt::BinaryOperatorClass;
828
829  case OO_Percent:
830    BinaryOp = BO_Rem;
831    return Stmt::BinaryOperatorClass;
832
833  case OO_Caret:
834    BinaryOp = BO_Xor;
835    return Stmt::BinaryOperatorClass;
836
837  case OO_Amp:
838    if (S->getNumArgs() == 1) {
839      UnaryOp = UO_AddrOf;
840      return Stmt::UnaryOperatorClass;
841    }
842
843    BinaryOp = BO_And;
844    return Stmt::BinaryOperatorClass;
845
846  case OO_Pipe:
847    BinaryOp = BO_Or;
848    return Stmt::BinaryOperatorClass;
849
850  case OO_Tilde:
851    UnaryOp = UO_Not;
852    return Stmt::UnaryOperatorClass;
853
854  case OO_Exclaim:
855    UnaryOp = UO_LNot;
856    return Stmt::UnaryOperatorClass;
857
858  case OO_Equal:
859    BinaryOp = BO_Assign;
860    return Stmt::BinaryOperatorClass;
861
862  case OO_Less:
863    BinaryOp = BO_LT;
864    return Stmt::BinaryOperatorClass;
865
866  case OO_Greater:
867    BinaryOp = BO_GT;
868    return Stmt::BinaryOperatorClass;
869
870  case OO_PlusEqual:
871    BinaryOp = BO_AddAssign;
872    return Stmt::CompoundAssignOperatorClass;
873
874  case OO_MinusEqual:
875    BinaryOp = BO_SubAssign;
876    return Stmt::CompoundAssignOperatorClass;
877
878  case OO_StarEqual:
879    BinaryOp = BO_MulAssign;
880    return Stmt::CompoundAssignOperatorClass;
881
882  case OO_SlashEqual:
883    BinaryOp = BO_DivAssign;
884    return Stmt::CompoundAssignOperatorClass;
885
886  case OO_PercentEqual:
887    BinaryOp = BO_RemAssign;
888    return Stmt::CompoundAssignOperatorClass;
889
890  case OO_CaretEqual:
891    BinaryOp = BO_XorAssign;
892    return Stmt::CompoundAssignOperatorClass;
893
894  case OO_AmpEqual:
895    BinaryOp = BO_AndAssign;
896    return Stmt::CompoundAssignOperatorClass;
897
898  case OO_PipeEqual:
899    BinaryOp = BO_OrAssign;
900    return Stmt::CompoundAssignOperatorClass;
901
902  case OO_LessLess:
903    BinaryOp = BO_Shl;
904    return Stmt::BinaryOperatorClass;
905
906  case OO_GreaterGreater:
907    BinaryOp = BO_Shr;
908    return Stmt::BinaryOperatorClass;
909
910  case OO_LessLessEqual:
911    BinaryOp = BO_ShlAssign;
912    return Stmt::CompoundAssignOperatorClass;
913
914  case OO_GreaterGreaterEqual:
915    BinaryOp = BO_ShrAssign;
916    return Stmt::CompoundAssignOperatorClass;
917
918  case OO_EqualEqual:
919    BinaryOp = BO_EQ;
920    return Stmt::BinaryOperatorClass;
921
922  case OO_ExclaimEqual:
923    BinaryOp = BO_NE;
924    return Stmt::BinaryOperatorClass;
925
926  case OO_LessEqual:
927    BinaryOp = BO_LE;
928    return Stmt::BinaryOperatorClass;
929
930  case OO_GreaterEqual:
931    BinaryOp = BO_GE;
932    return Stmt::BinaryOperatorClass;
933
934  case OO_AmpAmp:
935    BinaryOp = BO_LAnd;
936    return Stmt::BinaryOperatorClass;
937
938  case OO_PipePipe:
939    BinaryOp = BO_LOr;
940    return Stmt::BinaryOperatorClass;
941
942  case OO_PlusPlus:
943    UnaryOp = S->getNumArgs() == 1? UO_PreInc
944                                  : UO_PostInc;
945    return Stmt::UnaryOperatorClass;
946
947  case OO_MinusMinus:
948    UnaryOp = S->getNumArgs() == 1? UO_PreDec
949                                  : UO_PostDec;
950    return Stmt::UnaryOperatorClass;
951
952  case OO_Comma:
953    BinaryOp = BO_Comma;
954    return Stmt::BinaryOperatorClass;
955
956
957  case OO_ArrowStar:
958    BinaryOp = BO_PtrMemI;
959    return Stmt::BinaryOperatorClass;
960
961  case OO_Subscript:
962    return Stmt::ArraySubscriptExprClass;
963  }
964
965  llvm_unreachable("Invalid overloaded operator expression");
966}
967
968
969void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
970  if (S->isTypeDependent()) {
971    // Type-dependent operator calls are profiled like their underlying
972    // syntactic operator.
973    UnaryOperatorKind UnaryOp = UO_Extension;
974    BinaryOperatorKind BinaryOp = BO_Comma;
975    Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
976
977    ID.AddInteger(SC);
978    for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
979      Visit(S->getArg(I));
980    if (SC == Stmt::UnaryOperatorClass)
981      ID.AddInteger(UnaryOp);
982    else if (SC == Stmt::BinaryOperatorClass ||
983             SC == Stmt::CompoundAssignOperatorClass)
984      ID.AddInteger(BinaryOp);
985    else
986      assert(SC == Stmt::ArraySubscriptExprClass);
987
988    return;
989  }
990
991  VisitCallExpr(S);
992  ID.AddInteger(S->getOperator());
993}
994
995void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
996  VisitCallExpr(S);
997}
998
999void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
1000  VisitCallExpr(S);
1001}
1002
1003void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
1004  VisitExpr(S);
1005}
1006
1007void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
1008  VisitExplicitCastExpr(S);
1009}
1010
1011void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
1012  VisitCXXNamedCastExpr(S);
1013}
1014
1015void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
1016  VisitCXXNamedCastExpr(S);
1017}
1018
1019void
1020StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
1021  VisitCXXNamedCastExpr(S);
1022}
1023
1024void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
1025  VisitCXXNamedCastExpr(S);
1026}
1027
1028void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
1029  VisitCallExpr(S);
1030}
1031
1032void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
1033  VisitExpr(S);
1034  ID.AddBoolean(S->getValue());
1035}
1036
1037void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
1038  VisitExpr(S);
1039}
1040
1041void StmtProfiler::VisitCXXStdInitializerListExpr(
1042    const CXXStdInitializerListExpr *S) {
1043  VisitExpr(S);
1044}
1045
1046void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
1047  VisitExpr(S);
1048  if (S->isTypeOperand())
1049    VisitType(S->getTypeOperandSourceInfo()->getType());
1050}
1051
1052void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
1053  VisitExpr(S);
1054  if (S->isTypeOperand())
1055    VisitType(S->getTypeOperandSourceInfo()->getType());
1056}
1057
1058void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
1059  VisitExpr(S);
1060  VisitDecl(S->getPropertyDecl());
1061}
1062
1063void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
1064  VisitExpr(S);
1065  ID.AddBoolean(S->isImplicit());
1066}
1067
1068void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
1069  VisitExpr(S);
1070}
1071
1072void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
1073  VisitExpr(S);
1074  VisitDecl(S->getParam());
1075}
1076
1077void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
1078  VisitExpr(S);
1079  VisitDecl(S->getField());
1080}
1081
1082void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
1083  VisitExpr(S);
1084  VisitDecl(
1085         const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
1086}
1087
1088void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
1089  VisitExpr(S);
1090  VisitDecl(S->getConstructor());
1091  ID.AddBoolean(S->isElidable());
1092}
1093
1094void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
1095  VisitExplicitCastExpr(S);
1096}
1097
1098void
1099StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
1100  VisitCXXConstructExpr(S);
1101}
1102
1103void
1104StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
1105  VisitExpr(S);
1106  for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
1107                                 CEnd = S->explicit_capture_end();
1108       C != CEnd; ++C) {
1109    ID.AddInteger(C->getCaptureKind());
1110    switch (C->getCaptureKind()) {
1111    case LCK_This:
1112      break;
1113    case LCK_ByRef:
1114    case LCK_ByCopy:
1115      VisitDecl(C->getCapturedVar());
1116      ID.AddBoolean(C->isPackExpansion());
1117      break;
1118    case LCK_VLAType:
1119      llvm_unreachable("VLA type in explicit captures.");
1120    }
1121  }
1122  // Note: If we actually needed to be able to match lambda
1123  // expressions, we would have to consider parameters and return type
1124  // here, among other things.
1125  VisitStmt(S->getBody());
1126}
1127
1128void
1129StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
1130  VisitExpr(S);
1131}
1132
1133void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
1134  VisitExpr(S);
1135  ID.AddBoolean(S->isGlobalDelete());
1136  ID.AddBoolean(S->isArrayForm());
1137  VisitDecl(S->getOperatorDelete());
1138}
1139
1140
1141void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
1142  VisitExpr(S);
1143  VisitType(S->getAllocatedType());
1144  VisitDecl(S->getOperatorNew());
1145  VisitDecl(S->getOperatorDelete());
1146  ID.AddBoolean(S->isArray());
1147  ID.AddInteger(S->getNumPlacementArgs());
1148  ID.AddBoolean(S->isGlobalNew());
1149  ID.AddBoolean(S->isParenTypeId());
1150  ID.AddInteger(S->getInitializationStyle());
1151}
1152
1153void
1154StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
1155  VisitExpr(S);
1156  ID.AddBoolean(S->isArrow());
1157  VisitNestedNameSpecifier(S->getQualifier());
1158  ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
1159  if (S->getScopeTypeInfo())
1160    VisitType(S->getScopeTypeInfo()->getType());
1161  ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
1162  if (S->getDestroyedTypeInfo())
1163    VisitType(S->getDestroyedType());
1164  else
1165    ID.AddPointer(S->getDestroyedTypeIdentifier());
1166}
1167
1168void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
1169  VisitExpr(S);
1170  VisitNestedNameSpecifier(S->getQualifier());
1171  VisitName(S->getName());
1172  ID.AddBoolean(S->hasExplicitTemplateArgs());
1173  if (S->hasExplicitTemplateArgs())
1174    VisitTemplateArguments(S->getExplicitTemplateArgs().getTemplateArgs(),
1175                           S->getExplicitTemplateArgs().NumTemplateArgs);
1176}
1177
1178void
1179StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
1180  VisitOverloadExpr(S);
1181}
1182
1183void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
1184  VisitExpr(S);
1185  ID.AddInteger(S->getTrait());
1186  ID.AddInteger(S->getNumArgs());
1187  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
1188    VisitType(S->getArg(I)->getType());
1189}
1190
1191void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
1192  VisitExpr(S);
1193  ID.AddInteger(S->getTrait());
1194  VisitType(S->getQueriedType());
1195}
1196
1197void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
1198  VisitExpr(S);
1199  ID.AddInteger(S->getTrait());
1200  VisitExpr(S->getQueriedExpression());
1201}
1202
1203void StmtProfiler::VisitDependentScopeDeclRefExpr(
1204    const DependentScopeDeclRefExpr *S) {
1205  VisitExpr(S);
1206  VisitName(S->getDeclName());
1207  VisitNestedNameSpecifier(S->getQualifier());
1208  ID.AddBoolean(S->hasExplicitTemplateArgs());
1209  if (S->hasExplicitTemplateArgs())
1210    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
1211}
1212
1213void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
1214  VisitExpr(S);
1215}
1216
1217void StmtProfiler::VisitCXXUnresolvedConstructExpr(
1218    const CXXUnresolvedConstructExpr *S) {
1219  VisitExpr(S);
1220  VisitType(S->getTypeAsWritten());
1221}
1222
1223void StmtProfiler::VisitCXXDependentScopeMemberExpr(
1224    const CXXDependentScopeMemberExpr *S) {
1225  ID.AddBoolean(S->isImplicitAccess());
1226  if (!S->isImplicitAccess()) {
1227    VisitExpr(S);
1228    ID.AddBoolean(S->isArrow());
1229  }
1230  VisitNestedNameSpecifier(S->getQualifier());
1231  VisitName(S->getMember());
1232  ID.AddBoolean(S->hasExplicitTemplateArgs());
1233  if (S->hasExplicitTemplateArgs())
1234    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
1235}
1236
1237void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
1238  ID.AddBoolean(S->isImplicitAccess());
1239  if (!S->isImplicitAccess()) {
1240    VisitExpr(S);
1241    ID.AddBoolean(S->isArrow());
1242  }
1243  VisitNestedNameSpecifier(S->getQualifier());
1244  VisitName(S->getMemberName());
1245  ID.AddBoolean(S->hasExplicitTemplateArgs());
1246  if (S->hasExplicitTemplateArgs())
1247    VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
1248}
1249
1250void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
1251  VisitExpr(S);
1252}
1253
1254void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
1255  VisitExpr(S);
1256}
1257
1258void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
1259  VisitExpr(S);
1260  VisitDecl(S->getPack());
1261}
1262
1263void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
1264    const SubstNonTypeTemplateParmPackExpr *S) {
1265  VisitExpr(S);
1266  VisitDecl(S->getParameterPack());
1267  VisitTemplateArgument(S->getArgumentPack());
1268}
1269
1270void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
1271    const SubstNonTypeTemplateParmExpr *E) {
1272  // Profile exactly as the replacement expression.
1273  Visit(E->getReplacement());
1274}
1275
1276void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
1277  VisitExpr(S);
1278  VisitDecl(S->getParameterPack());
1279  ID.AddInteger(S->getNumExpansions());
1280  for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
1281    VisitDecl(*I);
1282}
1283
1284void StmtProfiler::VisitMaterializeTemporaryExpr(
1285                                           const MaterializeTemporaryExpr *S) {
1286  VisitExpr(S);
1287}
1288
1289void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
1290  VisitExpr(S);
1291  ID.AddInteger(S->getOperator());
1292}
1293
1294void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
1295  VisitExpr(E);
1296}
1297
1298void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
1299  VisitExpr(E);
1300}
1301
1302void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
1303  VisitExpr(S);
1304}
1305
1306void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
1307  VisitExpr(E);
1308}
1309
1310void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
1311  VisitExpr(E);
1312}
1313
1314void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
1315  VisitExpr(E);
1316}
1317
1318void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
1319  VisitExpr(S);
1320  VisitType(S->getEncodedType());
1321}
1322
1323void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
1324  VisitExpr(S);
1325  VisitName(S->getSelector());
1326}
1327
1328void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
1329  VisitExpr(S);
1330  VisitDecl(S->getProtocol());
1331}
1332
1333void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
1334  VisitExpr(S);
1335  VisitDecl(S->getDecl());
1336  ID.AddBoolean(S->isArrow());
1337  ID.AddBoolean(S->isFreeIvar());
1338}
1339
1340void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
1341  VisitExpr(S);
1342  if (S->isImplicitProperty()) {
1343    VisitDecl(S->getImplicitPropertyGetter());
1344    VisitDecl(S->getImplicitPropertySetter());
1345  } else {
1346    VisitDecl(S->getExplicitProperty());
1347  }
1348  if (S->isSuperReceiver()) {
1349    ID.AddBoolean(S->isSuperReceiver());
1350    VisitType(S->getSuperReceiverType());
1351  }
1352}
1353
1354void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
1355  VisitExpr(S);
1356  VisitDecl(S->getAtIndexMethodDecl());
1357  VisitDecl(S->setAtIndexMethodDecl());
1358}
1359
1360void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
1361  VisitExpr(S);
1362  VisitName(S->getSelector());
1363  VisitDecl(S->getMethodDecl());
1364}
1365
1366void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
1367  VisitExpr(S);
1368  ID.AddBoolean(S->isArrow());
1369}
1370
1371void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
1372  VisitExpr(S);
1373  ID.AddBoolean(S->getValue());
1374}
1375
1376void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
1377    const ObjCIndirectCopyRestoreExpr *S) {
1378  VisitExpr(S);
1379  ID.AddBoolean(S->shouldCopy());
1380}
1381
1382void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
1383  VisitExplicitCastExpr(S);
1384  ID.AddBoolean(S->getBridgeKind());
1385}
1386
1387void StmtProfiler::VisitDecl(const Decl *D) {
1388  ID.AddInteger(D? D->getKind() : 0);
1389
1390  if (Canonical && D) {
1391    if (const NonTypeTemplateParmDecl *NTTP =
1392          dyn_cast<NonTypeTemplateParmDecl>(D)) {
1393      ID.AddInteger(NTTP->getDepth());
1394      ID.AddInteger(NTTP->getIndex());
1395      ID.AddBoolean(NTTP->isParameterPack());
1396      VisitType(NTTP->getType());
1397      return;
1398    }
1399
1400    if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
1401      // The Itanium C++ ABI uses the type, scope depth, and scope
1402      // index of a parameter when mangling expressions that involve
1403      // function parameters, so we will use the parameter's type for
1404      // establishing function parameter identity. That way, our
1405      // definition of "equivalent" (per C++ [temp.over.link]) is at
1406      // least as strong as the definition of "equivalent" used for
1407      // name mangling.
1408      VisitType(Parm->getType());
1409      ID.AddInteger(Parm->getFunctionScopeDepth());
1410      ID.AddInteger(Parm->getFunctionScopeIndex());
1411      return;
1412    }
1413
1414    if (const TemplateTypeParmDecl *TTP =
1415          dyn_cast<TemplateTypeParmDecl>(D)) {
1416      ID.AddInteger(TTP->getDepth());
1417      ID.AddInteger(TTP->getIndex());
1418      ID.AddBoolean(TTP->isParameterPack());
1419      return;
1420    }
1421
1422    if (const TemplateTemplateParmDecl *TTP =
1423          dyn_cast<TemplateTemplateParmDecl>(D)) {
1424      ID.AddInteger(TTP->getDepth());
1425      ID.AddInteger(TTP->getIndex());
1426      ID.AddBoolean(TTP->isParameterPack());
1427      return;
1428    }
1429  }
1430
1431  ID.AddPointer(D? D->getCanonicalDecl() : nullptr);
1432}
1433
1434void StmtProfiler::VisitType(QualType T) {
1435  if (Canonical)
1436    T = Context.getCanonicalType(T);
1437
1438  ID.AddPointer(T.getAsOpaquePtr());
1439}
1440
1441void StmtProfiler::VisitName(DeclarationName Name) {
1442  ID.AddPointer(Name.getAsOpaquePtr());
1443}
1444
1445void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
1446  if (Canonical)
1447    NNS = Context.getCanonicalNestedNameSpecifier(NNS);
1448  ID.AddPointer(NNS);
1449}
1450
1451void StmtProfiler::VisitTemplateName(TemplateName Name) {
1452  if (Canonical)
1453    Name = Context.getCanonicalTemplateName(Name);
1454
1455  Name.Profile(ID);
1456}
1457
1458void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
1459                                          unsigned NumArgs) {
1460  ID.AddInteger(NumArgs);
1461  for (unsigned I = 0; I != NumArgs; ++I)
1462    VisitTemplateArgument(Args[I].getArgument());
1463}
1464
1465void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
1466  // Mostly repetitive with TemplateArgument::Profile!
1467  ID.AddInteger(Arg.getKind());
1468  switch (Arg.getKind()) {
1469  case TemplateArgument::Null:
1470    break;
1471
1472  case TemplateArgument::Type:
1473    VisitType(Arg.getAsType());
1474    break;
1475
1476  case TemplateArgument::Template:
1477  case TemplateArgument::TemplateExpansion:
1478    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1479    break;
1480
1481  case TemplateArgument::Declaration:
1482    VisitDecl(Arg.getAsDecl());
1483    break;
1484
1485  case TemplateArgument::NullPtr:
1486    VisitType(Arg.getNullPtrType());
1487    break;
1488
1489  case TemplateArgument::Integral:
1490    Arg.getAsIntegral().Profile(ID);
1491    VisitType(Arg.getIntegralType());
1492    break;
1493
1494  case TemplateArgument::Expression:
1495    Visit(Arg.getAsExpr());
1496    break;
1497
1498  case TemplateArgument::Pack:
1499    for (const auto &P : Arg.pack_elements())
1500      VisitTemplateArgument(P);
1501    break;
1502  }
1503}
1504
1505void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
1506                   bool Canonical) const {
1507  StmtProfiler Profiler(ID, Context, Canonical);
1508  Profiler.Visit(this);
1509}
1510