OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // A general interface for filtering and only acting on classes in Chromium C++ | 5 // A general interface for filtering and only acting on classes in Chromium C++ |
6 // code. | 6 // code. |
7 | 7 |
8 #include "ChromeClassTester.h" | 8 #include "ChromeClassTester.h" |
9 | 9 |
10 #include <sys/param.h> | |
11 | |
10 using namespace clang; | 12 using namespace clang; |
11 | 13 |
12 namespace { | 14 namespace { |
13 | 15 |
14 bool starts_with(const std::string& one, const std::string& two) { | 16 bool starts_with(const std::string& one, const std::string& two) { |
15 return one.substr(0, two.size()) == two; | 17 return one.substr(0, two.size()) == two; |
16 } | 18 } |
17 | 19 |
18 bool ends_with(const std::string& one, const std::string& two) { | 20 bool ends_with(const std::string& one, const std::string& two) { |
19 if (two.size() > one.size()) | 21 if (two.size() > one.size()) |
20 return false; | 22 return false; |
21 | 23 |
22 return one.substr(one.size() - two.size(), two.size()) == two; | 24 return one.substr(one.size() - two.size(), two.size()) == two; |
23 } | 25 } |
24 | 26 |
25 } // namespace | 27 } // namespace |
26 | 28 |
27 ChromeClassTester::ChromeClassTester(CompilerInstance& instance) | 29 ChromeClassTester::ChromeClassTester(CompilerInstance& instance) |
28 : instance_(instance), | 30 : instance_(instance), |
29 diagnostic_(instance.getDiagnostics()) { | 31 diagnostic_(instance.getDiagnostics()) { |
32 FigureOutSrcRoot(); | |
33 BuildBannedLists(); | |
34 } | |
35 | |
36 void ChromeClassTester::FigureOutSrcRoot() { | |
37 char c_cwd[MAXPATHLEN]; | |
38 if (getcwd(c_cwd, MAXPATHLEN) > 0) { | |
39 size_t pos = 1; | |
40 std::string cwd = c_cwd; | |
41 | |
42 // Add a trailing '/' because the search below requires it. | |
43 if (cwd[cwd.size() - 1] != '/') | |
44 cwd += '/'; | |
45 | |
46 // Search the directory tree downwards until we find a path that contains | |
47 // "build/common.gypi" and assume that that is our srcroot. | |
48 size_t next_slash = cwd.find('/', pos); | |
49 while (next_slash != std::string::npos) { | |
50 next_slash++; | |
51 std::string candidate = cwd.substr(0, next_slash); | |
52 std::string common = candidate + "build/common.gypi"; | |
53 | |
54 if (access(common.c_str(), F_OK) != -1) { | |
Nico
2011/02/25 02:08:41
you can save quite a few stats here if you only ch
| |
55 srcroot_ = candidate; | |
56 break; | |
57 } | |
58 | |
59 pos = next_slash; | |
60 next_slash = cwd.find('/', pos); | |
61 } | |
62 } | |
63 | |
64 if (srcroot_.empty()) { | |
65 llvm::errs() << "WARNING: Can't figure out srcroot!\n"; | |
Nico
2011/02/25 02:08:41
emit an error?
| |
66 } | |
67 } | |
68 | |
69 void ChromeClassTester::BuildBannedLists() { | |
30 banned_namespaces_.push_back("std"); | 70 banned_namespaces_.push_back("std"); |
31 banned_namespaces_.push_back("__gnu_cxx"); | 71 banned_namespaces_.push_back("__gnu_cxx"); |
32 | 72 |
33 banned_directories_.push_back("third_party"); | 73 banned_directories_.push_back("third_party"); |
34 banned_directories_.push_back("native_client"); | 74 banned_directories_.push_back("native_client"); |
35 banned_directories_.push_back("breakpad"); | 75 banned_directories_.push_back("breakpad"); |
36 banned_directories_.push_back("courgette"); | 76 banned_directories_.push_back("courgette"); |
37 banned_directories_.push_back("ppapi"); | 77 banned_directories_.push_back("ppapi"); |
38 banned_directories_.push_back("/usr"); | 78 banned_directories_.push_back("/usr"); |
39 banned_directories_.push_back("testing"); | 79 banned_directories_.push_back("testing"); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 // Don't complain about these things in implementation files. | 217 // Don't complain about these things in implementation files. |
178 if (ends_with(b, ".cc") || ends_with(b, ".cpp") || ends_with(b, ".mm")) { | 218 if (ends_with(b, ".cc") || ends_with(b, ".cpp") || ends_with(b, ".mm")) { |
179 return true; | 219 return true; |
180 } | 220 } |
181 | 221 |
182 // Don't complain about autogenerated protobuf files. | 222 // Don't complain about autogenerated protobuf files. |
183 if (ends_with(b, ".pb.h")) { | 223 if (ends_with(b, ".pb.h")) { |
184 return true; | 224 return true; |
185 } | 225 } |
186 | 226 |
187 // Strip out all preceding path garbage. Linux and mac builds have | 227 // We need to munge the paths so that they are relative to the repository |
188 // different path garbage, but after doing this, the path should be | 228 // srcroot. We first resolve the symlinktastic relative path and then |
189 // relative to the root of the source tree. (If we didn't require | 229 // remove our known srcroot from it if needed. |
190 // relative paths, we could have just used realpath().) | 230 char resolvedPath[MAXPATHLEN]; |
191 if (!b.empty() && b[0] != '/') { | 231 if (realpath(b.c_str(), resolvedPath)) { |
192 size_t i = 0; | 232 std::string resolved = resolvedPath; |
193 for (; i < b.size() && (b[i] == '.' || b[i] == '/'); ++i) {} | 233 if (starts_with(resolved, srcroot_)) { |
194 b = b.substr(i); | 234 b = resolved.substr(srcroot_.size()); |
235 } | |
195 } | 236 } |
196 | 237 |
197 for (std::vector<std::string>::const_iterator it = | 238 for (std::vector<std::string>::const_iterator it = |
198 banned_directories_.begin(); | 239 banned_directories_.begin(); |
199 it != banned_directories_.end(); ++it) { | 240 it != banned_directories_.end(); ++it) { |
200 if (starts_with(b, *it)) | 241 if (starts_with(b, *it)) |
201 return true; | 242 return true; |
202 } | 243 } |
203 } | 244 } |
204 } | 245 } |
205 | 246 |
206 return false; | 247 return false; |
207 } | 248 } |
208 | 249 |
209 bool ChromeClassTester::IsIgnoredType(const std::string& base_name) { | 250 bool ChromeClassTester::IsIgnoredType(const std::string& base_name) { |
210 for (std::vector<std::string>::const_iterator it = | 251 for (std::vector<std::string>::const_iterator it = |
211 ignored_record_names_.begin(); | 252 ignored_record_names_.begin(); |
212 it != ignored_record_names_.end(); ++it) { | 253 it != ignored_record_names_.end(); ++it) { |
213 if (base_name == *it) | 254 if (base_name == *it) |
214 return true; | 255 return true; |
215 } | 256 } |
216 | 257 |
217 return false; | 258 return false; |
218 } | 259 } |
OLD | NEW |