1 //===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Stmt::Profile method, which builds a unique bit
11 // representation that identifies a statement/expression.
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 using namespace clang;
26 class StmtProfiler : public StmtVisitor<StmtProfiler> {
27 llvm::FoldingSetNodeID &ID;
32 StmtProfiler(llvm::FoldingSetNodeID &ID, ASTContext &Context,
34 : ID(ID), Context(Context), Canonical(Canonical) { }
36 void VisitStmt(Stmt *S);
38 #define STMT(Node, Base) void Visit##Node(Node *S);
39 #include "clang/AST/StmtNodes.def"
41 /// \brief Visit a declaration that is referenced within an expression
43 void VisitDecl(Decl *D);
45 /// \brief Visit a type that is referenced within an expression or
47 void VisitType(QualType T);
49 /// \brief Visit a name that occurs within an expression or statement.
50 void VisitName(DeclarationName Name);
52 /// \brief Visit a nested-name-specifier that occurs within an expression
54 void VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
56 /// \brief Visit a template name that occurs within an expression or
58 void VisitTemplateName(TemplateName Name);
60 /// \brief Visit template arguments that occur within an expression or
62 void VisitTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs);
64 /// \brief Visit a single template argument.
65 void VisitTemplateArgument(const TemplateArgument &Arg);
69 void StmtProfiler::VisitStmt(Stmt *S) {
70 ID.AddInteger(S->getStmtClass());
71 for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
76 void StmtProfiler::VisitDeclStmt(DeclStmt *S) {
78 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
83 void StmtProfiler::VisitNullStmt(NullStmt *S) {
87 void StmtProfiler::VisitCompoundStmt(CompoundStmt *S) {
91 void StmtProfiler::VisitSwitchCase(SwitchCase *S) {
95 void StmtProfiler::VisitCaseStmt(CaseStmt *S) {
99 void StmtProfiler::VisitDefaultStmt(DefaultStmt *S) {
103 void StmtProfiler::VisitLabelStmt(LabelStmt *S) {
105 VisitName(S->getID());
108 void StmtProfiler::VisitIfStmt(IfStmt *S) {
110 VisitDecl(S->getConditionVariable());
113 void StmtProfiler::VisitSwitchStmt(SwitchStmt *S) {
115 VisitDecl(S->getConditionVariable());
118 void StmtProfiler::VisitWhileStmt(WhileStmt *S) {
120 VisitDecl(S->getConditionVariable());
123 void StmtProfiler::VisitDoStmt(DoStmt *S) {
127 void StmtProfiler::VisitForStmt(ForStmt *S) {
131 void StmtProfiler::VisitGotoStmt(GotoStmt *S) {
133 VisitName(S->getLabel()->getID());
136 void StmtProfiler::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
140 void StmtProfiler::VisitContinueStmt(ContinueStmt *S) {
144 void StmtProfiler::VisitBreakStmt(BreakStmt *S) {
148 void StmtProfiler::VisitReturnStmt(ReturnStmt *S) {
152 void StmtProfiler::VisitAsmStmt(AsmStmt *S) {
154 ID.AddBoolean(S->isVolatile());
155 ID.AddBoolean(S->isSimple());
156 VisitStringLiteral(S->getAsmString());
157 ID.AddInteger(S->getNumOutputs());
158 for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
159 ID.AddString(S->getOutputName(I));
160 VisitStringLiteral(S->getOutputConstraintLiteral(I));
162 ID.AddInteger(S->getNumInputs());
163 for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
164 ID.AddString(S->getInputName(I));
165 VisitStringLiteral(S->getInputConstraintLiteral(I));
167 ID.AddInteger(S->getNumClobbers());
168 for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
169 VisitStringLiteral(S->getClobber(I));
172 void StmtProfiler::VisitCXXCatchStmt(CXXCatchStmt *S) {
174 VisitType(S->getCaughtType());
177 void StmtProfiler::VisitCXXTryStmt(CXXTryStmt *S) {
181 void StmtProfiler::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
185 void StmtProfiler::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
187 ID.AddBoolean(S->hasEllipsis());
188 if (S->getCatchParamDecl())
189 VisitType(S->getCatchParamDecl()->getType());
192 void StmtProfiler::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
196 void StmtProfiler::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
200 void StmtProfiler::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
204 void StmtProfiler::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
208 void StmtProfiler::VisitExpr(Expr *S) {
212 void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) {
214 VisitNestedNameSpecifier(S->getQualifier());
215 VisitDecl(S->getDecl());
216 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
219 void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) {
221 ID.AddInteger(S->getIdentType());
224 void StmtProfiler::VisitIntegerLiteral(IntegerLiteral *S) {
226 S->getValue().Profile(ID);
229 void StmtProfiler::VisitCharacterLiteral(CharacterLiteral *S) {
231 ID.AddBoolean(S->isWide());
232 ID.AddInteger(S->getValue());
235 void StmtProfiler::VisitFloatingLiteral(FloatingLiteral *S) {
237 S->getValue().Profile(ID);
238 ID.AddBoolean(S->isExact());
241 void StmtProfiler::VisitImaginaryLiteral(ImaginaryLiteral *S) {
245 void StmtProfiler::VisitStringLiteral(StringLiteral *S) {
247 ID.AddString(S->getString());
248 ID.AddBoolean(S->isWide());
251 void StmtProfiler::VisitParenExpr(ParenExpr *S) {
255 void StmtProfiler::VisitParenListExpr(ParenListExpr *S) {
259 void StmtProfiler::VisitUnaryOperator(UnaryOperator *S) {
261 ID.AddInteger(S->getOpcode());
264 void StmtProfiler::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *S) {
266 ID.AddBoolean(S->isSizeOf());
267 if (S->isArgumentType())
268 VisitType(S->getArgumentType());
271 void StmtProfiler::VisitArraySubscriptExpr(ArraySubscriptExpr *S) {
275 void StmtProfiler::VisitCallExpr(CallExpr *S) {
279 void StmtProfiler::VisitMemberExpr(MemberExpr *S) {
281 VisitDecl(S->getMemberDecl());
282 VisitNestedNameSpecifier(S->getQualifier());
283 ID.AddBoolean(S->isArrow());
286 void StmtProfiler::VisitCompoundLiteralExpr(CompoundLiteralExpr *S) {
288 ID.AddBoolean(S->isFileScope());
291 void StmtProfiler::VisitCastExpr(CastExpr *S) {
295 void StmtProfiler::VisitImplicitCastExpr(ImplicitCastExpr *S) {
297 ID.AddBoolean(S->isLvalueCast());
300 void StmtProfiler::VisitExplicitCastExpr(ExplicitCastExpr *S) {
302 VisitType(S->getTypeAsWritten());
305 void StmtProfiler::VisitCStyleCastExpr(CStyleCastExpr *S) {
306 VisitExplicitCastExpr(S);
309 void StmtProfiler::VisitBinaryOperator(BinaryOperator *S) {
311 ID.AddInteger(S->getOpcode());
314 void StmtProfiler::VisitCompoundAssignOperator(CompoundAssignOperator *S) {
315 VisitBinaryOperator(S);
318 void StmtProfiler::VisitConditionalOperator(ConditionalOperator *S) {
322 void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) {
324 VisitName(S->getLabel()->getID());
327 void StmtProfiler::VisitStmtExpr(StmtExpr *S) {
331 void StmtProfiler::VisitTypesCompatibleExpr(TypesCompatibleExpr *S) {
333 VisitType(S->getArgType1());
334 VisitType(S->getArgType2());
337 void StmtProfiler::VisitShuffleVectorExpr(ShuffleVectorExpr *S) {
341 void StmtProfiler::VisitChooseExpr(ChooseExpr *S) {
345 void StmtProfiler::VisitGNUNullExpr(GNUNullExpr *S) {
349 void StmtProfiler::VisitVAArgExpr(VAArgExpr *S) {
353 void StmtProfiler::VisitInitListExpr(InitListExpr *S) {
354 if (S->getSyntacticForm()) {
355 VisitInitListExpr(S->getSyntacticForm());
362 void StmtProfiler::VisitDesignatedInitExpr(DesignatedInitExpr *S) {
364 ID.AddBoolean(S->usesGNUSyntax());
365 for (DesignatedInitExpr::designators_iterator D = S->designators_begin(),
366 DEnd = S->designators_end();
368 if (D->isFieldDesignator()) {
370 VisitName(D->getFieldName());
374 if (D->isArrayDesignator()) {
377 assert(D->isArrayRangeDesignator());
380 ID.AddInteger(D->getFirstExprIndex());
384 void StmtProfiler::VisitImplicitValueInitExpr(ImplicitValueInitExpr *S) {
388 void StmtProfiler::VisitExtVectorElementExpr(ExtVectorElementExpr *S) {
390 VisitName(&S->getAccessor());
393 void StmtProfiler::VisitBlockExpr(BlockExpr *S) {
395 VisitDecl(S->getBlockDecl());
398 void StmtProfiler::VisitBlockDeclRefExpr(BlockDeclRefExpr *S) {
400 VisitDecl(S->getDecl());
401 ID.AddBoolean(S->isByRef());
402 ID.AddBoolean(S->isConstQualAdded());
405 void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
407 ID.AddInteger(S->getOperator());
410 void StmtProfiler::VisitCXXMemberCallExpr(CXXMemberCallExpr *S) {
414 void StmtProfiler::VisitCXXNamedCastExpr(CXXNamedCastExpr *S) {
415 VisitExplicitCastExpr(S);
418 void StmtProfiler::VisitCXXStaticCastExpr(CXXStaticCastExpr *S) {
419 VisitCXXNamedCastExpr(S);
422 void StmtProfiler::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *S) {
423 VisitCXXNamedCastExpr(S);
426 void StmtProfiler::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *S) {
427 VisitCXXNamedCastExpr(S);
430 void StmtProfiler::VisitCXXConstCastExpr(CXXConstCastExpr *S) {
431 VisitCXXNamedCastExpr(S);
434 void StmtProfiler::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) {
436 ID.AddBoolean(S->getValue());
439 void StmtProfiler::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) {
443 void StmtProfiler::VisitCXXTypeidExpr(CXXTypeidExpr *S) {
445 if (S->isTypeOperand())
446 VisitType(S->getTypeOperand());
449 void StmtProfiler::VisitCXXThisExpr(CXXThisExpr *S) {
453 void StmtProfiler::VisitCXXThrowExpr(CXXThrowExpr *S) {
457 void StmtProfiler::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *S) {
459 VisitDecl(S->getParam());
462 void StmtProfiler::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *S) {
465 const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
468 void StmtProfiler::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *S) {
472 void StmtProfiler::VisitCXXConstructExpr(CXXConstructExpr *S) {
474 VisitDecl(S->getConstructor());
475 ID.AddBoolean(S->isElidable());
478 void StmtProfiler::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *S) {
479 VisitExplicitCastExpr(S);
482 void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) {
483 VisitCXXConstructExpr(S);
486 void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
490 void StmtProfiler::VisitCXXDeleteExpr(CXXDeleteExpr *S) {
492 ID.AddBoolean(S->isGlobalDelete());
493 ID.AddBoolean(S->isArrayForm());
494 VisitDecl(S->getOperatorDelete());
498 void StmtProfiler::VisitCXXNewExpr(CXXNewExpr *S) {
500 VisitType(S->getAllocatedType());
501 VisitDecl(S->getOperatorNew());
502 VisitDecl(S->getOperatorDelete());
503 VisitDecl(S->getConstructor());
504 ID.AddBoolean(S->isArray());
505 ID.AddInteger(S->getNumPlacementArgs());
506 ID.AddBoolean(S->isGlobalNew());
507 ID.AddBoolean(S->isParenTypeId());
508 ID.AddBoolean(S->hasInitializer());
509 ID.AddInteger(S->getNumConstructorArgs());
512 void StmtProfiler::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *S) {
514 ID.AddBoolean(S->isArrow());
515 VisitNestedNameSpecifier(S->getQualifier());
516 VisitType(S->getDestroyedType());
520 StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
522 VisitNestedNameSpecifier(S->getQualifier());
523 VisitName(S->getName());
524 ID.AddBoolean(S->hasExplicitTemplateArgs());
525 if (S->hasExplicitTemplateArgs())
526 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
529 void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
531 ID.AddInteger(S->getTrait());
532 VisitType(S->getQueriedType());
536 StmtProfiler::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
538 VisitName(S->getDeclName());
539 VisitNestedNameSpecifier(S->getQualifier());
540 ID.AddBoolean(S->hasExplicitTemplateArgs());
541 if (S->hasExplicitTemplateArgs())
542 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
545 void StmtProfiler::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *S) {
547 for (unsigned I = 0, N = S->getNumTemporaries(); I != N; ++I)
549 const_cast<CXXDestructorDecl *>(S->getTemporary(I)->getDestructor()));
553 StmtProfiler::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *S) {
555 VisitType(S->getTypeAsWritten());
559 StmtProfiler::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *S) {
560 ID.AddBoolean(S->isImplicitAccess());
561 if (!S->isImplicitAccess()) {
563 ID.AddBoolean(S->isArrow());
565 VisitNestedNameSpecifier(S->getQualifier());
566 VisitName(S->getMember());
567 ID.AddBoolean(S->hasExplicitTemplateArgs());
568 if (S->hasExplicitTemplateArgs())
569 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
572 void StmtProfiler::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *S) {
573 ID.AddBoolean(S->isImplicitAccess());
574 if (!S->isImplicitAccess()) {
576 ID.AddBoolean(S->isArrow());
578 VisitNestedNameSpecifier(S->getQualifier());
579 VisitName(S->getMemberName());
580 ID.AddBoolean(S->hasExplicitTemplateArgs());
581 if (S->hasExplicitTemplateArgs())
582 VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
585 void StmtProfiler::VisitObjCStringLiteral(ObjCStringLiteral *S) {
589 void StmtProfiler::VisitObjCEncodeExpr(ObjCEncodeExpr *S) {
591 VisitType(S->getEncodedType());
594 void StmtProfiler::VisitObjCSelectorExpr(ObjCSelectorExpr *S) {
596 VisitName(S->getSelector());
599 void StmtProfiler::VisitObjCProtocolExpr(ObjCProtocolExpr *S) {
601 VisitDecl(S->getProtocol());
604 void StmtProfiler::VisitObjCIvarRefExpr(ObjCIvarRefExpr *S) {
606 VisitDecl(S->getDecl());
607 ID.AddBoolean(S->isArrow());
608 ID.AddBoolean(S->isFreeIvar());
611 void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) {
613 VisitDecl(S->getProperty());
616 void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr(
617 ObjCImplicitSetterGetterRefExpr *S) {
619 VisitDecl(S->getGetterMethod());
620 VisitDecl(S->getSetterMethod());
621 VisitDecl(S->getInterfaceDecl());
624 void StmtProfiler::VisitObjCMessageExpr(ObjCMessageExpr *S) {
626 VisitName(S->getSelector());
627 VisitDecl(S->getMethodDecl());
630 void StmtProfiler::VisitObjCSuperExpr(ObjCSuperExpr *S) {
634 void StmtProfiler::VisitObjCIsaExpr(ObjCIsaExpr *S) {
636 ID.AddBoolean(S->isArrow());
639 void StmtProfiler::VisitDecl(Decl *D) {
640 ID.AddInteger(D? D->getKind() : 0);
642 if (Canonical && D) {
643 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
644 ID.AddInteger(NTTP->getDepth());
645 ID.AddInteger(NTTP->getIndex());
646 VisitType(NTTP->getType());
650 if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
651 // The Itanium C++ ABI uses the type of a parameter when mangling
652 // expressions that involve function parameters, so we will use the
653 // parameter's type for establishing function parameter identity. That
654 // way, our definition of "equivalent" (per C++ [temp.over.link])
655 // matches the definition of "equivalent" used for name mangling.
656 VisitType(Parm->getType());
660 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
661 ID.AddInteger(TTP->getDepth());
662 ID.AddInteger(TTP->getIndex());
667 ID.AddPointer(D? D->getCanonicalDecl() : 0);
670 void StmtProfiler::VisitType(QualType T) {
672 T = Context.getCanonicalType(T);
674 ID.AddPointer(T.getAsOpaquePtr());
677 void StmtProfiler::VisitName(DeclarationName Name) {
678 ID.AddPointer(Name.getAsOpaquePtr());
681 void StmtProfiler::VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
683 NNS = Context.getCanonicalNestedNameSpecifier(NNS);
687 void StmtProfiler::VisitTemplateName(TemplateName Name) {
689 Name = Context.getCanonicalTemplateName(Name);
694 void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
696 ID.AddInteger(NumArgs);
697 for (unsigned I = 0; I != NumArgs; ++I)
698 VisitTemplateArgument(Args[I].getArgument());
701 void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
702 // Mostly repetitive with TemplateArgument::Profile!
703 ID.AddInteger(Arg.getKind());
704 switch (Arg.getKind()) {
705 case TemplateArgument::Null:
708 case TemplateArgument::Type:
709 VisitType(Arg.getAsType());
712 case TemplateArgument::Template:
713 VisitTemplateName(Arg.getAsTemplate());
716 case TemplateArgument::Declaration:
717 VisitDecl(Arg.getAsDecl());
720 case TemplateArgument::Integral:
721 Arg.getAsIntegral()->Profile(ID);
722 VisitType(Arg.getIntegralType());
725 case TemplateArgument::Expression:
726 Visit(Arg.getAsExpr());
729 case TemplateArgument::Pack:
730 const TemplateArgument *Pack = Arg.pack_begin();
731 for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
732 VisitTemplateArgument(Pack[i]);
737 void Stmt::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
739 StmtProfiler Profiler(ID, Context, Canonical);
740 Profiler.Visit(this);