Skip to content

Commit

Permalink
Merge commit '60bb2707f53c' from swift/release/5.4 into swift/main
Browse files Browse the repository at this point in the history
  • Loading branch information
git apple-llvm automerger committed Jan 22, 2021
2 parents 25bd41d + 60bb270 commit 3bb55ca
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 45 deletions.
Expand Up @@ -55,9 +55,38 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
return true;
}

/// Utility function for just appending two paths.
static std::string MakePath(llvm::StringRef lhs, llvm::StringRef rhs) {
llvm::SmallString<256> result(lhs);
llvm::sys::path::append(result, rhs);
return std::string(result);
}

bool CppModuleConfiguration::hasValidConfig() {
// We all these include directories to have a valid usable configuration.
return m_c_inc.Valid() && m_std_inc.Valid();
// We need to have a C and C++ include dir for a valid configuration.
if (!m_c_inc.Valid() || !m_std_inc.Valid())
return false;

// Do some basic sanity checks on the directories that we don't activate
// the module when it's clear that it's not usable.
const std::vector<std::string> files_to_check = {
// * Check that the C library contains at least one random C standard
// library header.
MakePath(m_c_inc.Get(), "stdio.h"),
// * Without a libc++ modulemap file we can't have a 'std' module that
// could be imported.
MakePath(m_std_inc.Get(), "module.modulemap"),
// * Check for a random libc++ header (vector in this case) that has to
// exist in a working libc++ setup.
MakePath(m_std_inc.Get(), "vector"),
};

for (llvm::StringRef file_to_check : files_to_check) {
if (!FileSystem::Instance().Exists(file_to_check))
return false;
}

return true;
}

CppModuleConfiguration::CppModuleConfiguration(
Expand All @@ -76,7 +105,8 @@ CppModuleConfiguration::CppModuleConfiguration(
m_resource_inc = std::string(resource_dir.str());

// This order matches the way Clang orders these directories.
m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()};
m_include_dirs = {m_std_inc.Get().str(), m_resource_inc,
m_c_inc.Get().str()};
m_imported_modules = {"std"};
}
}
Expand Up @@ -32,7 +32,7 @@ class CppModuleConfiguration {
/// the path was already set.
LLVM_NODISCARD bool TrySet(llvm::StringRef path);
/// Return the path if there is one.
std::string Get() const {
llvm::StringRef Get() const {
assert(m_valid && "Called Get() on an invalid SetOncePath?");
return m_path;
}
Expand All @@ -57,9 +57,6 @@ class CppModuleConfiguration {

public:
/// Creates a configuration by analyzing the given list of used source files.
///
/// Currently only looks at the used paths and doesn't actually access the
/// files on the disk.
explicit CppModuleConfiguration(const FileSpecList &support_files);
/// Creates an empty and invalid configuration.
CppModuleConfiguration() {}
Expand Down
Expand Up @@ -2,7 +2,7 @@
// library module so the actual contents of the module are missing.
#ifdef ENABLE_STD_CONTENT

#include "libc_header.h"
#include "stdio.h"

namespace std {
inline namespace __1 {
Expand Down
@@ -1,4 +1,4 @@
#include "libc_header.h"
#include "stdio.h"

namespace std {
inline namespace __1 {
Expand Down
@@ -0,0 +1,10 @@
# We don't have any standard include directories, so we can't
# parse the test_common.h header we usually inject as it includes
# system headers.
NO_TEST_COMMON_H := 1

# Take the libc++ from the build directory (which will be later deleted).
CXXFLAGS_EXTRAS = -I $(BUILDDIR)/root/usr/include/c++/v1/ -I $(BUILDDIR)/root/usr/include/ -nostdinc -nostdinc++
CXX_SOURCES := main.cpp

include Makefile.rules
@@ -0,0 +1,60 @@
"""
Check that missing module source files are correctly handled by LLDB.
"""

from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
import os
import shutil


class TestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)

# We only emulate a fake libc++ in this test and don't use the real libc++,
# but we still add the libc++ category so that this test is only run in
# test configurations where libc++ is actually supposed to be tested.
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
def test(self):
# The path to our temporary target root that contains the temporary
# module sources.
target_sysroot = self.getBuildArtifact("root")

# Copy the sources to the root.
shutil.copytree(self.getSourcePath("root"), target_sysroot)
# Build the binary with the copied sources.
self.build()
# Delete the copied sources so that they are now unavailable.
shutil.rmtree(target_sysroot)

# Set the sysroot where our dummy libc++ used to exist. Just to make
# sure we don't find some existing headers on the system that could
# XPASS this test.
self.runCmd("platform select --sysroot '" + target_sysroot + "' host")

lldbutil.run_to_source_breakpoint(self,
"// Set break point at this line.",
lldb.SBFileSpec("main.cpp"))

# Import the std C++ module and run an expression.
# As we deleted the sources, LLDB should refuse the load the module
# and just print the normal error we get from the expression.
self.runCmd("settings set target.import-std-module true")
self.expect("expr v.unknown_identifier", error=True,
substrs=["no member named 'unknown_identifier'"])
# Check that there is no confusing error about failing to build the
# module.
self.expect("expr v.unknown_identifier", error=True, matching=False,
substrs=["could not build module 'std'"])

# Test the fallback mode. It should also just print the normal
# error but not mention a failed module build.
self.runCmd("settings set target.import-std-module fallback")

self.expect("expr v.unknown_identifier", error=True,
substrs=["no member named 'unknown_identifier'"])
self.expect("expr v.unknown_identifier", error=True, matching=False,
substrs=["could not build module 'std'"])
@@ -0,0 +1,8 @@
#include <vector>

int main(int argc, char **argv) {
// Makes sure we have the mock libc headers in the debug information.
libc_struct s;
std::vector<int> v;
return 0; // Set break point at this line.
}
@@ -0,0 +1,3 @@
module std {
module "vector" { header "vector" export * }
}
@@ -0,0 +1,9 @@
#include "stdio.h"

namespace std {
inline namespace __1 {
template<typename T>
struct vector {
};
}
}
@@ -1,4 +1,4 @@
#include "libc_header.h"
#include "stdio.h"

namespace std {
// Makes sure we get a support file for this header.
Expand Down
Empty file.
@@ -0,0 +1 @@
struct libc_struct {};

0 comments on commit 3bb55ca

Please sign in to comment.