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