From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- build/build-clang/README | 45 +++ build/build-clang/build-clang.py | 425 +++++++++++++++++++++ .../build-clang/clang-static-analysis-linux64.json | 30 ++ .../clang-static-analysis-macosx64.json | 29 ++ build/build-clang/clang-static-analysis-win32.json | 16 + build/build-clang/clang-static-analysis-win64.json | 16 + build/build-clang/disable-mac-tsan.patch | 11 + build/build-clang/llvm-debug-frame.patch | 13 + build/build-clang/query-selector-visibility.patch | 79 ++++ .../return-empty-string-non-mangled.patch | 19 + 10 files changed, 683 insertions(+) create mode 100644 build/build-clang/README create mode 100755 build/build-clang/build-clang.py create mode 100644 build/build-clang/clang-static-analysis-linux64.json create mode 100644 build/build-clang/clang-static-analysis-macosx64.json create mode 100644 build/build-clang/clang-static-analysis-win32.json create mode 100644 build/build-clang/clang-static-analysis-win64.json create mode 100644 build/build-clang/disable-mac-tsan.patch create mode 100644 build/build-clang/llvm-debug-frame.patch create mode 100644 build/build-clang/query-selector-visibility.patch create mode 100644 build/build-clang/return-empty-string-non-mangled.patch (limited to 'build/build-clang') diff --git a/build/build-clang/README b/build/build-clang/README new file mode 100644 index 000000000..8e93eeaa6 --- /dev/null +++ b/build/build-clang/README @@ -0,0 +1,45 @@ +build-clang.py +============== + +A script to build clang from source. + +``` +usage: build-clang.py [-h] -c CONFIG [--clean] + +optional arguments: + -h, --help show this help message and exit + -c CONFIG, --config CONFIG + Clang configuration file + --clean Clean the build directory +``` + +Pre-requisites +-------------- +* Working build toolchain. +* Subversion +* CMake +* Ninja +* Python 2.7 + +Please use the latest available CMake for your platform to avoid surprises. + +Config file format +------------------ + +build-clang.py accepts a JSON config format with the following fields: + +* llvm_revision: The LLVM SVN revision to build. +* stages: Use 1, 2, or 3 to select different compiler stages. The default is 3. +* llvm_repo: SVN path to the LLVM repo. +* clang_repo: SVN path to the Clang repo. +* compiler_repo: SVN path to the compiler-rt repo. +* libcxx_repo: SVN path to the libcxx repo. +* libcxxabi_repo: SVN path to the libcxxabi repo. +* python_path: Path to the Python 2.7 installation on the machine building clang. +* gcc_dir: Path to the gcc toolchain installation, only required on Linux. +* cc: Path to the bootsraping C Compiler. +* cxx: Path to the bootsraping C++ Compiler. +* patches: Optional list of patches to apply per platform. Supported platforms: macosx64, linux32, linux64. The default is Release. +* build_type: The type of build to make. Supported types: Release, Debug, RelWithDebInfo or MinSizeRel. +* build_libcxx: Whether to build with libcxx. The default is false. +* assertions: Whether to enable LLVM assertions. The default is false. diff --git a/build/build-clang/build-clang.py b/build/build-clang/build-clang.py new file mode 100755 index 000000000..697bbb9b8 --- /dev/null +++ b/build/build-clang/build-clang.py @@ -0,0 +1,425 @@ +#!/usr/bin/python2.7 +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import os.path +import shutil +import subprocess +import platform +import json +import argparse +import tempfile +import glob +import errno +import re +from contextlib import contextmanager +import sys +import which + +DEBUG = os.getenv("DEBUG") + + +def symlink(source, link_name): + os_symlink = getattr(os, "symlink", None) + if callable(os_symlink): + os_symlink(source, link_name) + else: + if os.path.isdir(source): + # Fall back to copying the directory :( + copy_dir_contents(source, link_name) + + +def check_run(args): + global DEBUG + if DEBUG: + print >> sys.stderr, ' '.join(args) + r = subprocess.call(args) + assert r == 0 + + +def run_in(path, args): + d = os.getcwd() + global DEBUG + if DEBUG: + print >> sys.stderr, 'cd "%s"' % path + os.chdir(path) + check_run(args) + if DEBUG: + print >> sys.stderr, 'cd "%s"' % d + os.chdir(d) + + +def patch(patch, srcdir): + patch = os.path.realpath(patch) + check_run(['patch', '-d', srcdir, '-p1', '-i', patch, '--fuzz=0', + '-s']) + + +def build_package(package_build_dir, run_cmake, cmake_args): + if not os.path.exists(package_build_dir): + os.mkdir(package_build_dir) + if run_cmake: + run_in(package_build_dir, ["cmake"] + cmake_args) + run_in(package_build_dir, ["ninja", "install"]) + + +@contextmanager +def updated_env(env): + old_env = os.environ.copy() + os.environ.update(env) + yield + os.environ.clear() + os.environ.update(old_env) + + +def build_tar_package(tar, name, base, directory): + name = os.path.realpath(name) + # On Windows, we have to convert this into an msys path so that tar can + # understand it. + if is_windows(): + name = name.replace('\\', '/') + def f(match): + return '/' + match.group(1).lower() + name = re.sub(r'^([A-Z]):', f, name) + run_in(base, [tar, + "-c", + "-%s" % ("J" if ".xz" in name else "j"), + "-f", + name, directory]) + + +def copy_dir_contents(src, dest): + for f in glob.glob("%s/*" % src): + try: + destname = "%s/%s" % (dest, os.path.basename(f)) + if os.path.isdir(f): + shutil.copytree(f, destname) + else: + shutil.copy2(f, destname) + except OSError as e: + if e.errno == errno.ENOTDIR: + shutil.copy2(f, destname) + elif e.errno == errno.EEXIST: + if os.path.isdir(f): + copy_dir_contents(f, destname) + else: + os.remove(destname) + shutil.copy2(f, destname) + else: + raise Exception('Directory not copied. Error: %s' % e) + + +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST or not os.path.isdir(path): + raise + + +def install_libgcc(gcc_dir, clang_dir): + out = subprocess.check_output([os.path.join(gcc_dir, "bin", "gcc"), + '-print-libgcc-file-name']) + + libgcc_dir = os.path.dirname(out.rstrip()) + clang_lib_dir = os.path.join(clang_dir, "lib", "gcc", + "x86_64-unknown-linux-gnu", + os.path.basename(libgcc_dir)) + mkdir_p(clang_lib_dir) + copy_dir_contents(libgcc_dir, clang_lib_dir) + libgcc_dir = os.path.join(gcc_dir, "lib64") + clang_lib_dir = os.path.join(clang_dir, "lib") + copy_dir_contents(libgcc_dir, clang_lib_dir) + include_dir = os.path.join(gcc_dir, "include") + clang_include_dir = os.path.join(clang_dir, "include") + copy_dir_contents(include_dir, clang_include_dir) + + +def svn_co(source_dir, url, directory, revision): + run_in(source_dir, ["svn", "co", "-q", "-r", revision, url, directory]) + + +def svn_update(directory, revision): + run_in(directory, ["svn", "update", "-q", "-r", revision]) + + +def get_platform(): + p = platform.system() + if p == "Darwin": + return "macosx64" + elif p == "Linux": + if platform.architecture() == "AMD64": + return "linux64" + else: + return "linux32" + elif p == "Windows": + if platform.architecture() == "AMD64": + return "win64" + else: + return "win32" + else: + raise NotImplementedError("Not supported platform") + + +def is_darwin(): + return platform.system() == "Darwin" + + +def is_linux(): + return platform.system() == "Linux" + + +def is_windows(): + return platform.system() == "Windows" + + +def build_one_stage(cc, cxx, src_dir, stage_dir, build_libcxx, + build_type, assertions, python_path, gcc_dir): + if not os.path.exists(stage_dir): + os.mkdir(stage_dir) + + build_dir = stage_dir + "/build" + inst_dir = stage_dir + "/clang" + + run_cmake = True + if os.path.exists(build_dir + "/build.ninja"): + run_cmake = False + + # cmake doesn't deal well with backslashes in paths. + def slashify_path(path): + return path.replace('\\', '/') + + cmake_args = ["-GNinja", + "-DCMAKE_C_COMPILER=%s" % slashify_path(cc[0]), + "-DCMAKE_CXX_COMPILER=%s" % slashify_path(cxx[0]), + "-DCMAKE_ASM_COMPILER=%s" % slashify_path(cc[0]), + "-DCMAKE_C_FLAGS=%s" % ' '.join(cc[1:]), + "-DCMAKE_CXX_FLAGS=%s" % ' '.join(cxx[1:]), + "-DCMAKE_BUILD_TYPE=%s" % build_type, + "-DLLVM_TARGETS_TO_BUILD=X86;ARM", + "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"), + "-DPYTHON_EXECUTABLE=%s" % slashify_path(python_path), + "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir, + "-DLLVM_TOOL_LIBCXX_BUILD=%s" % ("ON" if build_libcxx else "OFF"), + "-DLIBCXX_LIBCPPABI_VERSION=\"\"", + src_dir]; + build_package(build_dir, run_cmake, cmake_args) + + if is_linux(): + install_libgcc(gcc_dir, inst_dir) + + +def get_compiler(config, key): + if key not in config: + raise ValueError("Config file needs to set %s" % key) + + f = config[key] + if os.path.isabs(f): + if not os.path.exists(f): + raise ValueError("%s must point to an existing path" % key) + return f + + # Assume that we have the name of some program that should be on PATH. + try: + return which.which(f) + except which.WhichError: + raise ValueError("%s not found on PATH" % f) + +if __name__ == "__main__": + # The directories end up in the debug info, so the easy way of getting + # a reproducible build is to run it in a know absolute directory. + # We use a directory in /builds/slave because the mozilla infrastructure + # cleans it up automatically. + base_dir = "/builds/slave/moz-toolchain" + if is_windows(): + # TODO: Because Windows taskcluster builds are run with distinct + # user IDs for each job, we can't store things in some globally + # accessible directory: one job will run, checkout LLVM to that + # directory, and then if another job runs, the new user won't be + # able to access the previously-checked out code--or be able to + # delete it. So on Windows, we build in the task-specific home + # directory; we will eventually add -fdebug-prefix-map options + # to the LLVM build to bring back reproducibility. + base_dir = os.path.join(os.getcwd(), 'llvm-sources') + + source_dir = base_dir + "/src" + build_dir = base_dir + "/build" + + llvm_source_dir = source_dir + "/llvm" + clang_source_dir = source_dir + "/clang" + compiler_rt_source_dir = source_dir + "/compiler-rt" + libcxx_source_dir = source_dir + "/libcxx" + libcxxabi_source_dir = source_dir + "/libcxxabi" + + if is_darwin(): + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7' + + exe_ext = "" + if is_windows(): + exe_ext = ".exe" + + cc_name = "clang" + cxx_name = "clang++" + if is_windows(): + cc_name = "clang-cl" + cxx_name = "clang-cl" + + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', required=True, + type=argparse.FileType('r'), + help="Clang configuration file") + parser.add_argument('--clean', required=False, + action='store_true', + help="Clean the build directory") + + args = parser.parse_args() + config = json.load(args.config) + + if args.clean: + shutil.rmtree(build_dir) + os.sys.exit(0) + + llvm_revision = config["llvm_revision"] + llvm_repo = config["llvm_repo"] + clang_repo = config["clang_repo"] + compiler_repo = config["compiler_repo"] + libcxx_repo = config["libcxx_repo"] + libcxxabi_repo = config.get("libcxxabi_repo") + stages = 3 + if "stages" in config: + stages = int(config["stages"]) + if stages not in (1, 2, 3): + raise ValueError("We only know how to build 1, 2, or 3 stages") + build_type = "Release" + if "build_type" in config: + build_type = config["build_type"] + if build_type not in ("Release", "Debug", "RelWithDebInfo", "MinSizeRel"): + raise ValueError("We only know how to do Release, Debug, RelWithDebInfo or MinSizeRel builds") + build_libcxx = False + if "build_libcxx" in config: + build_libcxx = config["build_libcxx"] + if build_libcxx not in (True, False): + raise ValueError("Only boolean values are accepted for build_libcxx.") + assertions = False + if "assertions" in config: + assertions = config["assertions"] + if assertions not in (True, False): + raise ValueError("Only boolean values are accepted for assertions.") + python_path = None + if "python_path" not in config: + raise ValueError("Config file needs to set python_path") + python_path = config["python_path"] + gcc_dir = None + if "gcc_dir" in config: + gcc_dir = config["gcc_dir"] + if not os.path.exists(gcc_dir): + raise ValueError("gcc_dir must point to an existing path") + if is_linux() and gcc_dir is None: + raise ValueError("Config file needs to set gcc_dir") + cc = get_compiler(config, "cc") + cxx = get_compiler(config, "cxx") + + if not os.path.exists(source_dir): + os.makedirs(source_dir) + svn_co(source_dir, llvm_repo, llvm_source_dir, llvm_revision) + svn_co(source_dir, clang_repo, clang_source_dir, llvm_revision) + svn_co(source_dir, compiler_repo, compiler_rt_source_dir, llvm_revision) + svn_co(source_dir, libcxx_repo, libcxx_source_dir, llvm_revision) + if libcxxabi_repo: + svn_co(source_dir, libcxxabi_repo, libcxxabi_source_dir, llvm_revision) + for p in config.get("patches", {}).get(get_platform(), []): + patch(p, source_dir) + else: + svn_update(llvm_source_dir, llvm_revision) + svn_update(clang_source_dir, llvm_revision) + svn_update(compiler_rt_source_dir, llvm_revision) + svn_update(libcxx_source_dir, llvm_revision) + if libcxxabi_repo: + svn_update(libcxxabi_source_dir, llvm_revision) + + symlinks = [(source_dir + "/clang", + llvm_source_dir + "/tools/clang"), + (source_dir + "/compiler-rt", + llvm_source_dir + "/projects/compiler-rt"), + (source_dir + "/libcxx", + llvm_source_dir + "/projects/libcxx"), + (source_dir + "/libcxxabi", + llvm_source_dir + "/projects/libcxxabi")] + for l in symlinks: + # On Windows, we have to re-copy the whole directory every time. + if not is_windows() and os.path.islink(l[1]): + continue + if os.path.isdir(l[1]): + shutil.rmtree(l[1]) + elif os.path.exists(l[1]): + os.unlink(l[1]) + if os.path.exists(l[0]): + symlink(l[0], l[1]) + + if not os.path.exists(build_dir): + os.makedirs(build_dir) + + stage1_dir = build_dir + '/stage1' + stage1_inst_dir = stage1_dir + '/clang' + + final_stage_dir = stage1_dir + + if is_darwin(): + extra_cflags = [] + extra_cxxflags = ["-stdlib=libc++"] + extra_cflags2 = [] + extra_cxxflags2 = ["-stdlib=libc++"] + elif is_linux(): + extra_cflags = ["-static-libgcc"] + extra_cxxflags = ["-static-libgcc", "-static-libstdc++"] + extra_cflags2 = ["-fPIC"] + extra_cxxflags2 = ["-fPIC", "-static-libstdc++"] + + if os.environ.has_key('LD_LIBRARY_PATH'): + os.environ['LD_LIBRARY_PATH'] = '%s/lib64/:%s' % (gcc_dir, os.environ['LD_LIBRARY_PATH']); + else: + os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir + elif is_windows(): + extra_cflags = [] + extra_cxxflags = [] + # clang-cl would like to figure out what it's supposed to be emulating + # by looking at an MSVC install, but we don't really have that here. + # Force things on. + extra_cflags2 = [] + extra_cxxflags2 = ['-fms-compatibility-version=19.00.24213', '-Xclang', '-std=c++14'] + + build_one_stage( + [cc] + extra_cflags, + [cxx] + extra_cxxflags, + llvm_source_dir, stage1_dir, build_libcxx, + build_type, assertions, python_path, gcc_dir) + + if stages > 1: + stage2_dir = build_dir + '/stage2' + stage2_inst_dir = stage2_dir + '/clang' + final_stage_dir = stage2_dir + build_one_stage( + [stage1_inst_dir + "/bin/%s%s" % + (cc_name, exe_ext)] + extra_cflags2, + [stage1_inst_dir + "/bin/%s%s" % + (cxx_name, exe_ext)] + extra_cxxflags2, + llvm_source_dir, stage2_dir, build_libcxx, + build_type, assertions, python_path, gcc_dir) + + if stages > 2: + stage3_dir = build_dir + '/stage3' + final_stage_dir = stage3_dir + build_one_stage( + [stage2_inst_dir + "/bin/%s%s" % + (cc_name, exe_ext)] + extra_cflags2, + [stage2_inst_dir + "/bin/%s%s" % + (cxx_name, exe_ext)] + extra_cxxflags2, + llvm_source_dir, stage3_dir, build_libcxx, + build_type, assertions, python_path, gcc_dir) + + if is_darwin() or is_windows(): + build_tar_package("tar", "clang.tar.bz2", final_stage_dir, "clang") + else: + build_tar_package("tar", "clang.tar.xz", final_stage_dir, "clang") diff --git a/build/build-clang/clang-static-analysis-linux64.json b/build/build-clang/clang-static-analysis-linux64.json new file mode 100644 index 000000000..d3ae6c8ad --- /dev/null +++ b/build/build-clang/clang-static-analysis-linux64.json @@ -0,0 +1,30 @@ +{ + "llvm_revision": "262557", + "stages": "3", + "build_libcxx": true, + "build_type": "Release", + "assertions": false, + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_380/final", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_380/final", + "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_380/final", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_380/final", + "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_380/final", + "python_path": "/usr/bin/python2.7", + "gcc_dir": "/home/worker/workspace/build/src/gcc", + "cc": "/home/worker/workspace/build/src/gcc/bin/gcc", + "cxx": "/home/worker/workspace/build/src/gcc/bin/g++", + "patches": { + "macosx64": [ + "llvm-debug-frame.patch", + "return-empty-string-non-mangled.patch" + ], + "linux64": [ + "llvm-debug-frame.patch", + "return-empty-string-non-mangled.patch" + ], + "linux32": [ + "llvm-debug-frame.patch", + "return-empty-string-non-mangled.patch" + ] + } +} diff --git a/build/build-clang/clang-static-analysis-macosx64.json b/build/build-clang/clang-static-analysis-macosx64.json new file mode 100644 index 000000000..16818825b --- /dev/null +++ b/build/build-clang/clang-static-analysis-macosx64.json @@ -0,0 +1,29 @@ +{ + "llvm_revision": "262557", + "stages": "3", + "build_libcxx": true, + "build_type": "Release", + "assertions": false, + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_380/final", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_380/final", + "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_380/final", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_380/final", + "python_path": "/usr/local/bin/python2.7", + "cc": "/Users/cltbld/clang/bin/clang", + "cxx": "/Users/cltbld/clang/bin/clang++", + "patches": { + "macosx64": [ + "disable-mac-tsan.patch", + "llvm-debug-frame.patch", + "return-empty-string-non-mangled.patch" + ], + "linux64": [ + "llvm-debug-frame.patch", + "return-empty-string-non-mangled.patch" + ], + "linux32": [ + "llvm-debug-frame.patch", + "return-empty-string-non-mangled.patch" + ] + } +} diff --git a/build/build-clang/clang-static-analysis-win32.json b/build/build-clang/clang-static-analysis-win32.json new file mode 100644 index 000000000..01cddad85 --- /dev/null +++ b/build/build-clang/clang-static-analysis-win32.json @@ -0,0 +1,16 @@ +{ + "llvm_revision": "283955", + "stages": "3", + "build_libcxx": false, + "build_type": "Release", + "assertions": false, + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk", + "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk", + "python_path": "c:/mozilla-build/python/python.exe", + "cc": "cl.exe", + "cxx": "cl.exe", + "patches": { + } +} diff --git a/build/build-clang/clang-static-analysis-win64.json b/build/build-clang/clang-static-analysis-win64.json new file mode 100644 index 000000000..cf626f05e --- /dev/null +++ b/build/build-clang/clang-static-analysis-win64.json @@ -0,0 +1,16 @@ +{ + "llvm_revision": "262971", + "stages": "3", + "build_libcxx": false, + "build_type": "Release", + "assertions": false, + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk", + "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk", + "python_path": "c:/mozilla-build/python/python.exe", + "cc": "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64/cl.exe", + "cxx": "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64/cl.exe", + "patches": { + } +} diff --git a/build/build-clang/disable-mac-tsan.patch b/build/build-clang/disable-mac-tsan.patch new file mode 100644 index 000000000..3bd0d3c60 --- /dev/null +++ b/build/build-clang/disable-mac-tsan.patch @@ -0,0 +1,11 @@ +--- a/compiler-rt/cmake/config-ix.cmake ++++ b/compiler-rt/cmake/config-ix.cmake +@@ -617,7 +617,7 @@ + endif() + + if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND +- OS_NAME MATCHES "Darwin|Linux|FreeBSD") ++ OS_NAME MATCHES "Linux|FreeBSD") + set(COMPILER_RT_HAS_TSAN TRUE) + else() + set(COMPILER_RT_HAS_TSAN FALSE) diff --git a/build/build-clang/llvm-debug-frame.patch b/build/build-clang/llvm-debug-frame.patch new file mode 100644 index 000000000..a8c57ce6f --- /dev/null +++ b/build/build-clang/llvm-debug-frame.patch @@ -0,0 +1,13 @@ +Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp +=================================================================== +--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (revision 226419) ++++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (working copy) +@@ -210,6 +210,8 @@ + OutStreamer->EmitFileDirective(M.getModuleIdentifier()); + } + ++ OutStreamer->EmitCFISections(true, true); ++ + GCModuleInfo *MI = getAnalysisIfAvailable(); + assert(MI && "AsmPrinter didn't require GCModuleInfo?"); + for (auto &I : *MI) diff --git a/build/build-clang/query-selector-visibility.patch b/build/build-clang/query-selector-visibility.patch new file mode 100644 index 000000000..46a9642bd --- /dev/null +++ b/build/build-clang/query-selector-visibility.patch @@ -0,0 +1,79 @@ +commit 865b9340996f9f9d04b73b187248737dc6fd845e +Author: Michael Wu +Date: Mon Sep 14 17:47:21 2015 -0400 + + Add support for querying the visibility of a cursor + +diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h +index fad9cfa..311bfcb 100644 +--- a/clang/include/clang-c/Index.h ++++ b/clang/include/clang-c/Index.h +@@ -2440,6 +2440,24 @@ enum CXLinkageKind { + CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor); + + /** ++ * \brief Describe the visibility of the entity referred to by a cursor. ++ */ ++enum CXVisibilityKind { ++ /** \brief This value indicates that no visibility information is available ++ * for a provided CXCursor. */ ++ CXVisibility_Invalid, ++ ++ /** \brief Symbol not seen by the linker. */ ++ CXVisibility_Hidden, ++ /** \brief Symbol seen by the linker but resolves to a symbol inside this object. */ ++ CXVisibility_Protected, ++ /** \brief Symbol seen by the linker and acts like a normal symbol. */ ++ CXVisibility_Default, ++}; ++ ++CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor); ++ ++/** + * \brief Determine the availability of the entity that this cursor refers to, + * taking the current target platform into account. + * +diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp +index 8225a6c..9fa18d3 100644 +--- a/clang/tools/libclang/CIndex.cpp ++++ b/clang/tools/libclang/CIndex.cpp +@@ -6361,6 +6361,27 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { + } // end: extern "C" + + //===----------------------------------------------------------------------===// ++// Operations for querying visibility of a cursor. ++//===----------------------------------------------------------------------===// ++ ++extern "C" { ++CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) { ++ if (!clang_isDeclaration(cursor.kind)) ++ return CXVisibility_Invalid; ++ ++ const Decl *D = cxcursor::getCursorDecl(cursor); ++ if (const NamedDecl *ND = dyn_cast_or_null(D)) ++ switch (ND->getVisibility()) { ++ case HiddenVisibility: return CXVisibility_Hidden; ++ case ProtectedVisibility: return CXVisibility_Protected; ++ case DefaultVisibility: return CXVisibility_Default; ++ }; ++ ++ return CXVisibility_Invalid; ++} ++} // end: extern "C" ++ ++//===----------------------------------------------------------------------===// + // Operations for querying language of a cursor. + //===----------------------------------------------------------------------===// + +diff --git a/clang/tools/libclang/libclang.exports b/clang/tools/libclang/libclang.exports +index f6a7175..a919a8e 100644 +--- a/clang/tools/libclang/libclang.exports ++++ b/clang/tools/libclang/libclang.exports +@@ -173,6 +173,7 @@ clang_getCursorSemanticParent + clang_getCursorSpelling + clang_getCursorType + clang_getCursorUSR ++clang_getCursorVisibility + clang_getDeclObjCTypeEncoding + clang_getDefinitionSpellingAndExtent + clang_getDiagnostic diff --git a/build/build-clang/return-empty-string-non-mangled.patch b/build/build-clang/return-empty-string-non-mangled.patch new file mode 100644 index 000000000..33a391703 --- /dev/null +++ b/build/build-clang/return-empty-string-non-mangled.patch @@ -0,0 +1,19 @@ +Author: Michael Wu +Date: Thu Sep 24 11:36:08 2015 -0400 + + Return an empty string when a symbol isn't mangled + +diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp +--- a/clang/tools/libclang/CIndex.cpp ++++ b/clang/tools/libclang/CIndex.cpp +@@ -3990,6 +3990,10 @@ + ASTContext &Ctx = ND->getASTContext(); + std::unique_ptr MC(Ctx.createMangleContext()); + ++ // Don't mangle if we don't need to. ++ if (!MC->shouldMangleCXXName(ND)) ++ return cxstring::createEmpty(); ++ + std::string FrontendBuf; + llvm::raw_string_ostream FrontendBufOS(FrontendBuf); + if (MC->shouldMangleDeclName(ND)) { -- cgit v1.2.3