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