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

Side by Side Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 827693004: Blink GC plugin: improve handling of type dependent bases. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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 | « no previous file | tools/clang/blink_gc_plugin/RecordInfo.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // This clang plugin checks various invariants of the Blink garbage 5 // This clang plugin checks various invariants of the Blink garbage
6 // collection infrastructure. 6 // collection infrastructure.
7 // 7 //
8 // Errors are described at: 8 // Errors are described at:
9 // http://www.chromium.org/developers/blink-gc-plugin-errors 9 // http://www.chromium.org/developers/blink-gc-plugin-errors
10 10
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 393
394 CXXRecordDecl* GetDependentTemplatedDecl(CXXDependentScopeMemberExpr* expr) { 394 CXXRecordDecl* GetDependentTemplatedDecl(CXXDependentScopeMemberExpr* expr) {
395 NestedNameSpecifier* qual = expr->getQualifier(); 395 NestedNameSpecifier* qual = expr->getQualifier();
396 if (!qual) 396 if (!qual)
397 return 0; 397 return 0;
398 398
399 const Type* type = qual->getAsType(); 399 const Type* type = qual->getAsType();
400 if (!type) 400 if (!type)
401 return 0; 401 return 0;
402 402
403 const TemplateSpecializationType* tmpl_type = 403 return RecordInfo::GetDependentTemplatedDecl(*type);
404 type->getAs<TemplateSpecializationType>();
405 if (!tmpl_type)
406 return 0;
407
408 TemplateDecl* tmpl_decl = tmpl_type->getTemplateName().getAsTemplateDecl();
409 if (!tmpl_decl)
410 return 0;
411
412 return dyn_cast<CXXRecordDecl>(tmpl_decl->getTemplatedDecl());
413 } 404 }
414 405
415 void CheckCXXDependentScopeMemberExpr(CallExpr* call, 406 void CheckCXXDependentScopeMemberExpr(CallExpr* call,
416 CXXDependentScopeMemberExpr* expr) { 407 CXXDependentScopeMemberExpr* expr) {
417 string fn_name = expr->getMember().getAsString(); 408 string fn_name = expr->getMember().getAsString();
418 CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr); 409 CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr);
419 if (!tmpl) 410 if (!tmpl)
420 return; 411 return;
421 412
422 // Check for Super<T>::trace(visitor) 413 // Check for Super<T>::trace(visitor)
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 // ensure that the left-most base defines a vtable. This ensures that the 1026 // ensure that the left-most base defines a vtable. This ensures that the
1036 // first thing to be initialized when constructing the object is the vtable 1027 // first thing to be initialized when constructing the object is the vtable
1037 // itself. 1028 // itself.
1038 void CheckPolymorphicClass(RecordInfo* info, CXXMethodDecl* trace) { 1029 void CheckPolymorphicClass(RecordInfo* info, CXXMethodDecl* trace) {
1039 CXXRecordDecl* left_most = info->record(); 1030 CXXRecordDecl* left_most = info->record();
1040 CXXRecordDecl::base_class_iterator it = left_most->bases_begin(); 1031 CXXRecordDecl::base_class_iterator it = left_most->bases_begin();
1041 CXXRecordDecl* left_most_base = 0; 1032 CXXRecordDecl* left_most_base = 0;
1042 while (it != left_most->bases_end()) { 1033 while (it != left_most->bases_end()) {
1043 left_most_base = it->getType()->getAsCXXRecordDecl(); 1034 left_most_base = it->getType()->getAsCXXRecordDecl();
1044 if (!left_most_base && it->getType()->isDependentType()) 1035 if (!left_most_base && it->getType()->isDependentType())
1045 left_most_base = GetDependentTemplatedDecl(*it->getType()); 1036 left_most_base = RecordInfo::GetDependentTemplatedDecl(*it->getType());
1046 1037
1047 // TODO: Find a way to correctly check actual instantiations 1038 // TODO: Find a way to correctly check actual instantiations
1048 // for dependent types. The escape below will be hit, eg, when 1039 // for dependent types. The escape below will be hit, eg, when
1049 // we have a primary template with no definition and 1040 // we have a primary template with no definition and
1050 // specializations for each case (such as SupplementBase) in 1041 // specializations for each case (such as SupplementBase) in
1051 // which case we don't succeed in checking the required 1042 // which case we don't succeed in checking the required
1052 // properties. 1043 // properties.
1053 if (!left_most_base || !left_most_base->hasDefinition()) 1044 if (!left_most_base || !left_most_base->hasDefinition())
1054 return; 1045 return;
1055 1046
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 } 1087 }
1097 } 1088 }
1098 ReportLeftMostBaseMustBePolymorphic(info, left_most); 1089 ReportLeftMostBaseMustBePolymorphic(info, left_most);
1099 } 1090 }
1100 } 1091 }
1101 1092
1102 CXXRecordDecl* GetLeftMostBase(CXXRecordDecl* left_most) { 1093 CXXRecordDecl* GetLeftMostBase(CXXRecordDecl* left_most) {
1103 CXXRecordDecl::base_class_iterator it = left_most->bases_begin(); 1094 CXXRecordDecl::base_class_iterator it = left_most->bases_begin();
1104 while (it != left_most->bases_end()) { 1095 while (it != left_most->bases_end()) {
1105 if (it->getType()->isDependentType()) 1096 if (it->getType()->isDependentType())
1106 left_most = GetDependentTemplatedDecl(*it->getType()); 1097 left_most = RecordInfo::GetDependentTemplatedDecl(*it->getType());
1107 else 1098 else
1108 left_most = it->getType()->getAsCXXRecordDecl(); 1099 left_most = it->getType()->getAsCXXRecordDecl();
1109 if (!left_most || !left_most->hasDefinition()) 1100 if (!left_most || !left_most->hasDefinition())
1110 return 0; 1101 return 0;
1111 it = left_most->bases_begin(); 1102 it = left_most->bases_begin();
1112 } 1103 }
1113 return left_most; 1104 return left_most;
1114 } 1105 }
1115 1106
1116 bool DeclaresVirtualMethods(CXXRecordDecl* decl) { 1107 bool DeclaresVirtualMethods(CXXRecordDecl* decl) {
1117 CXXRecordDecl::method_iterator it = decl->method_begin(); 1108 CXXRecordDecl::method_iterator it = decl->method_begin();
1118 for (; it != decl->method_end(); ++it) 1109 for (; it != decl->method_end(); ++it)
1119 if (it->isVirtual() && !it->isPure()) 1110 if (it->isVirtual() && !it->isPure())
1120 return true; 1111 return true;
1121 return false; 1112 return false;
1122 } 1113 }
1123 1114
1124 void CheckLeftMostDerived(RecordInfo* info) { 1115 void CheckLeftMostDerived(RecordInfo* info) {
1125 CXXRecordDecl* left_most = info->record(); 1116 CXXRecordDecl* left_most = GetLeftMostBase(info->record());
1126 CXXRecordDecl::base_class_iterator it = left_most->bases_begin(); 1117 if (!left_most)
1127 while (it != left_most->bases_end()) { 1118 return;
1128 left_most = it->getType()->getAsCXXRecordDecl();
1129 it = left_most->bases_begin();
1130 }
1131 if (!Config::IsGCBase(left_most->getName())) 1119 if (!Config::IsGCBase(left_most->getName()))
1132 ReportClassMustLeftMostlyDeriveGC(info); 1120 ReportClassMustLeftMostlyDeriveGC(info);
1133 } 1121 }
1134 1122
1135 void CheckDispatch(RecordInfo* info) { 1123 void CheckDispatch(RecordInfo* info) {
1136 bool finalized = info->IsGCFinalized(); 1124 bool finalized = info->IsGCFinalized();
1137 CXXMethodDecl* trace_dispatch = info->GetTraceDispatchMethod(); 1125 CXXMethodDecl* trace_dispatch = info->GetTraceDispatchMethod();
1138 CXXMethodDecl* finalize_dispatch = info->GetFinalizeDispatchMethod(); 1126 CXXMethodDecl* finalize_dispatch = info->GetFinalizeDispatchMethod();
1139 if (!trace_dispatch && !finalize_dispatch) 1127 if (!trace_dispatch && !finalize_dispatch)
1140 return; 1128 return;
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 1875
1888 private: 1876 private:
1889 BlinkGCPluginOptions options_; 1877 BlinkGCPluginOptions options_;
1890 }; 1878 };
1891 1879
1892 } // namespace 1880 } // namespace
1893 1881
1894 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 1882 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
1895 "blink-gc-plugin", 1883 "blink-gc-plugin",
1896 "Check Blink GC invariants"); 1884 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/RecordInfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698