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

Side by Side Diff: tools/clang/plugins/FindBadConstructsConsumer.cpp

Issue 951673002: Revert "Pull chromium at 2c3ffb2355a27c32f45e508ef861416b820c823b" (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « tools/clang/plugins/FindBadConstructsAction.cpp ('k') | tools/clang/plugins/Options.h » ('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 (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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 if (!record->hasUserDeclaredConstructor()) { 276 if (!record->hasUserDeclaredConstructor()) {
277 emitWarning(record_location, 277 emitWarning(record_location,
278 "Complex class/struct needs an explicit out-of-line " 278 "Complex class/struct needs an explicit out-of-line "
279 "constructor."); 279 "constructor.");
280 } else { 280 } else {
281 // Iterate across all the constructors in this file and yell if we 281 // Iterate across all the constructors in this file and yell if we
282 // find one that tries to be inline. 282 // find one that tries to be inline.
283 for (CXXRecordDecl::ctor_iterator it = record->ctor_begin(); 283 for (CXXRecordDecl::ctor_iterator it = record->ctor_begin();
284 it != record->ctor_end(); 284 it != record->ctor_end();
285 ++it) { 285 ++it) {
286 // The current check is buggy. An implicit copy constructor does not
287 // have an inline body, so this check never fires for classes with a
288 // user-declared out-of-line constructor.
289 if (it->hasInlineBody()) { 286 if (it->hasInlineBody()) {
290 if (it->isCopyConstructor() && 287 if (it->isCopyConstructor() &&
291 !record->hasUserDeclaredCopyConstructor()) { 288 !record->hasUserDeclaredCopyConstructor()) {
292 emitWarning(record_location, 289 emitWarning(record_location,
293 "Complex class/struct needs an explicit out-of-line " 290 "Complex class/struct needs an explicit out-of-line "
294 "copy constructor."); 291 "copy constructor.");
295 } else { 292 } else {
296 emitWarning(it->getInnerLocStart(), 293 emitWarning(it->getInnerLocStart(),
297 "Complex constructor has an inlined body."); 294 "Complex constructor has an inlined body.");
298 } 295 }
299 } else if (it->isInlined() && (!it->isCopyOrMoveConstructor() ||
300 it->isExplicitlyDefaulted())) {
301 // isInlined() is a more reliable check than hasInlineBody(), but
302 // unfortunately, it results in warnings for implicit copy/move
303 // constructors in the previously mentioned situation. To preserve
304 // compatibility with existing Chromium code, only warn if it's an
305 // explicitly defaulted copy or move constructor.
306 emitWarning(it->getInnerLocStart(),
307 "Complex constructor has an inlined body.");
308 } 296 }
309 } 297 }
310 } 298 }
311 } 299 }
312 300
313 // The destructor side is equivalent except that we don't check for 301 // The destructor side is equivalent except that we don't check for
314 // trivial members; 20 ints don't need a destructor. 302 // trivial members; 20 ints don't need a destructor.
315 if (dtor_score >= 10 && !record->hasTrivialDestructor()) { 303 if (dtor_score >= 10 && !record->hasTrivialDestructor()) {
316 if (!record->hasUserDeclaredDestructor()) { 304 if (!record->hasUserDeclaredDestructor()) {
317 emitWarning(record_location, 305 emitWarning(record_location,
318 "Complex class/struct needs an explicit out-of-line " 306 "Complex class/struct needs an explicit out-of-line "
319 "destructor."); 307 "destructor.");
320 } else if (CXXDestructorDecl* dtor = record->getDestructor()) { 308 } else if (CXXDestructorDecl* dtor = record->getDestructor()) {
321 if (dtor->isInlined()) { 309 if (dtor->hasInlineBody()) {
322 emitWarning(dtor->getInnerLocStart(), 310 emitWarning(dtor->getInnerLocStart(),
323 "Complex destructor has an inline body."); 311 "Complex destructor has an inline body.");
324 } 312 }
325 } 313 }
326 } 314 }
327 } 315 }
328 316
329 bool FindBadConstructsConsumer::InTestingNamespace(const Decl* record) { 317 bool FindBadConstructsConsumer::InTestingNamespace(const Decl* record) {
330 return GetNamespace(record).find("testing") != std::string::npos; 318 return GetNamespace(record).find("testing") != std::string::npos;
331 } 319 }
332 320
333 bool FindBadConstructsConsumer::IsMethodInBannedOrTestingNamespace( 321 bool FindBadConstructsConsumer::IsMethodInBannedOrTestingNamespace(
334 const CXXMethodDecl* method) { 322 const CXXMethodDecl* method) {
335 if (InBannedNamespace(method)) 323 if (InBannedNamespace(method))
336 return true; 324 return true;
337 for (CXXMethodDecl::method_iterator i = method->begin_overridden_methods(); 325 for (CXXMethodDecl::method_iterator i = method->begin_overridden_methods();
338 i != method->end_overridden_methods(); 326 i != method->end_overridden_methods();
339 ++i) { 327 ++i) {
340 const CXXMethodDecl* overridden = *i; 328 const CXXMethodDecl* overridden = *i;
341 if (IsMethodInBannedOrTestingNamespace(overridden) || 329 if (IsMethodInBannedOrTestingNamespace(overridden) ||
342 // Provide an exception for ::testing::Test. gtest itself uses some 330 // Provide an exception for ::testing::Test. gtest itself uses some
343 // magic to try to make sure SetUp()/TearDown() aren't capitalized 331 // magic to try to make sure SetUp()/TearDown() aren't capitalized
344 // incorrectly, but having the plugin enforce override is also nice. 332 // incorrectly, but having the plugin enforce override is also nice.
345 (InTestingNamespace(overridden) && 333 (InTestingNamespace(overridden) &&
346 !IsGtestTestFixture(overridden->getParent()))) { 334 (!options_.strict_virtual_specifiers ||
335 !IsGtestTestFixture(overridden->getParent())))) {
347 return true; 336 return true;
348 } 337 }
349 } 338 }
350 339
351 return false; 340 return false;
352 } 341 }
353 342
354 // Checks that virtual methods are correctly annotated, and have no body in a 343 // Checks that virtual methods are correctly annotated, and have no body in a
355 // header file. 344 // header file.
356 void FindBadConstructsConsumer::CheckVirtualMethods( 345 void FindBadConstructsConsumer::CheckVirtualMethods(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 // virtual method overrides a method from a base class, only the override 386 // virtual method overrides a method from a base class, only the override
398 // specifier should be used. If the method should not be overridden by derived 387 // specifier should be used. If the method should not be overridden by derived
399 // classes, only the final specifier should be used. 388 // classes, only the final specifier should be used.
400 void FindBadConstructsConsumer::CheckVirtualSpecifiers( 389 void FindBadConstructsConsumer::CheckVirtualSpecifiers(
401 const CXXMethodDecl* method) { 390 const CXXMethodDecl* method) {
402 bool is_override = method->size_overridden_methods() > 0; 391 bool is_override = method->size_overridden_methods() > 0;
403 bool has_virtual = method->isVirtualAsWritten(); 392 bool has_virtual = method->isVirtualAsWritten();
404 OverrideAttr* override_attr = method->getAttr<OverrideAttr>(); 393 OverrideAttr* override_attr = method->getAttr<OverrideAttr>();
405 FinalAttr* final_attr = method->getAttr<FinalAttr>(); 394 FinalAttr* final_attr = method->getAttr<FinalAttr>();
406 395
396 if (method->isPure() && !options_.strict_virtual_specifiers)
397 return;
398
407 if (IsMethodInBannedOrTestingNamespace(method)) 399 if (IsMethodInBannedOrTestingNamespace(method))
408 return; 400 return;
409 401
402 if (isa<CXXDestructorDecl>(method) && !options_.strict_virtual_specifiers)
403 return;
404
410 SourceManager& manager = instance().getSourceManager(); 405 SourceManager& manager = instance().getSourceManager();
411 406
412 // Complain if a method is annotated virtual && (override || final). 407 // Complain if a method is annotated virtual && (override || final).
413 if (has_virtual && (override_attr || final_attr)) { 408 if (has_virtual && (override_attr || final_attr) &&
409 options_.strict_virtual_specifiers) {
414 diagnostic().Report(method->getLocStart(), 410 diagnostic().Report(method->getLocStart(),
415 diag_redundant_virtual_specifier_) 411 diag_redundant_virtual_specifier_)
416 << "'virtual'" 412 << "'virtual'"
417 << (override_attr ? static_cast<Attr*>(override_attr) : final_attr) 413 << (override_attr ? static_cast<Attr*>(override_attr) : final_attr)
418 << FixItRemovalForVirtual(manager, method); 414 << FixItRemovalForVirtual(manager, method);
419 } 415 }
420 416
421 // Complain if a method is an override and is not annotated with override or 417 // Complain if a method is an override and is not annotated with override or
422 // final. 418 // final.
423 if (is_override && !override_attr && !final_attr) { 419 if (is_override && !override_attr && !final_attr) {
424 SourceRange type_info_range = 420 SourceRange type_info_range =
425 method->getTypeSourceInfo()->getTypeLoc().getSourceRange(); 421 method->getTypeSourceInfo()->getTypeLoc().getSourceRange();
426 FullSourceLoc loc(type_info_range.getBegin(), manager); 422 FullSourceLoc loc(type_info_range.getBegin(), manager);
427 423
428 // Build the FixIt insertion point after the end of the method definition, 424 // Build the FixIt insertion point after the end of the method definition,
429 // including any const-qualifiers and attributes, and before the opening 425 // including any const-qualifiers and attributes, and before the opening
430 // of the l-curly-brace (if inline) or the semi-color (if a declaration). 426 // of the l-curly-brace (if inline) or the semi-color (if a declaration).
431 SourceLocation spelling_end = 427 SourceLocation spelling_end =
432 manager.getSpellingLoc(type_info_range.getEnd()); 428 manager.getSpellingLoc(type_info_range.getEnd());
433 if (spelling_end.isValid()) { 429 if (spelling_end.isValid()) {
434 SourceLocation token_end = 430 SourceLocation token_end =
435 Lexer::getLocForEndOfToken(spelling_end, 0, manager, LangOptions()); 431 Lexer::getLocForEndOfToken(spelling_end, 0, manager, LangOptions());
436 diagnostic().Report(token_end, diag_method_requires_override_) 432 diagnostic().Report(token_end, diag_method_requires_override_)
437 << FixItHint::CreateInsertion(token_end, " override"); 433 << FixItHint::CreateInsertion(token_end, " override");
438 } else { 434 } else {
439 diagnostic().Report(loc, diag_method_requires_override_); 435 diagnostic().Report(loc, diag_method_requires_override_);
440 } 436 }
441 } 437 }
442 438
443 if (final_attr && override_attr) { 439 if (final_attr && override_attr && options_.strict_virtual_specifiers) {
444 diagnostic().Report(override_attr->getLocation(), 440 diagnostic().Report(override_attr->getLocation(),
445 diag_redundant_virtual_specifier_) 441 diag_redundant_virtual_specifier_)
446 << override_attr << final_attr 442 << override_attr << final_attr
447 << FixItHint::CreateRemoval(override_attr->getRange()); 443 << FixItHint::CreateRemoval(override_attr->getRange());
448 } 444 }
449 445
450 if (final_attr && !is_override) { 446 if (final_attr && !is_override && options_.strict_virtual_specifiers) {
451 diagnostic().Report(method->getLocStart(), 447 diagnostic().Report(method->getLocStart(),
452 diag_base_method_virtual_and_final_) 448 diag_base_method_virtual_and_final_)
453 << FixItRemovalForVirtual(manager, method) 449 << FixItRemovalForVirtual(manager, method)
454 << FixItHint::CreateRemoval(final_attr->getRange()); 450 << FixItHint::CreateRemoval(final_attr->getRange());
455 } 451 }
456 } 452 }
457 453
458 void FindBadConstructsConsumer::CheckVirtualBodies( 454 void FindBadConstructsConsumer::CheckVirtualBodies(
459 const CXXMethodDecl* method) { 455 const CXXMethodDecl* method) {
460 // Virtual methods should not have inline definitions beyond "{}". This 456 // Virtual methods should not have inline definitions beyond "{}". This
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 // one of those, it means there is at least one member after a factory. 781 // one of those, it means there is at least one member after a factory.
786 if (weak_ptr_factory_location.isValid() && 782 if (weak_ptr_factory_location.isValid() &&
787 !param_is_weak_ptr_factory_to_self) { 783 !param_is_weak_ptr_factory_to_self) {
788 diagnostic().Report(weak_ptr_factory_location, 784 diagnostic().Report(weak_ptr_factory_location,
789 diag_weak_ptr_factory_order_); 785 diag_weak_ptr_factory_order_);
790 } 786 }
791 } 787 }
792 } 788 }
793 789
794 } // namespace chrome_checker 790 } // namespace chrome_checker
OLDNEW
« no previous file with comments | « tools/clang/plugins/FindBadConstructsAction.cpp ('k') | tools/clang/plugins/Options.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698