| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 return true; | 324 return true; |
| 325 for (CXXMethodDecl::method_iterator i = method->begin_overridden_methods(); | 325 for (CXXMethodDecl::method_iterator i = method->begin_overridden_methods(); |
| 326 i != method->end_overridden_methods(); | 326 i != method->end_overridden_methods(); |
| 327 ++i) { | 327 ++i) { |
| 328 const CXXMethodDecl* overridden = *i; | 328 const CXXMethodDecl* overridden = *i; |
| 329 if (IsMethodInBannedOrTestingNamespace(overridden) || | 329 if (IsMethodInBannedOrTestingNamespace(overridden) || |
| 330 // Provide an exception for ::testing::Test. gtest itself uses some | 330 // Provide an exception for ::testing::Test. gtest itself uses some |
| 331 // magic to try to make sure SetUp()/TearDown() aren't capitalized | 331 // magic to try to make sure SetUp()/TearDown() aren't capitalized |
| 332 // incorrectly, but having the plugin enforce override is also nice. | 332 // incorrectly, but having the plugin enforce override is also nice. |
| 333 (InTestingNamespace(overridden) && | 333 (InTestingNamespace(overridden) && |
| 334 (!options_.strict_virtual_specifiers || | 334 !IsGtestTestFixture(overridden->getParent()))) { |
| 335 !IsGtestTestFixture(overridden->getParent())))) { | |
| 336 return true; | 335 return true; |
| 337 } | 336 } |
| 338 } | 337 } |
| 339 | 338 |
| 340 return false; | 339 return false; |
| 341 } | 340 } |
| 342 | 341 |
| 343 // Checks that virtual methods are correctly annotated, and have no body in a | 342 // Checks that virtual methods are correctly annotated, and have no body in a |
| 344 // header file. | 343 // header file. |
| 345 void FindBadConstructsConsumer::CheckVirtualMethods( | 344 void FindBadConstructsConsumer::CheckVirtualMethods( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 // virtual method overrides a method from a base class, only the override | 385 // virtual method overrides a method from a base class, only the override |
| 387 // specifier should be used. If the method should not be overridden by derived | 386 // specifier should be used. If the method should not be overridden by derived |
| 388 // classes, only the final specifier should be used. | 387 // classes, only the final specifier should be used. |
| 389 void FindBadConstructsConsumer::CheckVirtualSpecifiers( | 388 void FindBadConstructsConsumer::CheckVirtualSpecifiers( |
| 390 const CXXMethodDecl* method) { | 389 const CXXMethodDecl* method) { |
| 391 bool is_override = method->size_overridden_methods() > 0; | 390 bool is_override = method->size_overridden_methods() > 0; |
| 392 bool has_virtual = method->isVirtualAsWritten(); | 391 bool has_virtual = method->isVirtualAsWritten(); |
| 393 OverrideAttr* override_attr = method->getAttr<OverrideAttr>(); | 392 OverrideAttr* override_attr = method->getAttr<OverrideAttr>(); |
| 394 FinalAttr* final_attr = method->getAttr<FinalAttr>(); | 393 FinalAttr* final_attr = method->getAttr<FinalAttr>(); |
| 395 | 394 |
| 396 if (method->isPure() && !options_.strict_virtual_specifiers) | |
| 397 return; | |
| 398 | |
| 399 if (IsMethodInBannedOrTestingNamespace(method)) | 395 if (IsMethodInBannedOrTestingNamespace(method)) |
| 400 return; | 396 return; |
| 401 | 397 |
| 402 if (isa<CXXDestructorDecl>(method) && !options_.strict_virtual_specifiers) | |
| 403 return; | |
| 404 | |
| 405 SourceManager& manager = instance().getSourceManager(); | 398 SourceManager& manager = instance().getSourceManager(); |
| 406 | 399 |
| 407 // Complain if a method is annotated virtual && (override || final). | 400 // Complain if a method is annotated virtual && (override || final). |
| 408 if (has_virtual && (override_attr || final_attr) && | 401 if (has_virtual && (override_attr || final_attr)) { |
| 409 options_.strict_virtual_specifiers) { | |
| 410 diagnostic().Report(method->getLocStart(), | 402 diagnostic().Report(method->getLocStart(), |
| 411 diag_redundant_virtual_specifier_) | 403 diag_redundant_virtual_specifier_) |
| 412 << "'virtual'" | 404 << "'virtual'" |
| 413 << (override_attr ? static_cast<Attr*>(override_attr) : final_attr) | 405 << (override_attr ? static_cast<Attr*>(override_attr) : final_attr) |
| 414 << FixItRemovalForVirtual(manager, method); | 406 << FixItRemovalForVirtual(manager, method); |
| 415 } | 407 } |
| 416 | 408 |
| 417 // Complain if a method is an override and is not annotated with override or | 409 // Complain if a method is an override and is not annotated with override or |
| 418 // final. | 410 // final. |
| 419 if (is_override && !override_attr && !final_attr) { | 411 if (is_override && !override_attr && !final_attr) { |
| 420 SourceRange type_info_range = | 412 SourceRange type_info_range = |
| 421 method->getTypeSourceInfo()->getTypeLoc().getSourceRange(); | 413 method->getTypeSourceInfo()->getTypeLoc().getSourceRange(); |
| 422 FullSourceLoc loc(type_info_range.getBegin(), manager); | 414 FullSourceLoc loc(type_info_range.getBegin(), manager); |
| 423 | 415 |
| 424 // Build the FixIt insertion point after the end of the method definition, | 416 // Build the FixIt insertion point after the end of the method definition, |
| 425 // including any const-qualifiers and attributes, and before the opening | 417 // including any const-qualifiers and attributes, and before the opening |
| 426 // of the l-curly-brace (if inline) or the semi-color (if a declaration). | 418 // of the l-curly-brace (if inline) or the semi-color (if a declaration). |
| 427 SourceLocation spelling_end = | 419 SourceLocation spelling_end = |
| 428 manager.getSpellingLoc(type_info_range.getEnd()); | 420 manager.getSpellingLoc(type_info_range.getEnd()); |
| 429 if (spelling_end.isValid()) { | 421 if (spelling_end.isValid()) { |
| 430 SourceLocation token_end = | 422 SourceLocation token_end = |
| 431 Lexer::getLocForEndOfToken(spelling_end, 0, manager, LangOptions()); | 423 Lexer::getLocForEndOfToken(spelling_end, 0, manager, LangOptions()); |
| 432 diagnostic().Report(token_end, diag_method_requires_override_) | 424 diagnostic().Report(token_end, diag_method_requires_override_) |
| 433 << FixItHint::CreateInsertion(token_end, " override"); | 425 << FixItHint::CreateInsertion(token_end, " override"); |
| 434 } else { | 426 } else { |
| 435 diagnostic().Report(loc, diag_method_requires_override_); | 427 diagnostic().Report(loc, diag_method_requires_override_); |
| 436 } | 428 } |
| 437 } | 429 } |
| 438 | 430 |
| 439 if (final_attr && override_attr && options_.strict_virtual_specifiers) { | 431 if (final_attr && override_attr) { |
| 440 diagnostic().Report(override_attr->getLocation(), | 432 diagnostic().Report(override_attr->getLocation(), |
| 441 diag_redundant_virtual_specifier_) | 433 diag_redundant_virtual_specifier_) |
| 442 << override_attr << final_attr | 434 << override_attr << final_attr |
| 443 << FixItHint::CreateRemoval(override_attr->getRange()); | 435 << FixItHint::CreateRemoval(override_attr->getRange()); |
| 444 } | 436 } |
| 445 | 437 |
| 446 if (final_attr && !is_override && options_.strict_virtual_specifiers) { | 438 if (final_attr && !is_override) { |
| 447 diagnostic().Report(method->getLocStart(), | 439 diagnostic().Report(method->getLocStart(), |
| 448 diag_base_method_virtual_and_final_) | 440 diag_base_method_virtual_and_final_) |
| 449 << FixItRemovalForVirtual(manager, method) | 441 << FixItRemovalForVirtual(manager, method) |
| 450 << FixItHint::CreateRemoval(final_attr->getRange()); | 442 << FixItHint::CreateRemoval(final_attr->getRange()); |
| 451 } | 443 } |
| 452 } | 444 } |
| 453 | 445 |
| 454 void FindBadConstructsConsumer::CheckVirtualBodies( | 446 void FindBadConstructsConsumer::CheckVirtualBodies( |
| 455 const CXXMethodDecl* method) { | 447 const CXXMethodDecl* method) { |
| 456 // Virtual methods should not have inline definitions beyond "{}". This | 448 // Virtual methods should not have inline definitions beyond "{}". This |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 // one of those, it means there is at least one member after a factory. | 773 // one of those, it means there is at least one member after a factory. |
| 782 if (weak_ptr_factory_location.isValid() && | 774 if (weak_ptr_factory_location.isValid() && |
| 783 !param_is_weak_ptr_factory_to_self) { | 775 !param_is_weak_ptr_factory_to_self) { |
| 784 diagnostic().Report(weak_ptr_factory_location, | 776 diagnostic().Report(weak_ptr_factory_location, |
| 785 diag_weak_ptr_factory_order_); | 777 diag_weak_ptr_factory_order_); |
| 786 } | 778 } |
| 787 } | 779 } |
| 788 } | 780 } |
| 789 | 781 |
| 790 } // namespace chrome_checker | 782 } // namespace chrome_checker |
| OLD | NEW |