Add a boolean flag to a Feature to specify whether it is enabled by default.
This enables us to configure default features for each toolchain without having
to hard-code anything in class such as CcCommon.

--
PiperOrigin-RevId: 146904287
MOS_MIGRATED_REVID=146904287
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index 1c7d0d1..8e58a10 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -535,9 +535,10 @@
     ImmutableSet.Builder<String> requestedFeatures = ImmutableSet.builder();
     for (String feature :
         Iterables.concat(
-            ImmutableSet.of(toolchain.getCompilationMode().toString()),
-            ImmutableSet.of(getHostOrNonHostFeature(ruleContext)),
+            ImmutableSet.of(
+                toolchain.getCompilationMode().toString(), getHostOrNonHostFeature(ruleContext)),
             DEFAULT_FEATURES,
+            toolchain.getFeatures().getDefaultFeatures(),
             ruleContext.getFeatures())) {
       if (!unsupportedFeatures.contains(feature)) {
         requestedFeatures.add(feature);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
index 47a9fa6..f9295c6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
@@ -1820,13 +1820,15 @@
    * was disabled.
    */
   private final ImmutableMultimap<CrosstoolSelectable, CrosstoolSelectable> requiredBy;
+
+  private final ImmutableList<String> defaultFeatures;
  
   /**
-   * A cache of feature selection results, so we do not recalculate the feature selection for
-   * all actions.
+   * A cache of feature selection results, so we do not recalculate the feature selection for all
+   * actions.
    */
-  private transient LoadingCache<Collection<String>, FeatureConfiguration>
-      configurationCache = buildConfigurationCache();
+  private transient LoadingCache<Collection<String>, FeatureConfiguration> configurationCache =
+      buildConfigurationCache();
 
   /**
    * Constructs the feature configuration from a {@code CToolchain} protocol buffer.
@@ -1846,11 +1848,16 @@
     // Also build a map from action -> action_config, for use in tool lookups
     ImmutableMap.Builder<String, ActionConfig> actionConfigsByActionName = ImmutableMap.builder();
 
+    ImmutableList.Builder<String> defaultFeaturesBuilder = ImmutableList.builder();
     for (CToolchain.Feature toolchainFeature : toolchain.getFeatureList()) {
       Feature feature = new Feature(toolchainFeature);
       selectablesBuilder.add(feature);
       selectablesByName.put(feature.getName(), feature);
+      if (toolchainFeature.getEnabled()) {
+        defaultFeaturesBuilder.add(feature.getName());
+      }
     }
+    this.defaultFeatures = defaultFeaturesBuilder.build();
     
     for (CToolchain.ActionConfig toolchainActionConfig : toolchain.getActionConfigList()) {
       ActionConfig actionConfig = new ActionConfig(toolchainActionConfig);
@@ -2006,6 +2013,11 @@
     return getFeatureConfiguration(Arrays.asList(requestedFeatures));
   }
 
+  /** Returns the list of features that specify themselves as enabled by default. */
+  public ImmutableList<String> getDefaultFeatures() {
+    return defaultFeatures;
+  }
+
   /**
    * @return the selectable with the given {@code name}.
    *
diff --git a/src/main/protobuf/crosstool_config.proto b/src/main/protobuf/crosstool_config.proto
index a6d9c64..dbdd508 100644
--- a/src/main/protobuf/crosstool_config.proto
+++ b/src/main/protobuf/crosstool_config.proto
@@ -178,7 +178,7 @@
   }
 
   // Contains all flag specifications for one feature.
-  // Next ID: 7
+  // Next ID: 8
   message Feature {
     // The feature's name. Feature names are generally defined by Bazel; it is
     // possible to introduce a feature without a change to Bazel by adding a
@@ -186,6 +186,11 @@
     // feature in the BUILD file.
     optional string name = 1;
 
+    // If 'true', this feature is enabled unless a rule type explicitly marks it
+    // as unssupported. Such features cannot be turned of from with in a BUILD
+    // file or the command line.
+    optional bool enabled = 7;
+
     // If the given feature is enabled, the flag sets will be applied for the
     // actions in the modes that they are specified for.
     repeated FlagSet flag_set = 2;
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java
index 52ebddb..188794f 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java
@@ -1040,6 +1040,13 @@
     assertThat(features.getFeatureConfiguration("b").getCommandLine(CppCompileAction.CPP_COMPILE,
         createVariables("v", "1"))).containsExactly("-f", "1");
   }
+  
+  @Test
+  public void testDefaultFeatures() throws Exception {
+    CcToolchainFeatures features =
+        buildFeatures("feature { name: 'a' }", "feature { name: 'b' enabled: true }");
+    assertThat(features.getDefaultFeatures()).containsExactly("b");
+  }
 
   @Test
   public void testActivateActionConfigFromFeature() throws Exception {