clang API Documentation

StmtProfile.cpp
Go to the documentation of this file.
00001 //===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the Stmt::Profile method, which builds a unique bit
00011 // representation that identifies a statement/expression.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #include "clang/AST/ASTContext.h"
00015 #include "clang/AST/DeclCXX.h"
00016 #include "clang/AST/DeclObjC.h"
00017 #include "clang/AST/DeclTemplate.h"
00018 #include "clang/AST/Expr.h"
00019 #include "clang/AST/ExprCXX.h"
00020 #include "clang/AST/ExprObjC.h"
00021 #include "clang/AST/StmtVisitor.h"
00022 #include "llvm/ADT/FoldingSet.h"
00023 using namespace clang;
00024 
00025 namespace {
00026   class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
00027     llvm::FoldingSetNodeID &ID;
00028     const ASTContext &Context;
00029     bool Canonical;
00030 
00031   public:
00032     StmtProfiler(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
00033                  bool Canonical)
00034       : ID(ID), Context(Context), Canonical(Canonical) { }
00035 
00036     void VisitStmt(const Stmt *S);
00037 
00038 #define STMT(Node, Base) void Visit##Node(const Node *S);
00039 #include "clang/AST/StmtNodes.inc"
00040 
00041     /// \brief Visit a declaration that is referenced within an expression
00042     /// or statement.
00043     void VisitDecl(const Decl *D);
00044 
00045     /// \brief Visit a type that is referenced within an expression or
00046     /// statement.
00047     void VisitType(QualType T);
00048 
00049     /// \brief Visit a name that occurs within an expression or statement.
00050     void VisitName(DeclarationName Name);
00051 
00052     /// \brief Visit a nested-name-specifier that occurs within an expression
00053     /// or statement.
00054     void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
00055 
00056     /// \brief Visit a template name that occurs within an expression or
00057     /// statement.
00058     void VisitTemplateName(TemplateName Name);
00059 
00060     /// \brief Visit template arguments that occur within an expression or
00061     /// statement.
00062     void VisitTemplateArguments(const TemplateArgumentLoc *Args,
00063                                 unsigned NumArgs);
00064 
00065     /// \brief Visit a single template argument.
00066     void VisitTemplateArgument(const TemplateArgument &Arg);
00067   };
00068 }
00069 
00070 void StmtProfiler::VisitStmt(const Stmt *S) {
00071   ID.AddInteger(S->getStmtClass());
00072   for (Stmt::const_child_range C = S->children(); C; ++C) {
00073     if (*C)
00074       Visit(*C);
00075     else
00076       ID.AddInteger(0);
00077   }
00078 }
00079 
00080 void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
00081   VisitStmt(S);
00082   for (const auto *D : S->decls())
00083     VisitDecl(D);
00084 }
00085 
00086 void StmtProfiler::VisitNullStmt(const NullStmt *S) {
00087   VisitStmt(S);
00088 }
00089 
00090 void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
00091   VisitStmt(S);
00092 }
00093 
00094 void StmtProfiler::VisitSwitchCase(const SwitchCase *S) {
00095   VisitStmt(S);
00096 }
00097 
00098 void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
00099   VisitStmt(S);
00100 }
00101 
00102 void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
00103   VisitStmt(S);
00104 }
00105 
00106 void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
00107   VisitStmt(S);
00108   VisitDecl(S->getDecl());
00109 }
00110 
00111 void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
00112   VisitStmt(S);
00113   // TODO: maybe visit attributes?
00114 }
00115 
00116 void StmtProfiler::VisitIfStmt(const IfStmt *S) {
00117   VisitStmt(S);
00118   VisitDecl(S->getConditionVariable());
00119 }
00120 
00121 void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
00122   VisitStmt(S);
00123   VisitDecl(S->getConditionVariable());
00124 }
00125 
00126 void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
00127   VisitStmt(S);
00128   VisitDecl(S->getConditionVariable());
00129 }
00130 
00131 void StmtProfiler::VisitDoStmt(const DoStmt *S) {
00132   VisitStmt(S);
00133 }
00134 
00135 void StmtProfiler::VisitForStmt(const ForStmt *S) {
00136   VisitStmt(S);
00137 }
00138 
00139 void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
00140   VisitStmt(S);
00141   VisitDecl(S->getLabel());
00142 }
00143 
00144 void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
00145   VisitStmt(S);
00146 }
00147 
00148 void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
00149   VisitStmt(S);
00150 }
00151 
00152 void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
00153   VisitStmt(S);
00154 }
00155 
00156 void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
00157   VisitStmt(S);
00158 }
00159 
00160 void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
00161   VisitStmt(S);
00162   ID.AddBoolean(S->isVolatile());
00163   ID.AddBoolean(S->isSimple());
00164   VisitStringLiteral(S->getAsmString());
00165   ID.AddInteger(S->getNumOutputs());
00166   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
00167     ID.AddString(S->getOutputName(I));
00168     VisitStringLiteral(S->getOutputConstraintLiteral(I));
00169   }
00170   ID.AddInteger(S->getNumInputs());
00171   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
00172     ID.AddString(S->getInputName(I));
00173     VisitStringLiteral(S->getInputConstraintLiteral(I));
00174   }
00175   ID.AddInteger(S->getNumClobbers());
00176   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
00177     VisitStringLiteral(S->getClobberStringLiteral(I));
00178 }
00179 
00180 void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) {
00181   // FIXME: Implement MS style inline asm statement profiler.
00182   VisitStmt(S);
00183 }
00184 
00185 void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
00186   VisitStmt(S);
00187   VisitType(S->getCaughtType());
00188 }
00189 
00190 void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
00191   VisitStmt(S);
00192 }
00193 
00194 void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
00195   VisitStmt(S);
00196 }
00197 
00198 void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
00199   VisitStmt(S);
00200   ID.AddBoolean(S->isIfExists());
00201   VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
00202   VisitName(S->getNameInfo().getName());
00203 }
00204 
00205 void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
00206   VisitStmt(S);
00207 }
00208 
00209 void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
00210   VisitStmt(S);
00211 }
00212 
00213 void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
00214   VisitStmt(S);
00215 }
00216 
00217 void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
00218   VisitStmt(S);
00219 }
00220 
00221 void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
00222   VisitStmt(S);
00223 }
00224 
00225 void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
00226   VisitStmt(S);
00227 }
00228 
00229 void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
00230   VisitStmt(S);
00231   ID.AddBoolean(S->hasEllipsis());
00232   if (S->getCatchParamDecl())
00233     VisitType(S->getCatchParamDecl()->getType());
00234 }
00235 
00236 void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
00237   VisitStmt(S);
00238 }
00239 
00240 void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
00241   VisitStmt(S);
00242 }
00243 
00244 void
00245 StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
00246   VisitStmt(S);
00247 }
00248 
00249 void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
00250   VisitStmt(S);
00251 }
00252 
00253 void
00254 StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
00255   VisitStmt(S);
00256 }
00257 
00258 namespace {
00259 class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
00260   StmtProfiler *Profiler;
00261   /// \brief Process clauses with list of variables.
00262   template <typename T>
00263   void VisitOMPClauseList(T *Node);
00264 public:
00265   OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
00266 #define OPENMP_CLAUSE(Name, Class)                                             \
00267   void Visit##Class(const Class *C);
00268 #include "clang/Basic/OpenMPKinds.def"
00269 };
00270 
00271 void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
00272   if (C->getCondition())
00273     Profiler->VisitStmt(C->getCondition());
00274 }
00275 
00276 void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
00277   if (C->getCondition())
00278     Profiler->VisitStmt(C->getCondition());
00279 }
00280 
00281 void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
00282   if (C->getNumThreads())
00283     Profiler->VisitStmt(C->getNumThreads());
00284 }
00285 
00286 void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
00287   if (C->getSafelen())
00288     Profiler->VisitStmt(C->getSafelen());
00289 }
00290 
00291 void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
00292   if (C->getNumForLoops())
00293     Profiler->VisitStmt(C->getNumForLoops());
00294 }
00295 
00296 void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
00297 
00298 void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
00299 
00300 void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
00301   if (C->getChunkSize())
00302     Profiler->VisitStmt(C->getChunkSize());
00303 }
00304 
00305 void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {}
00306 
00307 void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
00308 
00309 void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
00310 
00311 void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
00312 
00313 void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}
00314 
00315 void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {}
00316 
00317 void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
00318 
00319 void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
00320 
00321 void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
00322 
00323 template<typename T>
00324 void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
00325   for (auto *E : Node->varlists()) {
00326     Profiler->VisitStmt(E);
00327   }
00328 }
00329 
00330 void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
00331   VisitOMPClauseList(C);
00332   for (auto *E : C->private_copies()) {
00333     Profiler->VisitStmt(E);
00334   }
00335 }
00336 void
00337 OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
00338   VisitOMPClauseList(C);
00339   for (auto *E : C->private_copies()) {
00340     Profiler->VisitStmt(E);
00341   }
00342   for (auto *E : C->inits()) {
00343     Profiler->VisitStmt(E);
00344   }
00345 }
00346 void
00347 OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
00348   VisitOMPClauseList(C);
00349 }
00350 void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
00351   VisitOMPClauseList(C);
00352 }
00353 void OMPClauseProfiler::VisitOMPReductionClause(
00354                                          const OMPReductionClause *C) {
00355   Profiler->VisitNestedNameSpecifier(
00356       C->getQualifierLoc().getNestedNameSpecifier());
00357   Profiler->VisitName(C->getNameInfo().getName());
00358   VisitOMPClauseList(C);
00359 }
00360 void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
00361   VisitOMPClauseList(C);
00362   Profiler->VisitStmt(C->getStep());
00363 }
00364 void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
00365   VisitOMPClauseList(C);
00366   Profiler->VisitStmt(C->getAlignment());
00367 }
00368 void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
00369   VisitOMPClauseList(C);
00370 }
00371 void
00372 OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
00373   VisitOMPClauseList(C);
00374 }
00375 void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
00376   VisitOMPClauseList(C);
00377 }
00378 }
00379 
00380 void
00381 StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
00382   VisitStmt(S);
00383   OMPClauseProfiler P(this);
00384   ArrayRef<OMPClause *> Clauses = S->clauses();
00385   for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
00386        I != E; ++I)
00387     if (*I)
00388       P.Visit(*I);
00389 }
00390 
00391 void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
00392   VisitOMPExecutableDirective(S);
00393 }
00394 
00395 void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
00396   VisitOMPExecutableDirective(S);
00397 }
00398 
00399 void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
00400   VisitOMPLoopDirective(S);
00401 }
00402 
00403 void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
00404   VisitOMPLoopDirective(S);
00405 }
00406 
00407 void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
00408   VisitOMPLoopDirective(S);
00409 }
00410 
00411 void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
00412   VisitOMPExecutableDirective(S);
00413 }
00414 
00415 void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
00416   VisitOMPExecutableDirective(S);
00417 }
00418 
00419 void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
00420   VisitOMPExecutableDirective(S);
00421 }
00422 
00423 void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
00424   VisitOMPExecutableDirective(S);
00425 }
00426 
00427 void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
00428   VisitOMPExecutableDirective(S);
00429   VisitName(S->getDirectiveName().getName());
00430 }
00431 
00432 void
00433 StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
00434   VisitOMPLoopDirective(S);
00435 }
00436 
00437 void StmtProfiler::VisitOMPParallelForSimdDirective(
00438     const OMPParallelForSimdDirective *S) {
00439   VisitOMPLoopDirective(S);
00440 }
00441 
00442 void StmtProfiler::VisitOMPParallelSectionsDirective(
00443     const OMPParallelSectionsDirective *S) {
00444   VisitOMPExecutableDirective(S);
00445 }
00446 
00447 void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
00448   VisitOMPExecutableDirective(S);
00449 }
00450 
00451 void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
00452   VisitOMPExecutableDirective(S);
00453 }
00454 
00455 void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
00456   VisitOMPExecutableDirective(S);
00457 }
00458 
00459 void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
00460   VisitOMPExecutableDirective(S);
00461 }
00462 
00463 void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
00464   VisitOMPExecutableDirective(S);
00465 }
00466 
00467 void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
00468   VisitOMPExecutableDirective(S);
00469 }
00470 
00471 void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
00472   VisitOMPExecutableDirective(S);
00473 }
00474 
00475 void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
00476   VisitOMPExecutableDirective(S);
00477 }
00478 
00479 void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
00480   VisitOMPExecutableDirective(S);
00481 }
00482 
00483 void StmtProfiler::VisitExpr(const Expr *S) {
00484   VisitStmt(S);
00485 }
00486 
00487 void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
00488   VisitExpr(S);
00489   if (!Canonical)
00490     VisitNestedNameSpecifier(S->getQualifier());
00491   VisitDecl(S->getDecl());
00492   if (!Canonical)
00493     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
00494 }
00495 
00496 void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
00497   VisitExpr(S);
00498   ID.AddInteger(S->getIdentType());
00499 }
00500 
00501 void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
00502   VisitExpr(S);
00503   S->getValue().Profile(ID);
00504 }
00505 
00506 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
00507   VisitExpr(S);
00508   ID.AddInteger(S->getKind());
00509   ID.AddInteger(S->getValue());
00510 }
00511 
00512 void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
00513   VisitExpr(S);
00514   S->getValue().Profile(ID);
00515   ID.AddBoolean(S->isExact());
00516 }
00517 
00518 void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
00519   VisitExpr(S);
00520 }
00521 
00522 void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
00523   VisitExpr(S);
00524   ID.AddString(S->getBytes());
00525   ID.AddInteger(S->getKind());
00526 }
00527 
00528 void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
00529   VisitExpr(S);
00530 }
00531 
00532 void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
00533   VisitExpr(S);
00534 }
00535 
00536 void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
00537   VisitExpr(S);
00538   ID.AddInteger(S->getOpcode());
00539 }
00540 
00541 void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
00542   VisitType(S->getTypeSourceInfo()->getType());
00543   unsigned n = S->getNumComponents();
00544   for (unsigned i = 0; i < n; ++i) {
00545     const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
00546     ID.AddInteger(ON.getKind());
00547     switch (ON.getKind()) {
00548     case OffsetOfExpr::OffsetOfNode::Array:
00549       // Expressions handled below.
00550       break;
00551 
00552     case OffsetOfExpr::OffsetOfNode::Field:
00553       VisitDecl(ON.getField());
00554       break;
00555 
00556     case OffsetOfExpr::OffsetOfNode::Identifier:
00557       ID.AddPointer(ON.getFieldName());
00558       break;
00559         
00560     case OffsetOfExpr::OffsetOfNode::Base:
00561       // These nodes are implicit, and therefore don't need profiling.
00562       break;
00563     }
00564   }
00565   
00566   VisitExpr(S);
00567 }
00568 
00569 void
00570 StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
00571   VisitExpr(S);
00572   ID.AddInteger(S->getKind());
00573   if (S->isArgumentType())
00574     VisitType(S->getArgumentType());
00575 }
00576 
00577 void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
00578   VisitExpr(S);
00579 }
00580 
00581 void StmtProfiler::VisitCallExpr(const CallExpr *S) {
00582   VisitExpr(S);
00583 }
00584 
00585 void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
00586   VisitExpr(S);
00587   VisitDecl(S->getMemberDecl());
00588   if (!Canonical)
00589     VisitNestedNameSpecifier(S->getQualifier());
00590   ID.AddBoolean(S->isArrow());
00591 }
00592 
00593 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
00594   VisitExpr(S);
00595   ID.AddBoolean(S->isFileScope());
00596 }
00597 
00598 void StmtProfiler::VisitCastExpr(const CastExpr *S) {
00599   VisitExpr(S);
00600 }
00601 
00602 void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
00603   VisitCastExpr(S);
00604   ID.AddInteger(S->getValueKind());
00605 }
00606 
00607 void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
00608   VisitCastExpr(S);
00609   VisitType(S->getTypeAsWritten());
00610 }
00611 
00612 void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
00613   VisitExplicitCastExpr(S);
00614 }
00615 
00616 void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
00617   VisitExpr(S);
00618   ID.AddInteger(S->getOpcode());
00619 }
00620 
00621 void
00622 StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
00623   VisitBinaryOperator(S);
00624 }
00625 
00626 void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
00627   VisitExpr(S);
00628 }
00629 
00630 void StmtProfiler::VisitBinaryConditionalOperator(
00631     const BinaryConditionalOperator *S) {
00632   VisitExpr(S);
00633 }
00634 
00635 void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
00636   VisitExpr(S);
00637   VisitDecl(S->getLabel());
00638 }
00639 
00640 void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
00641   VisitExpr(S);
00642 }
00643 
00644 void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
00645   VisitExpr(S);
00646 }
00647 
00648 void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
00649   VisitExpr(S);
00650 }
00651 
00652 void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
00653   VisitExpr(S);
00654 }
00655 
00656 void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
00657   VisitExpr(S);
00658 }
00659 
00660 void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
00661   VisitExpr(S);
00662 }
00663 
00664 void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
00665   if (S->getSyntacticForm()) {
00666     VisitInitListExpr(S->getSyntacticForm());
00667     return;
00668   }
00669 
00670   VisitExpr(S);
00671 }
00672 
00673 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
00674   VisitExpr(S);
00675   ID.AddBoolean(S->usesGNUSyntax());
00676   for (DesignatedInitExpr::const_designators_iterator D =
00677          S->designators_begin(), DEnd = S->designators_end();
00678        D != DEnd; ++D) {
00679     if (D->isFieldDesignator()) {
00680       ID.AddInteger(0);
00681       VisitName(D->getFieldName());
00682       continue;
00683     }
00684 
00685     if (D->isArrayDesignator()) {
00686       ID.AddInteger(1);
00687     } else {
00688       assert(D->isArrayRangeDesignator());
00689       ID.AddInteger(2);
00690     }
00691     ID.AddInteger(D->getFirstExprIndex());
00692   }
00693 }
00694 
00695 void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
00696   VisitExpr(S);
00697 }
00698 
00699 void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
00700   VisitExpr(S);
00701   VisitName(&S->getAccessor());
00702 }
00703 
00704 void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
00705   VisitExpr(S);
00706   VisitDecl(S->getBlockDecl());
00707 }
00708 
00709 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
00710   VisitExpr(S);
00711   for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
00712     QualType T = S->getAssocType(i);
00713     if (T.isNull())
00714       ID.AddPointer(nullptr);
00715     else
00716       VisitType(T);
00717     VisitExpr(S->getAssocExpr(i));
00718   }
00719 }
00720 
00721 void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
00722   VisitExpr(S);
00723   for (PseudoObjectExpr::const_semantics_iterator
00724          i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
00725     // Normally, we would not profile the source expressions of OVEs.
00726     if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
00727       Visit(OVE->getSourceExpr());
00728 }
00729 
00730 void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
00731   VisitExpr(S);
00732   ID.AddInteger(S->getOp());
00733 }
00734 
00735 static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
00736                                           UnaryOperatorKind &UnaryOp,
00737                                           BinaryOperatorKind &BinaryOp) {
00738   switch (S->getOperator()) {
00739   case OO_None:
00740   case OO_New:
00741   case OO_Delete:
00742   case OO_Array_New:
00743   case OO_Array_Delete:
00744   case OO_Arrow:
00745   case OO_Call:
00746   case OO_Conditional:
00747   case NUM_OVERLOADED_OPERATORS:
00748     llvm_unreachable("Invalid operator call kind");
00749       
00750   case OO_Plus:
00751     if (S->getNumArgs() == 1) {
00752       UnaryOp = UO_Plus;
00753       return Stmt::UnaryOperatorClass;
00754     }
00755     
00756     BinaryOp = BO_Add;
00757     return Stmt::BinaryOperatorClass;
00758       
00759   case OO_Minus:
00760     if (S->getNumArgs() == 1) {
00761       UnaryOp = UO_Minus;
00762       return Stmt::UnaryOperatorClass;
00763     }
00764     
00765     BinaryOp = BO_Sub;
00766     return Stmt::BinaryOperatorClass;
00767 
00768   case OO_Star:
00769     if (S->getNumArgs() == 1) {
00770       UnaryOp = UO_Deref;
00771       return Stmt::UnaryOperatorClass;
00772     }
00773     
00774     BinaryOp = BO_Mul;
00775     return Stmt::BinaryOperatorClass;
00776 
00777   case OO_Slash:
00778     BinaryOp = BO_Div;
00779     return Stmt::BinaryOperatorClass;
00780       
00781   case OO_Percent:
00782     BinaryOp = BO_Rem;
00783     return Stmt::BinaryOperatorClass;
00784 
00785   case OO_Caret:
00786     BinaryOp = BO_Xor;
00787     return Stmt::BinaryOperatorClass;
00788 
00789   case OO_Amp:
00790     if (S->getNumArgs() == 1) {
00791       UnaryOp = UO_AddrOf;
00792       return Stmt::UnaryOperatorClass;
00793     }
00794     
00795     BinaryOp = BO_And;
00796     return Stmt::BinaryOperatorClass;
00797       
00798   case OO_Pipe:
00799     BinaryOp = BO_Or;
00800     return Stmt::BinaryOperatorClass;
00801 
00802   case OO_Tilde:
00803     UnaryOp = UO_Not;
00804     return Stmt::UnaryOperatorClass;
00805 
00806   case OO_Exclaim:
00807     UnaryOp = UO_LNot;
00808     return Stmt::UnaryOperatorClass;
00809 
00810   case OO_Equal:
00811     BinaryOp = BO_Assign;
00812     return Stmt::BinaryOperatorClass;
00813 
00814   case OO_Less:
00815     BinaryOp = BO_LT;
00816     return Stmt::BinaryOperatorClass;
00817 
00818   case OO_Greater:
00819     BinaryOp = BO_GT;
00820     return Stmt::BinaryOperatorClass;
00821       
00822   case OO_PlusEqual:
00823     BinaryOp = BO_AddAssign;
00824     return Stmt::CompoundAssignOperatorClass;
00825 
00826   case OO_MinusEqual:
00827     BinaryOp = BO_SubAssign;
00828     return Stmt::CompoundAssignOperatorClass;
00829 
00830   case OO_StarEqual:
00831     BinaryOp = BO_MulAssign;
00832     return Stmt::CompoundAssignOperatorClass;
00833 
00834   case OO_SlashEqual:
00835     BinaryOp = BO_DivAssign;
00836     return Stmt::CompoundAssignOperatorClass;
00837 
00838   case OO_PercentEqual:
00839     BinaryOp = BO_RemAssign;
00840     return Stmt::CompoundAssignOperatorClass;
00841 
00842   case OO_CaretEqual:
00843     BinaryOp = BO_XorAssign;
00844     return Stmt::CompoundAssignOperatorClass;
00845     
00846   case OO_AmpEqual:
00847     BinaryOp = BO_AndAssign;
00848     return Stmt::CompoundAssignOperatorClass;
00849     
00850   case OO_PipeEqual:
00851     BinaryOp = BO_OrAssign;
00852     return Stmt::CompoundAssignOperatorClass;
00853       
00854   case OO_LessLess:
00855     BinaryOp = BO_Shl;
00856     return Stmt::BinaryOperatorClass;
00857     
00858   case OO_GreaterGreater:
00859     BinaryOp = BO_Shr;
00860     return Stmt::BinaryOperatorClass;
00861 
00862   case OO_LessLessEqual:
00863     BinaryOp = BO_ShlAssign;
00864     return Stmt::CompoundAssignOperatorClass;
00865     
00866   case OO_GreaterGreaterEqual:
00867     BinaryOp = BO_ShrAssign;
00868     return Stmt::CompoundAssignOperatorClass;
00869 
00870   case OO_EqualEqual:
00871     BinaryOp = BO_EQ;
00872     return Stmt::BinaryOperatorClass;
00873     
00874   case OO_ExclaimEqual:
00875     BinaryOp = BO_NE;
00876     return Stmt::BinaryOperatorClass;
00877       
00878   case OO_LessEqual:
00879     BinaryOp = BO_LE;
00880     return Stmt::BinaryOperatorClass;
00881     
00882   case OO_GreaterEqual:
00883     BinaryOp = BO_GE;
00884     return Stmt::BinaryOperatorClass;
00885       
00886   case OO_AmpAmp:
00887     BinaryOp = BO_LAnd;
00888     return Stmt::BinaryOperatorClass;
00889     
00890   case OO_PipePipe:
00891     BinaryOp = BO_LOr;
00892     return Stmt::BinaryOperatorClass;
00893 
00894   case OO_PlusPlus:
00895     UnaryOp = S->getNumArgs() == 1? UO_PreInc 
00896                                   : UO_PostInc;
00897     return Stmt::UnaryOperatorClass;
00898 
00899   case OO_MinusMinus:
00900     UnaryOp = S->getNumArgs() == 1? UO_PreDec
00901                                   : UO_PostDec;
00902     return Stmt::UnaryOperatorClass;
00903 
00904   case OO_Comma:
00905     BinaryOp = BO_Comma;
00906     return Stmt::BinaryOperatorClass;
00907 
00908 
00909   case OO_ArrowStar:
00910     BinaryOp = BO_PtrMemI;
00911     return Stmt::BinaryOperatorClass;
00912       
00913   case OO_Subscript:
00914     return Stmt::ArraySubscriptExprClass;
00915   }
00916   
00917   llvm_unreachable("Invalid overloaded operator expression");
00918 }
00919 
00920 
00921 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
00922   if (S->isTypeDependent()) {
00923     // Type-dependent operator calls are profiled like their underlying
00924     // syntactic operator.
00925     UnaryOperatorKind UnaryOp = UO_Extension;
00926     BinaryOperatorKind BinaryOp = BO_Comma;
00927     Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
00928 
00929     ID.AddInteger(SC);
00930     for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
00931       Visit(S->getArg(I));
00932     if (SC == Stmt::UnaryOperatorClass)
00933       ID.AddInteger(UnaryOp);
00934     else if (SC == Stmt::BinaryOperatorClass || 
00935              SC == Stmt::CompoundAssignOperatorClass)
00936       ID.AddInteger(BinaryOp);
00937     else
00938       assert(SC == Stmt::ArraySubscriptExprClass);
00939 
00940     return;
00941   }
00942 
00943   VisitCallExpr(S);
00944   ID.AddInteger(S->getOperator());
00945 }
00946 
00947 void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
00948   VisitCallExpr(S);
00949 }
00950 
00951 void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
00952   VisitCallExpr(S);
00953 }
00954 
00955 void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
00956   VisitExpr(S);
00957 }
00958 
00959 void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
00960   VisitExplicitCastExpr(S);
00961 }
00962 
00963 void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
00964   VisitCXXNamedCastExpr(S);
00965 }
00966 
00967 void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
00968   VisitCXXNamedCastExpr(S);
00969 }
00970 
00971 void
00972 StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
00973   VisitCXXNamedCastExpr(S);
00974 }
00975 
00976 void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
00977   VisitCXXNamedCastExpr(S);
00978 }
00979 
00980 void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
00981   VisitCallExpr(S);
00982 }
00983 
00984 void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
00985   VisitExpr(S);
00986   ID.AddBoolean(S->getValue());
00987 }
00988 
00989 void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
00990   VisitExpr(S);
00991 }
00992 
00993 void StmtProfiler::VisitCXXStdInitializerListExpr(
00994     const CXXStdInitializerListExpr *S) {
00995   VisitExpr(S);
00996 }
00997 
00998 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
00999   VisitExpr(S);
01000   if (S->isTypeOperand())
01001     VisitType(S->getTypeOperandSourceInfo()->getType());
01002 }
01003 
01004 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
01005   VisitExpr(S);
01006   if (S->isTypeOperand())
01007     VisitType(S->getTypeOperandSourceInfo()->getType());
01008 }
01009 
01010 void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
01011   VisitExpr(S);
01012   VisitDecl(S->getPropertyDecl());
01013 }
01014 
01015 void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
01016   VisitExpr(S);
01017   ID.AddBoolean(S->isImplicit());
01018 }
01019 
01020 void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
01021   VisitExpr(S);
01022 }
01023 
01024 void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
01025   VisitExpr(S);
01026   VisitDecl(S->getParam());
01027 }
01028 
01029 void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
01030   VisitExpr(S);
01031   VisitDecl(S->getField());
01032 }
01033 
01034 void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
01035   VisitExpr(S);
01036   VisitDecl(
01037          const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
01038 }
01039 
01040 void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
01041   VisitExpr(S);
01042   VisitDecl(S->getConstructor());
01043   ID.AddBoolean(S->isElidable());
01044 }
01045 
01046 void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
01047   VisitExplicitCastExpr(S);
01048 }
01049 
01050 void
01051 StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
01052   VisitCXXConstructExpr(S);
01053 }
01054 
01055 void
01056 StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
01057   VisitExpr(S);
01058   for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
01059                                  CEnd = S->explicit_capture_end();
01060        C != CEnd; ++C) {
01061     ID.AddInteger(C->getCaptureKind());
01062     switch (C->getCaptureKind()) {
01063     case LCK_This:
01064       break;
01065     case LCK_ByRef:
01066     case LCK_ByCopy:
01067       VisitDecl(C->getCapturedVar());
01068       ID.AddBoolean(C->isPackExpansion());
01069       break;
01070     case LCK_VLAType:
01071       llvm_unreachable("VLA type in explicit captures.");
01072     }
01073   }
01074   // Note: If we actually needed to be able to match lambda
01075   // expressions, we would have to consider parameters and return type
01076   // here, among other things.
01077   VisitStmt(S->getBody());
01078 }
01079 
01080 void
01081 StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
01082   VisitExpr(S);
01083 }
01084 
01085 void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
01086   VisitExpr(S);
01087   ID.AddBoolean(S->isGlobalDelete());
01088   ID.AddBoolean(S->isArrayForm());
01089   VisitDecl(S->getOperatorDelete());
01090 }
01091 
01092 
01093 void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
01094   VisitExpr(S);
01095   VisitType(S->getAllocatedType());
01096   VisitDecl(S->getOperatorNew());
01097   VisitDecl(S->getOperatorDelete());
01098   ID.AddBoolean(S->isArray());
01099   ID.AddInteger(S->getNumPlacementArgs());
01100   ID.AddBoolean(S->isGlobalNew());
01101   ID.AddBoolean(S->isParenTypeId());
01102   ID.AddInteger(S->getInitializationStyle());
01103 }
01104 
01105 void
01106 StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
01107   VisitExpr(S);
01108   ID.AddBoolean(S->isArrow());
01109   VisitNestedNameSpecifier(S->getQualifier());
01110   ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
01111   if (S->getScopeTypeInfo())
01112     VisitType(S->getScopeTypeInfo()->getType());
01113   ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
01114   if (S->getDestroyedTypeInfo())
01115     VisitType(S->getDestroyedType());
01116   else
01117     ID.AddPointer(S->getDestroyedTypeIdentifier());
01118 }
01119 
01120 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
01121   VisitExpr(S);
01122   VisitNestedNameSpecifier(S->getQualifier());
01123   VisitName(S->getName());
01124   ID.AddBoolean(S->hasExplicitTemplateArgs());
01125   if (S->hasExplicitTemplateArgs())
01126     VisitTemplateArguments(S->getExplicitTemplateArgs().getTemplateArgs(),
01127                            S->getExplicitTemplateArgs().NumTemplateArgs);
01128 }
01129 
01130 void
01131 StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
01132   VisitOverloadExpr(S);
01133 }
01134 
01135 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
01136   VisitExpr(S);
01137   ID.AddInteger(S->getTrait());
01138   ID.AddInteger(S->getNumArgs());
01139   for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
01140     VisitType(S->getArg(I)->getType());
01141 }
01142 
01143 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
01144   VisitExpr(S);
01145   ID.AddInteger(S->getTrait());
01146   VisitType(S->getQueriedType());
01147 }
01148 
01149 void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
01150   VisitExpr(S);
01151   ID.AddInteger(S->getTrait());
01152   VisitExpr(S->getQueriedExpression());
01153 }
01154 
01155 void StmtProfiler::VisitDependentScopeDeclRefExpr(
01156     const DependentScopeDeclRefExpr *S) {
01157   VisitExpr(S);
01158   VisitName(S->getDeclName());
01159   VisitNestedNameSpecifier(S->getQualifier());
01160   ID.AddBoolean(S->hasExplicitTemplateArgs());
01161   if (S->hasExplicitTemplateArgs())
01162     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
01163 }
01164 
01165 void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
01166   VisitExpr(S);
01167 }
01168 
01169 void StmtProfiler::VisitCXXUnresolvedConstructExpr(
01170     const CXXUnresolvedConstructExpr *S) {
01171   VisitExpr(S);
01172   VisitType(S->getTypeAsWritten());
01173 }
01174 
01175 void StmtProfiler::VisitCXXDependentScopeMemberExpr(
01176     const CXXDependentScopeMemberExpr *S) {
01177   ID.AddBoolean(S->isImplicitAccess());
01178   if (!S->isImplicitAccess()) {
01179     VisitExpr(S);
01180     ID.AddBoolean(S->isArrow());
01181   }
01182   VisitNestedNameSpecifier(S->getQualifier());
01183   VisitName(S->getMember());
01184   ID.AddBoolean(S->hasExplicitTemplateArgs());
01185   if (S->hasExplicitTemplateArgs())
01186     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
01187 }
01188 
01189 void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
01190   ID.AddBoolean(S->isImplicitAccess());
01191   if (!S->isImplicitAccess()) {
01192     VisitExpr(S);
01193     ID.AddBoolean(S->isArrow());
01194   }
01195   VisitNestedNameSpecifier(S->getQualifier());
01196   VisitName(S->getMemberName());
01197   ID.AddBoolean(S->hasExplicitTemplateArgs());
01198   if (S->hasExplicitTemplateArgs())
01199     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
01200 }
01201 
01202 void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
01203   VisitExpr(S);
01204 }
01205 
01206 void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
01207   VisitExpr(S);
01208 }
01209 
01210 void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
01211   VisitExpr(S);
01212   VisitDecl(S->getPack());
01213 }
01214 
01215 void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
01216     const SubstNonTypeTemplateParmPackExpr *S) {
01217   VisitExpr(S);
01218   VisitDecl(S->getParameterPack());
01219   VisitTemplateArgument(S->getArgumentPack());
01220 }
01221 
01222 void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
01223     const SubstNonTypeTemplateParmExpr *E) {
01224   // Profile exactly as the replacement expression.
01225   Visit(E->getReplacement());
01226 }
01227 
01228 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
01229   VisitExpr(S);
01230   VisitDecl(S->getParameterPack());
01231   ID.AddInteger(S->getNumExpansions());
01232   for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
01233     VisitDecl(*I);
01234 }
01235 
01236 void StmtProfiler::VisitMaterializeTemporaryExpr(
01237                                            const MaterializeTemporaryExpr *S) {
01238   VisitExpr(S);
01239 }
01240 
01241 void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
01242   VisitExpr(S);
01243   ID.AddInteger(S->getOperator());
01244 }
01245 
01246 void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
01247   VisitExpr(E);  
01248 }
01249 
01250 void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
01251   VisitExpr(E);
01252 }
01253 
01254 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
01255   VisitExpr(S);
01256 }
01257 
01258 void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
01259   VisitExpr(E);
01260 }
01261 
01262 void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
01263   VisitExpr(E);
01264 }
01265 
01266 void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
01267   VisitExpr(E);
01268 }
01269 
01270 void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
01271   VisitExpr(S);
01272   VisitType(S->getEncodedType());
01273 }
01274 
01275 void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
01276   VisitExpr(S);
01277   VisitName(S->getSelector());
01278 }
01279 
01280 void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
01281   VisitExpr(S);
01282   VisitDecl(S->getProtocol());
01283 }
01284 
01285 void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
01286   VisitExpr(S);
01287   VisitDecl(S->getDecl());
01288   ID.AddBoolean(S->isArrow());
01289   ID.AddBoolean(S->isFreeIvar());
01290 }
01291 
01292 void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
01293   VisitExpr(S);
01294   if (S->isImplicitProperty()) {
01295     VisitDecl(S->getImplicitPropertyGetter());
01296     VisitDecl(S->getImplicitPropertySetter());
01297   } else {
01298     VisitDecl(S->getExplicitProperty());
01299   }
01300   if (S->isSuperReceiver()) {
01301     ID.AddBoolean(S->isSuperReceiver());
01302     VisitType(S->getSuperReceiverType());
01303   }
01304 }
01305 
01306 void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
01307   VisitExpr(S);
01308   VisitDecl(S->getAtIndexMethodDecl());
01309   VisitDecl(S->setAtIndexMethodDecl());
01310 }
01311 
01312 void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
01313   VisitExpr(S);
01314   VisitName(S->getSelector());
01315   VisitDecl(S->getMethodDecl());
01316 }
01317 
01318 void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
01319   VisitExpr(S);
01320   ID.AddBoolean(S->isArrow());
01321 }
01322 
01323 void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
01324   VisitExpr(S);
01325   ID.AddBoolean(S->getValue());
01326 }
01327 
01328 void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
01329     const ObjCIndirectCopyRestoreExpr *S) {
01330   VisitExpr(S);
01331   ID.AddBoolean(S->shouldCopy());
01332 }
01333 
01334 void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
01335   VisitExplicitCastExpr(S);
01336   ID.AddBoolean(S->getBridgeKind());
01337 }
01338 
01339 void StmtProfiler::VisitDecl(const Decl *D) {
01340   ID.AddInteger(D? D->getKind() : 0);
01341 
01342   if (Canonical && D) {
01343     if (const NonTypeTemplateParmDecl *NTTP =
01344           dyn_cast<NonTypeTemplateParmDecl>(D)) {
01345       ID.AddInteger(NTTP->getDepth());
01346       ID.AddInteger(NTTP->getIndex());
01347       ID.AddBoolean(NTTP->isParameterPack());
01348       VisitType(NTTP->getType());
01349       return;
01350     }
01351 
01352     if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
01353       // The Itanium C++ ABI uses the type, scope depth, and scope
01354       // index of a parameter when mangling expressions that involve
01355       // function parameters, so we will use the parameter's type for
01356       // establishing function parameter identity. That way, our
01357       // definition of "equivalent" (per C++ [temp.over.link]) is at
01358       // least as strong as the definition of "equivalent" used for
01359       // name mangling.
01360       VisitType(Parm->getType());
01361       ID.AddInteger(Parm->getFunctionScopeDepth());
01362       ID.AddInteger(Parm->getFunctionScopeIndex());
01363       return;
01364     }
01365 
01366     if (const TemplateTypeParmDecl *TTP =
01367           dyn_cast<TemplateTypeParmDecl>(D)) {
01368       ID.AddInteger(TTP->getDepth());
01369       ID.AddInteger(TTP->getIndex());
01370       ID.AddBoolean(TTP->isParameterPack());
01371       return;
01372     }
01373 
01374     if (const TemplateTemplateParmDecl *TTP =
01375           dyn_cast<TemplateTemplateParmDecl>(D)) {
01376       ID.AddInteger(TTP->getDepth());
01377       ID.AddInteger(TTP->getIndex());
01378       ID.AddBoolean(TTP->isParameterPack());
01379       return;
01380     }
01381   }
01382 
01383   ID.AddPointer(D? D->getCanonicalDecl() : nullptr);
01384 }
01385 
01386 void StmtProfiler::VisitType(QualType T) {
01387   if (Canonical)
01388     T = Context.getCanonicalType(T);
01389 
01390   ID.AddPointer(T.getAsOpaquePtr());
01391 }
01392 
01393 void StmtProfiler::VisitName(DeclarationName Name) {
01394   ID.AddPointer(Name.getAsOpaquePtr());
01395 }
01396 
01397 void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
01398   if (Canonical)
01399     NNS = Context.getCanonicalNestedNameSpecifier(NNS);
01400   ID.AddPointer(NNS);
01401 }
01402 
01403 void StmtProfiler::VisitTemplateName(TemplateName Name) {
01404   if (Canonical)
01405     Name = Context.getCanonicalTemplateName(Name);
01406 
01407   Name.Profile(ID);
01408 }
01409 
01410 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
01411                                           unsigned NumArgs) {
01412   ID.AddInteger(NumArgs);
01413   for (unsigned I = 0; I != NumArgs; ++I)
01414     VisitTemplateArgument(Args[I].getArgument());
01415 }
01416 
01417 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
01418   // Mostly repetitive with TemplateArgument::Profile!
01419   ID.AddInteger(Arg.getKind());
01420   switch (Arg.getKind()) {
01421   case TemplateArgument::Null:
01422     break;
01423 
01424   case TemplateArgument::Type:
01425     VisitType(Arg.getAsType());
01426     break;
01427 
01428   case TemplateArgument::Template:
01429   case TemplateArgument::TemplateExpansion:
01430     VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
01431     break;
01432       
01433   case TemplateArgument::Declaration:
01434     VisitDecl(Arg.getAsDecl());
01435     break;
01436 
01437   case TemplateArgument::NullPtr:
01438     VisitType(Arg.getNullPtrType());
01439     break;
01440 
01441   case TemplateArgument::Integral:
01442     Arg.getAsIntegral().Profile(ID);
01443     VisitType(Arg.getIntegralType());
01444     break;
01445 
01446   case TemplateArgument::Expression:
01447     Visit(Arg.getAsExpr());
01448     break;
01449 
01450   case TemplateArgument::Pack:
01451     for (const auto &P : Arg.pack_elements())
01452       VisitTemplateArgument(P);
01453     break;
01454   }
01455 }
01456 
01457 void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
01458                    bool Canonical) const {
01459   StmtProfiler Profiler(ID, Context, Canonical);
01460   Profiler.Visit(this);
01461 }