1d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks// Use of this source code is governed by a BSD-style license that can be 3d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks// found in the LICENSE file. 4d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 5d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks// A general interface for filtering and only acting on classes in Chromium C++ 6d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks// code. 7d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 8d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks#include "ChromeClassTester.h" 9d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 10d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks#include <sys/param.h> 11d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 12d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks#include "clang/AST/AST.h" 13d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks#include "clang/Basic/FileManager.h" 14d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks#include "clang/Basic/SourceManager.h" 15d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruthusing namespace clang; 17d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 18d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksnamespace { 19d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 20d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool starts_with(const std::string& one, const std::string& two) { 21d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return one.compare(0, two.size(), two) == 0; 22d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 23d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 24d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksstd::string lstrip(const std::string& one, const std::string& two) { 25d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (starts_with(one, two)) 26d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return one.substr(two.size()); 27d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return one; 2865bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose} 29d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 30d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool ends_with(const std::string& one, const std::string& two) { 31d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (two.size() > one.size()) 32d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return false; 33d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 34d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return one.compare(one.size() - two.size(), two.size(), two) == 0; 35d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 36d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 371f03a8a0334924719ff85c993d652480e93fda98Jordan Rose} // namespace 381f03a8a0334924719ff85c993d652480e93fda98Jordan Rose 39d699ade396154238d2fa89bb09fdcfb79e5587d2Anna ZaksChromeClassTester::ChromeClassTester(CompilerInstance& instance) 40d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks : instance_(instance), 4196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose diagnostic_(instance.getDiagnostics()) { 4296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose BuildBannedLists(); 43d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 44d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 45d699ade396154238d2fa89bb09fdcfb79e5587d2Anna ZaksChromeClassTester::~ChromeClassTester() {} 46d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 47344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaksvoid ChromeClassTester::HandleTagDeclDefinition(TagDecl* tag) { 48d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks pending_class_decls_.push_back(tag); 49d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 50d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 51d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool ChromeClassTester::HandleTopLevelDecl(DeclGroupRef group_ref) { 52d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks for (size_t i = 0; i < pending_class_decls_.size(); ++i) 53d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks CheckTag(pending_class_decls_[i]); 54bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks pending_class_decls_.clear(); 55123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks 56d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return true; // true means continue parsing. 57d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 58d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 59d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksvoid ChromeClassTester::CheckTag(TagDecl* tag) { 60d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // We handle class types here where we have semantic information. We can only 61d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // check structs/classes/enums here, but we get a bunch of nice semantic 62d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // information instead of just parsing information. 63d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 64d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (CXXRecordDecl* record = dyn_cast<CXXRecordDecl>(tag)) { 65d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // If this is a POD or a class template or a type dependent on a 66d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // templated class, assume there's no ctor/dtor/virtual method 67d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // optimization that we can do. 68d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (record->isPOD() || 69d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks record->getDescribedClassTemplate() || 701f03a8a0334924719ff85c993d652480e93fda98Jordan Rose record->getTemplateSpecializationKind() || 711f03a8a0334924719ff85c993d652480e93fda98Jordan Rose record->isDependentType()) 72d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return; 73d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 74d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (InBannedNamespace(record)) 75d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return; 76d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 77d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks SourceLocation record_location = record->getInnerLocStart(); 78d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (InBannedDirectory(record_location)) 79d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return; 801f03a8a0334924719ff85c993d652480e93fda98Jordan Rose 811f03a8a0334924719ff85c993d652480e93fda98Jordan Rose // We sadly need to maintain a blacklist of types that violate these 82d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // rules, but do so for good reason or due to limitations of this 8396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose // checker (i.e., we don't handle extern templates very well). 8496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose std::string base_name = record->getNameAsString(); 8596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose if (IsIgnoredType(base_name)) 8696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose return; 878919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 8896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose // We ignore all classes that end with "Matcher" because they're probably 8996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose // GMock artifacts. 90de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose if (ends_with(base_name, "Matcher")) 91d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return; 9296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 9396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose CheckChromeClass(record_location, record); 9496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose } else if (EnumDecl* enum_decl = dyn_cast<EnumDecl>(tag)) { 9596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose SourceLocation enum_location = enum_decl->getInnerLocStart(); 96de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose if (InBannedDirectory(enum_location)) 97d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return; 9896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 9996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose std::string base_name = enum_decl->getNameAsString(); 10096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose if (IsIgnoredType(base_name)) 10196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose return; 10296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 10396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose CheckChromeEnum(enum_location, enum_decl); 1041f03a8a0334924719ff85c993d652480e93fda98Jordan Rose } 1051f03a8a0334924719ff85c993d652480e93fda98Jordan Rose} 10696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 10796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosevoid ChromeClassTester::emitWarning(SourceLocation loc, 10896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose const char* raw_error) { 10996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose FullSourceLoc full(loc, instance().getSourceManager()); 11096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose std::string err; 11196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose err = "[chromium-style] "; 11296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose err += raw_error; 11396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose DiagnosticIDs::Level level = 11496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose diagnostic().getWarningsAsErrors() ? 11596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose DiagnosticIDs::Error : 116d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks DiagnosticIDs::Warning; 117d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks unsigned id = diagnostic().getDiagnosticIDs()->getCustomDiagID(level, err); 118d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks DiagnosticBuilder builder = diagnostic().Report(full, id); 119d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 120d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 121d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool ChromeClassTester::InBannedNamespace(const Decl* record) { 122d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks std::string n = GetNamespace(record); 123d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (!n.empty()) { 124d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return std::find(banned_namespaces_.begin(), banned_namespaces_.end(), n) 125d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks != banned_namespaces_.end(); 126d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks } 127d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 128d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return false; 12981c16fc757fe7b68cbd035765e3be92281625663James Dennett} 130d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 131d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksstd::string ChromeClassTester::GetNamespace(const Decl* record) { 132d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return GetNamespaceImpl(record->getDeclContext(), ""); 133d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 134d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 135d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool ChromeClassTester::InImplementationFile(SourceLocation record_location) { 136d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks std::string filename; 137d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (!GetFilename(record_location, &filename)) 13881c16fc757fe7b68cbd035765e3be92281625663James Dennett return false; 139d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 140d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (ends_with(filename, ".cc") || ends_with(filename, ".cpp") || 141d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ends_with(filename, ".mm")) { 142d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return true; 143d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks } 144d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 145d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return false; 146d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 147d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 148d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksvoid ChromeClassTester::BuildBannedLists() { 149d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_namespaces_.push_back("std"); 150d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_namespaces_.push_back("__gnu_cxx"); 151d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 152d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_namespaces_.push_back("blink"); 153d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_namespaces_.push_back("WTF"); 154d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 155d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/third_party/"); 156d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/native_client/"); 157344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks banned_directories_.push_back("/breakpad/"); 15865bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose banned_directories_.push_back("/courgette/"); 159d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/pdf/"); 160344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks banned_directories_.push_back("/ppapi/"); 161344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks banned_directories_.push_back("/usr/"); 162d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/testing/"); 163d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/v8/"); 164d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/dart/"); 165d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/sdch/"); 166d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/icu4c/"); 167d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/frameworks/"); 168d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 169d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Don't check autogenerated headers. 170d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Make puts them below $(builddir_name)/.../gen and geni. 171d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Ninja puts them below OUTPUT_DIR/.../gen 172d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Xcode has a fixed output directory for everything. 173d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/gen/"); 174d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/geni/"); 175d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/xcodebuild/"); 176d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 177d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // You are standing in a mazy of twisty dependencies, all resolved by 178d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // putting everything in the header. 179e8018f24f0f0e1cb1490c37b158da5d5c456e577Anton Yartsev banned_directories_.push_back("/automation/"); 180e8018f24f0f0e1cb1490c37b158da5d5c456e577Anton Yartsev 181e8018f24f0f0e1cb1490c37b158da5d5c456e577Anton Yartsev // Don't check system headers. 182d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks banned_directories_.push_back("/Developer/"); 183d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 184d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Used in really low level threading code that probably shouldn't be out of 185d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // lined. 186d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("ThreadLocalBoolean"); 187d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 188d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // A complicated pickle derived struct that is all packed integers. 189d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("Header"); 190d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 191d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Part of the GPU system that uses multiple included header 192d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // weirdness. Never getting this right. 193872db39510372c4acd8851a3b956e1a135cfcd41Duncan Sands ignored_record_names_.insert("Validators"); 194d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 195d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Has a UNIT_TEST only constructor. Isn't *terribly* complex... 196d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("AutocompleteController"); 197d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("HistoryURLProvider"); 198d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 199d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Because of chrome frame 200d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("ReliabilityTestSuite"); 201d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 202d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Used over in the net unittests. A large enough bundle of integers with 1 203d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // non-pod class member. Probably harmless. 204d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("MockTransaction"); 205d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 206d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Enum type with _LAST members where _LAST doesn't mean last enum value. 2078bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ignored_record_names_.insert("ServerFieldType"); 208d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 209d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Used heavily in ui_unittests and once in views_unittests. Fixing this 210d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // isn't worth the overhead of an additional library. 211d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("TestAnimationDelegate"); 212d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 213d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Part of our public interface that nacl and friends use. (Arguably, this 214d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // should mean that this is a higher priority but fixing this looks hard.) 215d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks ignored_record_names_.insert("PluginVersionInfo"); 2168bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek 217d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // Measured performance improvement on cc_perftests. See 21865bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose // https://codereview.chromium.org/11299290/ 21965bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose ignored_record_names_.insert("QuadF"); 22065bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose 22165bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose // Enum type with _LAST members where _LAST doesn't mean last enum value. 22265bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose ignored_record_names_.insert("ViewID"); 22365bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose} 2248bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek 22566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaksstd::string ChromeClassTester::GetNamespaceImpl(const DeclContext* context, 22665bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose const std::string& candidate) { 22765bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose switch (context->getDeclKind()) { 22865bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose case Decl::TranslationUnit: { 22965bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose return candidate; 23065bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose } 23181c16fc757fe7b68cbd035765e3be92281625663James Dennett case Decl::Namespace: { 23281c16fc757fe7b68cbd035765e3be92281625663James Dennett const NamespaceDecl* decl = dyn_cast<NamespaceDecl>(context); 23381c16fc757fe7b68cbd035765e3be92281625663James Dennett std::string name_str; 23466c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks llvm::raw_string_ostream OS(name_str); 23565bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose if (decl->isAnonymousNamespace()) 23665bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose OS << "<anonymous namespace>"; 23765bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose else 23865bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose OS << *decl; 23965bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose return GetNamespaceImpl(context->getParent(), 24065bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose OS.str()); 24165bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose } 24265bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose default: { 24365bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose return GetNamespaceImpl(context->getParent(), candidate); 24465bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose } 24565bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose } 24665bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose} 24781c16fc757fe7b68cbd035765e3be92281625663James Dennett 24881c16fc757fe7b68cbd035765e3be92281625663James Dennettbool ChromeClassTester::InBannedDirectory(SourceLocation loc) { 2498bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek std::string filename; 2508bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (!GetFilename(loc, &filename)) { 251bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // If the filename cannot be determined, simply treat this as a banned 252d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // location, instead of going through the full lookup process. 25366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks return true; 254740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 255d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 256d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // We need to special case scratch space; which is where clang does its 257d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // macro expansion. We explicitly want to allow people to do otherwise bad 258bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // things through macros that were defined due to third party libraries. 259bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (filename == "<scratch space>") 260bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return true; 2611655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks 262bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // Don't complain about autogenerated protobuf files. 263bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (ends_with(filename, ".pb.h")) { 264bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return true; 265bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 266bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 267bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // We need to munge the paths so that they are relative to the repository 268bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // srcroot. We first resolve the symlinktastic relative path and then 269233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks // remove our known srcroot from it if needed. 270bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks char resolvedPath[MAXPATHLEN]; 271bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (realpath(filename.c_str(), resolvedPath)) { 272bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks filename = resolvedPath; 273233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks } 274233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks 275bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // On linux, chrome is often checked out to /usr/local/google. Due to the 276bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // "usr" rule in banned_directories_, all diagnostics would be suppressed 277bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // in that case. As a workaround, strip that prefix. 278123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks filename = lstrip(filename, "/usr/local/google"); 279123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks 280123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks for (size_t i = 0; i < banned_directories_.size(); ++i) { 281123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks // If any of the banned directories occur as a component in filename, 282123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks // this file is rejected. 283123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks const std::string& banned_dir = banned_directories_[i]; 284123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks assert(banned_dir.front() == '/' && "Banned dir must start with '/'"); 285123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks assert(banned_dir.back() == '/' && "Banned dir must end with '/'"); 286123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks 287123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks if (filename.find(banned_dir) != std::string::npos) 288123243cfd80f790a27edd1b829cd190a85f6c006Anna Zaks return true; 289d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks } 290d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 291d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return false; 292d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 293d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 294d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool ChromeClassTester::IsIgnoredType(const std::string& base_name) { 295d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return ignored_record_names_.find(base_name) != ignored_record_names_.end(); 296d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks} 297d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 298d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaksbool ChromeClassTester::GetFilename(SourceLocation loc, 299d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks std::string* filename) { 300d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks const SourceManager& source_manager = instance_.getSourceManager(); 301d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks SourceLocation spelling_location = source_manager.getSpellingLoc(loc); 302d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location); 303d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks if (ploc.isInvalid()) { 304d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // If we're in an invalid location, we're looking at things that aren't 305d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks // actually stated in the source. 3061f03a8a0334924719ff85c993d652480e93fda98Jordan Rose return false; 307d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks } 308d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks 309d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks *filename = ploc.getFilename(); 310d699ade396154238d2fa89bb09fdcfb79e5587d2Anna Zaks return true; 31165bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose} 31265bc6537509fcfb9e7e724e7d40546eea931e07fJordan Rose