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 (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
00083        D != DEnd; ++D)
00084     VisitDecl(*D);
00085 }
00086 
00087 void StmtProfiler::VisitNullStmt(const NullStmt *S) {
00088   VisitStmt(S);
00089 }
00090 
00091 void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
00092   VisitStmt(S);
00093 }
00094 
00095 void StmtProfiler::VisitSwitchCase(const SwitchCase *S) {
00096   VisitStmt(S);
00097 }
00098 
00099 void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
00100   VisitStmt(S);
00101 }
00102 
00103 void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
00104   VisitStmt(S);
00105 }
00106 
00107 void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
00108   VisitStmt(S);
00109   VisitDecl(S->getDecl());
00110 }
00111 
00112 void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
00113   VisitStmt(S);
00114   // TODO: maybe visit attributes?
00115 }
00116 
00117 void StmtProfiler::VisitIfStmt(const IfStmt *S) {
00118   VisitStmt(S);
00119   VisitDecl(S->getConditionVariable());
00120 }
00121 
00122 void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
00123   VisitStmt(S);
00124   VisitDecl(S->getConditionVariable());
00125 }
00126 
00127 void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
00128   VisitStmt(S);
00129   VisitDecl(S->getConditionVariable());
00130 }
00131 
00132 void StmtProfiler::VisitDoStmt(const DoStmt *S) {
00133   VisitStmt(S);
00134 }
00135 
00136 void StmtProfiler::VisitForStmt(const ForStmt *S) {
00137   VisitStmt(S);
00138 }
00139 
00140 void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
00141   VisitStmt(S);
00142   VisitDecl(S->getLabel());
00143 }
00144 
00145 void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
00146   VisitStmt(S);
00147 }
00148 
00149 void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
00150   VisitStmt(S);
00151 }
00152 
00153 void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
00154   VisitStmt(S);
00155 }
00156 
00157 void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
00158   VisitStmt(S);
00159 }
00160 
00161 void StmtProfiler::VisitAsmStmt(const AsmStmt *S) {
00162   VisitStmt(S);
00163   ID.AddBoolean(S->isVolatile());
00164   ID.AddBoolean(S->isSimple());
00165   VisitStringLiteral(S->getAsmString());
00166   ID.AddInteger(S->getNumOutputs());
00167   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
00168     ID.AddString(S->getOutputName(I));
00169     VisitStringLiteral(S->getOutputConstraintLiteral(I));
00170   }
00171   ID.AddInteger(S->getNumInputs());
00172   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
00173     ID.AddString(S->getInputName(I));
00174     VisitStringLiteral(S->getInputConstraintLiteral(I));
00175   }
00176   ID.AddInteger(S->getNumClobbers());
00177   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
00178     VisitStringLiteral(S->getClobber(I));
00179 }
00180 
00181 void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
00182   VisitStmt(S);
00183   VisitType(S->getCaughtType());
00184 }
00185 
00186 void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
00187   VisitStmt(S);
00188 }
00189 
00190 void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
00191   VisitStmt(S);
00192 }
00193 
00194 void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
00195   VisitStmt(S);
00196   ID.AddBoolean(S->isIfExists());
00197   VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
00198   VisitName(S->getNameInfo().getName());
00199 }
00200 
00201 void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
00202   VisitStmt(S);
00203 }
00204 
00205 void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
00206   VisitStmt(S);
00207 }
00208 
00209 void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
00210   VisitStmt(S);
00211 }
00212 
00213 void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
00214   VisitStmt(S);
00215 }
00216 
00217 void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
00218   VisitStmt(S);
00219   ID.AddBoolean(S->hasEllipsis());
00220   if (S->getCatchParamDecl())
00221     VisitType(S->getCatchParamDecl()->getType());
00222 }
00223 
00224 void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
00225   VisitStmt(S);
00226 }
00227 
00228 void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
00229   VisitStmt(S);
00230 }
00231 
00232 void
00233 StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
00234   VisitStmt(S);
00235 }
00236 
00237 void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
00238   VisitStmt(S);
00239 }
00240 
00241 void
00242 StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
00243   VisitStmt(S);
00244 }
00245 
00246 void StmtProfiler::VisitExpr(const Expr *S) {
00247   VisitStmt(S);
00248 }
00249 
00250 void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
00251   VisitExpr(S);
00252   if (!Canonical)
00253     VisitNestedNameSpecifier(S->getQualifier());
00254   VisitDecl(S->getDecl());
00255   if (!Canonical)
00256     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
00257 }
00258 
00259 void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
00260   VisitExpr(S);
00261   ID.AddInteger(S->getIdentType());
00262 }
00263 
00264 void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
00265   VisitExpr(S);
00266   S->getValue().Profile(ID);
00267 }
00268 
00269 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
00270   VisitExpr(S);
00271   ID.AddInteger(S->getKind());
00272   ID.AddInteger(S->getValue());
00273 }
00274 
00275 void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
00276   VisitExpr(S);
00277   S->getValue().Profile(ID);
00278   ID.AddBoolean(S->isExact());
00279 }
00280 
00281 void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
00282   VisitExpr(S);
00283 }
00284 
00285 void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
00286   VisitExpr(S);
00287   ID.AddString(S->getBytes());
00288   ID.AddInteger(S->getKind());
00289 }
00290 
00291 void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
00292   VisitExpr(S);
00293 }
00294 
00295 void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
00296   VisitExpr(S);
00297 }
00298 
00299 void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
00300   VisitExpr(S);
00301   ID.AddInteger(S->getOpcode());
00302 }
00303 
00304 void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
00305   VisitType(S->getTypeSourceInfo()->getType());
00306   unsigned n = S->getNumComponents();
00307   for (unsigned i = 0; i < n; ++i) {
00308     const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
00309     ID.AddInteger(ON.getKind());
00310     switch (ON.getKind()) {
00311     case OffsetOfExpr::OffsetOfNode::Array:
00312       // Expressions handled below.
00313       break;
00314 
00315     case OffsetOfExpr::OffsetOfNode::Field:
00316       VisitDecl(ON.getField());
00317       break;
00318 
00319     case OffsetOfExpr::OffsetOfNode::Identifier:
00320       ID.AddPointer(ON.getFieldName());
00321       break;
00322         
00323     case OffsetOfExpr::OffsetOfNode::Base:
00324       // These nodes are implicit, and therefore don't need profiling.
00325       break;
00326     }
00327   }
00328   
00329   VisitExpr(S);
00330 }
00331 
00332 void
00333 StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
00334   VisitExpr(S);
00335   ID.AddInteger(S->getKind());
00336   if (S->isArgumentType())
00337     VisitType(S->getArgumentType());
00338 }
00339 
00340 void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
00341   VisitExpr(S);
00342 }
00343 
00344 void StmtProfiler::VisitCallExpr(const CallExpr *S) {
00345   VisitExpr(S);
00346 }
00347 
00348 void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
00349   VisitExpr(S);
00350   VisitDecl(S->getMemberDecl());
00351   if (!Canonical)
00352     VisitNestedNameSpecifier(S->getQualifier());
00353   ID.AddBoolean(S->isArrow());
00354 }
00355 
00356 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
00357   VisitExpr(S);
00358   ID.AddBoolean(S->isFileScope());
00359 }
00360 
00361 void StmtProfiler::VisitCastExpr(const CastExpr *S) {
00362   VisitExpr(S);
00363 }
00364 
00365 void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
00366   VisitCastExpr(S);
00367   ID.AddInteger(S->getValueKind());
00368 }
00369 
00370 void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
00371   VisitCastExpr(S);
00372   VisitType(S->getTypeAsWritten());
00373 }
00374 
00375 void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
00376   VisitExplicitCastExpr(S);
00377 }
00378 
00379 void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
00380   VisitExpr(S);
00381   ID.AddInteger(S->getOpcode());
00382 }
00383 
00384 void
00385 StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
00386   VisitBinaryOperator(S);
00387 }
00388 
00389 void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
00390   VisitExpr(S);
00391 }
00392 
00393 void StmtProfiler::VisitBinaryConditionalOperator(
00394     const BinaryConditionalOperator *S) {
00395   VisitExpr(S);
00396 }
00397 
00398 void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
00399   VisitExpr(S);
00400   VisitDecl(S->getLabel());
00401 }
00402 
00403 void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
00404   VisitExpr(S);
00405 }
00406 
00407 void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
00408   VisitExpr(S);
00409 }
00410 
00411 void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
00412   VisitExpr(S);
00413 }
00414 
00415 void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
00416   VisitExpr(S);
00417 }
00418 
00419 void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
00420   VisitExpr(S);
00421 }
00422 
00423 void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
00424   if (S->getSyntacticForm()) {
00425     VisitInitListExpr(S->getSyntacticForm());
00426     return;
00427   }
00428 
00429   VisitExpr(S);
00430 }
00431 
00432 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
00433   VisitExpr(S);
00434   ID.AddBoolean(S->usesGNUSyntax());
00435   for (DesignatedInitExpr::const_designators_iterator D =
00436          S->designators_begin(), DEnd = S->designators_end();
00437        D != DEnd; ++D) {
00438     if (D->isFieldDesignator()) {
00439       ID.AddInteger(0);
00440       VisitName(D->getFieldName());
00441       continue;
00442     }
00443 
00444     if (D->isArrayDesignator()) {
00445       ID.AddInteger(1);
00446     } else {
00447       assert(D->isArrayRangeDesignator());
00448       ID.AddInteger(2);
00449     }
00450     ID.AddInteger(D->getFirstExprIndex());
00451   }
00452 }
00453 
00454 void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
00455   VisitExpr(S);
00456 }
00457 
00458 void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
00459   VisitExpr(S);
00460   VisitName(&S->getAccessor());
00461 }
00462 
00463 void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
00464   VisitExpr(S);
00465   VisitDecl(S->getBlockDecl());
00466 }
00467 
00468 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
00469   VisitExpr(S);
00470   for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
00471     QualType T = S->getAssocType(i);
00472     if (T.isNull())
00473       ID.AddPointer(0);
00474     else
00475       VisitType(T);
00476     VisitExpr(S->getAssocExpr(i));
00477   }
00478 }
00479 
00480 void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
00481   VisitExpr(S);
00482   for (PseudoObjectExpr::const_semantics_iterator
00483          i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
00484     // Normally, we would not profile the source expressions of OVEs.
00485     if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
00486       Visit(OVE->getSourceExpr());
00487 }
00488 
00489 void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
00490   VisitExpr(S);
00491   ID.AddInteger(S->getOp());
00492 }
00493 
00494 static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
00495                                           UnaryOperatorKind &UnaryOp,
00496                                           BinaryOperatorKind &BinaryOp) {
00497   switch (S->getOperator()) {
00498   case OO_None:
00499   case OO_New:
00500   case OO_Delete:
00501   case OO_Array_New:
00502   case OO_Array_Delete:
00503   case OO_Arrow:
00504   case OO_Call:
00505   case OO_Conditional:
00506   case NUM_OVERLOADED_OPERATORS:
00507     llvm_unreachable("Invalid operator call kind");
00508       
00509   case OO_Plus:
00510     if (S->getNumArgs() == 1) {
00511       UnaryOp = UO_Plus;
00512       return Stmt::UnaryOperatorClass;
00513     }
00514     
00515     BinaryOp = BO_Add;
00516     return Stmt::BinaryOperatorClass;
00517       
00518   case OO_Minus:
00519     if (S->getNumArgs() == 1) {
00520       UnaryOp = UO_Minus;
00521       return Stmt::UnaryOperatorClass;
00522     }
00523     
00524     BinaryOp = BO_Sub;
00525     return Stmt::BinaryOperatorClass;
00526 
00527   case OO_Star:
00528     if (S->getNumArgs() == 1) {
00529       UnaryOp = UO_Minus;
00530       return Stmt::UnaryOperatorClass;
00531     }
00532     
00533     BinaryOp = BO_Sub;
00534     return Stmt::BinaryOperatorClass;
00535 
00536   case OO_Slash:
00537     BinaryOp = BO_Div;
00538     return Stmt::BinaryOperatorClass;
00539       
00540   case OO_Percent:
00541     BinaryOp = BO_Rem;
00542     return Stmt::BinaryOperatorClass;
00543 
00544   case OO_Caret:
00545     BinaryOp = BO_Xor;
00546     return Stmt::BinaryOperatorClass;
00547 
00548   case OO_Amp:
00549     if (S->getNumArgs() == 1) {
00550       UnaryOp = UO_AddrOf;
00551       return Stmt::UnaryOperatorClass;
00552     }
00553     
00554     BinaryOp = BO_And;
00555     return Stmt::BinaryOperatorClass;
00556       
00557   case OO_Pipe:
00558     BinaryOp = BO_Or;
00559     return Stmt::BinaryOperatorClass;
00560 
00561   case OO_Tilde:
00562     UnaryOp = UO_Not;
00563     return Stmt::UnaryOperatorClass;
00564 
00565   case OO_Exclaim:
00566     UnaryOp = UO_LNot;
00567     return Stmt::UnaryOperatorClass;
00568 
00569   case OO_Equal:
00570     BinaryOp = BO_Assign;
00571     return Stmt::BinaryOperatorClass;
00572 
00573   case OO_Less:
00574     BinaryOp = BO_LT;
00575     return Stmt::BinaryOperatorClass;
00576 
00577   case OO_Greater:
00578     BinaryOp = BO_GT;
00579     return Stmt::BinaryOperatorClass;
00580       
00581   case OO_PlusEqual:
00582     BinaryOp = BO_AddAssign;
00583     return Stmt::CompoundAssignOperatorClass;
00584 
00585   case OO_MinusEqual:
00586     BinaryOp = BO_SubAssign;
00587     return Stmt::CompoundAssignOperatorClass;
00588 
00589   case OO_StarEqual:
00590     BinaryOp = BO_MulAssign;
00591     return Stmt::CompoundAssignOperatorClass;
00592 
00593   case OO_SlashEqual:
00594     BinaryOp = BO_DivAssign;
00595     return Stmt::CompoundAssignOperatorClass;
00596 
00597   case OO_PercentEqual:
00598     BinaryOp = BO_RemAssign;
00599     return Stmt::CompoundAssignOperatorClass;
00600 
00601   case OO_CaretEqual:
00602     BinaryOp = BO_XorAssign;
00603     return Stmt::CompoundAssignOperatorClass;
00604     
00605   case OO_AmpEqual:
00606     BinaryOp = BO_AndAssign;
00607     return Stmt::CompoundAssignOperatorClass;
00608     
00609   case OO_PipeEqual:
00610     BinaryOp = BO_OrAssign;
00611     return Stmt::CompoundAssignOperatorClass;
00612       
00613   case OO_LessLess:
00614     BinaryOp = BO_Shl;
00615     return Stmt::BinaryOperatorClass;
00616     
00617   case OO_GreaterGreater:
00618     BinaryOp = BO_Shr;
00619     return Stmt::BinaryOperatorClass;
00620 
00621   case OO_LessLessEqual:
00622     BinaryOp = BO_ShlAssign;
00623     return Stmt::CompoundAssignOperatorClass;
00624     
00625   case OO_GreaterGreaterEqual:
00626     BinaryOp = BO_ShrAssign;
00627     return Stmt::CompoundAssignOperatorClass;
00628 
00629   case OO_EqualEqual:
00630     BinaryOp = BO_EQ;
00631     return Stmt::BinaryOperatorClass;
00632     
00633   case OO_ExclaimEqual:
00634     BinaryOp = BO_NE;
00635     return Stmt::BinaryOperatorClass;
00636       
00637   case OO_LessEqual:
00638     BinaryOp = BO_LE;
00639     return Stmt::BinaryOperatorClass;
00640     
00641   case OO_GreaterEqual:
00642     BinaryOp = BO_GE;
00643     return Stmt::BinaryOperatorClass;
00644       
00645   case OO_AmpAmp:
00646     BinaryOp = BO_LAnd;
00647     return Stmt::BinaryOperatorClass;
00648     
00649   case OO_PipePipe:
00650     BinaryOp = BO_LOr;
00651     return Stmt::BinaryOperatorClass;
00652 
00653   case OO_PlusPlus:
00654     UnaryOp = S->getNumArgs() == 1? UO_PreInc 
00655                                   : UO_PostInc;
00656     return Stmt::UnaryOperatorClass;
00657 
00658   case OO_MinusMinus:
00659     UnaryOp = S->getNumArgs() == 1? UO_PreDec
00660                                   : UO_PostDec;
00661     return Stmt::UnaryOperatorClass;
00662 
00663   case OO_Comma:
00664     BinaryOp = BO_Comma;
00665     return Stmt::BinaryOperatorClass;
00666 
00667 
00668   case OO_ArrowStar:
00669     BinaryOp = BO_PtrMemI;
00670     return Stmt::BinaryOperatorClass;
00671       
00672   case OO_Subscript:
00673     return Stmt::ArraySubscriptExprClass;
00674   }
00675   
00676   llvm_unreachable("Invalid overloaded operator expression");
00677 }
00678                                
00679 
00680 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
00681   if (S->isTypeDependent()) {
00682     // Type-dependent operator calls are profiled like their underlying
00683     // syntactic operator.
00684     UnaryOperatorKind UnaryOp = UO_Extension;
00685     BinaryOperatorKind BinaryOp = BO_Comma;
00686     Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
00687     
00688     ID.AddInteger(SC);
00689     for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
00690       Visit(S->getArg(I));
00691     if (SC == Stmt::UnaryOperatorClass)
00692       ID.AddInteger(UnaryOp);
00693     else if (SC == Stmt::BinaryOperatorClass || 
00694              SC == Stmt::CompoundAssignOperatorClass)
00695       ID.AddInteger(BinaryOp);
00696     else
00697       assert(SC == Stmt::ArraySubscriptExprClass);
00698                     
00699     return;
00700   }
00701   
00702   VisitCallExpr(S);
00703   ID.AddInteger(S->getOperator());
00704 }
00705 
00706 void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
00707   VisitCallExpr(S);
00708 }
00709 
00710 void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
00711   VisitCallExpr(S);
00712 }
00713 
00714 void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
00715   VisitExpr(S);
00716 }
00717 
00718 void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
00719   VisitExplicitCastExpr(S);
00720 }
00721 
00722 void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
00723   VisitCXXNamedCastExpr(S);
00724 }
00725 
00726 void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
00727   VisitCXXNamedCastExpr(S);
00728 }
00729 
00730 void
00731 StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
00732   VisitCXXNamedCastExpr(S);
00733 }
00734 
00735 void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
00736   VisitCXXNamedCastExpr(S);
00737 }
00738 
00739 void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
00740   VisitCallExpr(S);
00741 }
00742 
00743 void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
00744   VisitExpr(S);
00745   ID.AddBoolean(S->getValue());
00746 }
00747 
00748 void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
00749   VisitExpr(S);
00750 }
00751 
00752 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
00753   VisitExpr(S);
00754   if (S->isTypeOperand())
00755     VisitType(S->getTypeOperand());
00756 }
00757 
00758 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
00759   VisitExpr(S);
00760   if (S->isTypeOperand())
00761     VisitType(S->getTypeOperand());
00762 }
00763 
00764 void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
00765   VisitExpr(S);
00766   ID.AddBoolean(S->isImplicit());
00767 }
00768 
00769 void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
00770   VisitExpr(S);
00771 }
00772 
00773 void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
00774   VisitExpr(S);
00775   VisitDecl(S->getParam());
00776 }
00777 
00778 void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
00779   VisitExpr(S);
00780   VisitDecl(
00781          const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
00782 }
00783 
00784 void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
00785   VisitExpr(S);
00786   VisitDecl(S->getConstructor());
00787   ID.AddBoolean(S->isElidable());
00788 }
00789 
00790 void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
00791   VisitExplicitCastExpr(S);
00792 }
00793 
00794 void
00795 StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
00796   VisitCXXConstructExpr(S);
00797 }
00798 
00799 void
00800 StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
00801   VisitExpr(S);
00802   for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
00803                                  CEnd = S->explicit_capture_end();
00804        C != CEnd; ++C) {
00805     ID.AddInteger(C->getCaptureKind());
00806     if (C->capturesVariable()) {
00807       VisitDecl(C->getCapturedVar());
00808       ID.AddBoolean(C->isPackExpansion());
00809     }
00810   }
00811   // Note: If we actually needed to be able to match lambda
00812   // expressions, we would have to consider parameters and return type
00813   // here, among other things.
00814   VisitStmt(S->getBody());
00815 }
00816 
00817 void
00818 StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
00819   VisitExpr(S);
00820 }
00821 
00822 void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
00823   VisitExpr(S);
00824   ID.AddBoolean(S->isGlobalDelete());
00825   ID.AddBoolean(S->isArrayForm());
00826   VisitDecl(S->getOperatorDelete());
00827 }
00828 
00829 
00830 void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
00831   VisitExpr(S);
00832   VisitType(S->getAllocatedType());
00833   VisitDecl(S->getOperatorNew());
00834   VisitDecl(S->getOperatorDelete());
00835   ID.AddBoolean(S->isArray());
00836   ID.AddInteger(S->getNumPlacementArgs());
00837   ID.AddBoolean(S->isGlobalNew());
00838   ID.AddBoolean(S->isParenTypeId());
00839   ID.AddInteger(S->getInitializationStyle());
00840 }
00841 
00842 void
00843 StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
00844   VisitExpr(S);
00845   ID.AddBoolean(S->isArrow());
00846   VisitNestedNameSpecifier(S->getQualifier());
00847   VisitType(S->getDestroyedType());
00848 }
00849 
00850 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
00851   VisitExpr(S);
00852   VisitNestedNameSpecifier(S->getQualifier());
00853   VisitName(S->getName());
00854   ID.AddBoolean(S->hasExplicitTemplateArgs());
00855   if (S->hasExplicitTemplateArgs())
00856     VisitTemplateArguments(S->getExplicitTemplateArgs().getTemplateArgs(),
00857                            S->getExplicitTemplateArgs().NumTemplateArgs);
00858 }
00859 
00860 void
00861 StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
00862   VisitOverloadExpr(S);
00863 }
00864 
00865 void StmtProfiler::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *S) {
00866   VisitExpr(S);
00867   ID.AddInteger(S->getTrait());
00868   VisitType(S->getQueriedType());
00869 }
00870 
00871 void StmtProfiler::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *S) {
00872   VisitExpr(S);
00873   ID.AddInteger(S->getTrait());
00874   VisitType(S->getLhsType());
00875   VisitType(S->getRhsType());
00876 }
00877 
00878 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
00879   VisitExpr(S);
00880   ID.AddInteger(S->getTrait());
00881   ID.AddInteger(S->getNumArgs());
00882   for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
00883     VisitType(S->getArg(I)->getType());
00884 }
00885 
00886 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
00887   VisitExpr(S);
00888   ID.AddInteger(S->getTrait());
00889   VisitType(S->getQueriedType());
00890 }
00891 
00892 void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
00893   VisitExpr(S);
00894   ID.AddInteger(S->getTrait());
00895   VisitExpr(S->getQueriedExpression());
00896 }
00897 
00898 void StmtProfiler::VisitDependentScopeDeclRefExpr(
00899     const DependentScopeDeclRefExpr *S) {
00900   VisitExpr(S);
00901   VisitName(S->getDeclName());
00902   VisitNestedNameSpecifier(S->getQualifier());
00903   ID.AddBoolean(S->hasExplicitTemplateArgs());
00904   if (S->hasExplicitTemplateArgs())
00905     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
00906 }
00907 
00908 void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
00909   VisitExpr(S);
00910 }
00911 
00912 void StmtProfiler::VisitCXXUnresolvedConstructExpr(
00913     const CXXUnresolvedConstructExpr *S) {
00914   VisitExpr(S);
00915   VisitType(S->getTypeAsWritten());
00916 }
00917 
00918 void StmtProfiler::VisitCXXDependentScopeMemberExpr(
00919     const CXXDependentScopeMemberExpr *S) {
00920   ID.AddBoolean(S->isImplicitAccess());
00921   if (!S->isImplicitAccess()) {
00922     VisitExpr(S);
00923     ID.AddBoolean(S->isArrow());
00924   }
00925   VisitNestedNameSpecifier(S->getQualifier());
00926   VisitName(S->getMember());
00927   ID.AddBoolean(S->hasExplicitTemplateArgs());
00928   if (S->hasExplicitTemplateArgs())
00929     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
00930 }
00931 
00932 void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
00933   ID.AddBoolean(S->isImplicitAccess());
00934   if (!S->isImplicitAccess()) {
00935     VisitExpr(S);
00936     ID.AddBoolean(S->isArrow());
00937   }
00938   VisitNestedNameSpecifier(S->getQualifier());
00939   VisitName(S->getMemberName());
00940   ID.AddBoolean(S->hasExplicitTemplateArgs());
00941   if (S->hasExplicitTemplateArgs())
00942     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
00943 }
00944 
00945 void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
00946   VisitExpr(S);
00947 }
00948 
00949 void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
00950   VisitExpr(S);
00951 }
00952 
00953 void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
00954   VisitExpr(S);
00955   VisitDecl(S->getPack());
00956 }
00957 
00958 void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
00959     const SubstNonTypeTemplateParmPackExpr *S) {
00960   VisitExpr(S);
00961   VisitDecl(S->getParameterPack());
00962   VisitTemplateArgument(S->getArgumentPack());
00963 }
00964 
00965 void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
00966     const SubstNonTypeTemplateParmExpr *E) {
00967   // Profile exactly as the replacement expression.
00968   Visit(E->getReplacement());
00969 }
00970 
00971 void StmtProfiler::VisitMaterializeTemporaryExpr(
00972                                            const MaterializeTemporaryExpr *S) {
00973   VisitExpr(S);
00974 }
00975 
00976 void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
00977   VisitExpr(E);  
00978 }
00979 
00980 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
00981   VisitExpr(S);
00982 }
00983 
00984 void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
00985   VisitExpr(E);
00986 }
00987 
00988 void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
00989   VisitExpr(E);
00990 }
00991 
00992 void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
00993   VisitExpr(E);
00994 }
00995 
00996 void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
00997   VisitExpr(S);
00998   VisitType(S->getEncodedType());
00999 }
01000 
01001 void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
01002   VisitExpr(S);
01003   VisitName(S->getSelector());
01004 }
01005 
01006 void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
01007   VisitExpr(S);
01008   VisitDecl(S->getProtocol());
01009 }
01010 
01011 void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
01012   VisitExpr(S);
01013   VisitDecl(S->getDecl());
01014   ID.AddBoolean(S->isArrow());
01015   ID.AddBoolean(S->isFreeIvar());
01016 }
01017 
01018 void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
01019   VisitExpr(S);
01020   if (S->isImplicitProperty()) {
01021     VisitDecl(S->getImplicitPropertyGetter());
01022     VisitDecl(S->getImplicitPropertySetter());
01023   } else {
01024     VisitDecl(S->getExplicitProperty());
01025   }
01026   if (S->isSuperReceiver()) {
01027     ID.AddBoolean(S->isSuperReceiver());
01028     VisitType(S->getSuperReceiverType());
01029   }
01030 }
01031 
01032 void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
01033   VisitExpr(S);
01034   VisitDecl(S->getAtIndexMethodDecl());
01035   VisitDecl(S->setAtIndexMethodDecl());
01036 }
01037 
01038 void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
01039   VisitExpr(S);
01040   VisitName(S->getSelector());
01041   VisitDecl(S->getMethodDecl());
01042 }
01043 
01044 void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
01045   VisitExpr(S);
01046   ID.AddBoolean(S->isArrow());
01047 }
01048 
01049 void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
01050   VisitExpr(S);
01051   ID.AddBoolean(S->getValue());
01052 }
01053 
01054 void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
01055     const ObjCIndirectCopyRestoreExpr *S) {
01056   VisitExpr(S);
01057   ID.AddBoolean(S->shouldCopy());
01058 }
01059 
01060 void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
01061   VisitExplicitCastExpr(S);
01062   ID.AddBoolean(S->getBridgeKind());
01063 }
01064 
01065 void StmtProfiler::VisitDecl(const Decl *D) {
01066   ID.AddInteger(D? D->getKind() : 0);
01067 
01068   if (Canonical && D) {
01069     if (const NonTypeTemplateParmDecl *NTTP =
01070           dyn_cast<NonTypeTemplateParmDecl>(D)) {
01071       ID.AddInteger(NTTP->getDepth());
01072       ID.AddInteger(NTTP->getIndex());
01073       ID.AddBoolean(NTTP->isParameterPack());
01074       VisitType(NTTP->getType());
01075       return;
01076     }
01077 
01078     if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
01079       // The Itanium C++ ABI uses the type, scope depth, and scope
01080       // index of a parameter when mangling expressions that involve
01081       // function parameters, so we will use the parameter's type for
01082       // establishing function parameter identity. That way, our
01083       // definition of "equivalent" (per C++ [temp.over.link]) is at
01084       // least as strong as the definition of "equivalent" used for
01085       // name mangling.
01086       VisitType(Parm->getType());
01087       ID.AddInteger(Parm->getFunctionScopeDepth());
01088       ID.AddInteger(Parm->getFunctionScopeIndex());
01089       return;
01090     }
01091 
01092     if (const TemplateTypeParmDecl *TTP =
01093           dyn_cast<TemplateTypeParmDecl>(D)) {
01094       ID.AddInteger(TTP->getDepth());
01095       ID.AddInteger(TTP->getIndex());
01096       ID.AddBoolean(TTP->isParameterPack());
01097       return;
01098     }
01099 
01100     if (const TemplateTemplateParmDecl *TTP =
01101           dyn_cast<TemplateTemplateParmDecl>(D)) {
01102       ID.AddInteger(TTP->getDepth());
01103       ID.AddInteger(TTP->getIndex());
01104       ID.AddBoolean(TTP->isParameterPack());
01105       return;
01106     }
01107   }
01108 
01109   ID.AddPointer(D? D->getCanonicalDecl() : 0);
01110 }
01111 
01112 void StmtProfiler::VisitType(QualType T) {
01113   if (Canonical)
01114     T = Context.getCanonicalType(T);
01115 
01116   ID.AddPointer(T.getAsOpaquePtr());
01117 }
01118 
01119 void StmtProfiler::VisitName(DeclarationName Name) {
01120   ID.AddPointer(Name.getAsOpaquePtr());
01121 }
01122 
01123 void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
01124   if (Canonical)
01125     NNS = Context.getCanonicalNestedNameSpecifier(NNS);
01126   ID.AddPointer(NNS);
01127 }
01128 
01129 void StmtProfiler::VisitTemplateName(TemplateName Name) {
01130   if (Canonical)
01131     Name = Context.getCanonicalTemplateName(Name);
01132 
01133   Name.Profile(ID);
01134 }
01135 
01136 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
01137                                           unsigned NumArgs) {
01138   ID.AddInteger(NumArgs);
01139   for (unsigned I = 0; I != NumArgs; ++I)
01140     VisitTemplateArgument(Args[I].getArgument());
01141 }
01142 
01143 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
01144   // Mostly repetitive with TemplateArgument::Profile!
01145   ID.AddInteger(Arg.getKind());
01146   switch (Arg.getKind()) {
01147   case TemplateArgument::Null:
01148     break;
01149 
01150   case TemplateArgument::Type:
01151     VisitType(Arg.getAsType());
01152     break;
01153 
01154   case TemplateArgument::Template:
01155   case TemplateArgument::TemplateExpansion:
01156     VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
01157     break;
01158       
01159   case TemplateArgument::Declaration:
01160     VisitDecl(Arg.getAsDecl());
01161     break;
01162 
01163   case TemplateArgument::Integral:
01164     Arg.getAsIntegral()->Profile(ID);
01165     VisitType(Arg.getIntegralType());
01166     break;
01167 
01168   case TemplateArgument::Expression:
01169     Visit(Arg.getAsExpr());
01170     break;
01171 
01172   case TemplateArgument::Pack:
01173     const TemplateArgument *Pack = Arg.pack_begin();
01174     for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
01175       VisitTemplateArgument(Pack[i]);
01176     break;
01177   }
01178 }
01179 
01180 void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
01181                    bool Canonical) const {
01182   StmtProfiler Profiler(ID, Context, Canonical);
01183   Profiler.Visit(this);
01184 }