Skip to content

[pull] swiftwasm from swift/main #1088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
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"};
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "libc_header.h"
#include "stdio.h"

namespace std {
inline namespace __1 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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'"])
Original file line number Diff line number Diff line change
@@ -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.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module std {
module "vector" { header "vector" export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "stdio.h"

namespace std {
inline namespace __1 {
template<typename T>
struct vector {
};
}
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
struct libc_struct {};
Loading