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