Chromium Code Reviews| 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 "clang/Sema/Sema.h" | 10 #include "clang/Sema/Sema.h" |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 bool FindBadConstructsConsumer::VisitCallExpr(CallExpr* call_expr) { | 209 bool FindBadConstructsConsumer::VisitCallExpr(CallExpr* call_expr) { |
| 210 if (ipc_visitor_) ipc_visitor_->VisitCallExpr(call_expr); | 210 if (ipc_visitor_) ipc_visitor_->VisitCallExpr(call_expr); |
| 211 return true; | 211 return true; |
| 212 } | 212 } |
| 213 | 213 |
| 214 bool FindBadConstructsConsumer::VisitVarDecl(clang::VarDecl* var_decl) { | 214 bool FindBadConstructsConsumer::VisitVarDecl(clang::VarDecl* var_decl) { |
| 215 CheckVarDecl(var_decl); | 215 CheckVarDecl(var_decl); |
| 216 return true; | 216 return true; |
| 217 } | 217 } |
| 218 | 218 |
| 219 void FindBadConstructsConsumer::CheckChromeClass(SourceLocation record_location, | 219 void FindBadConstructsConsumer::CheckChromeClass(LocationType location_type, |
| 220 SourceLocation record_location, | |
| 220 CXXRecordDecl* record) { | 221 CXXRecordDecl* record) { |
| 222 // TODO(dcheng): After emitWarning() is removed, move warning filtering into | |
| 223 // ReportIfSpellingLocNotIgnored. | |
| 224 if (location_type == LocationType::kBlink) | |
| 225 return; | |
| 226 | |
| 221 bool implementation_file = InImplementationFile(record_location); | 227 bool implementation_file = InImplementationFile(record_location); |
| 222 | 228 |
| 223 if (!implementation_file) { | 229 if (!implementation_file) { |
| 224 // Only check for "heavy" constructors/destructors in header files; | 230 // Only check for "heavy" constructors/destructors in header files; |
| 225 // within implementation files, there is no performance cost. | 231 // within implementation files, there is no performance cost. |
| 226 | 232 |
| 227 // If this is a POD or a class template or a type dependent on a | 233 // If this is a POD or a class template or a type dependent on a |
| 228 // templated class, assume there's no ctor/dtor/virtual method | 234 // templated class, assume there's no ctor/dtor/virtual method |
| 229 // optimization that we should do. | 235 // optimization that we should do. |
| 230 if (!IsPodOrTemplateType(*record)) | 236 if (!IsPodOrTemplateType(*record)) |
| 231 CheckCtorDtorWeight(record_location, record); | 237 CheckCtorDtorWeight(record_location, record); |
| 232 } | 238 } |
| 233 | 239 |
| 234 bool warn_on_inline_bodies = !implementation_file; | 240 bool warn_on_inline_bodies = !implementation_file; |
| 235 // Check that all virtual methods are annotated with override or final. | 241 // Check that all virtual methods are annotated with override or final. |
| 236 // Note this could also apply to templates, but for some reason Clang | 242 // Note this could also apply to templates, but for some reason Clang |
| 237 // does not always see the "override", so we get false positives. | 243 // does not always see the "override", so we get false positives. |
| 238 // See http://llvm.org/bugs/show_bug.cgi?id=18440 and | 244 // See http://llvm.org/bugs/show_bug.cgi?id=18440 and |
| 239 // http://llvm.org/bugs/show_bug.cgi?id=21942 | 245 // http://llvm.org/bugs/show_bug.cgi?id=21942 |
| 240 if (!IsPodOrTemplateType(*record)) | 246 if (!IsPodOrTemplateType(*record)) |
| 241 CheckVirtualMethods(record_location, record, warn_on_inline_bodies); | 247 CheckVirtualMethods(record_location, record, warn_on_inline_bodies); |
| 242 | 248 |
| 243 CheckRefCountedDtors(record_location, record); | 249 CheckRefCountedDtors(record_location, record); |
| 244 | 250 |
| 245 CheckWeakPtrFactoryMembers(record_location, record); | 251 CheckWeakPtrFactoryMembers(record_location, record); |
| 246 } | 252 } |
| 247 | 253 |
| 248 void FindBadConstructsConsumer::CheckChromeEnum(SourceLocation enum_location, | 254 void FindBadConstructsConsumer::CheckChromeEnum(LocationType location_type, |
| 255 SourceLocation enum_location, | |
| 249 EnumDecl* enum_decl) { | 256 EnumDecl* enum_decl) { |
| 250 if (!options_.check_enum_last_value) | 257 if (!options_.check_enum_last_value) |
| 251 return; | 258 return; |
| 252 | 259 |
| 260 if (location_type == LocationType::kBlink) | |
| 261 return; | |
| 262 | |
| 253 bool got_one = false; | 263 bool got_one = false; |
| 254 bool is_signed = false; | 264 bool is_signed = false; |
| 255 llvm::APSInt max_so_far; | 265 llvm::APSInt max_so_far; |
| 256 EnumDecl::enumerator_iterator iter; | 266 EnumDecl::enumerator_iterator iter; |
| 257 for (iter = enum_decl->enumerator_begin(); | 267 for (iter = enum_decl->enumerator_begin(); |
| 258 iter != enum_decl->enumerator_end(); | 268 iter != enum_decl->enumerator_end(); |
| 259 ++iter) { | 269 ++iter) { |
| 260 llvm::APSInt current_value = iter->getInitVal(); | 270 llvm::APSInt current_value = iter->getInitVal(); |
| 261 if (!got_one) { | 271 if (!got_one) { |
| 262 max_so_far = current_value; | 272 max_so_far = current_value; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 444 } | 454 } |
| 445 } | 455 } |
| 446 | 456 |
| 447 return false; | 457 return false; |
| 448 } | 458 } |
| 449 | 459 |
| 450 SuppressibleDiagnosticBuilder | 460 SuppressibleDiagnosticBuilder |
| 451 FindBadConstructsConsumer::ReportIfSpellingLocNotIgnored( | 461 FindBadConstructsConsumer::ReportIfSpellingLocNotIgnored( |
| 452 SourceLocation loc, | 462 SourceLocation loc, |
| 453 unsigned diagnostic_id) { | 463 unsigned diagnostic_id) { |
| 454 return SuppressibleDiagnosticBuilder( | 464 LocationType type = |
| 455 &diagnostic(), loc, diagnostic_id, | 465 ClassifyLocation(instance().getSourceManager().getSpellingLoc(loc)); |
| 456 InBannedDirectory(instance().getSourceManager().getSpellingLoc(loc))); | 466 bool ignored = type == LocationType::kIgnored || type == LocationType::kBlink; |
|
dcheng
2017/03/29 04:18:40
In the future, when location type is kBlink, we wo
| |
| 467 return SuppressibleDiagnosticBuilder(&diagnostic(), loc, diagnostic_id, | |
| 468 ignored); | |
| 457 } | 469 } |
| 458 | 470 |
| 459 // Checks that virtual methods are correctly annotated, and have no body in a | 471 // Checks that virtual methods are correctly annotated, and have no body in a |
| 460 // header file. | 472 // header file. |
| 461 void FindBadConstructsConsumer::CheckVirtualMethods( | 473 void FindBadConstructsConsumer::CheckVirtualMethods( |
| 462 SourceLocation record_location, | 474 SourceLocation record_location, |
| 463 CXXRecordDecl* record, | 475 CXXRecordDecl* record, |
| 464 bool warn_on_inline_bodies) { | 476 bool warn_on_inline_bodies) { |
| 465 // Gmock objects trigger these for each MOCK_BLAH() macro used. So we have a | 477 // Gmock objects trigger these for each MOCK_BLAH() macro used. So we have a |
| 466 // trick to get around that. If a class has member variables whose types are | 478 // trick to get around that. If a class has member variables whose types are |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 if (method->hasBody() && method->hasInlineBody()) { | 614 if (method->hasBody() && method->hasInlineBody()) { |
| 603 if (CompoundStmt* cs = dyn_cast<CompoundStmt>(method->getBody())) { | 615 if (CompoundStmt* cs = dyn_cast<CompoundStmt>(method->getBody())) { |
| 604 if (cs->size()) { | 616 if (cs->size()) { |
| 605 SourceLocation loc = cs->getLBracLoc(); | 617 SourceLocation loc = cs->getLBracLoc(); |
| 606 // CR_BEGIN_MSG_MAP_EX and BEGIN_SAFE_MSG_MAP_EX try to be compatible | 618 // CR_BEGIN_MSG_MAP_EX and BEGIN_SAFE_MSG_MAP_EX try to be compatible |
| 607 // to BEGIN_MSG_MAP(_EX). So even though they are in chrome code, | 619 // to BEGIN_MSG_MAP(_EX). So even though they are in chrome code, |
| 608 // we can't easily fix them, so explicitly whitelist them here. | 620 // we can't easily fix them, so explicitly whitelist them here. |
| 609 bool emit = true; | 621 bool emit = true; |
| 610 if (loc.isMacroID()) { | 622 if (loc.isMacroID()) { |
| 611 SourceManager& manager = instance().getSourceManager(); | 623 SourceManager& manager = instance().getSourceManager(); |
| 612 if (InBannedDirectory(manager.getSpellingLoc(loc))) | 624 LocationType type = ClassifyLocation(manager.getSpellingLoc(loc)); |
| 625 if (type == LocationType::kIgnored || type == LocationType::kBlink) | |
|
dcheng
2017/03/29 04:18:40
Ditto: this is needed for now, but this should be
| |
| 613 emit = false; | 626 emit = false; |
| 614 else { | 627 else { |
| 615 StringRef name = Lexer::getImmediateMacroName( | 628 StringRef name = Lexer::getImmediateMacroName( |
| 616 loc, manager, instance().getLangOpts()); | 629 loc, manager, instance().getLangOpts()); |
| 617 if (name == "CR_BEGIN_MSG_MAP_EX" || | 630 if (name == "CR_BEGIN_MSG_MAP_EX" || |
| 618 name == "BEGIN_SAFE_MSG_MAP_EX") | 631 name == "BEGIN_SAFE_MSG_MAP_EX") |
| 619 emit = false; | 632 emit = false; |
| 620 } | 633 } |
| 621 } | 634 } |
| 622 if (emit) | 635 if (emit) |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 991 const clang::AutoType* auto_type = | 1004 const clang::AutoType* auto_type = |
| 992 non_reference_type->getAs<clang::AutoType>(); | 1005 non_reference_type->getAs<clang::AutoType>(); |
| 993 if (auto_type) { | 1006 if (auto_type) { |
| 994 if (auto_type->isDeduced()) { | 1007 if (auto_type->isDeduced()) { |
| 995 QualType deduced_type = auto_type->getDeducedType(); | 1008 QualType deduced_type = auto_type->getDeducedType(); |
| 996 if (!deduced_type.isNull() && deduced_type->isPointerType() && | 1009 if (!deduced_type.isNull() && deduced_type->isPointerType() && |
| 997 !deduced_type->isFunctionPointerType()) { | 1010 !deduced_type->isFunctionPointerType()) { |
| 998 // Check if we should even be considering this type (note that there | 1011 // Check if we should even be considering this type (note that there |
| 999 // should be fewer auto types than banned namespace/directory types, | 1012 // should be fewer auto types than banned namespace/directory types, |
| 1000 // so check this last. | 1013 // so check this last. |
| 1014 LocationType location_type = | |
| 1015 ClassifyLocation(var_decl->getLocStart()); | |
| 1001 if (!InBannedNamespace(var_decl) && | 1016 if (!InBannedNamespace(var_decl) && |
| 1002 !InBannedDirectory(var_decl->getLocStart())) { | 1017 location_type != LocationType::kIgnored) { |
|
dcheng
2017/03/29 04:18:40
Note: We only ignore kIgnored here: kBlink gets fi
| |
| 1003 // The range starts from |var_decl|'s loc start, which is the | 1018 // The range starts from |var_decl|'s loc start, which is the |
| 1004 // beginning of the full expression defining this |var_decl|. It | 1019 // beginning of the full expression defining this |var_decl|. It |
| 1005 // ends, however, where this |var_decl|'s type loc ends, since | 1020 // ends, however, where this |var_decl|'s type loc ends, since |
| 1006 // that's the end of the type of |var_decl|. | 1021 // that's the end of the type of |var_decl|. |
| 1007 // Note that the beginning source location of type loc omits cv | 1022 // Note that the beginning source location of type loc omits cv |
| 1008 // qualifiers, which is why it's not a good candidate to use for the | 1023 // qualifiers, which is why it's not a good candidate to use for the |
| 1009 // start of the range. | 1024 // start of the range. |
| 1010 clang::SourceRange range( | 1025 clang::SourceRange range( |
| 1011 var_decl->getLocStart(), | 1026 var_decl->getLocStart(), |
| 1012 var_decl->getTypeSourceInfo()->getTypeLoc().getLocEnd()); | 1027 var_decl->getTypeSourceInfo()->getTypeLoc().getLocEnd()); |
| 1013 ReportIfSpellingLocNotIgnored(range.getBegin(), | 1028 ReportIfSpellingLocNotIgnored(range.getBegin(), |
| 1014 diag_auto_deduced_to_a_pointer_type_) | 1029 diag_auto_deduced_to_a_pointer_type_) |
| 1015 << FixItHint::CreateReplacement( | 1030 << FixItHint::CreateReplacement( |
| 1016 range, | 1031 range, |
| 1017 GetAutoReplacementTypeAsString( | 1032 GetAutoReplacementTypeAsString( |
| 1018 var_decl->getType(), var_decl->getStorageClass())); | 1033 var_decl->getType(), var_decl->getStorageClass())); |
| 1019 } | 1034 } |
| 1020 } | 1035 } |
| 1021 } | 1036 } |
| 1022 } else if (non_reference_type->isPointerType()) { | 1037 } else if (non_reference_type->isPointerType()) { |
| 1023 non_reference_type = non_reference_type->getPointeeType(); | 1038 non_reference_type = non_reference_type->getPointeeType(); |
| 1024 continue; | 1039 continue; |
| 1025 } | 1040 } |
| 1026 break; | 1041 break; |
| 1027 } | 1042 } |
| 1028 } | 1043 } |
| 1029 | 1044 |
| 1030 } // namespace chrome_checker | 1045 } // namespace chrome_checker |
| OLD | NEW |