Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: tools/gcmole/gcmole.cc

Issue 445983002: Update gcmole to a more recent clang/llvm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Changes up to 3.5 Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gcmole/bootstrap.sh ('k') | tools/gcmole/gcmole.lua » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 #include <stack> 44 #include <stack>
45 45
46 namespace { 46 namespace {
47 47
48 typedef std::string MangledName; 48 typedef std::string MangledName;
49 typedef std::set<MangledName> CalleesSet; 49 typedef std::set<MangledName> CalleesSet;
50 50
51 static bool GetMangledName(clang::MangleContext* ctx, 51 static bool GetMangledName(clang::MangleContext* ctx,
52 const clang::NamedDecl* decl, 52 const clang::NamedDecl* decl,
53 MangledName* result) { 53 MangledName* result) {
54 if (!isa<clang::CXXConstructorDecl>(decl) && 54 if (!llvm::isa<clang::CXXConstructorDecl>(decl) &&
55 !isa<clang::CXXDestructorDecl>(decl)) { 55 !llvm::isa<clang::CXXDestructorDecl>(decl)) {
56 llvm::SmallVector<char, 512> output; 56 llvm::SmallVector<char, 512> output;
57 llvm::raw_svector_ostream out(output); 57 llvm::raw_svector_ostream out(output);
58 ctx->mangleName(decl, out); 58 ctx->mangleName(decl, out);
59 *result = out.str().str(); 59 *result = out.str().str();
60 return true; 60 return true;
61 } 61 }
62 62
63 return false; 63 return false;
64 } 64 }
65 65
66 66
67 static bool InV8Namespace(const clang::NamedDecl* decl) { 67 static bool InV8Namespace(const clang::NamedDecl* decl) {
68 return decl->getQualifiedNameAsString().compare(0, 4, "v8::") == 0; 68 return decl->getQualifiedNameAsString().compare(0, 4, "v8::") == 0;
69 } 69 }
70 70
71 71
72 static std::string EXTERNAL("EXTERNAL"); 72 static std::string EXTERNAL("EXTERNAL");
73 static std::string STATE_TAG("enum v8::internal::StateTag"); 73 static std::string STATE_TAG("enum v8::internal::StateTag");
74 74
75 static bool IsExternalVMState(const clang::ValueDecl* var) { 75 static bool IsExternalVMState(const clang::ValueDecl* var) {
76 const clang::EnumConstantDecl* enum_constant = 76 const clang::EnumConstantDecl* enum_constant =
77 dyn_cast<clang::EnumConstantDecl>(var); 77 llvm::dyn_cast<clang::EnumConstantDecl>(var);
78 if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) { 78 if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) {
79 clang::QualType type = enum_constant->getType(); 79 clang::QualType type = enum_constant->getType();
80 return (type.getAsString() == STATE_TAG); 80 return (type.getAsString() == STATE_TAG);
81 } 81 }
82 82
83 return false; 83 return false;
84 } 84 }
85 85
86 86
87 struct Resolver { 87 struct Resolver {
(...skipping 14 matching lines...) Expand all
102 return Resolver(ctx_, Resolve<clang::NamespaceDecl>(n)); 102 return Resolver(ctx_, Resolve<clang::NamespaceDecl>(n));
103 } 103 }
104 104
105 template<typename T> 105 template<typename T>
106 T* Resolve(const char* n) { 106 T* Resolve(const char* n) {
107 if (decl_ctx_ == NULL) return NULL; 107 if (decl_ctx_ == NULL) return NULL;
108 108
109 clang::DeclContext::lookup_result result = 109 clang::DeclContext::lookup_result result =
110 decl_ctx_->lookup(ResolveName(n)); 110 decl_ctx_->lookup(ResolveName(n));
111 111
112 clang::DeclContext::lookup_iterator end = result.second; 112 clang::DeclContext::lookup_iterator end = result.end();
113 for (clang::DeclContext::lookup_iterator i = result.first; 113 for (clang::DeclContext::lookup_iterator i = result.begin(); i != end;
114 i != end;
115 i++) { 114 i++) {
116 if (isa<T>(*i)) return cast<T>(*i); 115 if (llvm::isa<T>(*i)) return llvm::cast<T>(*i);
117 } 116 }
118 117
119 return NULL; 118 return NULL;
120 } 119 }
121 120
122 private: 121 private:
123 clang::ASTContext& ctx_; 122 clang::ASTContext& ctx_;
124 clang::DeclContext* decl_ctx_; 123 clang::DeclContext* decl_ctx_;
125 }; 124 };
126 125
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 200
202 std::stack<CalleesSet* > scopes_; 201 std::stack<CalleesSet* > scopes_;
203 Callgraph callgraph_; 202 Callgraph callgraph_;
204 }; 203 };
205 204
206 205
207 class FunctionDeclarationFinder 206 class FunctionDeclarationFinder
208 : public clang::ASTConsumer, 207 : public clang::ASTConsumer,
209 public clang::RecursiveASTVisitor<FunctionDeclarationFinder> { 208 public clang::RecursiveASTVisitor<FunctionDeclarationFinder> {
210 public: 209 public:
211 explicit FunctionDeclarationFinder(clang::Diagnostic& d, 210 explicit FunctionDeclarationFinder(clang::DiagnosticsEngine& d,
212 clang::SourceManager& sm, 211 clang::SourceManager& sm,
213 const std::vector<std::string>& args) 212 const std::vector<std::string>& args)
214 : d_(d), sm_(sm) { } 213 : d_(d), sm_(sm) {}
215 214
216 virtual void HandleTranslationUnit(clang::ASTContext &ctx) { 215 virtual void HandleTranslationUnit(clang::ASTContext &ctx) {
217 mangle_context_ = clang::createItaniumMangleContext(ctx, d_); 216 mangle_context_ = clang::ItaniumMangleContext::create(ctx, d_);
218 callees_printer_ = new CalleesPrinter(mangle_context_); 217 callees_printer_ = new CalleesPrinter(mangle_context_);
219 218
220 TraverseDecl(ctx.getTranslationUnitDecl()); 219 TraverseDecl(ctx.getTranslationUnitDecl());
221 220
222 callees_printer_->PrintCallGraph(); 221 callees_printer_->PrintCallGraph();
223 } 222 }
224 223
225 virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { 224 virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) {
226 callees_printer_->AnalyzeFunction(decl); 225 callees_printer_->AnalyzeFunction(decl);
227 return true; 226 return true;
228 } 227 }
229 228
230 private: 229 private:
231 clang::Diagnostic& d_; 230 clang::DiagnosticsEngine& d_;
232 clang::SourceManager& sm_; 231 clang::SourceManager& sm_;
233 clang::MangleContext* mangle_context_; 232 clang::MangleContext* mangle_context_;
234 233
235 CalleesPrinter* callees_printer_; 234 CalleesPrinter* callees_printer_;
236 }; 235 };
237 236
238 237
239 static bool loaded = false; 238 static bool loaded = false;
240 static CalleesSet gc_suspects; 239 static CalleesSet gc_suspects;
241 240
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 500
502 501
503 static std::string THIS ("this"); 502 static std::string THIS ("this");
504 503
505 504
506 class FunctionAnalyzer { 505 class FunctionAnalyzer {
507 public: 506 public:
508 FunctionAnalyzer(clang::MangleContext* ctx, 507 FunctionAnalyzer(clang::MangleContext* ctx,
509 clang::DeclarationName handle_decl_name, 508 clang::DeclarationName handle_decl_name,
510 clang::CXXRecordDecl* object_decl, 509 clang::CXXRecordDecl* object_decl,
511 clang::CXXRecordDecl* smi_decl, 510 clang::CXXRecordDecl* smi_decl, clang::DiagnosticsEngine& d,
512 clang::Diagnostic& d, 511 clang::SourceManager& sm, bool dead_vars_analysis)
513 clang::SourceManager& sm,
514 bool dead_vars_analysis)
515 : ctx_(ctx), 512 : ctx_(ctx),
516 handle_decl_name_(handle_decl_name), 513 handle_decl_name_(handle_decl_name),
517 object_decl_(object_decl), 514 object_decl_(object_decl),
518 smi_decl_(smi_decl), 515 smi_decl_(smi_decl),
519 d_(d), 516 d_(d),
520 sm_(sm), 517 sm_(sm),
521 block_(NULL), 518 block_(NULL),
522 dead_vars_analysis_(dead_vars_analysis) { 519 dead_vars_analysis_(dead_vars_analysis) {}
523 }
524 520
525 521
526 // -------------------------------------------------------------------------- 522 // --------------------------------------------------------------------------
527 // Expressions 523 // Expressions
528 // -------------------------------------------------------------------------- 524 // --------------------------------------------------------------------------
529 525
530 ExprEffect VisitExpr(clang::Expr* expr, const Environment& env) { 526 ExprEffect VisitExpr(clang::Expr* expr, const Environment& env) {
531 #define VISIT(type) do { \ 527 #define VISIT(type) \
532 clang::type* concrete_expr = dyn_cast_or_null<clang::type>(expr); \ 528 do { \
533 if (concrete_expr != NULL) { \ 529 clang::type* concrete_expr = llvm::dyn_cast_or_null<clang::type>(expr); \
534 return Visit##type (concrete_expr, env); \ 530 if (concrete_expr != NULL) { \
535 } \ 531 return Visit##type(concrete_expr, env); \
536 } while(0); 532 } \
533 } while (0);
537 534
538 VISIT(AbstractConditionalOperator); 535 VISIT(AbstractConditionalOperator);
539 VISIT(AddrLabelExpr); 536 VISIT(AddrLabelExpr);
540 VISIT(ArraySubscriptExpr); 537 VISIT(ArraySubscriptExpr);
541 VISIT(BinaryOperator); 538 VISIT(BinaryOperator);
542 VISIT(BinaryTypeTraitExpr);
543 VISIT(BlockDeclRefExpr);
544 VISIT(BlockExpr); 539 VISIT(BlockExpr);
545 VISIT(CallExpr); 540 VISIT(CallExpr);
546 VISIT(CastExpr); 541 VISIT(CastExpr);
547 VISIT(CharacterLiteral); 542 VISIT(CharacterLiteral);
548 VISIT(ChooseExpr); 543 VISIT(ChooseExpr);
549 VISIT(CompoundLiteralExpr); 544 VISIT(CompoundLiteralExpr);
550 VISIT(CXXBindTemporaryExpr); 545 VISIT(CXXBindTemporaryExpr);
551 VISIT(CXXBoolLiteralExpr); 546 VISIT(CXXBoolLiteralExpr);
552 VISIT(CXXConstructExpr); 547 VISIT(CXXConstructExpr);
553 VISIT(CXXDefaultArgExpr); 548 VISIT(CXXDefaultArgExpr);
(...skipping 26 matching lines...) Expand all
580 VISIT(OverloadExpr); 575 VISIT(OverloadExpr);
581 VISIT(PackExpansionExpr); 576 VISIT(PackExpansionExpr);
582 VISIT(ParenExpr); 577 VISIT(ParenExpr);
583 VISIT(ParenListExpr); 578 VISIT(ParenListExpr);
584 VISIT(PredefinedExpr); 579 VISIT(PredefinedExpr);
585 VISIT(ShuffleVectorExpr); 580 VISIT(ShuffleVectorExpr);
586 VISIT(SizeOfPackExpr); 581 VISIT(SizeOfPackExpr);
587 VISIT(StmtExpr); 582 VISIT(StmtExpr);
588 VISIT(StringLiteral); 583 VISIT(StringLiteral);
589 VISIT(SubstNonTypeTemplateParmPackExpr); 584 VISIT(SubstNonTypeTemplateParmPackExpr);
585 VISIT(TypeTraitExpr);
590 VISIT(UnaryOperator); 586 VISIT(UnaryOperator);
591 VISIT(UnaryTypeTraitExpr);
592 VISIT(VAArgExpr); 587 VISIT(VAArgExpr);
593 #undef VISIT 588 #undef VISIT
594 589
595 return ExprEffect::None(); 590 return ExprEffect::None();
596 } 591 }
597 592
598 #define DECL_VISIT_EXPR(type) \ 593 #define DECL_VISIT_EXPR(type) \
599 ExprEffect Visit##type (clang::type* expr, const Environment& env) 594 ExprEffect Visit##type (clang::type* expr, const Environment& env)
600 595
601 #define IGNORE_EXPR(type) \ 596 #define IGNORE_EXPR(type) \
602 ExprEffect Visit##type (clang::type* expr, const Environment& env) { \ 597 ExprEffect Visit##type (clang::type* expr, const Environment& env) { \
603 return ExprEffect::None(); \ 598 return ExprEffect::None(); \
604 } 599 }
605 600
606 IGNORE_EXPR(AddrLabelExpr); 601 IGNORE_EXPR(AddrLabelExpr);
607 IGNORE_EXPR(BinaryTypeTraitExpr);
608 IGNORE_EXPR(BlockExpr); 602 IGNORE_EXPR(BlockExpr);
609 IGNORE_EXPR(CharacterLiteral); 603 IGNORE_EXPR(CharacterLiteral);
610 IGNORE_EXPR(ChooseExpr); 604 IGNORE_EXPR(ChooseExpr);
611 IGNORE_EXPR(CompoundLiteralExpr); 605 IGNORE_EXPR(CompoundLiteralExpr);
612 IGNORE_EXPR(CXXBoolLiteralExpr); 606 IGNORE_EXPR(CXXBoolLiteralExpr);
613 IGNORE_EXPR(CXXDependentScopeMemberExpr); 607 IGNORE_EXPR(CXXDependentScopeMemberExpr);
614 IGNORE_EXPR(CXXNullPtrLiteralExpr); 608 IGNORE_EXPR(CXXNullPtrLiteralExpr);
615 IGNORE_EXPR(CXXPseudoDestructorExpr); 609 IGNORE_EXPR(CXXPseudoDestructorExpr);
616 IGNORE_EXPR(CXXScalarValueInitExpr); 610 IGNORE_EXPR(CXXScalarValueInitExpr);
617 IGNORE_EXPR(CXXNoexceptExpr); 611 IGNORE_EXPR(CXXNoexceptExpr);
618 IGNORE_EXPR(CXXTypeidExpr); 612 IGNORE_EXPR(CXXTypeidExpr);
619 IGNORE_EXPR(CXXUnresolvedConstructExpr); 613 IGNORE_EXPR(CXXUnresolvedConstructExpr);
620 IGNORE_EXPR(CXXUuidofExpr); 614 IGNORE_EXPR(CXXUuidofExpr);
621 IGNORE_EXPR(DependentScopeDeclRefExpr); 615 IGNORE_EXPR(DependentScopeDeclRefExpr);
622 IGNORE_EXPR(DesignatedInitExpr); 616 IGNORE_EXPR(DesignatedInitExpr);
623 IGNORE_EXPR(ExtVectorElementExpr); 617 IGNORE_EXPR(ExtVectorElementExpr);
624 IGNORE_EXPR(FloatingLiteral); 618 IGNORE_EXPR(FloatingLiteral);
625 IGNORE_EXPR(ImaginaryLiteral); 619 IGNORE_EXPR(ImaginaryLiteral);
626 IGNORE_EXPR(IntegerLiteral); 620 IGNORE_EXPR(IntegerLiteral);
627 IGNORE_EXPR(OffsetOfExpr); 621 IGNORE_EXPR(OffsetOfExpr);
628 IGNORE_EXPR(ImplicitValueInitExpr); 622 IGNORE_EXPR(ImplicitValueInitExpr);
629 IGNORE_EXPR(PackExpansionExpr); 623 IGNORE_EXPR(PackExpansionExpr);
630 IGNORE_EXPR(PredefinedExpr); 624 IGNORE_EXPR(PredefinedExpr);
631 IGNORE_EXPR(ShuffleVectorExpr); 625 IGNORE_EXPR(ShuffleVectorExpr);
632 IGNORE_EXPR(SizeOfPackExpr); 626 IGNORE_EXPR(SizeOfPackExpr);
633 IGNORE_EXPR(StmtExpr); 627 IGNORE_EXPR(StmtExpr);
634 IGNORE_EXPR(StringLiteral); 628 IGNORE_EXPR(StringLiteral);
635 IGNORE_EXPR(SubstNonTypeTemplateParmPackExpr); 629 IGNORE_EXPR(SubstNonTypeTemplateParmPackExpr);
636 IGNORE_EXPR(UnaryTypeTraitExpr); 630 IGNORE_EXPR(TypeTraitExpr);
637 IGNORE_EXPR(VAArgExpr); 631 IGNORE_EXPR(VAArgExpr);
638 IGNORE_EXPR(GNUNullExpr); 632 IGNORE_EXPR(GNUNullExpr);
639 IGNORE_EXPR(OverloadExpr); 633 IGNORE_EXPR(OverloadExpr);
640 634
641 DECL_VISIT_EXPR(CXXThisExpr) { 635 DECL_VISIT_EXPR(CXXThisExpr) {
642 return Use(expr, expr->getType(), THIS, env); 636 return Use(expr, expr->getType(), THIS, env);
643 } 637 }
644 638
645 DECL_VISIT_EXPR(AbstractConditionalOperator) { 639 DECL_VISIT_EXPR(AbstractConditionalOperator) {
646 Environment after_cond = env.ApplyEffect(VisitExpr(expr->getCond(), env)); 640 Environment after_cond = env.ApplyEffect(VisitExpr(expr->getCond(), env));
647 return ExprEffect::Merge(VisitExpr(expr->getTrueExpr(), after_cond), 641 return ExprEffect::Merge(VisitExpr(expr->getTrueExpr(), after_cond),
648 VisitExpr(expr->getFalseExpr(), after_cond)); 642 VisitExpr(expr->getFalseExpr(), after_cond));
649 } 643 }
650 644
651 DECL_VISIT_EXPR(ArraySubscriptExpr) { 645 DECL_VISIT_EXPR(ArraySubscriptExpr) {
652 clang::Expr* exprs[2] = {expr->getBase(), expr->getIdx()}; 646 clang::Expr* exprs[2] = {expr->getBase(), expr->getIdx()};
653 return Par(expr, 2, exprs, env); 647 return Par(expr, 2, exprs, env);
654 } 648 }
655 649
656 bool IsRawPointerVar(clang::Expr* expr, std::string* var_name) { 650 bool IsRawPointerVar(clang::Expr* expr, std::string* var_name) {
657 if (isa<clang::BlockDeclRefExpr>(expr)) { 651 if (llvm::isa<clang::DeclRefExpr>(expr)) {
658 *var_name = cast<clang::BlockDeclRefExpr>(expr)->getDecl()-> 652 *var_name =
659 getNameAsString(); 653 llvm::cast<clang::DeclRefExpr>(expr)->getDecl()->getNameAsString();
660 return true;
661 } else if (isa<clang::DeclRefExpr>(expr)) {
662 *var_name = cast<clang::DeclRefExpr>(expr)->getDecl()->getNameAsString();
663 return true; 654 return true;
664 } 655 }
665 return false; 656 return false;
666 } 657 }
667 658
668 DECL_VISIT_EXPR(BinaryOperator) { 659 DECL_VISIT_EXPR(BinaryOperator) {
669 clang::Expr* lhs = expr->getLHS(); 660 clang::Expr* lhs = expr->getLHS();
670 clang::Expr* rhs = expr->getRHS(); 661 clang::Expr* rhs = expr->getRHS();
671 clang::Expr* exprs[2] = {lhs, rhs}; 662 clang::Expr* exprs[2] = {lhs, rhs};
672 663
(...skipping 27 matching lines...) Expand all
700 } 691 }
701 692
702 DECL_VISIT_EXPR(CXXDefaultArgExpr) { 693 DECL_VISIT_EXPR(CXXDefaultArgExpr) {
703 return VisitExpr(expr->getExpr(), env); 694 return VisitExpr(expr->getExpr(), env);
704 } 695 }
705 696
706 DECL_VISIT_EXPR(CXXDeleteExpr) { 697 DECL_VISIT_EXPR(CXXDeleteExpr) {
707 return VisitExpr(expr->getArgument(), env); 698 return VisitExpr(expr->getArgument(), env);
708 } 699 }
709 700
710 DECL_VISIT_EXPR(CXXNewExpr) { 701 DECL_VISIT_EXPR(CXXNewExpr) { return VisitExpr(expr->getInitializer(), env); }
711 return Par(expr,
712 expr->getNumConstructorArgs(),
713 expr->getConstructorArgs(),
714 env);
715 }
716 702
717 DECL_VISIT_EXPR(ExprWithCleanups) { 703 DECL_VISIT_EXPR(ExprWithCleanups) {
718 return VisitExpr(expr->getSubExpr(), env); 704 return VisitExpr(expr->getSubExpr(), env);
719 } 705 }
720 706
721 DECL_VISIT_EXPR(CXXThrowExpr) { 707 DECL_VISIT_EXPR(CXXThrowExpr) {
722 return VisitExpr(expr->getSubExpr(), env); 708 return VisitExpr(expr->getSubExpr(), env);
723 } 709 }
724 710
725 DECL_VISIT_EXPR(InitListExpr) { 711 DECL_VISIT_EXPR(InitListExpr) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 } 745 }
760 746
761 DECL_VISIT_EXPR(CastExpr) { 747 DECL_VISIT_EXPR(CastExpr) {
762 return VisitExpr(expr->getSubExpr(), env); 748 return VisitExpr(expr->getSubExpr(), env);
763 } 749 }
764 750
765 DECL_VISIT_EXPR(DeclRefExpr) { 751 DECL_VISIT_EXPR(DeclRefExpr) {
766 return Use(expr, expr->getDecl(), env); 752 return Use(expr, expr->getDecl(), env);
767 } 753 }
768 754
769 DECL_VISIT_EXPR(BlockDeclRefExpr) {
770 return Use(expr, expr->getDecl(), env);
771 }
772
773 ExprEffect Par(clang::Expr* parent, 755 ExprEffect Par(clang::Expr* parent,
774 int n, 756 int n,
775 clang::Expr** exprs, 757 clang::Expr** exprs,
776 const Environment& env) { 758 const Environment& env) {
777 CallProps props; 759 CallProps props;
778 760
779 for (int i = 0; i < n; ++i) { 761 for (int i = 0; i < n; ++i) {
780 props.SetEffect(i, VisitExpr(exprs[i], env)); 762 props.SetEffect(i, VisitExpr(exprs[i], env));
781 } 763 }
782 764
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 props->SetEffect(arg + 1, VisitExpr(call->getArg(arg), env)); 819 props->SetEffect(arg + 1, VisitExpr(call->getArg(arg), env));
838 } 820 }
839 } 821 }
840 822
841 823
842 ExprEffect VisitCallExpr(clang::CallExpr* call, 824 ExprEffect VisitCallExpr(clang::CallExpr* call,
843 const Environment& env) { 825 const Environment& env) {
844 CallProps props; 826 CallProps props;
845 827
846 clang::CXXMemberCallExpr* memcall = 828 clang::CXXMemberCallExpr* memcall =
847 dyn_cast_or_null<clang::CXXMemberCallExpr>(call); 829 llvm::dyn_cast_or_null<clang::CXXMemberCallExpr>(call);
848 if (memcall != NULL) { 830 if (memcall != NULL) {
849 clang::Expr* receiver = memcall->getImplicitObjectArgument(); 831 clang::Expr* receiver = memcall->getImplicitObjectArgument();
850 props.SetEffect(0, VisitExpr(receiver, env)); 832 props.SetEffect(0, VisitExpr(receiver, env));
851 } 833 }
852 834
853 VisitArguments<>(call, &props, env); 835 VisitArguments<>(call, &props, env);
854 836
855 if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); 837 if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG);
856 838
857 ExprEffect out = 839 ExprEffect out =
858 props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); 840 props.ComputeCumulativeEffect(IsRawPointerType(call->getType()));
859 841
860 clang::FunctionDecl* callee = call->getDirectCallee(); 842 clang::FunctionDecl* callee = call->getDirectCallee();
861 if ((callee != NULL) && KnownToCauseGC(ctx_, callee)) { 843 if ((callee != NULL) && KnownToCauseGC(ctx_, callee)) {
862 out.setGC(); 844 out.setGC();
863 } 845 }
864 846
865 return out; 847 return out;
866 } 848 }
867 849
868 // -------------------------------------------------------------------------- 850 // --------------------------------------------------------------------------
869 // Statements 851 // Statements
870 // -------------------------------------------------------------------------- 852 // --------------------------------------------------------------------------
871 853
872 Environment VisitStmt(clang::Stmt* stmt, const Environment& env) { 854 Environment VisitStmt(clang::Stmt* stmt, const Environment& env) {
873 #define VISIT(type) do { \ 855 #define VISIT(type) \
874 clang::type* concrete_stmt = dyn_cast_or_null<clang::type>(stmt); \ 856 do { \
875 if (concrete_stmt != NULL) { \ 857 clang::type* concrete_stmt = llvm::dyn_cast_or_null<clang::type>(stmt); \
876 return Visit##type (concrete_stmt, env); \ 858 if (concrete_stmt != NULL) { \
877 } \ 859 return Visit##type(concrete_stmt, env); \
878 } while(0); 860 } \
861 } while (0);
879 862
880 if (clang::Expr* expr = dyn_cast_or_null<clang::Expr>(stmt)) { 863 if (clang::Expr* expr = llvm::dyn_cast_or_null<clang::Expr>(stmt)) {
881 return env.ApplyEffect(VisitExpr(expr, env)); 864 return env.ApplyEffect(VisitExpr(expr, env));
882 } 865 }
883 866
884 VISIT(AsmStmt); 867 VISIT(AsmStmt);
885 VISIT(BreakStmt); 868 VISIT(BreakStmt);
886 VISIT(CompoundStmt); 869 VISIT(CompoundStmt);
887 VISIT(ContinueStmt); 870 VISIT(ContinueStmt);
888 VISIT(CXXCatchStmt); 871 VISIT(CXXCatchStmt);
889 VISIT(CXXTryStmt); 872 VISIT(CXXTryStmt);
890 VISIT(DeclStmt); 873 VISIT(DeclStmt);
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 } 1054 }
1072 1055
1073 DECL_VISIT_STMT(ReturnStmt) { 1056 DECL_VISIT_STMT(ReturnStmt) {
1074 VisitExpr(stmt->getRetValue(), env); 1057 VisitExpr(stmt->getRetValue(), env);
1075 return Environment::Unreachable(); 1058 return Environment::Unreachable();
1076 } 1059 }
1077 1060
1078 const clang::TagType* ToTagType(const clang::Type* t) { 1061 const clang::TagType* ToTagType(const clang::Type* t) {
1079 if (t == NULL) { 1062 if (t == NULL) {
1080 return NULL; 1063 return NULL;
1081 } else if (isa<clang::TagType>(t)) { 1064 } else if (llvm::isa<clang::TagType>(t)) {
1082 return cast<clang::TagType>(t); 1065 return llvm::cast<clang::TagType>(t);
1083 } else if (isa<clang::SubstTemplateTypeParmType>(t)) { 1066 } else if (llvm::isa<clang::SubstTemplateTypeParmType>(t)) {
1084 return ToTagType(cast<clang::SubstTemplateTypeParmType>(t)-> 1067 return ToTagType(llvm::cast<clang::SubstTemplateTypeParmType>(t)
1085 getReplacementType().getTypePtr()); 1068 ->getReplacementType()
1069 .getTypePtr());
1086 } else { 1070 } else {
1087 return NULL; 1071 return NULL;
1088 } 1072 }
1089 } 1073 }
1090 1074
1091 bool IsDerivedFrom(clang::CXXRecordDecl* record, 1075 bool IsDerivedFrom(clang::CXXRecordDecl* record,
1092 clang::CXXRecordDecl* base) { 1076 clang::CXXRecordDecl* base) {
1093 return (record == base) || record->isDerivedFrom(base); 1077 return (record == base) || record->isDerivedFrom(base);
1094 } 1078 }
1095 1079
1096 bool IsRawPointerType(clang::QualType qtype) { 1080 bool IsRawPointerType(clang::QualType qtype) {
1097 const clang::PointerType* type = 1081 const clang::PointerType* type =
1098 dyn_cast_or_null<clang::PointerType>(qtype.getTypePtrOrNull()); 1082 llvm::dyn_cast_or_null<clang::PointerType>(qtype.getTypePtrOrNull());
1099 if (type == NULL) return false; 1083 if (type == NULL) return false;
1100 1084
1101 const clang::TagType* pointee = 1085 const clang::TagType* pointee =
1102 ToTagType(type->getPointeeType().getTypePtr()); 1086 ToTagType(type->getPointeeType().getTypePtr());
1103 if (pointee == NULL) return false; 1087 if (pointee == NULL) return false;
1104 1088
1105 clang::CXXRecordDecl* record = 1089 clang::CXXRecordDecl* record =
1106 dyn_cast_or_null<clang::CXXRecordDecl>(pointee->getDecl()); 1090 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(pointee->getDecl());
1107 if (record == NULL) return false; 1091 if (record == NULL) return false;
1108 1092
1109 if (!InV8Namespace(record)) return false; 1093 if (!InV8Namespace(record)) return false;
1110 1094
1111 if (!record->hasDefinition()) return false; 1095 if (!record->hasDefinition()) return false;
1112 1096
1113 record = record->getDefinition(); 1097 record = record->getDefinition();
1114 1098
1115 return IsDerivedFrom(record, object_decl_) && 1099 return IsDerivedFrom(record, object_decl_) &&
1116 !IsDerivedFrom(record, smi_decl_); 1100 !IsDerivedFrom(record, smi_decl_);
1117 } 1101 }
1118 1102
1119 Environment VisitDecl(clang::Decl* decl, const Environment& env) { 1103 Environment VisitDecl(clang::Decl* decl, const Environment& env) {
1120 if (clang::VarDecl* var = dyn_cast<clang::VarDecl>(decl)) { 1104 if (clang::VarDecl* var = llvm::dyn_cast<clang::VarDecl>(decl)) {
1121 Environment out = var->hasInit() ? VisitStmt(var->getInit(), env) : env; 1105 Environment out = var->hasInit() ? VisitStmt(var->getInit(), env) : env;
1122 1106
1123 if (IsRawPointerType(var->getType())) { 1107 if (IsRawPointerType(var->getType())) {
1124 out = out.Define(var->getNameAsString()); 1108 out = out.Define(var->getNameAsString());
1125 } 1109 }
1126 1110
1127 return out; 1111 return out;
1128 } 1112 }
1129 // TODO: handle other declarations? 1113 // TODO: handle other declarations?
1130 return env; 1114 return env;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 return parent; 1154 return parent;
1171 } 1155 }
1172 1156
1173 void LeaveBlock(Block* block) { 1157 void LeaveBlock(Block* block) {
1174 block_ = block; 1158 block_ = block;
1175 } 1159 }
1176 1160
1177 private: 1161 private:
1178 void ReportUnsafe(const clang::Expr* expr, const std::string& msg) { 1162 void ReportUnsafe(const clang::Expr* expr, const std::string& msg) {
1179 d_.Report(clang::FullSourceLoc(expr->getExprLoc(), sm_), 1163 d_.Report(clang::FullSourceLoc(expr->getExprLoc(), sm_),
1180 d_.getCustomDiagID(clang::Diagnostic::Warning, msg)); 1164 d_.getCustomDiagID(clang::DiagnosticsEngine::Warning, "%0"))
1165 << msg;
1181 } 1166 }
1182 1167
1183 1168
1184 clang::MangleContext* ctx_; 1169 clang::MangleContext* ctx_;
1185 clang::DeclarationName handle_decl_name_; 1170 clang::DeclarationName handle_decl_name_;
1186 clang::CXXRecordDecl* object_decl_; 1171 clang::CXXRecordDecl* object_decl_;
1187 clang::CXXRecordDecl* smi_decl_; 1172 clang::CXXRecordDecl* smi_decl_;
1188 1173
1189 clang::Diagnostic& d_; 1174 clang::DiagnosticsEngine& d_;
1190 clang::SourceManager& sm_; 1175 clang::SourceManager& sm_;
1191 1176
1192 Block* block_; 1177 Block* block_;
1193 bool dead_vars_analysis_; 1178 bool dead_vars_analysis_;
1194 }; 1179 };
1195 1180
1196 1181
1197 class ProblemsFinder : public clang::ASTConsumer, 1182 class ProblemsFinder : public clang::ASTConsumer,
1198 public clang::RecursiveASTVisitor<ProblemsFinder> { 1183 public clang::RecursiveASTVisitor<ProblemsFinder> {
1199 public: 1184 public:
1200 ProblemsFinder(clang::Diagnostic& d, 1185 ProblemsFinder(clang::DiagnosticsEngine& d, clang::SourceManager& sm,
1201 clang::SourceManager& sm,
1202 const std::vector<std::string>& args) 1186 const std::vector<std::string>& args)
1203 : d_(d), sm_(sm), dead_vars_analysis_(false) { 1187 : d_(d), sm_(sm), dead_vars_analysis_(false) {
1204 for (unsigned i = 0; i < args.size(); ++i) { 1188 for (unsigned i = 0; i < args.size(); ++i) {
1205 if (args[i] == "--dead-vars") { 1189 if (args[i] == "--dead-vars") {
1206 dead_vars_analysis_ = true; 1190 dead_vars_analysis_ = true;
1207 } 1191 }
1208 } 1192 }
1209 } 1193 }
1210 1194
1211 virtual void HandleTranslationUnit(clang::ASTContext &ctx) { 1195 virtual void HandleTranslationUnit(clang::ASTContext &ctx) {
1212 Resolver r(ctx); 1196 Resolver r(ctx);
1213 1197
1214 clang::CXXRecordDecl* object_decl = 1198 clang::CXXRecordDecl* object_decl =
1215 r.ResolveNamespace("v8").ResolveNamespace("internal"). 1199 r.ResolveNamespace("v8").ResolveNamespace("internal").
1216 Resolve<clang::CXXRecordDecl>("Object"); 1200 Resolve<clang::CXXRecordDecl>("Object");
1217 1201
1218 clang::CXXRecordDecl* smi_decl = 1202 clang::CXXRecordDecl* smi_decl =
1219 r.ResolveNamespace("v8").ResolveNamespace("internal"). 1203 r.ResolveNamespace("v8").ResolveNamespace("internal").
1220 Resolve<clang::CXXRecordDecl>("Smi"); 1204 Resolve<clang::CXXRecordDecl>("Smi");
1221 1205
1222 if (object_decl != NULL) object_decl = object_decl->getDefinition(); 1206 if (object_decl != NULL) object_decl = object_decl->getDefinition();
1223 1207
1224 if (smi_decl != NULL) smi_decl = smi_decl->getDefinition(); 1208 if (smi_decl != NULL) smi_decl = smi_decl->getDefinition();
1225 1209
1226 if (object_decl != NULL && smi_decl != NULL) { 1210 if (object_decl != NULL && smi_decl != NULL) {
1227 function_analyzer_ = 1211 function_analyzer_ = new FunctionAnalyzer(
1228 new FunctionAnalyzer(clang::createItaniumMangleContext(ctx, d_), 1212 clang::ItaniumMangleContext::create(ctx, d_), r.ResolveName("Handle"),
1229 r.ResolveName("Handle"), 1213 object_decl, smi_decl, d_, sm_, dead_vars_analysis_);
1230 object_decl,
1231 smi_decl,
1232 d_,
1233 sm_,
1234 dead_vars_analysis_);
1235 TraverseDecl(ctx.getTranslationUnitDecl()); 1214 TraverseDecl(ctx.getTranslationUnitDecl());
1236 } else { 1215 } else {
1237 if (object_decl == NULL) { 1216 if (object_decl == NULL) {
1238 llvm::errs() << "Failed to resolve v8::internal::Object\n"; 1217 llvm::errs() << "Failed to resolve v8::internal::Object\n";
1239 } 1218 }
1240 if (smi_decl == NULL) { 1219 if (smi_decl == NULL) {
1241 llvm::errs() << "Failed to resolve v8::internal::Smi\n"; 1220 llvm::errs() << "Failed to resolve v8::internal::Smi\n";
1242 } 1221 }
1243 } 1222 }
1244 } 1223 }
1245 1224
1246 virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { 1225 virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) {
1247 function_analyzer_->AnalyzeFunction(decl); 1226 function_analyzer_->AnalyzeFunction(decl);
1248 return true; 1227 return true;
1249 } 1228 }
1250 1229
1251 private: 1230 private:
1252 clang::Diagnostic& d_; 1231 clang::DiagnosticsEngine& d_;
1253 clang::SourceManager& sm_; 1232 clang::SourceManager& sm_;
1254 bool dead_vars_analysis_; 1233 bool dead_vars_analysis_;
1255 1234
1256 FunctionAnalyzer* function_analyzer_; 1235 FunctionAnalyzer* function_analyzer_;
1257 }; 1236 };
1258 1237
1259 1238
1260 template<typename ConsumerType> 1239 template<typename ConsumerType>
1261 class Action : public clang::PluginASTAction { 1240 class Action : public clang::PluginASTAction {
1262 protected: 1241 protected:
(...skipping 16 matching lines...) Expand all
1279 1258
1280 1259
1281 } 1260 }
1282 1261
1283 static clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> > 1262 static clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> >
1284 FindProblems("find-problems", "Find GC-unsafe places."); 1263 FindProblems("find-problems", "Find GC-unsafe places.");
1285 1264
1286 static clang::FrontendPluginRegistry::Add< 1265 static clang::FrontendPluginRegistry::Add<
1287 Action<FunctionDeclarationFinder> > 1266 Action<FunctionDeclarationFinder> >
1288 DumpCallees("dump-callees", "Dump callees for each function."); 1267 DumpCallees("dump-callees", "Dump callees for each function.");
OLDNEW
« no previous file with comments | « tools/gcmole/bootstrap.sh ('k') | tools/gcmole/gcmole.lua » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698