| Index: tools/gn/toolchain_manager.cc
|
| diff --git a/tools/gn/toolchain_manager.cc b/tools/gn/toolchain_manager.cc
|
| index affdec99ce0b37c4449752e3a92100b4bab43a1e..4edf212218ca747c8b648d9eaf62cae3e6825482 100644
|
| --- a/tools/gn/toolchain_manager.cc
|
| +++ b/tools/gn/toolchain_manager.cc
|
| @@ -78,11 +78,17 @@ struct ToolchainManager::Info {
|
| const Label& toolchain_name,
|
| const std::string& output_subdir_name)
|
| : state(TOOLCHAIN_NOT_LOADED),
|
| - toolchain(toolchain_name),
|
| + settings(build_settings, output_subdir_name),
|
| + toolchain(new Toolchain(&settings, toolchain_name)),
|
| toolchain_set(false),
|
| - settings(build_settings, &toolchain, output_subdir_name),
|
| toolchain_file_loaded(false),
|
| item_node(NULL) {
|
| + settings.set_toolchain_label(toolchain_name);
|
| + }
|
| +
|
| + ~Info() {
|
| + if (!item_node) // See toolchain definition for more.
|
| + delete toolchain;
|
| }
|
|
|
| // Makes sure that an ItemNode is created for the toolchain, which lets
|
| @@ -95,17 +101,13 @@ struct ToolchainManager::Info {
|
| void EnsureItemNode() {
|
| if (!item_node) {
|
| ItemTree& tree = settings.build_settings()->item_tree();
|
| - item_node = new ItemNode(&toolchain);
|
| + item_node = new ItemNode(toolchain);
|
| tree.AddNodeLocked(item_node);
|
| }
|
| }
|
|
|
| ToolchainState state;
|
|
|
| - Toolchain toolchain;
|
| - bool toolchain_set;
|
| - LocationRange toolchain_definition_location;
|
| -
|
| // The first place in the build that we saw a reference for this toolchain.
|
| // This allows us to report errors if it can't be loaded and blame some
|
| // reasonable place of the code. This will be empty for the default toolchain.
|
| @@ -118,6 +120,13 @@ struct ToolchainManager::Info {
|
| // is only ever read or written inside the lock.
|
| Settings settings;
|
|
|
| + // When we create an item node, this pointer will be owned by that node
|
| + // so it's lifetime is managed by the dependency graph. Before we've created
|
| + // the ItemNode, this class has to takre responsibility for this pointer.
|
| + Toolchain* toolchain;
|
| + bool toolchain_set;
|
| + LocationRange toolchain_definition_location;
|
| +
|
| // Set when the file corresponding to the toolchain definition is loaded.
|
| // This will normally be set right after "toolchain_set". However, if the
|
| // toolchain definition is missing, the file might be marked loaded but the
|
| @@ -202,7 +211,7 @@ const Toolchain* ToolchainManager::GetToolchainDefinitionUnlocked(
|
| // Since we don't allow defining a toolchain more than once, we know that
|
| // once it's set it won't be mutated, so we can safely return this pointer
|
| // for reading outside the lock.
|
| - return &found->second->toolchain;
|
| + return found->second->toolchain;
|
| }
|
|
|
| bool ToolchainManager::SetDefaultToolchainUnlocked(
|
| @@ -261,13 +270,10 @@ bool ToolchainManager::SetToolchainDefinitionLocked(
|
| }
|
|
|
| // The labels should match or else we're setting the wrong one!
|
| - CHECK(info->toolchain.label() == tc.label());
|
| + CHECK(info->toolchain->label() == tc.label());
|
|
|
| - // Save the toolchain. We can just overwrite our definition, but we need to
|
| - // be careful to preserve the is_default flag.
|
| - bool is_default = info->toolchain.is_default();
|
| - info->toolchain = tc;
|
| - info->toolchain.set_is_default(is_default);
|
| + // Save the toolchain. We can just overwrite our definition.
|
| + *info->toolchain = tc;
|
|
|
| if (info->toolchain_set) {
|
| *err = Err(defined_from, "Duplicate toolchain definition.");
|
| @@ -423,8 +429,9 @@ void ToolchainManager::FixupDefaultToolchainLocked() {
|
| // to set the label, but we can assign the toolchain to a new one. Loading
|
| // the build config can not change the toolchain, so we won't be overwriting
|
| // anything useful.
|
| - info->toolchain = Toolchain(default_toolchain_);
|
| - info->toolchain.set_is_default(true);
|
| + *info->toolchain = Toolchain(&info->settings, default_toolchain_);
|
| + info->settings.set_is_default(true);
|
| + info->settings.set_toolchain_label(default_toolchain_);
|
| info->EnsureItemNode();
|
|
|
| // The default toolchain is loaded in greedy mode so all targets we
|
| @@ -486,8 +493,8 @@ void ToolchainManager::BackgroundLoadBuildConfig(Info* info,
|
| Scope* base_config = info->settings.base_config();
|
| base_config->set_source_dir(SourceDir("//"));
|
|
|
| - info->settings.build_settings()->build_args().SetupRootScope(base_config,
|
| - info->settings.toolchain()->args());
|
| + info->settings.build_settings()->build_args().SetupRootScope(
|
| + base_config, info->toolchain->args());
|
|
|
| base_config->SetProcessingBuildConfig();
|
| if (is_default)
|
| @@ -495,7 +502,7 @@ void ToolchainManager::BackgroundLoadBuildConfig(Info* info,
|
|
|
| ScopedTrace trace(TraceItem::TRACE_FILE_EXECUTE,
|
| info->settings.build_settings()->build_config_file().value());
|
| - trace.SetToolchain(info->settings.toolchain()->label());
|
| + trace.SetToolchain(info->settings.toolchain_label());
|
|
|
| const BlockNode* root_block = root->AsBlock();
|
| Err err;
|
| @@ -540,7 +547,7 @@ void ToolchainManager::BackgroundInvoke(const Info* info,
|
| if (root && !g_scheduler->is_failed()) {
|
| if (g_scheduler->verbose_logging()) {
|
| g_scheduler->Log("Running", file_name.value() + " with toolchain " +
|
| - info->toolchain.label().GetUserVisibleName(false));
|
| + info->toolchain->label().GetUserVisibleName(false));
|
| }
|
|
|
| Scope our_scope(info->settings.base_config());
|
| @@ -548,7 +555,7 @@ void ToolchainManager::BackgroundInvoke(const Info* info,
|
| our_scope.set_source_dir(file_name.GetDir());
|
|
|
| ScopedTrace trace(TraceItem::TRACE_FILE_EXECUTE, file_name.value());
|
| - trace.SetToolchain(info->settings.toolchain()->label());
|
| + trace.SetToolchain(info->settings.toolchain_label());
|
|
|
| Err err;
|
| root->Execute(&our_scope, &err);
|
|
|