summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2014-12-05 01:16:31 +0000
committerSean Callanan <scallanan@apple.com>2014-12-05 01:16:31 +0000
commit5dc2981cf8ff580fda060c93e663730b17e9be95 (patch)
treea827450b8293fa54c68c0276e9663524cd1975f4 /lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
parentb1e1c62fac12bf5c48b57d5e90d65bf1e48170b7 (diff)
downloadbcm5719-llvm-5dc2981cf8ff580fda060c93e663730b17e9be95.tar.gz
bcm5719-llvm-5dc2981cf8ff580fda060c93e663730b17e9be95.zip
Added support to Platform to indicate (1) whether the
current platform supports Clang modules, and (2) what options to pass to Clang so it can load those Clang modules. llvm-svn: 223431
Diffstat (limited to 'lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp')
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp291
1 files changed, 290 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index fb48c01230b..acf99be1388 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1181,4 +1181,293 @@ void
PlatformDarwin::CalculateTrapHandlerSymbolNames ()
{
m_trap_handlers.push_back (ConstString ("_sigtramp"));
-}
+}
+
+
+static const char *const sdk_strings[] = {
+ "MacOSX",
+ "iPhoneSimulator",
+ "iPhoneOS",
+};
+
+static FileSpec
+GetXcodeContentsPath ()
+{
+ const char substr[] = ".app/Contents/";
+
+ // First, try based on the current shlib's location
+
+ {
+ FileSpec fspec;
+
+ if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBShlibDir, fspec))
+ {
+ std::string path_to_shlib = fspec.GetPath();
+ size_t pos = path_to_shlib.rfind(substr);
+ if (pos != std::string::npos)
+ {
+ path_to_shlib.erase(pos + strlen(substr));
+ return FileSpec(path_to_shlib.c_str(), false);
+ }
+ }
+ }
+
+ // Fall back to using xcrun
+
+ {
+ int status = 0;
+ int signo = 0;
+ std::string output;
+ const char *command = "xcrun -sdk macosx --show-sdk-path";
+ lldb_private::Error error = Host::RunShellCommand (command, // shell command to run
+ NULL, // current working directory
+ &status, // Put the exit status of the process in here
+ &signo, // Put the signal that caused the process to exit in here
+ &output, // Get the output from the command and place it in this string
+ 3); // Timeout in seconds to wait for shell program to finish
+ if (status == 0 && !output.empty())
+ {
+ size_t first_non_newline = output.find_last_not_of("\r\n");
+ if (first_non_newline != std::string::npos)
+ {
+ output.erase(first_non_newline+1);
+ }
+
+ size_t pos = output.rfind(substr);
+ if (pos != std::string::npos)
+ {
+ output.erase(pos + strlen(substr));
+ return FileSpec(output.c_str(), false);
+ }
+ }
+ }
+
+ return FileSpec();
+}
+
+bool
+PlatformDarwin::SDKSupportsModules (SDKType sdk_type, uint32_t major, uint32_t minor, uint32_t micro)
+{
+ switch (sdk_type)
+ {
+ default:
+ return false;
+ case SDKType::MacOSX:
+ if (major > 10 || (major == 10 && minor >= 10))
+ return true;
+ break;
+ case SDKType::iPhoneOS:
+ case SDKType::iPhoneSimulator:
+ if (major >= 8)
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+bool
+PlatformDarwin::SDKSupportsModules (SDKType desired_type, const FileSpec &sdk_path)
+{
+ ConstString last_path_component = sdk_path.GetLastPathComponent();
+
+ if (last_path_component)
+ {
+ const llvm::StringRef sdk_name = last_path_component.GetStringRef();
+
+ llvm::StringRef version_part;
+
+ if (sdk_name.startswith(sdk_strings[(int)desired_type]))
+ {
+ version_part = sdk_name.drop_front(strlen(sdk_strings[(int)desired_type]));
+ }
+ else
+ {
+ return false;
+ }
+
+ const size_t major_dot_offset = version_part.find('.');
+ if (major_dot_offset == llvm::StringRef::npos)
+ return false;
+
+ const llvm::StringRef major_version = version_part.slice(0, major_dot_offset);
+ const llvm::StringRef minor_part = version_part.drop_front(major_dot_offset + 1);
+
+ const size_t minor_dot_offset = minor_part.find('.');
+ if (minor_dot_offset == llvm::StringRef::npos)
+ return false;
+
+ const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset);
+
+ unsigned int major = 0;
+ unsigned int minor = 0;
+ unsigned int micro = 0;
+
+ if (major_version.getAsInteger(10, major))
+ return false;
+
+ if (minor_version.getAsInteger(10, minor))
+ return false;
+
+ return SDKSupportsModules(desired_type, major, minor, micro);
+ }
+
+ return false;
+}
+
+FileSpec::EnumerateDirectoryResult
+PlatformDarwin::DirectoryEnumerator(void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &spec)
+{
+ SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo*>(baton);
+
+ if (SDKSupportsModules(enumerator_info->sdk_type, spec))
+ {
+ enumerator_info->found_path = spec;
+ return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
+ }
+
+ return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
+};
+
+FileSpec
+PlatformDarwin::FindSDKInXcodeForModules (SDKType sdk_type,
+ const FileSpec &sdks_spec)
+{
+ // Look inside Xcode for the required installed iOS SDK version
+
+ if (!sdks_spec.IsDirectory())
+ return FileSpec();
+
+ const bool find_directories = true;
+ const bool find_files = false;
+ const bool find_other = true; // include symlinks
+
+ SDKEnumeratorInfo enumerator_info;
+
+ enumerator_info.sdk_type = sdk_type;
+
+ FileSpec::EnumerateDirectory(sdks_spec.GetPath().c_str(),
+ find_directories,
+ find_files,
+ find_other,
+ DirectoryEnumerator,
+ &enumerator_info);
+
+ if (enumerator_info.found_path.IsDirectory())
+ return enumerator_info.found_path;
+ else
+ return FileSpec();
+}
+
+FileSpec
+PlatformDarwin::GetSDKDirectoryForModules (SDKType sdk_type)
+{
+ switch (sdk_type)
+ {
+ default:
+ return FileSpec();
+ case SDKType::MacOSX:
+ case SDKType::iPhoneSimulator:
+ case SDKType::iPhoneOS:
+ break;
+ }
+
+ FileSpec sdks_spec = GetXcodeContentsPath();
+ sdks_spec.AppendPathComponent("Developer");
+ sdks_spec.AppendPathComponent("Platforms");
+
+ switch (sdk_type)
+ {
+ default:
+ return FileSpec();
+ case SDKType::MacOSX:
+ sdks_spec.AppendPathComponent("MacOSX.platform");
+ break;
+ case SDKType::iPhoneSimulator:
+ sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
+ break;
+ case SDKType::iPhoneOS:
+ sdks_spec.AppendPathComponent("iPhoneOS.platform");
+ break;
+ }
+
+ sdks_spec.AppendPathComponent("Developer");
+ sdks_spec.AppendPathComponent("SDKs");
+
+ if (sdk_type == SDKType::MacOSX)
+ {
+ uint32_t major = 0;
+ uint32_t minor = 0;
+ uint32_t micro = 0;
+
+ if (HostInfo::GetOSVersion(major, minor, micro))
+ {
+ if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro))
+ {
+ // We slightly prefer the exact SDK for this machine. See if it is there.
+
+ FileSpec native_sdk_spec = sdks_spec;
+ StreamString native_sdk_name;
+ native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor);
+ native_sdk_spec.AppendPathComponent(native_sdk_name.GetString().c_str());
+
+ if (native_sdk_spec.Exists())
+ {
+ return native_sdk_spec;
+ }
+ }
+ }
+ }
+
+ return FindSDKInXcodeForModules(sdk_type, sdks_spec);
+}
+
+void
+PlatformDarwin::AddClangModuleCompilationOptionsForSDKType (std::vector<std::string> &options, SDKType sdk_type)
+{
+ const std::vector<std::string> apple_arguments =
+ {
+ "-x", "objective-c++",
+ "-fobjc-arc",
+ "-fblocks",
+ "-D_ISO646_H",
+ "-D__ISO646_H"
+ };
+
+ options.insert(options.end(),
+ apple_arguments.begin(),
+ apple_arguments.end());
+
+ StreamString minimum_version_option;
+ unsigned int major = 0, minor = 0, micro = 0;
+ GetOSVersion(major, minor, micro);
+ if (micro == UINT32_MAX)
+ micro = 0; // FIXME who actually likes this behavior?
+
+ switch (sdk_type)
+ {
+ case SDKType::iPhoneOS:
+ minimum_version_option.PutCString("-mios-version-min=");
+ minimum_version_option.PutCString(clang::VersionTuple(major, minor, micro).getAsString().c_str());
+ break;
+ case SDKType::iPhoneSimulator:
+ minimum_version_option.PutCString("-mios-simulator-version-min=");
+ minimum_version_option.PutCString(clang::VersionTuple(major, minor, micro).getAsString().c_str());
+ break;
+ case SDKType::MacOSX:
+ minimum_version_option.PutCString("-mmacosx-version-min=");
+ minimum_version_option.PutCString(clang::VersionTuple(major, minor, micro).getAsString().c_str());
+ }
+
+ options.push_back(minimum_version_option.GetString());
+
+ FileSpec sysroot_spec = GetSDKDirectoryForModules(sdk_type);
+
+ if (sysroot_spec.IsDirectory())
+ {
+ options.push_back("-isysroot");
+ options.push_back(sysroot_spec.GetPath());
+ }
+}
OpenPOWER on IntegriCloud