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; |
| } |
| } |