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