Chromium Code Reviews| Index: tools/clang/translation_unit/TranslationUnitGenerator.cpp | 
| diff --git a/tools/clang/translation_unit/TranslationUnitGenerator.cpp b/tools/clang/translation_unit/TranslationUnitGenerator.cpp | 
| index 5db8d640b74c5c6e5b6328c9ee7ab49e6f8cbe95..6e27e6ce5f72eb6e4a7aca5fb14a279e63286a53 100644 | 
| --- a/tools/clang/translation_unit/TranslationUnitGenerator.cpp | 
| +++ b/tools/clang/translation_unit/TranslationUnitGenerator.cpp | 
| @@ -23,6 +23,7 @@ | 
| #include "clang/Basic/SourceManager.h" | 
| #include "clang/Frontend/CompilerInstance.h" | 
| #include "clang/Frontend/FrontendActions.h" | 
| +#include "clang/Lex/HeaderSearchOptions.h" | 
| #include "clang/Lex/PPCallbacks.h" | 
| #include "clang/Lex/Preprocessor.h" | 
| #include "clang/Tooling/CommonOptionsParser.h" | 
| @@ -31,6 +32,7 @@ | 
| #include "clang/Tooling/Tooling.h" | 
| #include "llvm/Support/CommandLine.h" | 
| +using clang::HeaderSearchOptions; | 
| using clang::tooling::CommonOptionsParser; | 
| using std::set; | 
| using std::stack; | 
| @@ -43,10 +45,8 @@ class IncludeFinderPPCallbacks : public clang::PPCallbacks { | 
| public: | 
| IncludeFinderPPCallbacks(clang::SourceManager* source_manager, | 
| string* main_source_file, | 
| - set<string>* source_file_paths) | 
| - : source_manager_(source_manager), | 
| - main_source_file_(main_source_file), | 
| - source_file_paths_(source_file_paths) {} | 
| + set<string>* source_file_paths, | 
| + const HeaderSearchOptions* header_search_options); | 
| void FileChanged(clang::SourceLocation /*loc*/, | 
| clang::PPCallbacks::FileChangeReason reason, | 
| clang::SrcMgr::CharacteristicKind /*file_type*/, | 
| @@ -64,9 +64,13 @@ class IncludeFinderPPCallbacks : public clang::PPCallbacks { | 
| void EndOfMainFile() override; | 
| private: | 
| + string DoubleSlashSystemHeaders(const string& search_path, | 
| + const string& relative_path) const; | 
| + | 
| clang::SourceManager* const source_manager_; | 
| string* const main_source_file_; | 
| set<string>* const source_file_paths_; | 
| + set<string> system_header_prefixes_; | 
| // The path of the file that was last referenced by an inclusion directive, | 
| // normalized for includes that are relative to a different source file. | 
| string last_inclusion_directive_; | 
| @@ -74,6 +78,35 @@ class IncludeFinderPPCallbacks : public clang::PPCallbacks { | 
| stack<string> current_files_; | 
| }; | 
| +IncludeFinderPPCallbacks::IncludeFinderPPCallbacks( | 
| + clang::SourceManager* source_manager, | 
| + string* main_source_file, | 
| + set<string>* source_file_paths, | 
| + const HeaderSearchOptions* header_search_options) | 
| + : source_manager_(source_manager), | 
| + main_source_file_(main_source_file), | 
| + source_file_paths_(source_file_paths) { | 
| + for (const auto& prefix : header_search_options->SystemHeaderPrefixes) { | 
| 
 
Adrian Kuegel
2016/02/01 09:46:25
In the documentation this is saying "User-specifie
 
Adrian Kuegel
2016/02/01 09:54:10
I just asked a team mate, and he told me that it i
 
dsansome
2016/02/02 06:48:58
It seems to be empty for me anyway.  All the syste
 
Adrian Kuegel
2016/02/02 08:37:19
Maybe I misunderstood him, or he was wrong. Anyway
 
 | 
| + system_header_prefixes_.insert(prefix.Prefix); | 
| + } | 
| + | 
| + for (const auto& entry : header_search_options->UserEntries) { | 
| 
 
Adrian Kuegel
2016/02/01 09:46:25
I am not so sure about if this works correctly. If
 
dsansome
2016/02/02 06:48:58
This list has all the paths in, but ones from -I h
 
Adrian Kuegel
2016/02/02 08:37:19
Interesting; that seems to indicate that Chromium
 
 | 
| + switch (entry.Group) { | 
| + case clang::frontend::System: | 
| + case clang::frontend::ExternCSystem: | 
| + case clang::frontend::CSystem: | 
| + case clang::frontend::CXXSystem: | 
| + case clang::frontend::ObjCSystem: | 
| + case clang::frontend::ObjCXXSystem: | 
| + case clang::frontend::After: | 
| + system_header_prefixes_.insert(entry.Path); | 
| + break; | 
| + default: | 
| + break; | 
| + } | 
| + } | 
| +} | 
| + | 
| void IncludeFinderPPCallbacks::FileChanged( | 
| clang::SourceLocation /*loc*/, | 
| clang::PPCallbacks::FileChangeReason reason, | 
| @@ -135,21 +168,30 @@ void IncludeFinderPPCallbacks::InclusionDirective( | 
| // Otherwise we take the literal path as we stored it for the current | 
| // file, and append the relative path. | 
| - last_inclusion_directive_ = parent + "/" + relative_path.str(); | 
| + last_inclusion_directive_ = | 
| + DoubleSlashSystemHeaders(parent, relative_path.str()); | 
| } else if (!search_path.empty()) { | 
| - // We want to be able to extract the search path relative to which the | 
| - // include statement is defined. Therefore if search_path is an absolute | 
| - // path (indicating it is most likely a system header) we use "//" as a | 
| - // separator between the search path and the relative path. | 
| - last_inclusion_directive_ = search_path.str() + | 
| - (llvm::sys::path::is_absolute(search_path) ? "//" : "/") + | 
| - relative_path.str(); | 
| + last_inclusion_directive_ = | 
| + DoubleSlashSystemHeaders(search_path.str(), relative_path.str()); | 
| } else { | 
| last_inclusion_directive_ = file_name.str(); | 
| } | 
| AddFile(last_inclusion_directive_); | 
| } | 
| +string IncludeFinderPPCallbacks::DoubleSlashSystemHeaders( | 
| + const string& search_path, | 
| + const string& relative_path) const { | 
| + // We want to be able to extract the search path relative to which the | 
| + // include statement is defined. Therefore if search_path is a system header | 
| + // we use "//" as a separator between the search path and the relative path. | 
| + const bool is_system_header = | 
| + system_header_prefixes_.find(search_path) != | 
| + system_header_prefixes_.end(); | 
| + | 
| + return search_path + (is_system_header ? "//" : "/") + relative_path; | 
| +} | 
| + | 
| void IncludeFinderPPCallbacks::EndOfMainFile() { | 
| const clang::FileEntry* main_file = | 
| source_manager_->getFileEntryForID(source_manager_->getMainFileID()); | 
| @@ -190,7 +232,8 @@ void CompilationIndexerAction::Preprocess() { | 
| preprocessor.addPPCallbacks(llvm::make_unique<IncludeFinderPPCallbacks>( | 
| &getCompilerInstance().getSourceManager(), | 
| &main_source_file_, | 
| - &source_file_paths_)); | 
| + &source_file_paths_, | 
| + &getCompilerInstance().getHeaderSearchOpts())); | 
| preprocessor.getDiagnostics().setIgnoreAllWarnings(true); | 
| preprocessor.SetSuppressIncludeNotFoundError(true); | 
| preprocessor.EnterMainSourceFile(); | 
| @@ -202,7 +245,7 @@ void CompilationIndexerAction::Preprocess() { | 
| void CompilationIndexerAction::EndSourceFileAction() { | 
| std::ofstream out(main_source_file_ + ".filepaths"); | 
| - for (string path : source_file_paths_) { | 
| + for (const string& path : source_file_paths_) { | 
| out << path << std::endl; | 
| } | 
| } |