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