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