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 |