OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "FindBadConstructsConsumer.h" | 5 #include "FindBadConstructsConsumer.h" |
6 | 6 |
7 #include "clang/Frontend/CompilerInstance.h" | 7 #include "clang/Frontend/CompilerInstance.h" |
8 #include "clang/AST/Attr.h" | 8 #include "clang/AST/Attr.h" |
9 #include "clang/Lex/Lexer.h" | 9 #include "clang/Lex/Lexer.h" |
10 #include "llvm/Support/raw_ostream.h" | 10 #include "llvm/Support/raw_ostream.h" |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 CXXRecordDecl* record) { | 717 CXXRecordDecl* record) { |
718 // Skip anonymous structs. | 718 // Skip anonymous structs. |
719 if (record->getIdentifier() == NULL) | 719 if (record->getIdentifier() == NULL) |
720 return; | 720 return; |
721 | 721 |
722 // Iterate through members of the class. | 722 // Iterate through members of the class. |
723 RecordDecl::field_iterator iter(record->field_begin()), | 723 RecordDecl::field_iterator iter(record->field_begin()), |
724 the_end(record->field_end()); | 724 the_end(record->field_end()); |
725 SourceLocation weak_ptr_factory_location; // Invalid initially. | 725 SourceLocation weak_ptr_factory_location; // Invalid initially. |
726 for (; iter != the_end; ++iter) { | 726 for (; iter != the_end; ++iter) { |
727 // If we enter the loop but have already seen a matching WeakPtrFactory, | |
728 // it means there is at least one member after the factory. | |
729 if (weak_ptr_factory_location.isValid()) { | |
730 diagnostic().Report(weak_ptr_factory_location, | |
731 diag_weak_ptr_factory_order_); | |
732 } | |
733 const TemplateSpecializationType* template_spec_type = | 727 const TemplateSpecializationType* template_spec_type = |
734 iter->getType().getTypePtr()->getAs<TemplateSpecializationType>(); | 728 iter->getType().getTypePtr()->getAs<TemplateSpecializationType>(); |
| 729 bool param_is_weak_ptr_factory_to_self = false; |
735 if (template_spec_type) { | 730 if (template_spec_type) { |
736 const TemplateDecl* template_decl = | 731 const TemplateDecl* template_decl = |
737 template_spec_type->getTemplateName().getAsTemplateDecl(); | 732 template_spec_type->getTemplateName().getAsTemplateDecl(); |
738 if (template_decl && template_spec_type->getNumArgs() >= 1) { | 733 if (template_decl && template_spec_type->getNumArgs() == 1) { |
739 if (template_decl->getNameAsString().compare("WeakPtrFactory") == 0 && | 734 if (template_decl->getNameAsString().compare("WeakPtrFactory") == 0 && |
740 GetNamespace(template_decl) == "base") { | 735 GetNamespace(template_decl) == "base") { |
| 736 // Only consider WeakPtrFactory members which are specialized for the |
| 737 // owning class. |
741 const TemplateArgument& arg = template_spec_type->getArg(0); | 738 const TemplateArgument& arg = template_spec_type->getArg(0); |
742 if (arg.getAsType().getTypePtr()->getAsCXXRecordDecl() == | 739 if (arg.getAsType().getTypePtr()->getAsCXXRecordDecl() == |
743 record->getTypeForDecl()->getAsCXXRecordDecl()) { | 740 record->getTypeForDecl()->getAsCXXRecordDecl()) { |
744 weak_ptr_factory_location = iter->getLocation(); | 741 if (!weak_ptr_factory_location.isValid()) { |
| 742 // Save the first matching WeakPtrFactory member for the |
| 743 // diagnostic. |
| 744 weak_ptr_factory_location = iter->getLocation(); |
| 745 } |
| 746 param_is_weak_ptr_factory_to_self = true; |
745 } | 747 } |
746 } | 748 } |
747 } | 749 } |
748 } | 750 } |
| 751 // If we've already seen a WeakPtrFactory<OwningType> and this param is not |
| 752 // one of those, it means there is at least one member after a factory. |
| 753 if (weak_ptr_factory_location.isValid() && |
| 754 !param_is_weak_ptr_factory_to_self) { |
| 755 diagnostic().Report(weak_ptr_factory_location, |
| 756 diag_weak_ptr_factory_order_); |
| 757 } |
749 } | 758 } |
750 } | 759 } |
751 | 760 |
752 } // namespace chrome_checker | 761 } // namespace chrome_checker |
OLD | NEW |