summaryrefslogtreecommitdiff
path: root/chromium/tools/clang
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-01 11:08:40 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 12:16:21 +0000
commit03c549e0392f92c02536d3f86d5e1d8dfa3435ac (patch)
treefe49d170a929b34ba82cd10db1a0bd8e3760fa4b /chromium/tools/clang
parent5d013f5804a0d91fcf6c626b2d6fb6eca5c845b0 (diff)
downloadqtwebengine-chromium-03c549e0392f92c02536d3f86d5e1d8dfa3435ac.tar.gz
BASELINE: Update Chromium to 91.0.4472.160
Change-Id: I0def1f08a2412aeed79a9ab95dd50eb5c3f65f31 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/tools/clang')
-rw-r--r--chromium/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp8
-rw-r--r--chromium/tools/clang/plugins/FindBadConstructsAction.cpp2
-rw-r--r--chromium/tools/clang/plugins/FindBadConstructsConsumer.cpp17
-rw-r--r--chromium/tools/clang/plugins/Options.h1
-rw-r--r--chromium/tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt15
-rw-r--r--chromium/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt11
-rwxr-xr-xchromium/tools/clang/rewrite_raw_ptr_fields/rewrite-multiple-platforms.sh160
-rwxr-xr-xchromium/tools/clang/scripts/analyze_includes.py313
-rwxr-xr-xchromium/tools/clang/scripts/build.py97
-rw-r--r--chromium/tools/clang/scripts/include-analysis.html207
-rwxr-xr-xchromium/tools/clang/scripts/package.py166
-rwxr-xr-xchromium/tools/clang/scripts/update.py32
-rwxr-xr-xchromium/tools/clang/scripts/upload_revision.py15
-rw-r--r--chromium/tools/clang/trace_annotator/TraceAnnotator.cpp11
14 files changed, 897 insertions, 158 deletions
diff --git a/chromium/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp b/chromium/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
index 312687f542d..a683aa9b1d1 100644
--- a/chromium/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
+++ b/chromium/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
@@ -231,14 +231,14 @@ class PassByValueRewriter : public MatchFinder::MatchCallback, public Rewriter {
// Adds std::move() to base::RepeatingCallback<> where it looks relevant.
// Example:
// // Before
-// void Foo(base::Callback<void(int)> cb1) {
-// base::Closure cb2 = base::Bind(cb1, 42);
+// void Foo(base::RepeatingCallback<void(int)> cb1) {
+// base::RepeatingClosure cb2 = base::BindRepeating(cb1, 42);
// PostTask(FROM_HERE, cb2);
// }
//
// // After
-// void Foo(base::Callback<void(int)> cb1) {
-// base::Closure cb2 = base::Bind(std::move(cb1), 42);
+// void Foo(base::RepeatingCallback<void(int)> cb1) {
+// base::RepeatingClosure cb2 = base::BindRepeating(std::move(cb1), 42);
// PostTask(FROM_HERE, std::move(cb2));
// }
class AddStdMoveRewriter : public MatchFinder::MatchCallback, public Rewriter {
diff --git a/chromium/tools/clang/plugins/FindBadConstructsAction.cpp b/chromium/tools/clang/plugins/FindBadConstructsAction.cpp
index e2395b94b43..54a8e04b119 100644
--- a/chromium/tools/clang/plugins/FindBadConstructsAction.cpp
+++ b/chromium/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -51,6 +51,8 @@ bool FindBadConstructsAction::ParseArgs(const CompilerInstance& instance,
options_.check_ipc = true;
} else if (args[i] == "check-gmock-objects") {
options_.check_gmock_objects = true;
+ } else if (args[i] == "checked-ptr-as-trivial-member") {
+ options_.checked_ptr_as_trivial_member = true;
} else {
parsed = false;
llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/chromium/tools/clang/plugins/FindBadConstructsConsumer.cpp b/chromium/tools/clang/plugins/FindBadConstructsConsumer.cpp
index d5a18d3144b..61e51d0f72f 100644
--- a/chromium/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/chromium/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -687,20 +687,23 @@ void FindBadConstructsConsumer::CountType(const Type* type,
case Type::TemplateSpecialization: {
TemplateName name =
dyn_cast<TemplateSpecializationType>(type)->getTemplateName();
- bool whitelisted_template = false;
// HACK: I'm at a loss about how to get the syntax checker to get
// whether a template is externed or not. For the first pass here,
// just do simple string comparisons.
if (TemplateDecl* decl = name.getAsTemplateDecl()) {
- std::string base_name = decl->getNameAsString();
- if (base_name == "basic_string")
- whitelisted_template = true;
+ std::string base_name = decl->getQualifiedNameAsString();
+ if (base_name == "std::basic_string") {
+ (*non_trivial_member)++;
+ break;
+ }
+ if (options_.checked_ptr_as_trivial_member &&
+ base_name == "base::CheckedPtr") {
+ (*trivial_member)++;
+ break;
+ }
}
- if (whitelisted_template)
- (*non_trivial_member)++;
- else
(*templated_non_trivial_member)++;
break;
}
diff --git a/chromium/tools/clang/plugins/Options.h b/chromium/tools/clang/plugins/Options.h
index 82e9decc2c5..6ad4c1dfb9c 100644
--- a/chromium/tools/clang/plugins/Options.h
+++ b/chromium/tools/clang/plugins/Options.h
@@ -11,6 +11,7 @@ struct Options {
bool check_base_classes = false;
bool check_ipc = false;
bool check_gmock_objects = false;
+ bool checked_ptr_as_trivial_member = false;
};
} // namespace chrome_checker
diff --git a/chromium/tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt b/chromium/tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt
index 6ac34e65192..9824e2afb16 100644
--- a/chromium/tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt
+++ b/chromium/tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt
@@ -19,6 +19,7 @@ base::trace_event::TraceLog::OptionalAutoLock::lock_
blink::xpath::EvaluationContext::node
WTF::HashTableAddResult::container_
WTF::HashTableAddResult::stored_value
+cast_channel::CastTransportTest::logger_
# Populated manually - conflicting types in an initializer list
WebUITabStripContainerView::tab_counter_
@@ -219,10 +220,24 @@ mojo::core::ports::PortLocker::port_refs_
# Populated manually - static pointee
mojo::core::RequestContext::tls_context_
+base::sequence_manager::LazyNow::tick_clock_
# Populated manually - on-stack pointee
+mojo::internal::ContainerValidateParams::key_validate_params
+mojo::internal::ContainerValidateParams::element_validate_params
mojo::internal::ValidationContext::ScopedDepthTracker::ctx_
+# Populated manually - usually on-stack pointer, pointing back to the collection
+# being iterated, owned by object that iterates over it.
+base::internal::circular_deque_const_iterator::parent_deque_
+
+# Populated manually - on-stack pointer + a large number of non-PA pointees through WeakLinkNode
+base::internal::LinkNodeBase::next_
+base::internal::LinkNodeBase::previous_
+
+# Populated manually - on-stack pointer
+base::internal::WeakLinkNode::list_
+
# Populated manually - using mmap, MapViewOfFile or base::AllocPages directly
blink::GCInfoTable::table_
cc::(anonymous namespace)::BitmapRasterBufferImpl::pixels_
diff --git a/chromium/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt b/chromium/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt
index 3e0cc942410..9369c1a8d57 100644
--- a/chromium/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt
+++ b/chromium/tools/clang/rewrite_raw_ptr_fields/manual-paths-to-ignore.txt
@@ -39,6 +39,7 @@ sandbox/win/sandbox_poc/pocdll
# Exclude directories that don't depend on //base, because nothing there uses
# anything from /base.
sandbox/linux/system_headers/
+components/history_clusters/core/
# The folder holds headers that are duplicated in the Android source and need to
# provide a stable C ABI. Can't depend on //base.
@@ -48,6 +49,15 @@ android_webview/public/
base/logging.h
base/synchronization/lock_impl.h
+# Performance related exclusion based on sampling profiler data
+base/bind_internal.h
+base/message_loop/
+base/task/
+base/threading/
+base/timer/
+cc/
+content/browser/scheduler/responsiveness/
+
# Exclude code that only runs inside a renderer process - renderer
# processes are excluded for now from the MiraclePtr project scope,
# because they are sensitive to performance regressions (to a much higher
@@ -90,7 +100,6 @@ chrome/app/vector_icons/google_chrome/
chrome/browser/google/linkdoctor_internal/
chrome/browser/internal/
chrome/browser/media/engagement_internal/
-chrome/browser/media/kaleidoscope/internal/
chrome/browser/resources/chromeos/quickoffice/
chrome/browser/resources/media_router/extension/src/
chrome/browser/resources/media_router_internal/
diff --git a/chromium/tools/clang/rewrite_raw_ptr_fields/rewrite-multiple-platforms.sh b/chromium/tools/clang/rewrite_raw_ptr_fields/rewrite-multiple-platforms.sh
new file mode 100755
index 00000000000..b601688d0bb
--- /dev/null
+++ b/chromium/tools/clang/rewrite_raw_ptr_fields/rewrite-multiple-platforms.sh
@@ -0,0 +1,160 @@
+#!/bin/bash
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# IMPORTANT! Before running this script you have to run
+# `rm -r ~/scratch && mkdir ~/scratch` first
+#
+#
+# For more fine-grained instructions, see:
+# https://docs.google.com/document/d/1chTvr3fSofQNV_PDPEHRyUgcJCQBgTDOOBriW9gIm9M/edit?ts=5e9549a2#heading=h.fjdnrdg1gcty
+
+set -e # makes the script quit on any command failure
+
+PLATFORMS="win,android"
+if [ "$1" != "" ]
+then
+ PLATFORMS="$1"
+fi
+
+SCRIPT_PATH=$(realpath $0)
+REWRITER_SRC_DIR=$(dirname $SCRIPT_PATH)
+
+COMPILE_DIRS=.
+EDIT_DIRS=.
+
+# Save llvm-build as it is about to be overwritten.
+mv third_party/llvm-build third_party/llvm-build-upstream
+
+# Build and test the rewriter.
+echo "*** Building the rewriter ***"
+time tools/clang/scripts/build.py \
+ --without-android \
+ --without-fuchsia \
+ --extra-tools rewrite_raw_ptr_fields
+tools/clang/rewrite_raw_ptr_fields/tests/run_all_tests.py
+
+args_for_platform() {
+ case "$1" in
+
+ android)
+ cat <<EOF
+target_os = "android"
+clang_use_chrome_plugins = false
+is_chrome_branded = true
+is_debug = false
+is_official_build = true
+symbol_level = 1
+use_goma = false
+enable_remoting = true
+enable_webview_bundles = true
+ffmpeg_branding = "Chrome"
+proprietary_codecs = true
+EOF
+ ;;
+
+ win)
+ cat <<EOF
+target_os = "win"
+clang_use_chrome_plugins = false
+enable_precompiled_headers = false
+is_chrome_branded = true
+is_debug = false
+is_official_build = true
+symbol_level = 1
+use_goma = false
+chrome_pgo_phase = 0
+EOF
+ ;;
+
+ *)
+ echo "unknown platform"
+ exit 1
+ ;;
+ esac
+}
+
+pre_process() {
+ PLATFORM="$1"
+ OUT_DIR="out/rewrite-$PLATFORM"
+
+ mkdir -p "$OUT_DIR"
+ args_for_platform "$PLATFORM" > "$OUT_DIR/args.gn"
+
+ # Build generated files that a successful compilation depends on.
+ echo "*** Preparing targets for $PLATFORM ***"
+ gn gen $OUT_DIR
+ GEN_H_TARGETS=`ninja -C $OUT_DIR -t targets all | grep '^gen/.*\(\.h\|inc\|css_tokenizer_codepoints.cc\)' | cut -d : -f 1`
+ time ninja -C $OUT_DIR $GEN_H_TARGETS
+
+ TARGET_OS_OPTION=""
+ if [ $PLATFORM = "win" ]; then
+ TARGET_OS_OPTION="--target_os=win"
+ fi
+
+ # A preliminary rewriter run in a special mode that generates a list of fields
+ # to ignore. These fields would likely lead to compiler errors if rewritten.
+ echo "*** Generating the ignore list for $PLATFORM ***"
+ time tools/clang/scripts/run_tool.py \
+ $TARGET_OS_OPTION \
+ --tool rewrite_raw_ptr_fields \
+ --tool-arg=--exclude-paths=$REWRITER_SRC_DIR/manual-paths-to-ignore.txt \
+ --generate-compdb \
+ -p $OUT_DIR \
+ $COMPILE_DIRS > ~/scratch/rewriter-$PLATFORM.out
+ cat ~/scratch/rewriter-$PLATFORM.out >> ~/scratch/rewriter.out
+}
+
+main_rewrite() {
+ PLATFORM=$1
+ OUT_DIR="out/rewrite-${PLATFORM}"
+
+ TARGET_OS_OPTION=""
+ if [ $PLATFORM = "win" ]; then
+ TARGET_OS_OPTION="--target_os=win"
+ fi
+
+ # Main rewrite.
+ echo "*** Running the main rewrite phase for $PLATFORM ***"
+ time tools/clang/scripts/run_tool.py \
+ $TARGET_OS_OPTION \
+ --tool rewrite_raw_ptr_fields \
+ --tool-arg=--exclude-fields="$HOME/scratch/combined-fields-to-ignore.txt" \
+ --tool-arg=--exclude-paths=$REWRITER_SRC_DIR/manual-paths-to-ignore.txt \
+ -p $OUT_DIR \
+ $COMPILE_DIRS > ~/scratch/rewriter-$PLATFORM.main.out
+ cat ~/scratch/rewriter-$PLATFORM.main.out >> ~/scratch/rewriter.main.out
+}
+
+for PLATFORM in ${PLATFORMS//,/ }
+do
+ pre_process "$PLATFORM"
+done
+
+cat ~/scratch/rewriter.out \
+ | sed '/^==== BEGIN FIELD FILTERS ====$/,/^==== END FIELD FILTERS ====$/{//!b};d' \
+ | sort | uniq > ~/scratch/automated-fields-to-ignore.txt
+cat ~/scratch/automated-fields-to-ignore.txt \
+ tools/clang/rewrite_raw_ptr_fields/manual-fields-to-ignore.txt \
+ | grep -v "base::FileDescriptorWatcher::Controller::watcher_" \
+ > ~/scratch/combined-fields-to-ignore.txt
+
+for PLATFORM in ${PLATFORMS//,/ }
+do
+ main_rewrite "$PLATFORM"
+done
+
+# Apply edits generated by the main rewrite.
+echo "*** Applying edits ***"
+cat ~/scratch/rewriter.main.out | \
+ tools/clang/scripts/extract_edits.py | \
+ tools/clang/scripts/apply_edits.py -p out/rewrite-win $EDIT_DIRS
+
+# Format sources, as many lines are likely over 80 chars now.
+echo "*** Formatting ***"
+time git cl format
+
+# Restore llvm-build. Without this, your future builds will be painfully slow.
+rm -r -f third_party/llvm-build
+mv third_party/llvm-build-upstream third_party/llvm-build
diff --git a/chromium/tools/clang/scripts/analyze_includes.py b/chromium/tools/clang/scripts/analyze_includes.py
new file mode 100755
index 00000000000..12f7003ca98
--- /dev/null
+++ b/chromium/tools/clang/scripts/analyze_includes.py
@@ -0,0 +1,313 @@
+#!/usr/bin/env python
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""This script is used to analyze #include graphs.
+
+It produces the .js file that accompanies include-analysis.html.
+
+Usage:
+
+$ gn gen --args="show_includes=true" out/Debug
+$ autoninja -C out/Debug -v base_unittests | tee /tmp/build_log
+$ analyze_includes.py base_unittests $(git rev-parse --short HEAD) \
+ /tmp/build_log /tmp/include-analysis.js
+
+(Optionally, add use_goma=true to the gn args.)
+
+The script takes a little under an hour to run on a fast machine for the chrome
+build target, which is considered fast enough for batch job purposes for now.
+"""
+
+from __future__ import print_function
+import argparse
+import json
+import os
+import re
+import sys
+import unittest
+from collections import defaultdict
+from datetime import datetime
+
+
+def parse_build(build_log):
+ """Parse the build_log (generated as in the Usage note above) to capture the
+ include graph. Returns a (roots, includes) pair, where roots is a list of root
+ nodes in the graph (the source files) and includes is a dict from filename to
+ list of filenames included by that filename."""
+ build_dir = '.'
+ file_stack = []
+ includes = {}
+ roots = set()
+
+ # Note: A file might include different files for different compiler
+ # invocations depending on -D flags. For such cases, includes[file] will be
+ # the union of those includes.
+
+ # ninja: Entering directory `out/foo'
+ ENTER_DIR_RE = re.compile(r'ninja: Entering directory `(.*?)\'$')
+ # ...clang... -c foo.cc -o foo.o ...
+ COMPILE_RE = re.compile(r'.*clang.* -c (.*?) ')
+ # . a.h
+ # .. b.h
+ # . c.h
+ INCLUDE_RE = re.compile(r'(\.+) (.*)$')
+
+ for line in build_log:
+ m = ENTER_DIR_RE.match(line)
+ if m:
+ build_dir = m.group(1)
+
+ m = COMPILE_RE.match(line)
+ if m:
+ filename = m.group(1)
+ roots.add(filename)
+ file_stack = [filename]
+ includes.setdefault(filename, set())
+
+ m = INCLUDE_RE.match(line)
+ if m:
+ prev_depth = len(file_stack) - 1
+ depth = len(m.group(1))
+ filename = m.group(2)
+ includes.setdefault(filename, set())
+
+ if depth > prev_depth:
+ assert depth == prev_depth + 1
+ else:
+ for _ in range(prev_depth - depth + 1):
+ file_stack.pop()
+
+ includes[file_stack[-1]].add(filename)
+ file_stack.append(filename)
+
+ # Normalize paths.
+ normalized = {}
+
+ def n(fn):
+ if not fn in normalized:
+ x = os.path.normpath(os.path.join(build_dir, fn))
+ normalized[fn] = x
+ return normalized[fn]
+
+ roots = set([n(x) for x in roots])
+ includes = dict([(n(k), set([n(x) for x in v])) for k, v in includes.items()])
+
+ return roots, includes
+
+
+class TestParseBuild(unittest.TestCase):
+ def test_basic(self):
+ x = [
+ 'ninja: Entering directory `out/foo\'',
+ 'clang -c ../../a.cc -o a.o',
+ '. ../../a.h',
+ 'clang -c gen/c.c -o a.o',
+ ]
+ (roots, includes) = parse_build(x)
+ self.assertEquals(roots, set(['a.cc', 'out/foo/gen/c.c']))
+ self.assertEquals(set(includes.keys()),
+ set(['a.cc', 'a.h', 'out/foo/gen/c.c']))
+ self.assertEquals(includes['a.cc'], set(['a.h']))
+ self.assertEquals(includes['a.h'], set())
+ self.assertEquals(includes['out/foo/gen/c.c'], set())
+
+ def test_more(self):
+ x = [
+ 'ninja: Entering directory `out/foo\'',
+ 'clang -c ../../a.cc -o a.o',
+ '. ../../a.h',
+ '. ../../b.h',
+ '.. ../../c.h',
+ '... ../../d.h',
+ '. ../../e.h',
+ ]
+ (roots, includes) = parse_build(x)
+ self.assertEquals(roots, set(['a.cc']))
+ self.assertEquals(includes['a.cc'], set(['a.h', 'b.h', 'e.h']))
+ self.assertEquals(includes['b.h'], set(['c.h']))
+ self.assertEquals(includes['c.h'], set(['d.h']))
+ self.assertEquals(includes['d.h'], set())
+ self.assertEquals(includes['e.h'], set())
+
+ def test_multiple(self):
+ x = [
+ 'ninja: Entering directory `out/foo\'',
+ 'clang -c ../../a.cc -o a.o',
+ '. ../../a.h',
+ 'clang -c ../../b.cc -o b.o',
+ '. ../../b.h',
+ ]
+ (roots, includes) = parse_build(x)
+ self.assertEquals(roots, set(['a.cc', 'b.cc']))
+ self.assertEquals(includes['a.cc'], set(['a.h']))
+ self.assertEquals(includes['b.cc'], set(['b.h']))
+
+
+def post_order_nodes(root, child_nodes):
+ """Generate the nodes reachable from root (including root itself) in
+ post-order traversal order. child_nodes maps each node to its children."""
+ visited = set()
+
+ def walk(n):
+ if n in visited:
+ return
+ visited.add(n)
+
+ for c in child_nodes[n]:
+ for x in walk(c):
+ yield x
+ yield n
+
+ return walk(root)
+
+
+def compute_doms(root, includes):
+ """Compute the dominators for all nodes reachable from root. Node A dominates
+ node B if all paths from the root to B go through A. Returns a dict from
+ filename to the set of dominators of that filename (including itself)."""
+ rpo = list(reversed(list(post_order_nodes(root, includes))))
+ assert rpo[0] == root
+
+ # Initialization.
+ # The data-flow analysis starts with full dom sets,
+ # except for root, where we know the end result already.
+ # preds[n] are the direct predecessors of node n.
+ # The order is not important here, rpo is just handy as a list of all nodes.
+ doms = {}
+ preds = defaultdict(set)
+ for n in rpo:
+ doms[n] = set(rpo)
+ for x in includes[n]:
+ preds[x].add(n)
+ doms[root] = set([root])
+
+ # Iterate to fixed point.
+ # This is not the fastest algorithm, but it's simple and fast enough for us.
+ # Processing the nodes in reverse post-order leads to faster convergence.
+ # rpo[0] (the root) is skipped, because its dominators are known, and its
+ # empty preds set would break the set.intersection() invocation.
+ changed = True
+ while changed:
+ changed = False
+ for n in rpo[1:]:
+ new_set = set.intersection(*[doms[p] for p in preds[n]])
+ new_set.add(n)
+ if new_set != doms[n]:
+ doms[n] = new_set
+ changed = True
+
+ return doms
+
+
+class TestComputeDoms(unittest.TestCase):
+ def test_basic(self):
+ includes = {}
+ includes[1] = [2]
+ includes[2] = [1]
+ includes[3] = [2]
+ includes[4] = [1]
+ includes[5] = [4, 3]
+ root = 5
+
+ doms = compute_doms(root, includes)
+
+ self.assertEqual(doms[1], set([5, 1]))
+ self.assertEqual(doms[2], set([5, 2]))
+ self.assertEqual(doms[3], set([5, 3]))
+ self.assertEqual(doms[4], set([5, 4]))
+ self.assertEqual(doms[5], set([5]))
+
+
+def trans_size(root, includes, sizes):
+ """Compute the transitive size of a file, i.e. the size of the file itself and
+ all its transitive includes."""
+ return sum([sizes[n] for n in post_order_nodes(root, includes)])
+
+
+def analyze(target, revision, build_log_file, json_file):
+ print('Parsing build log...')
+ (roots, includes) = parse_build(build_log_file)
+
+ print('Getting file sizes...')
+ sizes = {name: os.path.getsize(name) for name in includes}
+
+ print('Computing transitive sizes...')
+ trans_sizes = {n: trans_size(n, includes, sizes) for n in includes}
+
+ print('Counting prevalence...')
+ prevalence = {name: 0 for name in includes}
+ for r in roots:
+ for n in post_order_nodes(r, includes):
+ prevalence[n] += 1
+
+ # Map from file to files that include it.
+ print('Building reverse include map...')
+ included_by = {k: set() for k in includes}
+ for k in includes:
+ for i in includes[k]:
+ included_by[i].add(k)
+
+ build_size = sum([trans_sizes[n] for n in roots])
+
+ print('Computing added sizes...')
+ added_sizes = {name: 0 for name in includes}
+ for r in roots:
+ doms = compute_doms(r, includes)
+ for n in doms:
+ for d in doms[n]:
+ added_sizes[d] += sizes[n]
+
+ # Assign a number to each filename for tighter JSON representation.
+ names = []
+ name2nr = {}
+ for n in sorted(includes.keys()):
+ name2nr[n] = len(names)
+ names.append(n)
+
+ def nr(name):
+ return name2nr[name]
+
+ print('Writing output...')
+
+ # Provide a JS object for convenient inclusion in the HTML file.
+ # If someone really wants a proper JSON file, maybe we can reconsider this.
+ json_file.write('data = ')
+
+ json.dump(
+ {
+ 'target': target,
+ 'revision': revision,
+ 'date': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC'),
+ 'files': names,
+ 'roots': [nr(x) for x in sorted(roots)],
+ 'includes': [[nr(x) for x in includes[n]] for n in names],
+ 'included_by': [[nr(x) for x in included_by[n]] for n in names],
+ 'sizes': [sizes[n] for n in names],
+ 'tsizes': [trans_sizes[n] for n in names],
+ 'asizes': [added_sizes[n] for n in names],
+ 'prevalence': [prevalence[n] for n in names],
+ }, json_file)
+
+ print('All done!')
+
+
+def main():
+ result = unittest.main(argv=sys.argv[:1], exit=False, verbosity=2).result
+ if len(result.failures) > 0 or len(result.errors) > 0:
+ return 1
+
+ parser = argparse.ArgumentParser(description='Analyze an #include graph.')
+ parser.add_argument('target', nargs=1, help='The target that was built.')
+ parser.add_argument('revision', nargs=1, help='The build revision.')
+ parser.add_argument('build_log', nargs=1, help='The build log to analyze.')
+ parser.add_argument('output_file', nargs=1, help='The JSON output file.')
+ args = parser.parse_args()
+
+ with open(args.build_log[0], 'r') as build_log_file:
+ with open(args.output_file[0], 'w') as json_file:
+ analyze(args.target[0], args.revision[0], build_log_file, json_file)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/tools/clang/scripts/build.py b/chromium/tools/clang/scripts/build.py
index ba3cc0f6653..e5cdb26d33e 100755
--- a/chromium/tools/clang/scripts/build.py
+++ b/chromium/tools/clang/scripts/build.py
@@ -412,6 +412,8 @@ def main():
parser = argparse.ArgumentParser(description='Build Clang.')
parser.add_argument('--bootstrap', action='store_true',
help='first build clang with CC, then with itself.')
+ parser.add_argument('--build-mac-arm', action='store_true',
+ help='Build arm binaries. Only valid on macOS.')
parser.add_argument('--disable-asserts', action='store_true',
help='build with asserts disabled')
parser.add_argument('--gcc-toolchain', help='what gcc toolchain to use for '
@@ -439,6 +441,13 @@ def main():
parser.add_argument('--with-android', type=gn_arg, nargs='?', const=True,
help='build the Android ASan runtime (linux only)',
default=sys.platform.startswith('linux'))
+ parser.add_argument('--with-fuchsia',
+ type=gn_arg,
+ nargs='?',
+ const=True,
+ help='build the Fuchsia runtimes (linux and mac only)',
+ default=sys.platform.startswith('linux')
+ or sys.platform.startswith('darwin'))
parser.add_argument('--without-android', action='store_false',
help='don\'t build Android ASan runtime (linux only)',
dest='with_android')
@@ -459,10 +468,6 @@ def main():
print('for how to install the NDK, or pass --without-android.')
return 1
- if args.llvm_force_head_revision:
- # Don't build fuchsia runtime on ToT bots at all.
- args.with_fuchsia = False
-
if args.with_fuchsia and not os.path.exists(FUCHSIA_SDK_DIR):
print('Fuchsia SDK not found at ' + FUCHSIA_SDK_DIR)
print('The Fuchsia SDK is needed to build libclang_rt for Fuchsia.')
@@ -475,6 +480,9 @@ def main():
print('for general Fuchsia build instructions.')
return 1
+ if args.build_mac_arm and sys.platform != 'darwin':
+ print('--build-mac-arm only valid on macOS')
+ return 1
# Don't buffer stdout, so that print statements are immediately flushed.
# LLVM tests print output without newlines, so with buffering they won't be
@@ -582,7 +590,6 @@ def main():
'-DLLVM_LOCAL_RPATH=' + os.path.join(args.gcc_toolchain, 'lib64')
]
-
if sys.platform == 'darwin':
# For libc++, we only want the headers.
base_cmake_args.extend([
@@ -804,48 +811,9 @@ def main():
# iPhones). armv7k is Apple Watch, which we don't need.
'-DDARWIN_ios_ARCHS=armv7;armv7s;arm64',
'-DDARWIN_iossim_ARCHS=i386;x86_64;arm64',
+ # We don't need 32-bit intel support for macOS, we only ship 64-bit.
+ '-DDARWIN_osx_ARCHS=arm64;x86_64',
])
- if args.bootstrap:
- # mac/arm64 needs MacOSX11.0.sdk. System Xcode (+ SDK) may be something
- # else, so use the hermetic Xcode.
- # Options:
- # - temporarily set system Xcode to Xcode 12 beta while running this
- # script, (cf build/swarming_xcode_install.py, but it looks unused)
- # - use Xcode 12 beta for everything on tot bots, only need to fuzz with
- # scripts/slave/recipes/chromium_upload_clang.py then (but now the
- # chrome/ios build will use the 11.0 SDK too and we'd be on the hook for
- # keeping it green -- if it's currently green, who knows)
- # - pass flags to cmake to try to coax it into using Xcode 12 beta for the
- # LLVM build without it being system Xcode.
- #
- # The last option seems best, so let's go with that. We need to pass
- # -isysroot to the SDK and -B to the /usr/bin so that the new ld64 is
- # used.
- # The compiler-rt build overrides -isysroot flags set via cflags, and we
- # only need to use the 11 SDK for the compiler-rt build. So set only
- # DARWIN_macosx_CACHED_SYSROOT to the 11 SDK and use the regular SDK
- # for the rest of the build. (The new ld is used for all links.)
- sys.path.insert(1, os.path.join(CHROMIUM_DIR, 'build'))
- import mac_toolchain
- LLVM_XCODE = os.path.join(THIRD_PARTY_DIR, 'llvm-xcode')
- mac_toolchain.InstallXcodeBinaries(LLVM_XCODE)
- isysroot_11 = os.path.join(LLVM_XCODE, 'Contents', 'Developer',
- 'Platforms', 'MacOSX.platform', 'Developer',
- 'SDKs', 'MacOSX11.1.sdk')
- xcode_bin = os.path.join(LLVM_XCODE, 'Contents', 'Developer',
- 'Toolchains', 'XcodeDefault.xctoolchain', 'usr',
- 'bin')
- # Include an arm64 slice for libclang_rt.osx.a. This requires using
- # MacOSX11.x.sdk (via -isysroot, via DARWIN_macosx_CACHED_SYSROOT) and
- # the new ld, via -B
- compiler_rt_args.extend([
- # We don't need 32-bit intel support for macOS, we only ship 64-bit.
- '-DDARWIN_osx_ARCHS=arm64;x86_64',
- '-DDARWIN_macosx_CACHED_SYSROOT=' + isysroot_11,
- ])
- ldflags += ['-B', xcode_bin]
- else:
- compiler_rt_args.extend(['-DDARWIN_osx_ARCHS=x86_64'])
else:
compiler_rt_args.append('-DCOMPILER_RT_BUILD_BUILTINS=OFF')
@@ -904,9 +872,13 @@ def main():
cmake_args.append('-DLLVM_ENABLE_LTO=Thin')
if sys.platform == 'win32':
cmake_args.append('-DLLVM_ENABLE_ZLIB=FORCE_ON')
+
if sys.platform == 'darwin':
cmake_args += ['-DCOMPILER_RT_ENABLE_IOS=ON',
'-DSANITIZER_MIN_OSX_VERSION=10.7']
+ if args.build_mac_arm:
+ cmake_args += ['-DCMAKE_OSX_ARCHITECTURES=arm64',
+ '-DLLVM_USE_HOST_TOOLS=ON']
# TODO(crbug.com/962988): Use -DLLVM_EXTERNAL_PROJECTS instead.
CreateChromeToolsShim()
@@ -924,8 +896,9 @@ def main():
# If any Chromium tools were built, install those now.
RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
- VerifyVersionOfBuiltClangMatchesVERSION()
- VerifyZlibSupport()
+ if not args.build_mac_arm:
+ VerifyVersionOfBuiltClangMatchesVERSION()
+ VerifyZlibSupport()
if sys.platform == 'win32':
platform = 'windows'
@@ -997,6 +970,9 @@ def main():
# depends on a newer version of libxml2.so than what's available on
# the bots. To make things work, use our just-built lld as linker.
'-fuse-ld=lld',
+ # Clang defaults to compiler-rt when targeting android after
+ # a478b0a199f4. Stick with libgcc for now. (crbug.com/1184398).
+ '--rtlib=libgcc',
]
android_args = base_cmake_args + [
'-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
@@ -1045,14 +1021,20 @@ def main():
os.mkdir(os.path.join(build_dir))
os.chdir(build_dir)
target_spec = target_arch + '-fuchsia'
+ if args.build_mac_arm:
+ # Just-built clang can't run (it's an arm binary), so use the bootstrap
+ # compiler instead.
+ host_path = LLVM_BOOTSTRAP_INSTALL_DIR
+ else:
+ host_path = LLVM_BUILD_DIR
# TODO(thakis): Might have to pass -B here once sysroot contains
# binaries (e.g. gas for arm64?)
fuchsia_args = base_cmake_args + [
- '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
- '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
- '-DCMAKE_LINKER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
- '-DCMAKE_AR=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-ar'),
- '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
+ '-DCMAKE_C_COMPILER=' + os.path.join(host_path, 'bin/clang'),
+ '-DCMAKE_CXX_COMPILER=' + os.path.join(host_path, 'bin/clang++'),
+ '-DCMAKE_LINKER=' + os.path.join(host_path, 'bin/clang'),
+ '-DCMAKE_AR=' + os.path.join(host_path, 'bin/llvm-ar'),
+ '-DLLVM_CONFIG_PATH=' + os.path.join(host_path, 'bin/llvm-config'),
'-DCMAKE_SYSTEM_NAME=Fuchsia',
'-DCMAKE_C_COMPILER_TARGET=%s-fuchsia' % target_arch,
'-DCMAKE_ASM_COMPILER_TARGET=%s-fuchsia' % target_arch,
@@ -1090,7 +1072,9 @@ def main():
fuchsia_lib_dst_dir)
# Build the Fuchsia profile runtime.
- if target_arch == 'x86_64':
+ # TODO(thakis): Figure out why this doesn't build with the stage0
+ # compiler in arm builds.
+ if target_arch == 'x86_64' and not args.build_mac_arm:
fuchsia_args.extend([
'-DCOMPILER_RT_BUILD_BUILTINS=OFF',
'-DCOMPILER_RT_BUILD_PROFILE=ON',
@@ -1111,10 +1095,11 @@ def main():
fuchsia_lib_dst_dir)
# Run tests.
- if args.run_tests or args.llvm_force_head_revision:
+ if (not args.build_mac_arm and
+ (args.run_tests or args.llvm_force_head_revision)):
RunCommand(['ninja', '-C', LLVM_BUILD_DIR, 'cr-check-all'], msvc_arch='x64')
- if args.run_tests:
+ if not args.build_mac_arm and args.run_tests:
test_targets = [ 'check-all' ]
if sys.platform == 'darwin':
# TODO(thakis): Run check-all on Darwin too, https://crbug.com/959361
diff --git a/chromium/tools/clang/scripts/include-analysis.html b/chromium/tools/clang/scripts/include-analysis.html
new file mode 100644
index 00000000000..d82f76d03ac
--- /dev/null
+++ b/chromium/tools/clang/scripts/include-analysis.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Chrome #include Analysis</title>
+
+ <!--Generated by analyze_includes.py. Provides the 'data' object.-->
+ <script src="include-analysis.js"></script>
+
+ <style>
+ tr td { text-align: right; }
+ tr td:nth-child(1) { text-align: left; }
+ tr td:nth-child(2) { text-align: left; }
+ th a { text-decoration: none; }
+ tbody tr:hover { background-color: #dddddd; }
+ th { position: sticky; top: 0; background-color: #ffffff }
+ th:nth-child(n+2) { cursor: pointer; }
+ th.highlighted { background-color: #dddddd }
+ #filterResults { font-weight: bold }
+ </style>
+ </head>
+ <body>
+
+<h1>Chrome #include Analysis (go/chrome-includes)</h1>
+
+<p>Build target: <span id="buildTarget">x</span> (Linux). Revision: <span id="buildRevision">x</span>. Analyzed on: <span id="analysisDate">x</span>.</p>
+
+<p>Number of translation units: <span id="numRoots">x</span>. Total translation unit size: <span id="totBuildSize">x</span> bytes.</p>
+
+<p>Number of files: <span id="numFiles">x</span>. Total file size: <span id="totFileSize">x</span> bytes.</p>
+
+<hr>
+
+<p>
+<label for="filter">Filter: (regex)</label>
+<input type="text" id="filter" name="filter" size="60" onKeyUp="if (event.keyCode == 13) document.getElementById('apply').click()">
+<button onClick="changeState('filter', document.getElementById('filter').value)" id="apply">Apply</button>
+<button onClick="changeState('filter', '')">Clear</button>
+<span id="filterResults"></span>
+</p>
+
+<table border="1">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th id="filename" onclick="changeState('sort', 'filename')">Filename</th>
+ <th id="isize" colspan="2" onclick="changeState('sort', 'isize')">Individual Size (B)</th>
+ <th id="tsize" colspan="2" onclick="changeState('sort', 'tsize')">Expanded Size (B)</th>
+ <th id="asize" colspan="2" onclick="changeState('sort', 'asize')">Added Size (B)</th>
+ <th id="prevalence" colspan="2" onclick="changeState('sort', 'prevalence')">Occurrences</th>
+ <th id="icount" onclick="changeState('sort', 'icount')">Include Count</th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+</table>
+
+<hr>
+
+<h3>Legend</h3>
+<p>
+Translation Unit: The data processed during a compiler invocation.<br>
+Individual Size: The size of the file, and as a percentage of the total file size.<br>
+Expanded Size: The size of the file and all the files it includes, directly and indirectly. Also shown as percentage of the total translation unit size.<br>
+Added Size: How much size is added by this file being part of the build. In other words, if this file were empty and had no includes, how much smaller would the build be. Also shown as percentage of the total translation unit size.<br>
+Occurrences: How many translation units this file is part of. Also shown as a percentage of the total number of translation units.<br>
+Include Count: How many times this file is included directly.<br>
+</p>
+
+<p>File size does not correlate perfectly with compile time, but can serve as a rough guide to what files are slow to compile.</p>
+
+<p>Analysis by <a href="https://source.chromium.org/chromium/chromium/src/+/HEAD:tools/clang/scripts/analyze_includes.py">analyze_includes.py</a>.</p>
+
+<script>
+"use strict";
+
+function sum(arr) {
+ return arr.reduce((a, b) => a + b, 0);
+}
+
+const numberFormat = new Intl.NumberFormat('en-US');
+function fmt(num) {
+ return numberFormat.format(num);
+}
+
+function regexEscape(str) {
+ str = str.replaceAll('+', '\\+');
+ str = str.replaceAll('.', '\\.');
+ return str;
+}
+
+const totFileSize = sum(data.sizes);
+const totBuildSize = sum(data.roots.map(r => data.tsizes[r]));
+const numRoots = data.roots.length;
+
+document.getElementById('buildTarget').textContent = data.target;
+document.getElementById('buildRevision').innerHTML =
+ `<a href="https://crrev.com/${data.revision}">${data.revision}</a>`;
+document.getElementById('analysisDate').textContent = data.date;
+
+document.getElementById('numRoots').textContent = fmt(numRoots);
+document.getElementById('totBuildSize').textContent = fmt(totBuildSize);
+document.getElementById('numFiles').textContent = fmt(data.files.length);
+document.getElementById('totFileSize').textContent = fmt(totFileSize);
+
+
+function buildRow(i, rank) {
+ return `
+<tr>
+<td><a href="javascript:changeState('filter', '^' + regexEscape('${data.files[i]}' + '$'))">${rank + 1}</a></td>
+<td><a href="https://source.chromium.org/chromium/chromium/src/+/HEAD:${data.files[i]}">${data.files[i]}</a></td>
+<td>${fmt(data.sizes[i])}</td> <td>${(100 * data.sizes[i] / totFileSize).toFixed(2)}&nbsp;%</td>
+<td>${fmt(data.tsizes[i])}</td> <td>${(100 * data.tsizes[i] / totBuildSize).toFixed(2)}&nbsp;%</td>
+<td>${fmt(data.asizes[i])}</td> <td>${(100 * data.asizes[i] / totBuildSize).toFixed(2)}&nbsp;%</td>
+<td>${fmt(data.prevalence[i])}</td> <td>${(100 * data.prevalence[i] / numRoots).toFixed(2)}&nbsp;%</td>
+<td><a href="javascript:changeState('filter', 'includes:${data.files[i]}')">${fmt(data.included_by[i].length)}</a></td>
+</tr>
+ `;
+}
+
+function clearTable() {
+ const tbody = document.querySelector('tbody');
+ tbody.parentNode.removeChild(tbody);
+ document.getElementById('filterResults').innerHTML = '';
+}
+
+function intersect(arr1, arr2) {
+ let s2 = new Set(arr2);
+ return arr1.filter(x => s2.has(x));
+}
+
+function buildTable() {
+ clearTable();
+ let fileNums = [...Array(data.files.length).keys()];
+ const state = getState();
+
+ let filter = state.get('filter');
+ document.getElementById('filter').value = filter;
+
+ if (filter !== '') {
+ let match;
+
+ // Handle includes: operator.
+ const includesOp = new RegExp(' *includes:([^ ]*) *');
+ while (match = filter.match(includesOp)) {
+ const include = match[1];
+ const fileNum = data.files.findIndex(n => n === include);
+ fileNums = intersect(fileNums, data.included_by[fileNum]);
+ filter = filter.replace(includesOp, '');
+ }
+
+ const re = new RegExp(filter);
+ fileNums = fileNums.filter(i => data.files[i].match(re));
+
+ document.getElementById('filterResults').innerHTML =
+ `${fmt(fileNums.length)} result${fileNums.length == 1 ? '' : 's'}.`;
+ }
+
+ const sortFuncs = {
+ filename: (i, j) => data.files[i].localeCompare(data.files[j]),
+ isize: (i, j) => data.sizes[j] - data.sizes[i],
+ tsize: (i, j) => data.tsizes[j] - data.tsizes[i],
+ prevalence: (i, j) => data.prevalence[j] - data.prevalence[i],
+ icount: (i, j) => data.included_by[j].length - data.included_by[i].length,
+ asize: (i, j) => data.asizes[j] - data.asizes[i],
+ };
+
+ document.querySelectorAll('th').forEach(th => th.classList.remove('highlighted'));
+ document.getElementById(state.get('sort')).classList.add('highlighted');
+
+ fileNums.sort(sortFuncs[state.get('sort')]);
+
+ const limit = Math.min(1000, fileNums.length);
+ fileNums = fileNums.slice(0, limit);
+
+ const tbody = document.createElement('tbody');
+ tbody.innerHTML = fileNums.map(buildRow).join('');
+ document.querySelector('table').appendChild(tbody);
+}
+
+function setState(params) {
+ window.location.hash = params.toString();
+}
+
+function getState() {
+ let params = new URLSearchParams(window.location.hash.substring(1));
+
+ if (!params.has('filter'))
+ params.set('filter', '');
+ if (!params.has('sort'))
+ params.set('sort', 'asize');
+
+ return params;
+}
+
+function changeState(key, value) {
+ let s = getState();
+ s.set(key, value);
+ setState(s);
+}
+
+window.onhashchange = buildTable;
+
+buildTable();
+</script>
+ </body>
+</html>
diff --git a/chromium/tools/clang/scripts/package.py b/chromium/tools/clang/scripts/package.py
index 4ea0b6380b5..b6526f87ce0 100755
--- a/chromium/tools/clang/scripts/package.py
+++ b/chromium/tools/clang/scripts/package.py
@@ -12,6 +12,7 @@ import argparse
import fnmatch
import itertools
import os
+import platform
import shutil
import subprocess
import sys
@@ -90,9 +91,11 @@ def RunGsutil(args):
return subprocess.call([sys.executable, GetGsutilPath()] + args)
-def MaybeUpload(do_upload, filename, platform, extra_gsutil_args=[]):
- gsutil_args = ['cp'] + extra_gsutil_args + ['-a', 'public-read', filename,
- 'gs://chromium-browser-clang-staging/%s/%s' % (platform, filename)]
+def MaybeUpload(do_upload, filename, gcs_platform, extra_gsutil_args=[]):
+ gsutil_args = ['cp'] + extra_gsutil_args + [
+ '-a', 'public-read', filename,
+ 'gs://chromium-browser-clang-staging/%s/%s' % (gcs_platform, filename)
+ ]
if do_upload:
print('Uploading %s to Google Cloud Storage...' % filename)
exit_code = RunGsutil(gsutil_args)
@@ -156,18 +159,33 @@ def main():
parser = argparse.ArgumentParser(description='build and package clang')
parser.add_argument('--upload', action='store_true',
help='Upload the target archive to Google Cloud Storage.')
+ parser.add_argument('--build-mac-arm', action='store_true',
+ help='Build arm binaries. Only valid on macOS.')
args = parser.parse_args()
+ if args.build_mac_arm and sys.platform != 'darwin':
+ print('--build-mac-arm only valid on macOS')
+ return 1
+
expected_stamp = GetExpectedStamp()
pdir = 'clang-' + expected_stamp
print(pdir)
if sys.platform == 'darwin':
- platform = 'Mac'
+ # When we need to run this script on an arm machine, we need to add a
+ # --build-mac-intel switch to pick which clang to build, pick the
+ # 'Mac_arm64' here when there's no flag and 'Mac' when --build-mac-intel is
+ # passed. Also update the build script to explicitly pass a default triple
+ # then.
+ assert platform.machine() != 'arm64'
+ if args.build_mac_arm:
+ gcs_platform = 'Mac_arm64'
+ else:
+ gcs_platform = 'Mac'
elif sys.platform == 'win32':
- platform = 'Win'
+ gcs_platform = 'Win'
else:
- platform = 'Linux_x64'
+ gcs_platform = 'Linux_x64'
with open('buildlog.txt', 'w') as log:
Tee('Starting build\n', log)
@@ -182,6 +200,8 @@ def main():
os.path.join(THIS_DIR, 'build.py'), '--bootstrap', '--disable-asserts',
'--run-tests', '--pgo'
]
+ if args.build_mac_arm:
+ build_cmd.append('--build-mac-arm')
if sys.platform != 'darwin':
build_cmd.append('--thinlto')
@@ -219,8 +239,11 @@ def main():
# Include libclang_rt.builtins.a for Fuchsia targets.
'lib/clang/$V/lib/aarch64-fuchsia/libclang_rt.builtins.a',
'lib/clang/$V/lib/x86_64-fuchsia/libclang_rt.builtins.a',
- 'lib/clang/$V/lib/x86_64-fuchsia/libclang_rt.profile.a',
])
+ if not args.build_mac_arm:
+ # TODO(thakis): Figure out why this doesn't build in --build-mac-arm
+ # builds.
+ want.append('lib/clang/$V/lib/x86_64-fuchsia/libclang_rt.profile.a')
if sys.platform == 'darwin':
want.extend([
# AddressSanitizer runtime.
@@ -243,74 +266,77 @@ def main():
])
elif sys.platform.startswith('linux'):
want.extend([
- # Copy the stdlibc++.so.6 we linked the binaries against.
- 'lib/libstdc++.so.6',
+ # Copy the stdlibc++.so.6 we linked the binaries against.
+ 'lib/libstdc++.so.6',
- # Add LLD.
- 'bin/lld',
+ # Add LLD.
+ 'bin/lld',
- # Add llvm-ar for LTO.
- 'bin/llvm-ar',
+ # Add llvm-ar for LTO.
+ 'bin/llvm-ar',
- # Add llvm-objcopy for partition extraction on Android.
- 'bin/llvm-objcopy',
+ # Add llvm-objcopy for partition extraction on Android.
+ 'bin/llvm-objcopy',
- # AddressSanitizer C runtime (pure C won't link with *_cxx).
- 'lib/clang/$V/lib/linux/libclang_rt.asan-i386.a',
- 'lib/clang/$V/lib/linux/libclang_rt.asan-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.asan-x86_64.a.syms',
+ # Add llvm-nm.
+ 'bin/llvm-nm',
- # AddressSanitizer C++ runtime.
- 'lib/clang/$V/lib/linux/libclang_rt.asan_cxx-i386.a',
- 'lib/clang/$V/lib/linux/libclang_rt.asan_cxx-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.asan_cxx-x86_64.a.syms',
+ # AddressSanitizer C runtime (pure C won't link with *_cxx).
+ 'lib/clang/$V/lib/linux/libclang_rt.asan-i386.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.asan-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.asan-x86_64.a.syms',
- # AddressSanitizer Android runtime.
- 'lib/clang/$V/lib/linux/libclang_rt.asan-aarch64-android.so',
- 'lib/clang/$V/lib/linux/libclang_rt.asan-arm-android.so',
- 'lib/clang/$V/lib/linux/libclang_rt.asan-i686-android.so',
+ # AddressSanitizer C++ runtime.
+ 'lib/clang/$V/lib/linux/libclang_rt.asan_cxx-i386.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.asan_cxx-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.asan_cxx-x86_64.a.syms',
- # HWASAN Android runtime.
- 'lib/clang/$V/lib/linux/libclang_rt.hwasan-aarch64-android.so',
+ # AddressSanitizer Android runtime.
+ 'lib/clang/$V/lib/linux/libclang_rt.asan-aarch64-android.so',
+ 'lib/clang/$V/lib/linux/libclang_rt.asan-arm-android.so',
+ 'lib/clang/$V/lib/linux/libclang_rt.asan-i686-android.so',
- # MemorySanitizer C runtime (pure C won't link with *_cxx).
- 'lib/clang/$V/lib/linux/libclang_rt.msan-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.msan-x86_64.a.syms',
+ # HWASAN Android runtime.
+ 'lib/clang/$V/lib/linux/libclang_rt.hwasan-aarch64-android.so',
- # MemorySanitizer C++ runtime.
- 'lib/clang/$V/lib/linux/libclang_rt.msan_cxx-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.msan_cxx-x86_64.a.syms',
+ # MemorySanitizer C runtime (pure C won't link with *_cxx).
+ 'lib/clang/$V/lib/linux/libclang_rt.msan-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.msan-x86_64.a.syms',
- # Profile runtime (used by profiler and code coverage).
- 'lib/clang/$V/lib/linux/libclang_rt.profile-i386.a',
- 'lib/clang/$V/lib/linux/libclang_rt.profile-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.profile-aarch64-android.a',
- 'lib/clang/$V/lib/linux/libclang_rt.profile-arm-android.a',
+ # MemorySanitizer C++ runtime.
+ 'lib/clang/$V/lib/linux/libclang_rt.msan_cxx-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.msan_cxx-x86_64.a.syms',
- # ThreadSanitizer C runtime (pure C won't link with *_cxx).
- 'lib/clang/$V/lib/linux/libclang_rt.tsan-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.tsan-x86_64.a.syms',
+ # Profile runtime (used by profiler and code coverage).
+ 'lib/clang/$V/lib/linux/libclang_rt.profile-i386.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.profile-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.profile-aarch64-android.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.profile-arm-android.a',
- # ThreadSanitizer C++ runtime.
- 'lib/clang/$V/lib/linux/libclang_rt.tsan_cxx-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.tsan_cxx-x86_64.a.syms',
+ # ThreadSanitizer C runtime (pure C won't link with *_cxx).
+ 'lib/clang/$V/lib/linux/libclang_rt.tsan-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.tsan-x86_64.a.syms',
- # UndefinedBehaviorSanitizer C runtime (pure C won't link with *_cxx).
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-i386.a',
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-x86_64.a.syms',
+ # ThreadSanitizer C++ runtime.
+ 'lib/clang/$V/lib/linux/libclang_rt.tsan_cxx-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.tsan_cxx-x86_64.a.syms',
- # UndefinedBehaviorSanitizer C++ runtime.
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone_cxx-i386.a',
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone_cxx-x86_64.a',
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone_cxx-x86_64.a.syms',
+ # UndefinedBehaviorSanitizer C runtime (pure C won't link with *_cxx).
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-i386.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-x86_64.a.syms',
+
+ # UndefinedBehaviorSanitizer C++ runtime.
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone_cxx-i386.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone_cxx-x86_64.a',
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone_cxx-x86_64.a.syms',
- # UndefinedBehaviorSanitizer Android runtime, needed for CFI.
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-aarch64-android.so',
- 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-arm-android.so',
+ # UndefinedBehaviorSanitizer Android runtime, needed for CFI.
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-aarch64-android.so',
+ 'lib/clang/$V/lib/linux/libclang_rt.ubsan_standalone-arm-android.so',
- # Blacklist for MemorySanitizer (used on Linux only).
- 'lib/clang/$V/share/msan_blacklist.txt',
+ # Blacklist for MemorySanitizer (used on Linux only).
+ 'lib/clang/$V/share/msan_blacklist.txt',
])
elif sys.platform == 'win32':
want.extend([
@@ -392,8 +418,8 @@ def main():
if sys.platform.startswith('linux'):
os.symlink('lld', os.path.join(pdir, 'bin', 'ld.lld'))
os.symlink('lld', os.path.join(pdir, 'bin', 'ld64.lld'))
- os.symlink('lld', os.path.join(pdir, 'bin', 'ld64.lld.darwinnew'))
os.symlink('lld', os.path.join(pdir, 'bin', 'lld-link'))
+ os.symlink('llvm-objcopy', os.path.join(pdir, 'bin', 'llvm-strip'))
# Copy libc++ headers.
if sys.platform == 'darwin':
@@ -407,11 +433,13 @@ def main():
with tarfile.open(pdir + '.tgz', 'w:gz') as tar:
for entry in tar_entries:
tar.add(os.path.join(pdir, entry), arcname=entry, filter=PrintTarProgress)
- MaybeUpload(args.upload, pdir + '.tgz', platform)
+ MaybeUpload(args.upload, pdir + '.tgz', gcs_platform)
# Upload build log next to it.
os.rename('buildlog.txt', pdir + '-buildlog.txt')
- MaybeUpload(args.upload, pdir + '-buildlog.txt', platform,
+ MaybeUpload(args.upload,
+ pdir + '-buildlog.txt',
+ gcs_platform,
extra_gsutil_args=['-z', 'txt'])
os.remove(pdir + '-buildlog.txt')
@@ -425,7 +453,7 @@ def main():
with tarfile.open(code_coverage_dir + '.tgz', 'w:gz') as tar:
tar.add(os.path.join(code_coverage_dir, 'bin'), arcname='bin',
filter=PrintTarProgress)
- MaybeUpload(args.upload, code_coverage_dir + '.tgz', platform)
+ MaybeUpload(args.upload, code_coverage_dir + '.tgz', gcs_platform)
# Zip up llvm-objdump and related tools for sanitizer coverage and Supersize.
objdumpdir = 'llvmobjdump-' + stamp
@@ -447,7 +475,7 @@ def main():
filter=PrintTarProgress)
tar.add(llvmobjdump_stamp_file, arcname=llvmobjdump_stamp_file_base,
filter=PrintTarProgress)
- MaybeUpload(args.upload, objdumpdir + '.tgz', platform)
+ MaybeUpload(args.upload, objdumpdir + '.tgz', gcs_platform)
# Zip up clang-tidy for users who opt into it, and Tricium.
clang_tidy_dir = 'clang-tidy-' + stamp
@@ -458,7 +486,7 @@ def main():
with tarfile.open(clang_tidy_dir + '.tgz', 'w:gz') as tar:
tar.add(os.path.join(clang_tidy_dir, 'bin'), arcname='bin',
filter=PrintTarProgress)
- MaybeUpload(args.upload, clang_tidy_dir + '.tgz', platform)
+ MaybeUpload(args.upload, clang_tidy_dir + '.tgz', gcs_platform)
# On Mac, lld isn't part of the main zip. Upload it in a separate zip.
if sys.platform == 'darwin':
@@ -476,7 +504,7 @@ def main():
with tarfile.open(llddir + '.tgz', 'w:gz') as tar:
tar.add(os.path.join(llddir, 'bin'), arcname='bin',
filter=PrintTarProgress)
- MaybeUpload(args.upload, llddir + '.tgz', platform)
+ MaybeUpload(args.upload, llddir + '.tgz', gcs_platform)
# dsymutil isn't part of the main zip either, and it gets periodically
# deployed to CIPD (manually, not as part of clang rolls) for use in the
@@ -489,7 +517,7 @@ def main():
with tarfile.open(dsymdir + '.tgz', 'w:gz') as tar:
tar.add(os.path.join(dsymdir, 'bin'), arcname='bin',
filter=PrintTarProgress)
- MaybeUpload(args.upload, dsymdir + '.tgz', platform)
+ MaybeUpload(args.upload, dsymdir + '.tgz', gcs_platform)
# Zip up the translation_unit tool.
translation_unit_dir = 'translation_unit-' + stamp
@@ -501,7 +529,7 @@ def main():
with tarfile.open(translation_unit_dir + '.tgz', 'w:gz') as tar:
tar.add(os.path.join(translation_unit_dir, 'bin'), arcname='bin',
filter=PrintTarProgress)
- MaybeUpload(args.upload, translation_unit_dir + '.tgz', platform)
+ MaybeUpload(args.upload, translation_unit_dir + '.tgz', gcs_platform)
# Zip up the libclang binaries.
libclang_dir = 'libclang-' + stamp
@@ -520,7 +548,7 @@ def main():
for entry in tar_entries:
tar.add(os.path.join(libclang_dir, entry), arcname=entry,
filter=PrintTarProgress)
- MaybeUpload(args.upload, libclang_dir + '.tgz', platform)
+ MaybeUpload(args.upload, libclang_dir + '.tgz', gcs_platform)
if sys.platform == 'win32' and args.upload:
binaries = [f for f in want if f.endswith('.exe') or f.endswith('.dll')]
diff --git a/chromium/tools/clang/scripts/update.py b/chromium/tools/clang/scripts/update.py
index a9c0af0dc9f..6c9de809806 100755
--- a/chromium/tools/clang/scripts/update.py
+++ b/chromium/tools/clang/scripts/update.py
@@ -18,6 +18,7 @@ from __future__ import division
from __future__ import print_function
import argparse
import os
+import platform
import shutil
import stat
import sys
@@ -38,8 +39,8 @@ import zipfile
# https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
# Reverting problematic clang rolls is safe, though.
# This is the output of `git describe` and is usable as a commit-ish.
-CLANG_REVISION = 'llvmorg-13-init-1559-g01b87444'
-CLANG_SUB_REVISION = 3
+CLANG_REVISION = 'llvmorg-13-init-6429-g0e92cbd6'
+CLANG_SUB_REVISION = 2
PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
RELEASE_VERSION = '13.0.0'
@@ -160,6 +161,7 @@ def GetPlatformUrlPrefix(host_os):
_HOST_OS_URL_MAP = {
'linux': 'Linux_x64',
'mac': 'Mac',
+ 'mac-arm64': 'Mac_arm64',
'win': 'Win',
}
return CDS_URL + '/' + _HOST_OS_URL_MAP[host_os] + '/'
@@ -179,6 +181,9 @@ def DownloadAndUnpackPackage(package_file, output_dir, host_os):
def DownloadAndUnpackClangMacRuntime(output_dir):
cds_file = "clang-%s.tgz" % PACKAGE_VERSION
+ # We run this only for the runtime libraries, and 'mac' and 'mac-arm64' both
+ # have the same (universal) runtime libraries. It doesn't matter which one
+ # we download here.
cds_full_url = GetPlatformUrlPrefix('mac') + cds_file
path_prefixes = [
'lib/clang/' + RELEASE_VERSION + '/lib/darwin', 'include/c++/v1'
@@ -220,12 +225,11 @@ def UpdatePackage(package_name, host_os):
package_file = 'clang-tidy'
elif package_name == 'lld_mac':
package_file = 'lld'
- if host_os != 'mac':
- print(
- 'The lld_mac package cannot be downloaded for non-macs.',
- file=sys.stderr)
- print(
- 'On non-mac, lld is included in the clang package.', file=sys.stderr)
+ if host_os not in ('mac', 'mac-arm64'):
+ print('The lld_mac package can only be downloaded on macOS.',
+ file=sys.stderr)
+ print('On non-mac, lld is included in the clang package.',
+ file=sys.stderr)
return 1
elif package_name == 'objdump':
package_file = 'llvmobjdump'
@@ -290,6 +294,8 @@ def main():
'win32': 'win',
}
default_host_os = _PLATFORM_HOST_OS_MAP.get(sys.platform, sys.platform)
+ if default_host_os == 'mac' and platform.machine() == 'arm64':
+ default_host_os = 'mac-arm64'
parser = argparse.ArgumentParser(description='Update clang.')
parser.add_argument('--output-dir',
@@ -297,11 +303,11 @@ def main():
parser.add_argument('--package',
help='What package to update (default: clang)',
default='clang')
- parser.add_argument(
- '--host-os',
- help='Which host OS to download for (default: %s)' % default_host_os,
- default=default_host_os,
- choices=('linux', 'mac', 'win'))
+ parser.add_argument('--host-os',
+ help='Which host OS to download for (default: %s)' %
+ default_host_os,
+ default=default_host_os,
+ choices=('linux', 'mac', 'mac-arm64', 'win'))
parser.add_argument('--print-revision', action='store_true',
help='Print current clang revision and exit.')
parser.add_argument('--llvm-force-head-revision', action='store_true',
diff --git a/chromium/tools/clang/scripts/upload_revision.py b/chromium/tools/clang/scripts/upload_revision.py
index 2fb1aaa289d..f74a62918a4 100755
--- a/chromium/tools/clang/scripts/upload_revision.py
+++ b/chromium/tools/clang/scripts/upload_revision.py
@@ -40,8 +40,10 @@ Cq-Include-Trybots: chromium/try:linux_chromium_chromeos_msan_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_compile_dbg_32_ng
Cq-Include-Trybots: chromium/try:linux_chromium_msan_rel_ng
Cq-Include-Trybots: chromium/try:mac-arm64-rel,mac_chromium_asan_rel_ng
-Cq-Include-Trybots: chromium/try:win-angle-deqp-rel-64
-Cq-Include-Trybots: chromium/try:win-asan,win7-rel,win-angle-deqp-rel-32
+Cq-Include-Trybots: chromium/try:win-asan,win7-rel
+Cq-Include-Trybots: chromium/try:android-official,fuchsia-official
+Cq-Include-Trybots: chromium/try:mac-official,linux-official
+Cq-Include-Trybots: chromium/try:win-official,win32-official
Cq-Include-Trybots: chrome/try:iphone-device,ipad-device
Cq-Include-Trybots: chrome/try:linux-chromeos-chrome
Cq-Include-Trybots: chrome/try:win-chrome,win64-chrome,mac-chrome
@@ -104,13 +106,16 @@ def main():
Git(["add", UPDATE_PY_PATH])
commit_message = 'Ran `{}`.'.format(' '.join(sys.argv)) + COMMIT_FOOTER
- Git(["commit", "-m", "Roll clang {} : {}.\n\n{}".format(
- old_rev_string, rev_string, commit_message)])
+ Git([
+ "commit", "-m",
+ "Roll clang {} : {}\n\n{}".format(old_rev_string, rev_string,
+ commit_message)
+ ])
Git(["cl", "upload", "-f", "--bypass-hooks"])
Git([
"cl", "try", "-B", "chromium/try", "-b", "linux_upload_clang", "-b",
- "mac_upload_clang", "-b", "win_upload_clang"
+ "mac_upload_clang", "-b", "mac_upload_clang_arm", "-b", "win_upload_clang"
])
print ("Please, wait until the try bots succeeded "
diff --git a/chromium/tools/clang/trace_annotator/TraceAnnotator.cpp b/chromium/tools/clang/trace_annotator/TraceAnnotator.cpp
index c1ef48dc838..ea0ecb8b701 100644
--- a/chromium/tools/clang/trace_annotator/TraceAnnotator.cpp
+++ b/chromium/tools/clang/trace_annotator/TraceAnnotator.cpp
@@ -157,9 +157,14 @@ static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
int main(int argc, const char* argv[]) {
llvm::cl::OptionCategory category("TraceAnnotator Tool");
- CommonOptionsParser options(argc, argv, category);
- clang::tooling::ClangTool tool(options.getCompilations(),
- options.getSourcePathList());
+ llvm::Expected<CommonOptionsParser> options =
+ CommonOptionsParser::create(argc, argv, category);
+ if (!options) {
+ llvm::outs() << llvm::toString(options.takeError());
+ return 1;
+ }
+ clang::tooling::ClangTool tool(options->getCompilations(),
+ options->getSourcePathList());
std::vector<Replacement> replacements;
TraceAnnotator converter(&replacements);