From aaf6642f845b44a9d16091ced5c9ecff95221245 Mon Sep 17 00:00:00 2001 From: "erg@google.com" Date: Mon, 28 Feb 2011 20:05:32 +0000 Subject: Make the clang plugin look for path components. Previously, we assumed that paths were relative to the base of the src repository, which was bad. Now we'll search the entire path for the path component "third_party/" instead. BUG=carnitas TEST=compiles and reduces clang spew on mac trybots w/o harming linux outputs. Review URL: http://codereview.chromium.org/6577011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76247 0039d316-1c4b-4281-b951-d872f2087c98 --- tools/clang/plugins/ChromeClassTester.cpp | 62 +++++++++++++++++++++++++++---- tools/clang/plugins/ChromeClassTester.h | 5 +++ 2 files changed, 59 insertions(+), 8 deletions(-) (limited to 'tools/clang/plugins') diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp index 6565cf8..964d2c6 100644 --- a/tools/clang/plugins/ChromeClassTester.cpp +++ b/tools/clang/plugins/ChromeClassTester.cpp @@ -7,6 +7,8 @@ #include "ChromeClassTester.h" +#include + using namespace clang; namespace { @@ -27,6 +29,49 @@ bool ends_with(const std::string& one, const std::string& two) { ChromeClassTester::ChromeClassTester(CompilerInstance& instance) : instance_(instance), diagnostic_(instance.getDiagnostics()) { + FigureOutSrcRoot(); + BuildBannedLists(); +} + +void ChromeClassTester::FigureOutSrcRoot() { + char c_cwd[MAXPATHLEN]; + if (getcwd(c_cwd, MAXPATHLEN) > 0) { + size_t pos = 1; + std::string cwd = c_cwd; + + // Add a trailing '/' because the search below requires it. + if (cwd[cwd.size() - 1] != '/') + cwd += '/'; + + // Search the directory tree downwards until we find a path that contains + // "build/common.gypi" and assume that that is our srcroot. + size_t next_slash = cwd.find('/', pos); + while (next_slash != std::string::npos) { + next_slash++; + std::string candidate = cwd.substr(0, next_slash); + + if (ends_with(candidate, "src/")) { + std::string common = candidate + "build/common.gypi"; + if (access(common.c_str(), F_OK) != -1) { + src_root_ = candidate; + break; + } + } + + pos = next_slash; + next_slash = cwd.find('/', pos); + } + } + + if (src_root_.empty()) { + unsigned id = diagnostic().getCustomDiagID( + Diagnostic::Error, + "WARNING: Can't figure out srcroot!\n"); + diagnostic().Report(id); + } +} + +void ChromeClassTester::BuildBannedLists() { banned_namespaces_.push_back("std"); banned_namespaces_.push_back("__gnu_cxx"); @@ -184,14 +229,15 @@ bool ChromeClassTester::InBannedDirectory(const SourceLocation& loc) { return true; } - // Strip out all preceding path garbage. Linux and mac builds have - // different path garbage, but after doing this, the path should be - // relative to the root of the source tree. (If we didn't require - // relative paths, we could have just used realpath().) - if (!b.empty() && b[0] != '/') { - size_t i = 0; - for (; i < b.size() && (b[i] == '.' || b[i] == '/'); ++i) {} - b = b.substr(i); + // We need to munge the paths so that they are relative to the repository + // srcroot. We first resolve the symlinktastic relative path and then + // remove our known srcroot from it if needed. + char resolvedPath[MAXPATHLEN]; + if (realpath(b.c_str(), resolvedPath)) { + std::string resolved = resolvedPath; + if (starts_with(resolved, src_root_)) { + b = resolved.substr(src_root_.size()); + } } for (std::vector::const_iterator it = diff --git a/tools/clang/plugins/ChromeClassTester.h b/tools/clang/plugins/ChromeClassTester.h index 38b15e1..f755c1c 100644 --- a/tools/clang/plugins/ChromeClassTester.h +++ b/tools/clang/plugins/ChromeClassTester.h @@ -20,6 +20,9 @@ class ChromeClassTester : public clang::ASTConsumer { explicit ChromeClassTester(clang::CompilerInstance& instance); virtual ~ChromeClassTester(); + void FigureOutSrcRoot(); + void BuildBannedLists(); + // ASTConsumer: virtual void HandleTagDeclDefinition(clang::TagDecl* tag); @@ -54,6 +57,8 @@ class ChromeClassTester : public clang::ASTConsumer { clang::CompilerInstance& instance_; clang::Diagnostic& diagnostic_; + std::string src_root_; + // List of banned namespaces. std::vector banned_namespaces_; -- cgit v1.1