StmtProfile.cpp revision 41ef0c3472a3d09c29bc1792f3d26842f2b8a695
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 identifiers a statement/expression. 12// 13//===----------------------------------------------------------------------===// 14#include "clang/AST/ASTContext.h" 15#include "clang/AST/DeclTemplate.h" 16#include "clang/AST/Expr.h" 17#include "clang/AST/ExprCXX.h" 18#include "clang/AST/ExprObjC.h" 19#include "clang/AST/StmtVisitor.h" 20#include "llvm/ADT/FoldingSet.h" 21#include "llvm/Support/Compiler.h" 22using namespace clang; 23 24namespace { 25 class VISIBILITY_HIDDEN StmtProfiler : public StmtVisitor<StmtProfiler> { 26 llvm::FoldingSetNodeID &ID; 27 ASTContext &Context; 28 bool Canonical; 29 30 public: 31 StmtProfiler(llvm::FoldingSetNodeID &ID, ASTContext &Context, 32 bool Canonical) 33 : ID(ID), Context(Context), Canonical(Canonical) { } 34 35 // FIXME: Use StmtNodes.def to declare all VisitXXX functions 36 37 void VisitStmt(Stmt *S); 38 void VisitExpr(Expr *S); 39 void VisitDeclRefExpr(DeclRefExpr *S); 40 void VisitPredefinedExpr(PredefinedExpr *S); 41 void VisitIntegerLiteral(IntegerLiteral *S); 42 void VisitCharacterLiteral(CharacterLiteral *S); 43 void VisitFloatingLiteral(FloatingLiteral *S); 44 void VisitImaginaryLiteral(ImaginaryLiteral *S); 45 void VisitStringLiteral(StringLiteral *S); 46 void VisitParenExpr(ParenExpr *S); 47 void VisitUnaryOperator(UnaryOperator *S); 48 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S); 49 void VisitArraySubscriptExpr(ArraySubscriptExpr *S); 50 void VisitCallExpr(CallExpr *S); 51 void VisitMemberExpr(MemberExpr *S); 52 void VisitCompoundLiteralExpr(CompoundLiteralExpr *S); 53 void VisitCastExpr(CastExpr *S); 54 void VisitImplicitCastExpr(ImplicitCastExpr *S); 55 void VisitExplicitCastExpr(ExplicitCastExpr *S); 56 void VisitCStyleCastExpr(CStyleCastExpr *S); 57 void VisitBinaryOperator(BinaryOperator *S); 58 void VisitCompoundAssignOperator(CompoundAssignOperator *S); 59 void VisitConditionalOperator(ConditionalOperator *S); 60 void VisitAddrLabelExpr(AddrLabelExpr *S); 61 void VisitStmtExpr(StmtExpr *S); 62 void VisitTypesCompatibleExpr(TypesCompatibleExpr *S); 63 void VisitShuffleVectorExpr(ShuffleVectorExpr *S); 64 void VisitChooseExpr(ChooseExpr *S); 65 void VisitGNUNullExpr(GNUNullExpr *S); 66 void VisitInitListExpr(InitListExpr *S); 67 void VisitDesignatedInitExpr(DesignatedInitExpr *S); 68 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *S); 69 void VisitExtVectorElementExpr(ExtVectorElementExpr *S); 70 void VisitBlockExpr(BlockExpr *S); 71 void VisitBlockDeclRefExpr(BlockDeclRefExpr *S); 72 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S); 73 void VisitCXXMemberCallExpr(CXXMemberCallExpr *S); 74 void VisitCXXNamedCastExpr(CXXNamedCastExpr *S); 75 void VisitCXXStaticCastExpr(CXXStaticCastExpr *S); 76 void VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S); 77 void VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S); 78 void VisitCXXConstCastExpr(CXXConstCastExpr *S); 79 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S); 80 void VisitCXXTypeidExpr(CXXTypeidExpr *S); 81 void VisitCXXThisExpr(CXXThisExpr *S); 82 void VisitCXXThrowExpr(CXXThrowExpr *S); 83 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S); 84 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S); 85 void VisitCXXConstructExpr(CXXConstructExpr *S); 86 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S); 87 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S); 88 void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S); 89 void VisitCXXConditionDeclExpr(CXXConditionDeclExpr *S); 90 void VisitCXXNewExpr(CXXNewExpr *S); 91 void VisitCXXDeleteExpr(CXXDeleteExpr *S); 92 void VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S); 93 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S); 94 void VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *S); 95 void VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *S); 96 void VisitTemplateIdRefExpr(TemplateIdRefExpr *S); 97 // FIXME: pick up at CXXExprWithTemporaries, handle Objective-C expressions 98 99 /// \brief Visit a declaration that is referenced within an expression 100 /// or statement. 101 void VisitDecl(Decl *D); 102 103 /// \brief Visit a type that is referenced within an expression or 104 /// statement. 105 void VisitType(QualType T); 106 107 /// \brief Visit a name that occurs within an expression or statement. 108 void VisitName(DeclarationName Name); 109 110 /// \brief Visit a nested-name-specifier that occurs within an expression 111 /// or statement. 112 void VisitNestedNameSpecifier(NestedNameSpecifier *NNS); 113 114 /// \brief Visit a template name that occurs within an expression or 115 /// statement. 116 void VisitTemplateName(TemplateName Name); 117 118 /// \brief Visit template arguments that occur within an expression or 119 /// statement. 120 void VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs); 121 }; 122} 123 124void StmtProfiler::VisitStmt(Stmt *S) { 125 ID.AddInteger(S->getStmtClass()); 126 for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end(); 127 C != CEnd; ++C) 128 Visit(*C); 129} 130 131void StmtProfiler::VisitExpr(Expr *S) { 132 VisitStmt(S); 133} 134 135void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) { 136 VisitExpr(S); 137 VisitDecl(S->getDecl()); 138} 139 140void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) { 141 VisitExpr(S); 142 ID.AddInteger(S->getIdentType()); 143} 144 145void StmtProfiler::VisitIntegerLiteral(IntegerLiteral *S) { 146 VisitExpr(S); 147 S->getValue().Profile(ID); 148} 149 150void StmtProfiler::VisitCharacterLiteral(CharacterLiteral *S) { 151 VisitExpr(S); 152 ID.AddBoolean(S->isWide()); 153 ID.AddInteger(S->getValue()); 154} 155 156void StmtProfiler::VisitFloatingLiteral(FloatingLiteral *S) { 157 VisitExpr(S); 158 S->getValue().Profile(ID); 159 ID.AddBoolean(S->isExact()); 160} 161 162void StmtProfiler::VisitImaginaryLiteral(ImaginaryLiteral *S) { 163 VisitExpr(S); 164} 165 166void StmtProfiler::VisitStringLiteral(StringLiteral *S) { 167 VisitExpr(S); 168 ID.AddString(S->getStrData(), S->getStrData() + S->getByteLength()); 169 ID.AddBoolean(S->isWide()); 170} 171 172void StmtProfiler::VisitParenExpr(ParenExpr *S) { 173 VisitExpr(S); 174} 175 176void StmtProfiler::VisitUnaryOperator(UnaryOperator *S) { 177 VisitExpr(S); 178 ID.AddInteger(S->getOpcode()); 179} 180 181void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) { 182 VisitExpr(S); 183 ID.AddBoolean(S->isSizeOf()); 184 if (S->isArgumentType()) 185 VisitType(S->getArgumentType()); 186} 187 188void StmtProfiler::VisitArraySubscriptExpr(ArraySubscriptExpr *S) { 189 VisitExpr(S); 190} 191 192void StmtProfiler::VisitCallExpr(CallExpr *S) { 193 VisitExpr(S); 194} 195 196void StmtProfiler::VisitMemberExpr(MemberExpr *S) { 197 VisitExpr(S); 198 VisitDecl(S->getMemberDecl()); 199 ID.AddBoolean(S->isArrow()); 200} 201 202void StmtProfiler::VisitCompoundLiteralExpr(CompoundLiteralExpr *S) { 203 VisitExpr(S); 204 ID.AddBoolean(S->isFileScope()); 205} 206 207void StmtProfiler::VisitDecl(Decl *D) { 208 if (Canonical) { 209 if (NonTypeTemplateParmDecl *NTTP 210 = dyn_cast_or_null<NonTypeTemplateParmDecl>(D)) { 211 ID.AddInteger(NTTP->getDepth()); 212 ID.AddInteger(NTTP->getIndex()); 213 return; 214 } 215 216 // FIXME: Other template template parameters? 217 } 218 219 ID.AddPointer(D? D->getCanonicalDecl() : 0); 220} 221 222void StmtProfiler::VisitCastExpr(CastExpr *S) { 223 VisitExpr(S); 224} 225 226void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) { 227 VisitCastExpr(S); 228 ID.AddBoolean(S->isLvalueCast()); 229} 230 231void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) { 232 VisitCastExpr(S); 233 VisitType(S->getTypeAsWritten()); 234} 235 236void StmtProfiler::VisitCStyleCastExpr(CStyleCastExpr *S) { 237 VisitExplicitCastExpr(S); 238} 239 240void StmtProfiler::VisitBinaryOperator(BinaryOperator *S) { 241 VisitExpr(S); 242 ID.AddInteger(S->getOpcode()); 243} 244 245void StmtProfiler::VisitCompoundAssignOperator(CompoundAssignOperator *S) { 246 VisitBinaryOperator(S); 247} 248 249void StmtProfiler::VisitConditionalOperator(ConditionalOperator *S) { 250 VisitExpr(S); 251} 252 253void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) { 254 VisitExpr(S); 255 ID.AddPointer(S->getLabel()); 256} 257 258void StmtProfiler::VisitStmtExpr(StmtExpr *S) { 259 VisitExpr(S); 260} 261 262void StmtProfiler::VisitTypesCompatibleExpr(TypesCompatibleExpr *S) { 263 VisitExpr(S); 264 VisitType(S->getArgType1()); 265 VisitType(S->getArgType2()); 266} 267 268void StmtProfiler::VisitShuffleVectorExpr(ShuffleVectorExpr *S) { 269 VisitExpr(S); 270} 271 272void StmtProfiler::VisitChooseExpr(ChooseExpr *S) { 273 VisitExpr(S); 274} 275 276void StmtProfiler::VisitGNUNullExpr(GNUNullExpr *S) { 277 VisitExpr(S); 278} 279 280void StmtProfiler::VisitInitListExpr(InitListExpr *S) { 281 if (S->getSyntacticForm()) { 282 VisitInitListExpr(S->getSyntacticForm()); 283 return; 284 } 285 286 VisitExpr(S); 287} 288 289void StmtProfiler::VisitDesignatedInitExpr(DesignatedInitExpr *S) { 290 VisitExpr(S); 291 ID.AddBoolean(S->usesGNUSyntax()); 292 for (DesignatedInitExpr::designators_iterator D = S->designators_begin(), 293 DEnd = S->designators_end(); 294 D != DEnd; ++D) { 295 if (D->isFieldDesignator()) { 296 ID.AddInteger(0); 297 VisitName(D->getFieldName()); 298 continue; 299 } 300 301 if (D->isArrayDesignator()) { 302 ID.AddInteger(1); 303 } else { 304 assert(D->isArrayRangeDesignator()); 305 ID.AddInteger(2); 306 } 307 ID.AddInteger(D->getFirstExprIndex()); 308 } 309} 310 311void StmtProfiler::VisitImplicitValueInitExpr(ImplicitValueInitExpr *S) { 312 VisitExpr(S); 313} 314 315void StmtProfiler::VisitExtVectorElementExpr(ExtVectorElementExpr *S) { 316 VisitExpr(S); 317 VisitName(&S->getAccessor()); 318} 319 320void StmtProfiler::VisitBlockExpr(BlockExpr *S) { 321 VisitExpr(S); 322 VisitDecl(S->getBlockDecl()); 323} 324 325void StmtProfiler::VisitBlockDeclRefExpr(BlockDeclRefExpr *S) { 326 VisitExpr(S); 327 VisitDecl(S->getDecl()); 328 ID.AddBoolean(S->isByRef()); 329 ID.AddBoolean(S->isConstQualAdded()); 330} 331 332void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) { 333 VisitCallExpr(S); 334 ID.AddInteger(S->getOperator()); 335} 336 337void StmtProfiler::VisitCXXMemberCallExpr(CXXMemberCallExpr *S) { 338 VisitCallExpr(S); 339} 340 341void StmtProfiler::VisitCXXNamedCastExpr(CXXNamedCastExpr *S) { 342 VisitExplicitCastExpr(S); 343} 344 345void StmtProfiler::VisitCXXStaticCastExpr(CXXStaticCastExpr *S) { 346 VisitCXXNamedCastExpr(S); 347} 348 349void StmtProfiler::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S) { 350 VisitCXXNamedCastExpr(S); 351} 352 353void StmtProfiler::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S) { 354 VisitCXXNamedCastExpr(S); 355} 356 357void StmtProfiler::VisitCXXConstCastExpr(CXXConstCastExpr *S) { 358 VisitCXXNamedCastExpr(S); 359} 360 361void StmtProfiler::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) { 362 VisitExpr(S); 363 ID.AddBoolean(S->getValue()); 364} 365 366void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) { 367 VisitExpr(S); 368 if (S->isTypeOperand()) 369 VisitType(S->getTypeOperand()); 370} 371 372void StmtProfiler::VisitCXXThisExpr(CXXThisExpr *S) { 373 VisitExpr(S); 374} 375 376void StmtProfiler::VisitCXXThrowExpr(CXXThrowExpr *S) { 377 VisitExpr(S); 378} 379 380void StmtProfiler::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S) { 381 VisitExpr(S); 382 VisitDecl(S->getParam()); 383} 384 385void StmtProfiler::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S) { 386 VisitExpr(S); 387 VisitDecl( 388 const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor())); 389} 390 391void StmtProfiler::VisitCXXConstructExpr(CXXConstructExpr *S) { 392 VisitExpr(S); 393 VisitDecl(S->getConstructor()); 394 ID.AddBoolean(S->isElidable()); 395} 396 397void StmtProfiler::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S) { 398 VisitExplicitCastExpr(S); 399} 400 401void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) { 402 VisitCXXConstructExpr(S); 403} 404 405void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) { 406 VisitExpr(S); 407} 408 409void StmtProfiler::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *S) { 410 VisitDeclRefExpr(S); 411} 412 413void StmtProfiler::VisitCXXDeleteExpr(CXXDeleteExpr *S) { 414 VisitExpr(S); 415 ID.AddBoolean(S->isGlobalDelete()); 416 ID.AddBoolean(S->isArrayForm()); 417 VisitDecl(S->getOperatorDelete()); 418} 419 420 421void StmtProfiler::VisitCXXNewExpr(CXXNewExpr *S) { 422 VisitExpr(S); 423 VisitType(S->getAllocatedType()); 424 VisitDecl(S->getOperatorNew()); 425 VisitDecl(S->getOperatorDelete()); 426 VisitDecl(S->getConstructor()); 427 ID.AddBoolean(S->isArray()); 428 ID.AddInteger(S->getNumPlacementArgs()); 429 ID.AddBoolean(S->isGlobalNew()); 430 ID.AddBoolean(S->isParenTypeId()); 431 ID.AddBoolean(S->hasInitializer()); 432 ID.AddInteger(S->getNumConstructorArgs()); 433} 434 435void 436StmtProfiler::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S) { 437 VisitExpr(S); 438 VisitName(S->getName()); 439} 440 441void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) { 442 VisitExpr(S); 443 ID.AddInteger(S->getTrait()); 444 VisitType(S->getQueriedType()); 445} 446 447void StmtProfiler::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *S) { 448 VisitDeclRefExpr(S); 449 VisitNestedNameSpecifier(S->getQualifier()); 450} 451 452void StmtProfiler::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *S) { 453 VisitExpr(S); 454 VisitName(S->getDeclName()); 455 VisitNestedNameSpecifier(S->getQualifier()); 456 ID.AddBoolean(S->isAddressOfOperand()); 457} 458 459void StmtProfiler::VisitTemplateIdRefExpr(TemplateIdRefExpr *S) { 460 VisitExpr(S); 461 VisitNestedNameSpecifier(S->getQualifier()); 462 VisitTemplateName(S->getTemplateName()); 463 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); 464} 465 466void StmtProfiler::VisitType(QualType T) { 467 if (Canonical) { 468 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { 469 ID.AddInteger(TTP->getDepth()); 470 ID.AddInteger(TTP->getIndex()); 471 return; 472 } 473 474 T = Context.getCanonicalType(T); 475 } 476 477 ID.AddPointer(T.getAsOpaquePtr()); 478} 479 480void StmtProfiler::VisitName(DeclarationName Name) { 481 ID.AddPointer(Name.getAsOpaquePtr()); 482} 483 484void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) { 485 if (Canonical) 486 NNS = Context.getCanonicalNestedNameSpecifier(NNS); 487 ID.AddPointer(NNS); 488} 489 490void StmtProfiler::VisitTemplateName(TemplateName Name) { 491 if (Canonical) 492 Name = Context.getCanonicalTemplateName(Name); 493 494 Name.Profile(ID); 495} 496 497void StmtProfiler::VisitTemplateArguments(const TemplateArgument *Args, 498 unsigned NumArgs) { 499 ID.AddInteger(NumArgs); 500 for (unsigned I = 0; I != NumArgs; ++I) { 501 const TemplateArgument &Arg = Args[I]; 502 503 // Mostly repetitive with TemplateArgument::Profile! 504 ID.AddInteger(Arg.getKind()); 505 switch (Arg.getKind()) { 506 case TemplateArgument::Null: 507 break; 508 509 case TemplateArgument::Type: 510 VisitType(Arg.getAsType()); 511 break; 512 513 case TemplateArgument::Declaration: 514 VisitDecl(Arg.getAsDecl()); 515 break; 516 517 case TemplateArgument::Integral: 518 Arg.getAsIntegral()->Profile(ID); 519 VisitType(Arg.getIntegralType()); 520 break; 521 522 case TemplateArgument::Expression: 523 Visit(Arg.getAsExpr()); 524 break; 525 526 case TemplateArgument::Pack: 527 VisitTemplateArguments(Arg.pack_begin(), Arg.pack_size()); 528 break; 529 } 530 } 531} 532 533void Stmt::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, 534 bool Canonical) { 535 StmtProfiler Profiler(ID, Context, Canonical); 536 Profiler.Visit(this); 537} 538