brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.9 KiB · 017a074 Raw
303 lines · cpp
1//===-- CppModuleConfigurationTest.cpp ------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Plugins/ExpressionParser/Clang/CppModuleConfiguration.h"10#include "Plugins/ExpressionParser/Clang/ClangHost.h"11#include "TestingSupport/SubsystemRAII.h"12#include "lldb/Host/FileSystem.h"13#include "lldb/Host/HostInfo.h"14 15#include "gmock/gmock.h"16#include "gtest/gtest.h"17 18using namespace lldb_private;19 20namespace {21struct CppModuleConfigurationTest : public testing::Test {22  llvm::MemoryBufferRef m_empty_buffer;23  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> m_fs;24 25  CppModuleConfigurationTest()26      : m_empty_buffer("", "<empty buffer>"),27        m_fs(new llvm::vfs::InMemoryFileSystem()) {}28 29  void SetUp() override {30    FileSystem::Initialize(m_fs);31    HostInfo::Initialize();32  }33 34  void TearDown() override {35    HostInfo::Terminate();36    FileSystem::Terminate();37  }38 39  /// Utility function turning a list of paths into a FileSpecList.40  FileSpecList makeFiles(llvm::ArrayRef<std::string> paths) {41    FileSpecList result;42    for (const std::string &path : paths) {43      result.Append(FileSpec(path, FileSpec::Style::posix));44      if (!m_fs->addFileNoOwn(path, static_cast<time_t>(0), m_empty_buffer))45        llvm_unreachable("Invalid test configuration?");46    }47    return result;48  }49};50} // namespace51 52/// Returns the Clang resource include directory.53static std::string ResourceInc() {54  llvm::SmallString<256> resource_dir;55  llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(),56                          "include");57  return std::string(resource_dir);58}59 60TEST_F(CppModuleConfigurationTest, Linux) {61  // Test the average Linux configuration.62 63  std::string usr = "/usr/include";64  std::string libcpp = "/usr/include/c++/v1";65  std::vector<std::string> files = {// C library66                                    usr + "/stdio.h",67                                    // C++ library68                                    libcpp + "/vector",69                                    libcpp + "/module.modulemap"};70  CppModuleConfiguration config(makeFiles(files), llvm::Triple());71  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));72  EXPECT_THAT(config.GetIncludeDirs(),73              testing::ElementsAre(libcpp, ResourceInc(), usr));74}75 76TEST_F(CppModuleConfigurationTest, LinuxTargetSpecificInclude) {77  // Test the average Linux configuration.78 79  std::string usr = "/usr/include";80  std::string usr_target = "/usr/include/x86_64-linux-gnu";81  std::string libcpp = "/usr/include/c++/v1";82  std::string libcpp_target = "/usr/include/x86_64-unknown-linux-gnu/c++/v1";83  std::vector<std::string> files = {84      // C library85      usr + "/stdio.h", usr_target + "/sys/cdefs.h",86      // C++ library87      libcpp + "/vector", libcpp + "/module.modulemap"};88  CppModuleConfiguration config(makeFiles(files),89                                llvm::Triple("x86_64-unknown-linux-gnu"));90  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));91  EXPECT_THAT(config.GetIncludeDirs(),92              testing::ElementsAre(libcpp, ResourceInc(), usr, usr_target,93                                   libcpp_target));94}95 96TEST_F(CppModuleConfigurationTest, Sysroot) {97  // Test that having a sysroot for the whole system works fine.98 99  std::string libcpp = "/home/user/sysroot/usr/include/c++/v1";100  std::string usr = "/home/user/sysroot/usr/include";101  std::vector<std::string> files = {// C library102                                    usr + "/stdio.h",103                                    // C++ library104                                    libcpp + "/vector",105                                    libcpp + "/module.modulemap"};106  CppModuleConfiguration config(makeFiles(files), llvm::Triple());107  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));108  EXPECT_THAT(config.GetIncludeDirs(),109              testing::ElementsAre(libcpp, ResourceInc(), usr));110}111 112TEST_F(CppModuleConfigurationTest, LinuxLocalLibCpp) {113  // Test that a locally build libc++ is detected.114 115  std::string usr = "/usr/include";116  std::string libcpp = "/home/user/llvm-build/include/c++/v1";117  std::vector<std::string> files = {// C library118                                    usr + "/stdio.h",119                                    // C++ library120                                    libcpp + "/vector",121                                    libcpp + "/module.modulemap"};122  CppModuleConfiguration config(makeFiles(files), llvm::Triple());123  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));124  EXPECT_THAT(config.GetIncludeDirs(),125              testing::ElementsAre(libcpp, ResourceInc(), usr));126}127 128TEST_F(CppModuleConfigurationTest, UnrelatedLibrary) {129  // Test that having an unrelated library in /usr/include doesn't break.130 131  std::string usr = "/usr/include";132  std::string libcpp = "/home/user/llvm-build/include/c++/v1";133  std::vector<std::string> files = {// C library134                                    usr + "/stdio.h",135                                    // unrelated library136                                    usr + "/boost/vector",137                                    // C++ library138                                    libcpp + "/vector",139                                    libcpp + "/module.modulemap"};140  CppModuleConfiguration config(makeFiles(files), llvm::Triple());141  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));142  EXPECT_THAT(config.GetIncludeDirs(),143              testing::ElementsAre(libcpp, ResourceInc(), usr));144}145 146TEST_F(CppModuleConfigurationTest, UnrelatedLibraryWithTargetSpecificInclude) {147  // Test that having an unrelated library in /usr/include doesn't break.148 149  std::string usr = "/usr/include";150  std::string libcpp = "/home/user/llvm-build/include/c++/v1";151  std::string libcpp_target =152      "/home/user/llvm-build/include/x86_64-unknown-linux-gnu/c++/v1";153  std::vector<std::string> files = {// C library154                                    usr + "/stdio.h",155                                    // unrelated library156                                    usr + "/boost/vector",157                                    // C++ library158                                    libcpp + "/vector",159                                    libcpp + "/module.modulemap"};160  CppModuleConfiguration config(makeFiles(files),161                                llvm::Triple("x86_64-unknown-linux-gnu"));162  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));163  EXPECT_THAT(config.GetIncludeDirs(),164              testing::ElementsAre(libcpp, ResourceInc(), usr, libcpp_target));165}166 167TEST_F(CppModuleConfigurationTest, Xcode) {168  // Test detection of libc++ coming from Xcode with generic platform names.169 170  std::string p = "/Applications/Xcode.app/Contents/Developer/";171  std::string libcpp = p + "Toolchains/B.xctoolchain/usr/include/c++/v1";172  std::string usr =173      p + "Platforms/A.platform/Developer/SDKs/OSVers.sdk/usr/include";174  std::vector<std::string> files = {175      // C library176      usr + "/stdio.h",177      // C++ library178      libcpp + "/vector",179      libcpp + "/module.modulemap",180  };181  CppModuleConfiguration config(makeFiles(files), llvm::Triple());182  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));183  EXPECT_THAT(config.GetIncludeDirs(),184              testing::ElementsAre(libcpp, ResourceInc(), usr));185}186 187TEST_F(CppModuleConfigurationTest, LibCppV2) {188  // Test that a "v2" of libc++ is still correctly detected.189 190  std::string libcpp = "/usr/include/c++/v2";191  std::vector<std::string> files = {// C library192                                    "/usr/include/stdio.h",193                                    // C++ library194                                    libcpp + "/vector",195                                    libcpp + "/module.modulemap"};196  CppModuleConfiguration config(makeFiles(files), llvm::Triple());197  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));198  EXPECT_THAT(config.GetIncludeDirs(),199              testing::ElementsAre("/usr/include/c++/v2", ResourceInc(),200                                   "/usr/include"));201}202 203TEST_F(CppModuleConfigurationTest, UnknownLibCppFile) {204  // Test that having some unknown file in the libc++ path doesn't break205  // anything.206 207  std::string libcpp = "/usr/include/c++/v1";208  std::vector<std::string> files = {// C library209                                    "/usr/include/stdio.h",210                                    // C++ library211                                    libcpp + "/non_existing_file",212                                    libcpp + "/module.modulemap",213                                    libcpp + "/vector"};214  CppModuleConfiguration config(makeFiles(files), llvm::Triple());215  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std"));216  EXPECT_THAT(config.GetIncludeDirs(),217              testing::ElementsAre("/usr/include/c++/v1", ResourceInc(),218                                   "/usr/include"));219}220 221TEST_F(CppModuleConfigurationTest, MissingUsrInclude) {222  // Test that we don't load 'std' if we can't find the C standard library.223 224  std::string libcpp = "/usr/include/c++/v1";225  std::vector<std::string> files = {// C++ library226                                    libcpp + "/vector",227                                    libcpp + "/module.modulemap"};228  CppModuleConfiguration config(makeFiles(files), llvm::Triple());229  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre());230  EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre());231}232 233TEST_F(CppModuleConfigurationTest, MissingLibCpp) {234  // Test that we don't load 'std' if we don't have a libc++.235 236  std::string usr = "/usr/include";237  std::vector<std::string> files = {238      // C library239      usr + "/stdio.h",240  };241  CppModuleConfiguration config(makeFiles(files), llvm::Triple());242  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre());243  EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre());244}245 246TEST_F(CppModuleConfigurationTest, IgnoreLibStdCpp) {247  // Test that we don't do anything bad when we encounter libstdc++ paths.248 249  std::string usr = "/usr/include";250  std::vector<std::string> files = {251      // C library252      usr + "/stdio.h",253      // C++ library254      usr + "/c++/8.0.1/vector",255  };256  CppModuleConfiguration config(makeFiles(files), llvm::Triple());257  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre());258  EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre());259}260 261TEST_F(CppModuleConfigurationTest, AmbiguousCLib) {262  // Test that we don't do anything when we are not sure where the263  // right C standard library is.264 265  std::string usr1 = "/usr/include";266  std::string usr2 = "/usr/include/other/path";267  std::string libcpp = usr1 + "c++/v1";268  std::vector<std::string> files = {269      // First C library270      usr1 + "/stdio.h",271      // Second C library272      usr2 + "/stdio.h",273      // C++ library274      libcpp + "/vector",275      libcpp + "/module.modulemap",276  };277  CppModuleConfiguration config(makeFiles(files), llvm::Triple());278  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre());279  EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre());280}281 282TEST_F(CppModuleConfigurationTest, AmbiguousLibCpp) {283  // Test that we don't do anything when we are not sure where the284  // right libc++ is.285 286  std::string usr = "/usr/include";287  std::string libcpp1 = usr + "c++/v1";288  std::string libcpp2 = usr + "c++/v2";289  std::vector<std::string> files = {290      // C library291      usr + "/stdio.h",292      // First C++ library293      libcpp1 + "/vector",294      libcpp1 + "/module.modulemap",295      // Second C++ library296      libcpp2 + "/vector",297      libcpp2 + "/module.modulemap",298  };299  CppModuleConfiguration config(makeFiles(files), llvm::Triple());300  EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre());301  EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre());302}303