kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/extractor/cxx_details.cc (about) 1 /* 2 * Copyright 2015 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "kythe/cxx/extractor/cxx_details.h" 18 19 #include <string> 20 21 #include "absl/log/log.h" 22 #include "clang/Basic/SourceManager.h" 23 #include "clang/Lex/DirectoryLookup.h" 24 #include "clang/Lex/HeaderSearch.h" 25 #include "clang/Lex/HeaderSearchOptions.h" 26 #include "kythe/proto/cxx.pb.h" 27 28 namespace kythe { 29 30 /// The type URI for C++ details. 31 const char kCxxCompilationUnitDetailsURI[] = 32 "kythe.io/proto/kythe.proto.CxxCompilationUnitDetails"; 33 34 void HeaderSearchInfo::CopyTo( 35 kythe::proto::CxxCompilationUnitDetails* cxx_details) const { 36 auto* info = cxx_details->mutable_header_search_info(); 37 info->set_first_angled_dir(angled_dir_idx); 38 info->set_first_system_dir(system_dir_idx); 39 for (const auto& path : paths) { 40 auto* dir = info->add_dir(); 41 dir->set_path(path.path); 42 dir->set_characteristic_kind(path.characteristic_kind); 43 dir->set_is_framework(path.is_framework); 44 } 45 for (const auto& prefix : system_prefixes) { 46 auto* proto = cxx_details->add_system_header_prefix(); 47 proto->set_is_system_header(prefix.second); 48 proto->set_prefix(prefix.first); 49 } 50 } 51 52 bool HeaderSearchInfo::CopyFrom( 53 const kythe::proto::CxxCompilationUnitDetails& cxx_details) { 54 paths.clear(); 55 system_prefixes.clear(); 56 const auto& info = cxx_details.header_search_info(); 57 angled_dir_idx = info.first_angled_dir(); 58 system_dir_idx = info.first_system_dir(); 59 for (const auto& dir : info.dir()) { 60 paths.emplace_back( 61 HeaderSearchInfo::Path{dir.path(), 62 static_cast<clang::SrcMgr::CharacteristicKind>( 63 dir.characteristic_kind()), 64 dir.is_framework()}); 65 } 66 for (const auto& prefix : cxx_details.system_header_prefix()) { 67 system_prefixes.emplace_back(prefix.prefix(), prefix.is_system_header()); 68 } 69 return (angled_dir_idx <= system_dir_idx && system_dir_idx <= paths.size()); 70 } 71 72 bool HeaderSearchInfo::CopyFrom( 73 const clang::HeaderSearchOptions& header_search_options, 74 const clang::HeaderSearch& header_search_info) { 75 paths.clear(); 76 system_prefixes.clear(); 77 angled_dir_idx = header_search_info.search_dir_size(); 78 system_dir_idx = header_search_info.search_dir_size(); 79 unsigned cur_dir_idx = 0; 80 // Clang never sets no_cur_dir_search to true? (see InitHeaderSearch.cpp) 81 bool no_cur_dir_search = false; 82 auto first_angled_dir = header_search_info.angled_dir_begin(); 83 auto first_system_dir = header_search_info.system_dir_begin(); 84 auto last_dir = header_search_info.system_dir_end(); 85 for (const auto& prefix : header_search_options.SystemHeaderPrefixes) { 86 system_prefixes.emplace_back(prefix.Prefix, prefix.IsSystemHeader); 87 } 88 for (auto iter = header_search_info.search_dir_begin(); iter != last_dir; 89 ++cur_dir_idx, ++iter) { 90 if (iter == first_angled_dir) { 91 angled_dir_idx = cur_dir_idx; 92 } else if (iter == first_system_dir) { 93 system_dir_idx = cur_dir_idx; 94 } 95 switch (iter->getLookupType()) { 96 case clang::DirectoryLookup::LT_NormalDir: 97 paths.push_back(HeaderSearchInfo::Path{ 98 std::string(iter->getName()), iter->getDirCharacteristic(), false}); 99 break; 100 case clang::DirectoryLookup::LT_Framework: 101 paths.push_back(HeaderSearchInfo::Path{ 102 std::string(iter->getName()), iter->getDirCharacteristic(), true}); 103 break; 104 default: // clang::DirectoryLookup::LT_HeaderMap: 105 // TODO(zarko): Support LT_HeaderMap. 106 LOG(WARNING) << "Can't reproduce include lookup state: " 107 << iter->getName().str() << " is not a normal directory."; 108 return false; 109 } 110 } 111 return true; 112 } 113 114 } // namespace kythe