| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 // any namespace qualifiers. This is similar to desugaring, except that for | 59 // any namespace qualifiers. This is similar to desugaring, except that for |
| 60 // ElaboratedTypes, desugar will unwrap too much. | 60 // ElaboratedTypes, desugar will unwrap too much. |
| 61 const Type* UnwrapType(const Type* type) { | 61 const Type* UnwrapType(const Type* type) { |
| 62 if (const ElaboratedType* elaborated = dyn_cast<ElaboratedType>(type)) | 62 if (const ElaboratedType* elaborated = dyn_cast<ElaboratedType>(type)) |
| 63 return UnwrapType(elaborated->getNamedType().getTypePtr()); | 63 return UnwrapType(elaborated->getNamedType().getTypePtr()); |
| 64 if (const TypedefType* typedefed = dyn_cast<TypedefType>(type)) | 64 if (const TypedefType* typedefed = dyn_cast<TypedefType>(type)) |
| 65 return UnwrapType(typedefed->desugar().getTypePtr()); | 65 return UnwrapType(typedefed->desugar().getTypePtr()); |
| 66 return type; | 66 return type; |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool IsGtestTestFixture(const CXXRecordDecl* decl) { |
| 70 return decl->getQualifiedNameAsString() == "testing::Test"; |
| 71 } |
| 72 |
| 69 FixItHint FixItRemovalForVirtual(const SourceManager& manager, | 73 FixItHint FixItRemovalForVirtual(const SourceManager& manager, |
| 70 const CXXMethodDecl* method) { | 74 const CXXMethodDecl* method) { |
| 71 // Unfortunately, there doesn't seem to be a good way to determine the | 75 // Unfortunately, there doesn't seem to be a good way to determine the |
| 72 // location of the 'virtual' keyword. It's available in Declarator, but that | 76 // location of the 'virtual' keyword. It's available in Declarator, but that |
| 73 // isn't accessible from the AST. So instead, make an educated guess that the | 77 // isn't accessible from the AST. So instead, make an educated guess that the |
| 74 // first token is probably the virtual keyword. Strictly speaking, this | 78 // first token is probably the virtual keyword. Strictly speaking, this |
| 75 // doesn't have to be true, but it probably will be. | 79 // doesn't have to be true, but it probably will be. |
| 76 // TODO(dcheng): Add a warning to force virtual to always appear first ;-) | 80 // TODO(dcheng): Add a warning to force virtual to always appear first ;-) |
| 77 SourceRange range(method->getLocStart()); | 81 SourceRange range(method->getLocStart()); |
| 78 // Get the spelling loc just in case it was expanded from a macro. | 82 // Get the spelling loc just in case it was expanded from a macro. |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 291 |
| 288 bool FindBadConstructsConsumer::IsMethodInBannedOrTestingNamespace( | 292 bool FindBadConstructsConsumer::IsMethodInBannedOrTestingNamespace( |
| 289 const CXXMethodDecl* method) { | 293 const CXXMethodDecl* method) { |
| 290 if (InBannedNamespace(method)) | 294 if (InBannedNamespace(method)) |
| 291 return true; | 295 return true; |
| 292 for (CXXMethodDecl::method_iterator i = method->begin_overridden_methods(); | 296 for (CXXMethodDecl::method_iterator i = method->begin_overridden_methods(); |
| 293 i != method->end_overridden_methods(); | 297 i != method->end_overridden_methods(); |
| 294 ++i) { | 298 ++i) { |
| 295 const CXXMethodDecl* overridden = *i; | 299 const CXXMethodDecl* overridden = *i; |
| 296 if (IsMethodInBannedOrTestingNamespace(overridden) || | 300 if (IsMethodInBannedOrTestingNamespace(overridden) || |
| 297 InTestingNamespace(overridden)) { | 301 // Provide an exception for ::testing::Test. gtest itself uses some |
| 302 // magic to try to make sure SetUp()/TearDown() aren't capitalized |
| 303 // incorrectly, but having the plugin enforce override is also nice. |
| 304 (InTestingNamespace(overridden) && |
| 305 (!options_.strict_virtual_specifiers || |
| 306 !IsGtestTestFixture(overridden->getParent())))) { |
| 298 return true; | 307 return true; |
| 299 } | 308 } |
| 300 } | 309 } |
| 301 | 310 |
| 302 return false; | 311 return false; |
| 303 } | 312 } |
| 304 | 313 |
| 305 // Checks that virtual methods are correctly annotated, and have no body in a | 314 // Checks that virtual methods are correctly annotated, and have no body in a |
| 306 // header file. | 315 // header file. |
| 307 void FindBadConstructsConsumer::CheckVirtualMethods( | 316 void FindBadConstructsConsumer::CheckVirtualMethods( |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 record->getTypeForDecl()->getAsCXXRecordDecl()) { | 743 record->getTypeForDecl()->getAsCXXRecordDecl()) { |
| 735 weak_ptr_factory_location = iter->getLocation(); | 744 weak_ptr_factory_location = iter->getLocation(); |
| 736 } | 745 } |
| 737 } | 746 } |
| 738 } | 747 } |
| 739 } | 748 } |
| 740 } | 749 } |
| 741 } | 750 } |
| 742 | 751 |
| 743 } // namespace chrome_checker | 752 } // namespace chrome_checker |
| OLD | NEW |