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