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/ExprOpenMP.h" 22 #include "clang/AST/StmtVisitor.h" 23 #include "llvm/ADT/FoldingSet.h" 24 using namespace clang; 25 26 namespace { 27 class StmtProfiler : public ConstStmtVisitor<StmtProfiler> { 28 llvm::FoldingSetNodeID &ID; 29 const ASTContext &Context; 30 bool Canonical; 31 32 public: 33 StmtProfiler(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 34 bool Canonical) 35 : ID(ID), Context(Context), Canonical(Canonical) { } 36 37 void VisitStmt(const Stmt *S); 38 39 #define STMT(Node, Base) void Visit##Node(const Node *S); 40 #include "clang/AST/StmtNodes.inc" 41 42 /// \brief Visit a declaration that is referenced within an expression 43 /// or statement. 44 void VisitDecl(const Decl *D); 45 46 /// \brief Visit a type that is referenced within an expression or 47 /// statement. 48 void VisitType(QualType T); 49 50 /// \brief Visit a name that occurs within an expression or statement. 51 void VisitName(DeclarationName Name); 52 53 /// \brief Visit a nested-name-specifier that occurs within an expression 54 /// or statement. 55 void VisitNestedNameSpecifier(NestedNameSpecifier *NNS); 56 57 /// \brief Visit a template name that occurs within an expression or 58 /// statement. 59 void VisitTemplateName(TemplateName Name); 60 61 /// \brief Visit template arguments that occur within an expression or 62 /// statement. 63 void VisitTemplateArguments(const TemplateArgumentLoc *Args, 64 unsigned NumArgs); 65 66 /// \brief Visit a single template argument. 67 void VisitTemplateArgument(const TemplateArgument &Arg); 68 }; 69 } 70 71 void StmtProfiler::VisitStmt(const Stmt *S) { 72 ID.AddInteger(S->getStmtClass()); 73 for (const Stmt *SubStmt : S->children()) { 74 if (SubStmt) 75 Visit(SubStmt); 76 else 77 ID.AddInteger(0); 78 } 79 } 80 81 void StmtProfiler::VisitDeclStmt(const DeclStmt *S) { 82 VisitStmt(S); 83 for (const auto *D : S->decls()) 84 VisitDecl(D); 85 } 86 87 void StmtProfiler::VisitNullStmt(const NullStmt *S) { 88 VisitStmt(S); 89 } 90 91 void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) { 92 VisitStmt(S); 93 } 94 95 void StmtProfiler::VisitSwitchCase(const SwitchCase *S) { 96 VisitStmt(S); 97 } 98 99 void StmtProfiler::VisitCaseStmt(const CaseStmt *S) { 100 VisitStmt(S); 101 } 102 103 void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) { 104 VisitStmt(S); 105 } 106 107 void StmtProfiler::VisitLabelStmt(const LabelStmt *S) { 108 VisitStmt(S); 109 VisitDecl(S->getDecl()); 110 } 111 112 void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) { 113 VisitStmt(S); 114 // TODO: maybe visit attributes? 115 } 116 117 void StmtProfiler::VisitIfStmt(const IfStmt *S) { 118 VisitStmt(S); 119 VisitDecl(S->getConditionVariable()); 120 } 121 122 void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) { 123 VisitStmt(S); 124 VisitDecl(S->getConditionVariable()); 125 } 126 127 void StmtProfiler::VisitWhileStmt(const WhileStmt *S) { 128 VisitStmt(S); 129 VisitDecl(S->getConditionVariable()); 130 } 131 132 void StmtProfiler::VisitDoStmt(const DoStmt *S) { 133 VisitStmt(S); 134 } 135 136 void StmtProfiler::VisitForStmt(const ForStmt *S) { 137 VisitStmt(S); 138 } 139 140 void StmtProfiler::VisitGotoStmt(const GotoStmt *S) { 141 VisitStmt(S); 142 VisitDecl(S->getLabel()); 143 } 144 145 void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) { 146 VisitStmt(S); 147 } 148 149 void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) { 150 VisitStmt(S); 151 } 152 153 void StmtProfiler::VisitBreakStmt(const BreakStmt *S) { 154 VisitStmt(S); 155 } 156 157 void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) { 158 VisitStmt(S); 159 } 160 161 void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) { 162 VisitStmt(S); 163 ID.AddBoolean(S->isVolatile()); 164 ID.AddBoolean(S->isSimple()); 165 VisitStringLiteral(S->getAsmString()); 166 ID.AddInteger(S->getNumOutputs()); 167 for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) { 168 ID.AddString(S->getOutputName(I)); 169 VisitStringLiteral(S->getOutputConstraintLiteral(I)); 170 } 171 ID.AddInteger(S->getNumInputs()); 172 for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) { 173 ID.AddString(S->getInputName(I)); 174 VisitStringLiteral(S->getInputConstraintLiteral(I)); 175 } 176 ID.AddInteger(S->getNumClobbers()); 177 for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) 178 VisitStringLiteral(S->getClobberStringLiteral(I)); 179 } 180 181 void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) { 182 // FIXME: Implement MS style inline asm statement profiler. 183 VisitStmt(S); 184 } 185 186 void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) { 187 VisitStmt(S); 188 VisitType(S->getCaughtType()); 189 } 190 191 void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) { 192 VisitStmt(S); 193 } 194 195 void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 196 VisitStmt(S); 197 } 198 199 void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) { 200 VisitStmt(S); 201 ID.AddBoolean(S->isIfExists()); 202 VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier()); 203 VisitName(S->getNameInfo().getName()); 204 } 205 206 void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) { 207 VisitStmt(S); 208 } 209 210 void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) { 211 VisitStmt(S); 212 } 213 214 void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) { 215 VisitStmt(S); 216 } 217 218 void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) { 219 VisitStmt(S); 220 } 221 222 void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) { 223 VisitStmt(S); 224 } 225 226 void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 227 VisitStmt(S); 228 } 229 230 void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) { 231 VisitStmt(S); 232 ID.AddBoolean(S->hasEllipsis()); 233 if (S->getCatchParamDecl()) 234 VisitType(S->getCatchParamDecl()->getType()); 235 } 236 237 void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) { 238 VisitStmt(S); 239 } 240 241 void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) { 242 VisitStmt(S); 243 } 244 245 void 246 StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) { 247 VisitStmt(S); 248 } 249 250 void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) { 251 VisitStmt(S); 252 } 253 254 void 255 StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) { 256 VisitStmt(S); 257 } 258 259 namespace { 260 class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> { 261 StmtProfiler *Profiler; 262 /// \brief Process clauses with list of variables. 263 template <typename T> 264 void VisitOMPClauseList(T *Node); 265 266 public: 267 OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { } 268 #define OPENMP_CLAUSE(Name, Class) \ 269 void Visit##Class(const Class *C); 270 #include "clang/Basic/OpenMPKinds.def" 271 void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); 272 void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); 273 }; 274 275 void OMPClauseProfiler::VistOMPClauseWithPreInit( 276 const OMPClauseWithPreInit *C) { 277 if (auto *S = C->getPreInitStmt()) 278 Profiler->VisitStmt(S); 279 } 280 281 void OMPClauseProfiler::VistOMPClauseWithPostUpdate( 282 const OMPClauseWithPostUpdate *C) { 283 VistOMPClauseWithPreInit(C); 284 if (auto *E = C->getPostUpdateExpr()) 285 Profiler->VisitStmt(E); 286 } 287 288 void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) { 289 if (C->getCondition()) 290 Profiler->VisitStmt(C->getCondition()); 291 } 292 293 void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) { 294 if (C->getCondition()) 295 Profiler->VisitStmt(C->getCondition()); 296 } 297 298 void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) { 299 if (C->getNumThreads()) 300 Profiler->VisitStmt(C->getNumThreads()); 301 } 302 303 void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) { 304 if (C->getSafelen()) 305 Profiler->VisitStmt(C->getSafelen()); 306 } 307 308 void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) { 309 if (C->getSimdlen()) 310 Profiler->VisitStmt(C->getSimdlen()); 311 } 312 313 void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) { 314 if (C->getNumForLoops()) 315 Profiler->VisitStmt(C->getNumForLoops()); 316 } 317 318 void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { } 319 320 void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { } 321 322 void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { 323 VistOMPClauseWithPreInit(C); 324 if (auto *S = C->getChunkSize()) 325 Profiler->VisitStmt(S); 326 } 327 328 void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) { 329 if (auto *Num = C->getNumForLoops()) 330 Profiler->VisitStmt(Num); 331 } 332 333 void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {} 334 335 void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {} 336 337 void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {} 338 339 void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {} 340 341 void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {} 342 343 void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {} 344 345 void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {} 346 347 void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {} 348 349 void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {} 350 351 void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {} 352 353 void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {} 354 355 template<typename T> 356 void OMPClauseProfiler::VisitOMPClauseList(T *Node) { 357 for (auto *E : Node->varlists()) { 358 Profiler->VisitStmt(E); 359 } 360 } 361 362 void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) { 363 VisitOMPClauseList(C); 364 for (auto *E : C->private_copies()) { 365 Profiler->VisitStmt(E); 366 } 367 } 368 void 369 OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) { 370 VisitOMPClauseList(C); 371 VistOMPClauseWithPreInit(C); 372 for (auto *E : C->private_copies()) { 373 Profiler->VisitStmt(E); 374 } 375 for (auto *E : C->inits()) { 376 Profiler->VisitStmt(E); 377 } 378 } 379 void 380 OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) { 381 VisitOMPClauseList(C); 382 VistOMPClauseWithPostUpdate(C); 383 for (auto *E : C->source_exprs()) { 384 Profiler->VisitStmt(E); 385 } 386 for (auto *E : C->destination_exprs()) { 387 Profiler->VisitStmt(E); 388 } 389 for (auto *E : C->assignment_ops()) { 390 Profiler->VisitStmt(E); 391 } 392 } 393 void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) { 394 VisitOMPClauseList(C); 395 } 396 void OMPClauseProfiler::VisitOMPReductionClause( 397 const OMPReductionClause *C) { 398 Profiler->VisitNestedNameSpecifier( 399 C->getQualifierLoc().getNestedNameSpecifier()); 400 Profiler->VisitName(C->getNameInfo().getName()); 401 VisitOMPClauseList(C); 402 VistOMPClauseWithPostUpdate(C); 403 for (auto *E : C->privates()) { 404 Profiler->VisitStmt(E); 405 } 406 for (auto *E : C->lhs_exprs()) { 407 Profiler->VisitStmt(E); 408 } 409 for (auto *E : C->rhs_exprs()) { 410 Profiler->VisitStmt(E); 411 } 412 for (auto *E : C->reduction_ops()) { 413 Profiler->VisitStmt(E); 414 } 415 } 416 void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) { 417 VisitOMPClauseList(C); 418 VistOMPClauseWithPostUpdate(C); 419 for (auto *E : C->privates()) { 420 Profiler->VisitStmt(E); 421 } 422 for (auto *E : C->inits()) { 423 Profiler->VisitStmt(E); 424 } 425 for (auto *E : C->updates()) { 426 Profiler->VisitStmt(E); 427 } 428 for (auto *E : C->finals()) { 429 Profiler->VisitStmt(E); 430 } 431 Profiler->VisitStmt(C->getStep()); 432 Profiler->VisitStmt(C->getCalcStep()); 433 } 434 void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) { 435 VisitOMPClauseList(C); 436 Profiler->VisitStmt(C->getAlignment()); 437 } 438 void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) { 439 VisitOMPClauseList(C); 440 for (auto *E : C->source_exprs()) { 441 Profiler->VisitStmt(E); 442 } 443 for (auto *E : C->destination_exprs()) { 444 Profiler->VisitStmt(E); 445 } 446 for (auto *E : C->assignment_ops()) { 447 Profiler->VisitStmt(E); 448 } 449 } 450 void 451 OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) { 452 VisitOMPClauseList(C); 453 for (auto *E : C->source_exprs()) { 454 Profiler->VisitStmt(E); 455 } 456 for (auto *E : C->destination_exprs()) { 457 Profiler->VisitStmt(E); 458 } 459 for (auto *E : C->assignment_ops()) { 460 Profiler->VisitStmt(E); 461 } 462 } 463 void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) { 464 VisitOMPClauseList(C); 465 } 466 void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) { 467 VisitOMPClauseList(C); 468 } 469 void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) { 470 Profiler->VisitStmt(C->getDevice()); 471 } 472 void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) { 473 VisitOMPClauseList(C); 474 } 475 void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) { 476 Profiler->VisitStmt(C->getNumTeams()); 477 } 478 void OMPClauseProfiler::VisitOMPThreadLimitClause( 479 const OMPThreadLimitClause *C) { 480 Profiler->VisitStmt(C->getThreadLimit()); 481 } 482 void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) { 483 Profiler->VisitStmt(C->getPriority()); 484 } 485 void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) { 486 Profiler->VisitStmt(C->getGrainsize()); 487 } 488 void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) { 489 Profiler->VisitStmt(C->getNumTasks()); 490 } 491 void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) { 492 Profiler->VisitStmt(C->getHint()); 493 } 494 void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) { 495 VisitOMPClauseList(C); 496 } 497 void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) { 498 VisitOMPClauseList(C); 499 } 500 } 501 502 void 503 StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) { 504 VisitStmt(S); 505 OMPClauseProfiler P(this); 506 ArrayRef<OMPClause *> Clauses = S->clauses(); 507 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 508 I != E; ++I) 509 if (*I) 510 P.Visit(*I); 511 } 512 513 void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) { 514 VisitOMPExecutableDirective(S); 515 } 516 517 void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) { 518 VisitOMPExecutableDirective(S); 519 } 520 521 void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) { 522 VisitOMPLoopDirective(S); 523 } 524 525 void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) { 526 VisitOMPLoopDirective(S); 527 } 528 529 void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) { 530 VisitOMPLoopDirective(S); 531 } 532 533 void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) { 534 VisitOMPExecutableDirective(S); 535 } 536 537 void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) { 538 VisitOMPExecutableDirective(S); 539 } 540 541 void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) { 542 VisitOMPExecutableDirective(S); 543 } 544 545 void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) { 546 VisitOMPExecutableDirective(S); 547 } 548 549 void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) { 550 VisitOMPExecutableDirective(S); 551 VisitName(S->getDirectiveName().getName()); 552 } 553 554 void 555 StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) { 556 VisitOMPLoopDirective(S); 557 } 558 559 void StmtProfiler::VisitOMPParallelForSimdDirective( 560 const OMPParallelForSimdDirective *S) { 561 VisitOMPLoopDirective(S); 562 } 563 564 void StmtProfiler::VisitOMPParallelSectionsDirective( 565 const OMPParallelSectionsDirective *S) { 566 VisitOMPExecutableDirective(S); 567 } 568 569 void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) { 570 VisitOMPExecutableDirective(S); 571 } 572 573 void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) { 574 VisitOMPExecutableDirective(S); 575 } 576 577 void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) { 578 VisitOMPExecutableDirective(S); 579 } 580 581 void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) { 582 VisitOMPExecutableDirective(S); 583 } 584 585 void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) { 586 VisitOMPExecutableDirective(S); 587 } 588 589 void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) { 590 VisitOMPExecutableDirective(S); 591 } 592 593 void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) { 594 VisitOMPExecutableDirective(S); 595 } 596 597 void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) { 598 VisitOMPExecutableDirective(S); 599 } 600 601 void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) { 602 VisitOMPExecutableDirective(S); 603 } 604 605 void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) { 606 VisitOMPExecutableDirective(S); 607 } 608 609 void StmtProfiler::VisitOMPTargetEnterDataDirective( 610 const OMPTargetEnterDataDirective *S) { 611 VisitOMPExecutableDirective(S); 612 } 613 614 void StmtProfiler::VisitOMPTargetExitDataDirective( 615 const OMPTargetExitDataDirective *S) { 616 VisitOMPExecutableDirective(S); 617 } 618 619 void StmtProfiler::VisitOMPTargetParallelDirective( 620 const OMPTargetParallelDirective *S) { 621 VisitOMPExecutableDirective(S); 622 } 623 624 void StmtProfiler::VisitOMPTargetParallelForDirective( 625 const OMPTargetParallelForDirective *S) { 626 VisitOMPExecutableDirective(S); 627 } 628 629 void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) { 630 VisitOMPExecutableDirective(S); 631 } 632 633 void StmtProfiler::VisitOMPCancellationPointDirective( 634 const OMPCancellationPointDirective *S) { 635 VisitOMPExecutableDirective(S); 636 } 637 638 void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) { 639 VisitOMPExecutableDirective(S); 640 } 641 642 void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) { 643 VisitOMPLoopDirective(S); 644 } 645 646 void StmtProfiler::VisitOMPTaskLoopSimdDirective( 647 const OMPTaskLoopSimdDirective *S) { 648 VisitOMPLoopDirective(S); 649 } 650 651 void StmtProfiler::VisitOMPDistributeDirective( 652 const OMPDistributeDirective *S) { 653 VisitOMPLoopDirective(S); 654 } 655 656 void OMPClauseProfiler::VisitOMPDistScheduleClause( 657 const OMPDistScheduleClause *C) { 658 VistOMPClauseWithPreInit(C); 659 if (auto *S = C->getChunkSize()) 660 Profiler->VisitStmt(S); 661 } 662 663 void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {} 664 665 void StmtProfiler::VisitOMPTargetUpdateDirective( 666 const OMPTargetUpdateDirective *S) { 667 VisitOMPExecutableDirective(S); 668 } 669 670 void StmtProfiler::VisitExpr(const Expr *S) { 671 VisitStmt(S); 672 } 673 674 void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) { 675 VisitExpr(S); 676 if (!Canonical) 677 VisitNestedNameSpecifier(S->getQualifier()); 678 VisitDecl(S->getDecl()); 679 if (!Canonical) 680 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); 681 } 682 683 void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) { 684 VisitExpr(S); 685 ID.AddInteger(S->getIdentType()); 686 } 687 688 void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) { 689 VisitExpr(S); 690 S->getValue().Profile(ID); 691 ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind()); 692 } 693 694 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) { 695 VisitExpr(S); 696 ID.AddInteger(S->getKind()); 697 ID.AddInteger(S->getValue()); 698 } 699 700 void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) { 701 VisitExpr(S); 702 S->getValue().Profile(ID); 703 ID.AddBoolean(S->isExact()); 704 ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind()); 705 } 706 707 void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) { 708 VisitExpr(S); 709 } 710 711 void StmtProfiler::VisitStringLiteral(const StringLiteral *S) { 712 VisitExpr(S); 713 ID.AddString(S->getBytes()); 714 ID.AddInteger(S->getKind()); 715 } 716 717 void StmtProfiler::VisitParenExpr(const ParenExpr *S) { 718 VisitExpr(S); 719 } 720 721 void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) { 722 VisitExpr(S); 723 } 724 725 void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) { 726 VisitExpr(S); 727 ID.AddInteger(S->getOpcode()); 728 } 729 730 void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) { 731 VisitType(S->getTypeSourceInfo()->getType()); 732 unsigned n = S->getNumComponents(); 733 for (unsigned i = 0; i < n; ++i) { 734 const OffsetOfNode &ON = S->getComponent(i); 735 ID.AddInteger(ON.getKind()); 736 switch (ON.getKind()) { 737 case OffsetOfNode::Array: 738 // Expressions handled below. 739 break; 740 741 case OffsetOfNode::Field: 742 VisitDecl(ON.getField()); 743 break; 744 745 case OffsetOfNode::Identifier: 746 ID.AddPointer(ON.getFieldName()); 747 break; 748 749 case OffsetOfNode::Base: 750 // These nodes are implicit, and therefore don't need profiling. 751 break; 752 } 753 } 754 755 VisitExpr(S); 756 } 757 758 void 759 StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) { 760 VisitExpr(S); 761 ID.AddInteger(S->getKind()); 762 if (S->isArgumentType()) 763 VisitType(S->getArgumentType()); 764 } 765 766 void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) { 767 VisitExpr(S); 768 } 769 770 void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr *S) { 771 VisitExpr(S); 772 } 773 774 void StmtProfiler::VisitCallExpr(const CallExpr *S) { 775 VisitExpr(S); 776 } 777 778 void StmtProfiler::VisitMemberExpr(const MemberExpr *S) { 779 VisitExpr(S); 780 VisitDecl(S->getMemberDecl()); 781 if (!Canonical) 782 VisitNestedNameSpecifier(S->getQualifier()); 783 ID.AddBoolean(S->isArrow()); 784 } 785 786 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) { 787 VisitExpr(S); 788 ID.AddBoolean(S->isFileScope()); 789 } 790 791 void StmtProfiler::VisitCastExpr(const CastExpr *S) { 792 VisitExpr(S); 793 } 794 795 void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) { 796 VisitCastExpr(S); 797 ID.AddInteger(S->getValueKind()); 798 } 799 800 void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) { 801 VisitCastExpr(S); 802 VisitType(S->getTypeAsWritten()); 803 } 804 805 void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) { 806 VisitExplicitCastExpr(S); 807 } 808 809 void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) { 810 VisitExpr(S); 811 ID.AddInteger(S->getOpcode()); 812 } 813 814 void 815 StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) { 816 VisitBinaryOperator(S); 817 } 818 819 void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) { 820 VisitExpr(S); 821 } 822 823 void StmtProfiler::VisitBinaryConditionalOperator( 824 const BinaryConditionalOperator *S) { 825 VisitExpr(S); 826 } 827 828 void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) { 829 VisitExpr(S); 830 VisitDecl(S->getLabel()); 831 } 832 833 void StmtProfiler::VisitStmtExpr(const StmtExpr *S) { 834 VisitExpr(S); 835 } 836 837 void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) { 838 VisitExpr(S); 839 } 840 841 void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) { 842 VisitExpr(S); 843 } 844 845 void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) { 846 VisitExpr(S); 847 } 848 849 void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) { 850 VisitExpr(S); 851 } 852 853 void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) { 854 VisitExpr(S); 855 } 856 857 void StmtProfiler::VisitInitListExpr(const InitListExpr *S) { 858 if (S->getSyntacticForm()) { 859 VisitInitListExpr(S->getSyntacticForm()); 860 return; 861 } 862 863 VisitExpr(S); 864 } 865 866 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) { 867 VisitExpr(S); 868 ID.AddBoolean(S->usesGNUSyntax()); 869 for (DesignatedInitExpr::const_designators_iterator D = 870 S->designators_begin(), DEnd = S->designators_end(); 871 D != DEnd; ++D) { 872 if (D->isFieldDesignator()) { 873 ID.AddInteger(0); 874 VisitName(D->getFieldName()); 875 continue; 876 } 877 878 if (D->isArrayDesignator()) { 879 ID.AddInteger(1); 880 } else { 881 assert(D->isArrayRangeDesignator()); 882 ID.AddInteger(2); 883 } 884 ID.AddInteger(D->getFirstExprIndex()); 885 } 886 } 887 888 // Seems that if VisitInitListExpr() only works on the syntactic form of an 889 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered. 890 void StmtProfiler::VisitDesignatedInitUpdateExpr( 891 const DesignatedInitUpdateExpr *S) { 892 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of " 893 "initializer"); 894 } 895 896 void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) { 897 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer"); 898 } 899 900 void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) { 901 VisitExpr(S); 902 } 903 904 void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) { 905 VisitExpr(S); 906 VisitName(&S->getAccessor()); 907 } 908 909 void StmtProfiler::VisitBlockExpr(const BlockExpr *S) { 910 VisitExpr(S); 911 VisitDecl(S->getBlockDecl()); 912 } 913 914 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) { 915 VisitExpr(S); 916 for (unsigned i = 0; i != S->getNumAssocs(); ++i) { 917 QualType T = S->getAssocType(i); 918 if (T.isNull()) 919 ID.AddPointer(nullptr); 920 else 921 VisitType(T); 922 VisitExpr(S->getAssocExpr(i)); 923 } 924 } 925 926 void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) { 927 VisitExpr(S); 928 for (PseudoObjectExpr::const_semantics_iterator 929 i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) 930 // Normally, we would not profile the source expressions of OVEs. 931 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i)) 932 Visit(OVE->getSourceExpr()); 933 } 934 935 void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) { 936 VisitExpr(S); 937 ID.AddInteger(S->getOp()); 938 } 939 940 static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, 941 UnaryOperatorKind &UnaryOp, 942 BinaryOperatorKind &BinaryOp) { 943 switch (S->getOperator()) { 944 case OO_None: 945 case OO_New: 946 case OO_Delete: 947 case OO_Array_New: 948 case OO_Array_Delete: 949 case OO_Arrow: 950 case OO_Call: 951 case OO_Conditional: 952 case OO_Coawait: 953 case NUM_OVERLOADED_OPERATORS: 954 llvm_unreachable("Invalid operator call kind"); 955 956 case OO_Plus: 957 if (S->getNumArgs() == 1) { 958 UnaryOp = UO_Plus; 959 return Stmt::UnaryOperatorClass; 960 } 961 962 BinaryOp = BO_Add; 963 return Stmt::BinaryOperatorClass; 964 965 case OO_Minus: 966 if (S->getNumArgs() == 1) { 967 UnaryOp = UO_Minus; 968 return Stmt::UnaryOperatorClass; 969 } 970 971 BinaryOp = BO_Sub; 972 return Stmt::BinaryOperatorClass; 973 974 case OO_Star: 975 if (S->getNumArgs() == 1) { 976 UnaryOp = UO_Deref; 977 return Stmt::UnaryOperatorClass; 978 } 979 980 BinaryOp = BO_Mul; 981 return Stmt::BinaryOperatorClass; 982 983 case OO_Slash: 984 BinaryOp = BO_Div; 985 return Stmt::BinaryOperatorClass; 986 987 case OO_Percent: 988 BinaryOp = BO_Rem; 989 return Stmt::BinaryOperatorClass; 990 991 case OO_Caret: 992 BinaryOp = BO_Xor; 993 return Stmt::BinaryOperatorClass; 994 995 case OO_Amp: 996 if (S->getNumArgs() == 1) { 997 UnaryOp = UO_AddrOf; 998 return Stmt::UnaryOperatorClass; 999 } 1000 1001 BinaryOp = BO_And; 1002 return Stmt::BinaryOperatorClass; 1003 1004 case OO_Pipe: 1005 BinaryOp = BO_Or; 1006 return Stmt::BinaryOperatorClass; 1007 1008 case OO_Tilde: 1009 UnaryOp = UO_Not; 1010 return Stmt::UnaryOperatorClass; 1011 1012 case OO_Exclaim: 1013 UnaryOp = UO_LNot; 1014 return Stmt::UnaryOperatorClass; 1015 1016 case OO_Equal: 1017 BinaryOp = BO_Assign; 1018 return Stmt::BinaryOperatorClass; 1019 1020 case OO_Less: 1021 BinaryOp = BO_LT; 1022 return Stmt::BinaryOperatorClass; 1023 1024 case OO_Greater: 1025 BinaryOp = BO_GT; 1026 return Stmt::BinaryOperatorClass; 1027 1028 case OO_PlusEqual: 1029 BinaryOp = BO_AddAssign; 1030 return Stmt::CompoundAssignOperatorClass; 1031 1032 case OO_MinusEqual: 1033 BinaryOp = BO_SubAssign; 1034 return Stmt::CompoundAssignOperatorClass; 1035 1036 case OO_StarEqual: 1037 BinaryOp = BO_MulAssign; 1038 return Stmt::CompoundAssignOperatorClass; 1039 1040 case OO_SlashEqual: 1041 BinaryOp = BO_DivAssign; 1042 return Stmt::CompoundAssignOperatorClass; 1043 1044 case OO_PercentEqual: 1045 BinaryOp = BO_RemAssign; 1046 return Stmt::CompoundAssignOperatorClass; 1047 1048 case OO_CaretEqual: 1049 BinaryOp = BO_XorAssign; 1050 return Stmt::CompoundAssignOperatorClass; 1051 1052 case OO_AmpEqual: 1053 BinaryOp = BO_AndAssign; 1054 return Stmt::CompoundAssignOperatorClass; 1055 1056 case OO_PipeEqual: 1057 BinaryOp = BO_OrAssign; 1058 return Stmt::CompoundAssignOperatorClass; 1059 1060 case OO_LessLess: 1061 BinaryOp = BO_Shl; 1062 return Stmt::BinaryOperatorClass; 1063 1064 case OO_GreaterGreater: 1065 BinaryOp = BO_Shr; 1066 return Stmt::BinaryOperatorClass; 1067 1068 case OO_LessLessEqual: 1069 BinaryOp = BO_ShlAssign; 1070 return Stmt::CompoundAssignOperatorClass; 1071 1072 case OO_GreaterGreaterEqual: 1073 BinaryOp = BO_ShrAssign; 1074 return Stmt::CompoundAssignOperatorClass; 1075 1076 case OO_EqualEqual: 1077 BinaryOp = BO_EQ; 1078 return Stmt::BinaryOperatorClass; 1079 1080 case OO_ExclaimEqual: 1081 BinaryOp = BO_NE; 1082 return Stmt::BinaryOperatorClass; 1083 1084 case OO_LessEqual: 1085 BinaryOp = BO_LE; 1086 return Stmt::BinaryOperatorClass; 1087 1088 case OO_GreaterEqual: 1089 BinaryOp = BO_GE; 1090 return Stmt::BinaryOperatorClass; 1091 1092 case OO_AmpAmp: 1093 BinaryOp = BO_LAnd; 1094 return Stmt::BinaryOperatorClass; 1095 1096 case OO_PipePipe: 1097 BinaryOp = BO_LOr; 1098 return Stmt::BinaryOperatorClass; 1099 1100 case OO_PlusPlus: 1101 UnaryOp = S->getNumArgs() == 1? UO_PreInc 1102 : UO_PostInc; 1103 return Stmt::UnaryOperatorClass; 1104 1105 case OO_MinusMinus: 1106 UnaryOp = S->getNumArgs() == 1? UO_PreDec 1107 : UO_PostDec; 1108 return Stmt::UnaryOperatorClass; 1109 1110 case OO_Comma: 1111 BinaryOp = BO_Comma; 1112 return Stmt::BinaryOperatorClass; 1113 1114 case OO_ArrowStar: 1115 BinaryOp = BO_PtrMemI; 1116 return Stmt::BinaryOperatorClass; 1117 1118 case OO_Subscript: 1119 return Stmt::ArraySubscriptExprClass; 1120 } 1121 1122 llvm_unreachable("Invalid overloaded operator expression"); 1123 } 1124 1125 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) { 1126 if (S->isTypeDependent()) { 1127 // Type-dependent operator calls are profiled like their underlying 1128 // syntactic operator. 1129 UnaryOperatorKind UnaryOp = UO_Extension; 1130 BinaryOperatorKind BinaryOp = BO_Comma; 1131 Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp); 1132 1133 ID.AddInteger(SC); 1134 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I) 1135 Visit(S->getArg(I)); 1136 if (SC == Stmt::UnaryOperatorClass) 1137 ID.AddInteger(UnaryOp); 1138 else if (SC == Stmt::BinaryOperatorClass || 1139 SC == Stmt::CompoundAssignOperatorClass) 1140 ID.AddInteger(BinaryOp); 1141 else 1142 assert(SC == Stmt::ArraySubscriptExprClass); 1143 1144 return; 1145 } 1146 1147 VisitCallExpr(S); 1148 ID.AddInteger(S->getOperator()); 1149 } 1150 1151 void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) { 1152 VisitCallExpr(S); 1153 } 1154 1155 void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) { 1156 VisitCallExpr(S); 1157 } 1158 1159 void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) { 1160 VisitExpr(S); 1161 } 1162 1163 void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) { 1164 VisitExplicitCastExpr(S); 1165 } 1166 1167 void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) { 1168 VisitCXXNamedCastExpr(S); 1169 } 1170 1171 void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) { 1172 VisitCXXNamedCastExpr(S); 1173 } 1174 1175 void 1176 StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) { 1177 VisitCXXNamedCastExpr(S); 1178 } 1179 1180 void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) { 1181 VisitCXXNamedCastExpr(S); 1182 } 1183 1184 void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) { 1185 VisitCallExpr(S); 1186 } 1187 1188 void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) { 1189 VisitExpr(S); 1190 ID.AddBoolean(S->getValue()); 1191 } 1192 1193 void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) { 1194 VisitExpr(S); 1195 } 1196 1197 void StmtProfiler::VisitCXXStdInitializerListExpr( 1198 const CXXStdInitializerListExpr *S) { 1199 VisitExpr(S); 1200 } 1201 1202 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) { 1203 VisitExpr(S); 1204 if (S->isTypeOperand()) 1205 VisitType(S->getTypeOperandSourceInfo()->getType()); 1206 } 1207 1208 void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) { 1209 VisitExpr(S); 1210 if (S->isTypeOperand()) 1211 VisitType(S->getTypeOperandSourceInfo()->getType()); 1212 } 1213 1214 void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) { 1215 VisitExpr(S); 1216 VisitDecl(S->getPropertyDecl()); 1217 } 1218 1219 void StmtProfiler::VisitMSPropertySubscriptExpr( 1220 const MSPropertySubscriptExpr *S) { 1221 VisitExpr(S); 1222 } 1223 1224 void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) { 1225 VisitExpr(S); 1226 ID.AddBoolean(S->isImplicit()); 1227 } 1228 1229 void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) { 1230 VisitExpr(S); 1231 } 1232 1233 void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) { 1234 VisitExpr(S); 1235 VisitDecl(S->getParam()); 1236 } 1237 1238 void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) { 1239 VisitExpr(S); 1240 VisitDecl(S->getField()); 1241 } 1242 1243 void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) { 1244 VisitExpr(S); 1245 VisitDecl( 1246 const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor())); 1247 } 1248 1249 void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) { 1250 VisitExpr(S); 1251 VisitDecl(S->getConstructor()); 1252 ID.AddBoolean(S->isElidable()); 1253 } 1254 1255 void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) { 1256 VisitExplicitCastExpr(S); 1257 } 1258 1259 void 1260 StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) { 1261 VisitCXXConstructExpr(S); 1262 } 1263 1264 void 1265 StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) { 1266 VisitExpr(S); 1267 for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), 1268 CEnd = S->explicit_capture_end(); 1269 C != CEnd; ++C) { 1270 ID.AddInteger(C->getCaptureKind()); 1271 switch (C->getCaptureKind()) { 1272 case LCK_StarThis: 1273 case LCK_This: 1274 break; 1275 case LCK_ByRef: 1276 case LCK_ByCopy: 1277 VisitDecl(C->getCapturedVar()); 1278 ID.AddBoolean(C->isPackExpansion()); 1279 break; 1280 case LCK_VLAType: 1281 llvm_unreachable("VLA type in explicit captures."); 1282 } 1283 } 1284 // Note: If we actually needed to be able to match lambda 1285 // expressions, we would have to consider parameters and return type 1286 // here, among other things. 1287 VisitStmt(S->getBody()); 1288 } 1289 1290 void 1291 StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) { 1292 VisitExpr(S); 1293 } 1294 1295 void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) { 1296 VisitExpr(S); 1297 ID.AddBoolean(S->isGlobalDelete()); 1298 ID.AddBoolean(S->isArrayForm()); 1299 VisitDecl(S->getOperatorDelete()); 1300 } 1301 1302 void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) { 1303 VisitExpr(S); 1304 VisitType(S->getAllocatedType()); 1305 VisitDecl(S->getOperatorNew()); 1306 VisitDecl(S->getOperatorDelete()); 1307 ID.AddBoolean(S->isArray()); 1308 ID.AddInteger(S->getNumPlacementArgs()); 1309 ID.AddBoolean(S->isGlobalNew()); 1310 ID.AddBoolean(S->isParenTypeId()); 1311 ID.AddInteger(S->getInitializationStyle()); 1312 } 1313 1314 void 1315 StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) { 1316 VisitExpr(S); 1317 ID.AddBoolean(S->isArrow()); 1318 VisitNestedNameSpecifier(S->getQualifier()); 1319 ID.AddBoolean(S->getScopeTypeInfo() != nullptr); 1320 if (S->getScopeTypeInfo()) 1321 VisitType(S->getScopeTypeInfo()->getType()); 1322 ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr); 1323 if (S->getDestroyedTypeInfo()) 1324 VisitType(S->getDestroyedType()); 1325 else 1326 ID.AddPointer(S->getDestroyedTypeIdentifier()); 1327 } 1328 1329 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) { 1330 VisitExpr(S); 1331 VisitNestedNameSpecifier(S->getQualifier()); 1332 VisitName(S->getName()); 1333 ID.AddBoolean(S->hasExplicitTemplateArgs()); 1334 if (S->hasExplicitTemplateArgs()) 1335 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); 1336 } 1337 1338 void 1339 StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) { 1340 VisitOverloadExpr(S); 1341 } 1342 1343 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) { 1344 VisitExpr(S); 1345 ID.AddInteger(S->getTrait()); 1346 ID.AddInteger(S->getNumArgs()); 1347 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I) 1348 VisitType(S->getArg(I)->getType()); 1349 } 1350 1351 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) { 1352 VisitExpr(S); 1353 ID.AddInteger(S->getTrait()); 1354 VisitType(S->getQueriedType()); 1355 } 1356 1357 void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) { 1358 VisitExpr(S); 1359 ID.AddInteger(S->getTrait()); 1360 VisitExpr(S->getQueriedExpression()); 1361 } 1362 1363 void StmtProfiler::VisitDependentScopeDeclRefExpr( 1364 const DependentScopeDeclRefExpr *S) { 1365 VisitExpr(S); 1366 VisitName(S->getDeclName()); 1367 VisitNestedNameSpecifier(S->getQualifier()); 1368 ID.AddBoolean(S->hasExplicitTemplateArgs()); 1369 if (S->hasExplicitTemplateArgs()) 1370 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); 1371 } 1372 1373 void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) { 1374 VisitExpr(S); 1375 } 1376 1377 void StmtProfiler::VisitCXXUnresolvedConstructExpr( 1378 const CXXUnresolvedConstructExpr *S) { 1379 VisitExpr(S); 1380 VisitType(S->getTypeAsWritten()); 1381 } 1382 1383 void StmtProfiler::VisitCXXDependentScopeMemberExpr( 1384 const CXXDependentScopeMemberExpr *S) { 1385 ID.AddBoolean(S->isImplicitAccess()); 1386 if (!S->isImplicitAccess()) { 1387 VisitExpr(S); 1388 ID.AddBoolean(S->isArrow()); 1389 } 1390 VisitNestedNameSpecifier(S->getQualifier()); 1391 VisitName(S->getMember()); 1392 ID.AddBoolean(S->hasExplicitTemplateArgs()); 1393 if (S->hasExplicitTemplateArgs()) 1394 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); 1395 } 1396 1397 void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) { 1398 ID.AddBoolean(S->isImplicitAccess()); 1399 if (!S->isImplicitAccess()) { 1400 VisitExpr(S); 1401 ID.AddBoolean(S->isArrow()); 1402 } 1403 VisitNestedNameSpecifier(S->getQualifier()); 1404 VisitName(S->getMemberName()); 1405 ID.AddBoolean(S->hasExplicitTemplateArgs()); 1406 if (S->hasExplicitTemplateArgs()) 1407 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); 1408 } 1409 1410 void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) { 1411 VisitExpr(S); 1412 } 1413 1414 void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) { 1415 VisitExpr(S); 1416 } 1417 1418 void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) { 1419 VisitExpr(S); 1420 VisitDecl(S->getPack()); 1421 if (S->isPartiallySubstituted()) { 1422 auto Args = S->getPartialArguments(); 1423 ID.AddInteger(Args.size()); 1424 for (const auto &TA : Args) 1425 VisitTemplateArgument(TA); 1426 } else { 1427 ID.AddInteger(0); 1428 } 1429 } 1430 1431 void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr( 1432 const SubstNonTypeTemplateParmPackExpr *S) { 1433 VisitExpr(S); 1434 VisitDecl(S->getParameterPack()); 1435 VisitTemplateArgument(S->getArgumentPack()); 1436 } 1437 1438 void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( 1439 const SubstNonTypeTemplateParmExpr *E) { 1440 // Profile exactly as the replacement expression. 1441 Visit(E->getReplacement()); 1442 } 1443 1444 void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) { 1445 VisitExpr(S); 1446 VisitDecl(S->getParameterPack()); 1447 ID.AddInteger(S->getNumExpansions()); 1448 for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I) 1449 VisitDecl(*I); 1450 } 1451 1452 void StmtProfiler::VisitMaterializeTemporaryExpr( 1453 const MaterializeTemporaryExpr *S) { 1454 VisitExpr(S); 1455 } 1456 1457 void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) { 1458 VisitExpr(S); 1459 ID.AddInteger(S->getOperator()); 1460 } 1461 1462 void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) { 1463 VisitStmt(S); 1464 } 1465 1466 void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) { 1467 VisitStmt(S); 1468 } 1469 1470 void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) { 1471 VisitExpr(S); 1472 } 1473 1474 void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) { 1475 VisitExpr(S); 1476 } 1477 1478 void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { 1479 VisitExpr(E); 1480 } 1481 1482 void StmtProfiler::VisitTypoExpr(const TypoExpr *E) { 1483 VisitExpr(E); 1484 } 1485 1486 void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) { 1487 VisitExpr(S); 1488 } 1489 1490 void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) { 1491 VisitExpr(E); 1492 } 1493 1494 void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) { 1495 VisitExpr(E); 1496 } 1497 1498 void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) { 1499 VisitExpr(E); 1500 } 1501 1502 void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) { 1503 VisitExpr(S); 1504 VisitType(S->getEncodedType()); 1505 } 1506 1507 void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) { 1508 VisitExpr(S); 1509 VisitName(S->getSelector()); 1510 } 1511 1512 void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) { 1513 VisitExpr(S); 1514 VisitDecl(S->getProtocol()); 1515 } 1516 1517 void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) { 1518 VisitExpr(S); 1519 VisitDecl(S->getDecl()); 1520 ID.AddBoolean(S->isArrow()); 1521 ID.AddBoolean(S->isFreeIvar()); 1522 } 1523 1524 void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) { 1525 VisitExpr(S); 1526 if (S->isImplicitProperty()) { 1527 VisitDecl(S->getImplicitPropertyGetter()); 1528 VisitDecl(S->getImplicitPropertySetter()); 1529 } else { 1530 VisitDecl(S->getExplicitProperty()); 1531 } 1532 if (S->isSuperReceiver()) { 1533 ID.AddBoolean(S->isSuperReceiver()); 1534 VisitType(S->getSuperReceiverType()); 1535 } 1536 } 1537 1538 void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) { 1539 VisitExpr(S); 1540 VisitDecl(S->getAtIndexMethodDecl()); 1541 VisitDecl(S->setAtIndexMethodDecl()); 1542 } 1543 1544 void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) { 1545 VisitExpr(S); 1546 VisitName(S->getSelector()); 1547 VisitDecl(S->getMethodDecl()); 1548 } 1549 1550 void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) { 1551 VisitExpr(S); 1552 ID.AddBoolean(S->isArrow()); 1553 } 1554 1555 void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) { 1556 VisitExpr(S); 1557 ID.AddBoolean(S->getValue()); 1558 } 1559 1560 void StmtProfiler::VisitObjCIndirectCopyRestoreExpr( 1561 const ObjCIndirectCopyRestoreExpr *S) { 1562 VisitExpr(S); 1563 ID.AddBoolean(S->shouldCopy()); 1564 } 1565 1566 void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) { 1567 VisitExplicitCastExpr(S); 1568 ID.AddBoolean(S->getBridgeKind()); 1569 } 1570 1571 void StmtProfiler::VisitDecl(const Decl *D) { 1572 ID.AddInteger(D? D->getKind() : 0); 1573 1574 if (Canonical && D) { 1575 if (const NonTypeTemplateParmDecl *NTTP = 1576 dyn_cast<NonTypeTemplateParmDecl>(D)) { 1577 ID.AddInteger(NTTP->getDepth()); 1578 ID.AddInteger(NTTP->getIndex()); 1579 ID.AddBoolean(NTTP->isParameterPack()); 1580 VisitType(NTTP->getType()); 1581 return; 1582 } 1583 1584 if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) { 1585 // The Itanium C++ ABI uses the type, scope depth, and scope 1586 // index of a parameter when mangling expressions that involve 1587 // function parameters, so we will use the parameter's type for 1588 // establishing function parameter identity. That way, our 1589 // definition of "equivalent" (per C++ [temp.over.link]) is at 1590 // least as strong as the definition of "equivalent" used for 1591 // name mangling. 1592 VisitType(Parm->getType()); 1593 ID.AddInteger(Parm->getFunctionScopeDepth()); 1594 ID.AddInteger(Parm->getFunctionScopeIndex()); 1595 return; 1596 } 1597 1598 if (const TemplateTypeParmDecl *TTP = 1599 dyn_cast<TemplateTypeParmDecl>(D)) { 1600 ID.AddInteger(TTP->getDepth()); 1601 ID.AddInteger(TTP->getIndex()); 1602 ID.AddBoolean(TTP->isParameterPack()); 1603 return; 1604 } 1605 1606 if (const TemplateTemplateParmDecl *TTP = 1607 dyn_cast<TemplateTemplateParmDecl>(D)) { 1608 ID.AddInteger(TTP->getDepth()); 1609 ID.AddInteger(TTP->getIndex()); 1610 ID.AddBoolean(TTP->isParameterPack()); 1611 return; 1612 } 1613 } 1614 1615 ID.AddPointer(D? D->getCanonicalDecl() : nullptr); 1616 } 1617 1618 void StmtProfiler::VisitType(QualType T) { 1619 if (Canonical) 1620 T = Context.getCanonicalType(T); 1621 1622 ID.AddPointer(T.getAsOpaquePtr()); 1623 } 1624 1625 void StmtProfiler::VisitName(DeclarationName Name) { 1626 ID.AddPointer(Name.getAsOpaquePtr()); 1627 } 1628 1629 void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) { 1630 if (Canonical) 1631 NNS = Context.getCanonicalNestedNameSpecifier(NNS); 1632 ID.AddPointer(NNS); 1633 } 1634 1635 void StmtProfiler::VisitTemplateName(TemplateName Name) { 1636 if (Canonical) 1637 Name = Context.getCanonicalTemplateName(Name); 1638 1639 Name.Profile(ID); 1640 } 1641 1642 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args, 1643 unsigned NumArgs) { 1644 ID.AddInteger(NumArgs); 1645 for (unsigned I = 0; I != NumArgs; ++I) 1646 VisitTemplateArgument(Args[I].getArgument()); 1647 } 1648 1649 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { 1650 // Mostly repetitive with TemplateArgument::Profile! 1651 ID.AddInteger(Arg.getKind()); 1652 switch (Arg.getKind()) { 1653 case TemplateArgument::Null: 1654 break; 1655 1656 case TemplateArgument::Type: 1657 VisitType(Arg.getAsType()); 1658 break; 1659 1660 case TemplateArgument::Template: 1661 case TemplateArgument::TemplateExpansion: 1662 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); 1663 break; 1664 1665 case TemplateArgument::Declaration: 1666 VisitDecl(Arg.getAsDecl()); 1667 break; 1668 1669 case TemplateArgument::NullPtr: 1670 VisitType(Arg.getNullPtrType()); 1671 break; 1672 1673 case TemplateArgument::Integral: 1674 Arg.getAsIntegral().Profile(ID); 1675 VisitType(Arg.getIntegralType()); 1676 break; 1677 1678 case TemplateArgument::Expression: 1679 Visit(Arg.getAsExpr()); 1680 break; 1681 1682 case TemplateArgument::Pack: 1683 for (const auto &P : Arg.pack_elements()) 1684 VisitTemplateArgument(P); 1685 break; 1686 } 1687 } 1688 1689 void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, 1690 bool Canonical) const { 1691 StmtProfiler Profiler(ID, Context, Canonical); 1692 Profiler.Visit(this); 1693 } 1694