Introduce unfiltered_compile_flags build variable, rename copts variable to user_compile_flags

Also add magic to a feature named 'unfiltered_compile_flags' so the flags
expanded from it are not subject to nocopt filtering.

This is encore of https://github.com/bazelbuild/bazel/commit/268c0bcbf79f9f3f72d95fa51af0f1b18c5ce29e that was rolled back because it regressed
memory.

RELNOTES: None.
PiperOrigin-RevId: 167989075
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java
index 507cc76..48af3cf 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.bazel.rules.cpp;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -51,13 +53,16 @@
   public void finalizeCompileActionBuilder(
       RuleContext ruleContext,
       CppCompileActionBuilder actionBuilder,
-      FeatureSpecification featureSpecification) {
+      FeatureSpecification featureSpecification,
+      Predicate<String> coptsFilter,
+      ImmutableSet<String> features) {
     actionBuilder.setCppConfiguration(ruleContext.getFragment(CppConfiguration.class));
     actionBuilder.setActionContext(CppCompileActionContext.class);
     // Because Bazel does not support include scanning, we need the entire crosstool filegroup,
     // including header files, as opposed to just the "compile" filegroup.
     actionBuilder.addTransitiveMandatoryInputs(actionBuilder.getToolchain().getCrosstool());
     actionBuilder.setShouldScanIncludes(false);
+    actionBuilder.setCoptsFilter(coptsFilter);
   }
 
   @Override
@@ -88,7 +93,7 @@
   public boolean needsDotdInputPruning() {
     return true;
   }
-  
+
   @Override
   public void validateAttributes(RuleContext ruleContext) {
   }
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 4856b0a..47aa40a 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
@@ -14,6 +14,8 @@
 package com.google.devtools.build.lib.rules.cpp;
 
 import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -163,12 +165,15 @@
       }
     }
 
-    Pattern nocopts = getNoCopts(ruleContext);
-    if (nocopts != null && nocopts.matcher("-Wno-future-warnings").matches()) {
-      ruleContext.attributeWarning("nocopts",
-          "Regular expression '" + nocopts.pattern() + "' is too general; for example, it matches "
-          + "'-Wno-future-warnings'.  Thus it might *re-enable* compiler warnings we wish to "
-          + "disable globally.  To disable all compiler warnings, add '-w' to copts instead");
+    if (!getCoptsFilter(ruleContext).apply("-Wno-future-warnings")) {
+      ruleContext.attributeWarning(
+          "nocopts",
+          String.format(
+              "Regular expression '%s' is too general; for example, it matches "
+                  + "'-Wno-future-warnings'.  Thus it might *re-enable* compiler warnings we wish "
+                  + "to disable globally.  To disable all compiler warnings, add '-w' to copts "
+                  + "instead",
+              Preconditions.checkNotNull(getNoCoptsPattern(ruleContext))));
     }
 
     return ImmutableList.<String>builder()
@@ -349,27 +354,36 @@
     return ImmutableList.copyOf(CppHelper.expandMakeVariables(ruleContext, "copts", unexpanded));
   }
 
-  Pattern getNoCopts() {
-    return getNoCopts(ruleContext);
+  /** Returns copts filter built from the make variable expanded nocopts attribute. */
+  Predicate<String> getCoptsFilter() {
+    return getCoptsFilter(ruleContext);
   }
 
-  /**
-   * Returns nocopts pattern built from the make variable expanded nocopts
-   * attribute.
-   */
-  private static Pattern getNoCopts(RuleContext ruleContext) {
-    Pattern nocopts = null;
-    if (ruleContext.getRule().isAttrDefined(NO_COPTS_ATTRIBUTE, Type.STRING)) {
-      String nocoptsAttr = ruleContext.expandMakeVariables(NO_COPTS_ATTRIBUTE,
-          ruleContext.attributes().get(NO_COPTS_ATTRIBUTE, Type.STRING));
-      try {
-        nocopts = Pattern.compile(nocoptsAttr);
-      } catch (PatternSyntaxException e) {
-        ruleContext.attributeError(NO_COPTS_ATTRIBUTE,
-            "invalid regular expression '" + nocoptsAttr + "': " + e.getMessage());
-      }
+  /** @see CcCommon#getCoptsFilter() */
+  private static Predicate<String> getCoptsFilter(RuleContext ruleContext) {
+    Pattern noCoptsPattern = getNoCoptsPattern(ruleContext);
+    if (noCoptsPattern == null) {
+      return Predicates.alwaysTrue();
     }
-    return nocopts;
+    return flag -> !noCoptsPattern.matcher(flag).matches();
+  }
+
+  @Nullable
+  private static Pattern getNoCoptsPattern(RuleContext ruleContext) {
+    if (!ruleContext.getRule().isAttrDefined(NO_COPTS_ATTRIBUTE, Type.STRING)) {
+      return null;
+    }
+    String nocoptsAttr =
+        ruleContext.expandMakeVariables(
+            NO_COPTS_ATTRIBUTE, ruleContext.attributes().get(NO_COPTS_ATTRIBUTE, Type.STRING));
+    try {
+      return Pattern.compile(nocoptsAttr);
+    } catch (PatternSyntaxException e) {
+      ruleContext.attributeError(
+          NO_COPTS_ATTRIBUTE,
+          "invalid regular expression '" + nocoptsAttr + "': " + e.getMessage());
+      return null;
+    }
   }
 
   // TODO(bazel-team): calculating nocopts every time is not very efficient,
@@ -381,8 +395,7 @@
    * otherwise.
    */
   static boolean noCoptsMatches(String option, RuleContext ruleContext) {
-    Pattern nocopts = getNoCopts(ruleContext);
-    return nocopts == null ? false : nocopts.matcher(option).matches();
+    return !getCoptsFilter(ruleContext).apply(option);
   }
 
   private static final String DEFINES_ATTRIBUTE = "defines";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
index a7ffab3..02c7c26 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
@@ -19,6 +19,7 @@
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -67,7 +68,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.regex.Pattern;
 import javax.annotation.Nullable;
 
 /**
@@ -266,7 +266,7 @@
   private final List<Artifact> nonCodeLinkerInputs = new ArrayList<>();
   private ImmutableList<String> copts = ImmutableList.of();
   private final List<String> linkopts = new ArrayList<>();
-  @Nullable private Pattern nocopts;
+  private Predicate<String> coptsFilter = Predicates.alwaysTrue();
   private final Set<String> defines = new LinkedHashSet<>();
   private final List<TransitiveInfoCollection> deps = new ArrayList<>();
   private final List<CppCompilationContext> depContexts = new ArrayList<>();
@@ -378,7 +378,7 @@
     addLooseIncludeDirs(common.getLooseIncludeDirs());
     addNonCodeLinkerInputs(common.getLinkerScripts());
     addSystemIncludeDirs(common.getSystemIncludeDirs());
-    setNoCopts(common.getNoCopts());
+    setCoptsFilter(common.getCoptsFilter());
     setHeadersCheckingMode(semantics.determineHeadersCheckingMode(ruleContext));
     return this;
   }
@@ -640,11 +640,9 @@
     return this;
   }
 
-  /**
-   * Sets a pattern that is used to filter copts; set to {@code null} for no filtering.
-   */
-  public CcLibraryHelper setNoCopts(@Nullable Pattern nocopts) {
-    this.nocopts = nocopts;
+  /** Sets a pattern that is used to filter copts; set to {@code null} for no filtering. */
+  public CcLibraryHelper setCoptsFilter(Predicate<String> coptsFilter) {
+    this.coptsFilter = Preconditions.checkNotNull(coptsFilter);
     return this;
   }
 
@@ -1150,12 +1148,7 @@
    */
   private CppModel initializeCppModel() {
     return new CppModel(
-            ruleContext,
-            semantics,
-            ccToolchain,
-            fdoSupport,
-            configuration,
-            copts)
+            ruleContext, semantics, ccToolchain, fdoSupport, configuration, copts, coptsFilter)
         .addCompilationUnitSources(compilationUnitSources)
         .setLinkTargetType(linkType)
         .setNeverLink(neverlink)
@@ -1166,7 +1159,6 @@
         // Note: this doesn't actually save the temps, it just makes the CppModel use the
         // configurations --save_temps setting to decide whether to actually save the temps.
         .setSaveTemps(true)
-        .setNoCopts(nocopts)
         .setDynamicLibrary(dynamicLibrary)
         .addLinkopts(linkopts)
         .setFeatureConfiguration(featureConfiguration)
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 705dc80..4a31bd7 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
@@ -19,6 +19,7 @@
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
+import com.google.common.base.Supplier;
 import com.google.common.base.Throwables;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
@@ -31,10 +32,12 @@
 import com.google.common.collect.Sets;
 import com.google.common.collect.Sets.SetView;
 import com.google.common.collect.Streams;
+import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariableValue;
+import com.google.devtools.build.lib.util.Pair;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
 import java.io.IOException;
@@ -1001,6 +1004,52 @@
     }
 
     /**
+     * Lazily computed string sequence. Exists as a memory optimization. Make sure the {@param
+     * supplier} doesn't capture anything that shouldn't outlive analysis phase (e.g. {@link
+     * RuleContext}).
+     */
+    private static final class LazyStringSequence implements VariableValue {
+
+      private final Supplier<ImmutableList<String>> supplier;
+
+      private LazyStringSequence(Supplier<ImmutableList<String>> supplier) {
+        this.supplier = Preconditions.checkNotNull(supplier);
+      }
+
+      @Override
+      public VariableValue getFieldValue(String variableName, String field) {
+        throw new ExpansionException(
+            String.format(
+                "Invalid toolchain configuration: Cannot expand variable '%s.%s': variable '%s' is "
+                    + "sequence, expected structure",
+                variableName, field, variableName));
+      }
+
+      @Override
+      public String getStringValue(String variableName) {
+        throw new ExpansionException(
+            String.format(
+                "Invalid toolchain configuration: Cannot expand variable '%s': expected string, "
+                    + "found sequence",
+                variableName));
+      }
+
+      @Override
+      public Iterable<? extends VariableValue> getSequenceValue(String variableName) {
+        return supplier
+            .get()
+            .stream()
+            .map(flag -> new StringValue(flag))
+            .collect(ImmutableList.toImmutableList());
+      }
+
+      @Override
+      public boolean isTruthy() {
+        return !supplier.get().isEmpty();
+      }
+    }
+
+    /**
      * A sequence of structure values. Exists as a memory optimization - a typical build can contain
      * millions of feature values, so getting rid of the overhead of {@code StructureValue} objects
      * significantly reduces memory overhead.
@@ -1375,6 +1424,7 @@
     /**
      * Builder for {@code Variables}.
      */
+    // TODO(b/65472725): Forbid sequences with empty string in them.
     public static class Builder {
       private final Map<String, VariableValue> variablesMap = new LinkedHashMap<>();
       private final Map<String, String> stringVariablesMap = new LinkedHashMap<>();
@@ -1394,10 +1444,7 @@
 
       /** Add a string variable that expands {@code name} to {@code value}. */
       public Builder addStringVariable(String name, String value) {
-        Preconditions.checkArgument(
-            !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
-        Preconditions.checkArgument(
-            !stringVariablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+        checkVariableNotPresentAlready(name);
         Preconditions.checkNotNull(
             value, "Cannot set null as a value for variable '%s'", name);
         stringVariablesMap.put(name, value);
@@ -1412,6 +1459,14 @@
         return this;
       }
 
+      /** Overrides a variable to expands {@code name} to {@code value} instead. */
+      public Builder overrideLazyStringSequenceVariable(
+          String name, Supplier<ImmutableList<String>> supplier) {
+        Preconditions.checkNotNull(supplier, "Cannot set null as a value for variable '%s'", name);
+        variablesMap.put(name, new LazyStringSequence(supplier));
+        return this;
+      }
+
       /**
        * Add a sequence variable that expands {@code name} to {@code values}.
        *
@@ -1419,8 +1474,8 @@
        * the values into a new list.
        */
       public Builder addStringSequenceVariable(String name, ImmutableSet<String> values) {
-        Preconditions.checkArgument(
-            !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+        checkVariableNotPresentAlready(name);
+        Preconditions.checkNotNull(values, "Cannot set null as a value for variable '%s'", name);
         ImmutableList.Builder<String> builder = ImmutableList.builder();
         builder.addAll(values);
         variablesMap.put(name, new StringSequence(builder.build()));
@@ -1433,8 +1488,8 @@
        * <p>Accepts values as NestedSet. Nested set is stored directly, not cloned, not flattened.
        */
       public Builder addStringSequenceVariable(String name, NestedSet<String> values) {
-        Preconditions.checkArgument(
-            !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+        checkVariableNotPresentAlready(name);
+        Preconditions.checkNotNull(values, "Cannot set null as a value for variable '%s'", name);
         variablesMap.put(name, new StringSequence(values));
         return this;
       }
@@ -1448,19 +1503,26 @@
        * side effects.
        */
       public Builder addStringSequenceVariable(String name, Iterable<String> values) {
-        Preconditions.checkArgument(
-            !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+        checkVariableNotPresentAlready(name);
+        Preconditions.checkNotNull(values, "Cannot set null as a value for variable '%s'", name);
         variablesMap.put(name, new StringSequence(values));
         return this;
       }
 
+      public Builder addLazyStringSequenceVariable(
+          String name, Supplier<ImmutableList<String>> supplier) {
+        checkVariableNotPresentAlready(name);
+        Preconditions.checkNotNull(supplier, "Cannot set null as a value for variable '%s'", name);
+        variablesMap.put(name, new LazyStringSequence(supplier));
+        return this;
+      }
+
       /**
        * Add a variable built using {@code VariableValueBuilder} api that expands {@code name} to
        * the value returned by the {@code builder}.
        */
       public Builder addCustomBuiltVariable(String name, Variables.VariableValueBuilder builder) {
-        Preconditions.checkArgument(
-            !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+        checkVariableNotPresentAlready(name);
         Preconditions.checkNotNull(
             builder,
             "Cannot use null builder to get variable value for variable '%s'",
@@ -1472,15 +1534,19 @@
       /** Add all string variables in a map. */
       public Builder addAllStringVariables(Map<String, String> variables) {
         for (String name : variables.keySet()) {
-          Preconditions.checkArgument(
-              !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
-          Preconditions.checkArgument(
-              !stringVariablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+          checkVariableNotPresentAlready(name);
         }
         stringVariablesMap.putAll(variables);
         return this;
       }
 
+      private void checkVariableNotPresentAlready(String name) {
+        Preconditions.checkArgument(
+            !variablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+        Preconditions.checkArgument(
+            !stringVariablesMap.containsKey(name), "Cannot overwrite variable '%s'", name);
+      }
+
       /** Adds all variables to this builder. Note: cannot override already added variables. */
       public Builder addAll(Variables variables) {
         SetView<String> intersection =
@@ -1508,10 +1574,8 @@
         return this;
       }
 
-      /**
-       * @return a new {@Variables} object.
-       */
-      Variables build() {
+      /** @return a new {@Variables} object. */
+      public Variables build() {
         return new Variables(
             ImmutableMap.copyOf(variablesMap), ImmutableMap.copyOf(stringVariablesMap));
       }
@@ -1732,6 +1796,27 @@
       return commandLine;
     }
 
+    /** @return the flags expanded for the given {@code action} in per-feature buckets. */
+    public ImmutableList<Pair<String, List<String>>> getPerFeatureExpansions(
+        String action, Variables variables) {
+      ImmutableList.Builder<Pair<String, List<String>>> perFeatureExpansions =
+          ImmutableList.builder();
+      if (actionIsConfigured(action)) {
+        List<String> commandLine = new ArrayList<>();
+        ActionConfig actionConfig = actionConfigByActionName.get(action);
+        actionConfig.expandCommandLine(variables, enabledFeatureNames, commandLine);
+        perFeatureExpansions.add(Pair.of(actionConfig.getName(), commandLine));
+      }
+
+      for (Feature feature : enabledFeatures) {
+        List<String> commandLine = new ArrayList<>();
+        feature.expandCommandLine(action, variables, enabledFeatureNames, commandLine);
+        perFeatureExpansions.add(Pair.of(feature.getName(), commandLine));
+      }
+
+      return perFeatureExpansions.build();
+    }
+
     /** @return the environment variables (key/value pairs) for the given {@code action}. */
     ImmutableMap<String, String> getEnvironmentVariables(String action, Variables variables) {
       ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
index 4a7cc2d..6526877 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
@@ -354,10 +354,14 @@
         "Returns the default list of options which cannot be filtered by BUILD "
             + "rules. These should be appended to the command line after filtering."
   )
-  public ImmutableList<String> getUnfilteredCompilerOptions(Iterable<String> features) {
+  public ImmutableList<String> getUnfilteredCompilerOptionsWithSysroot(Iterable<String> features) {
     return cppConfiguration.getUnfilteredCompilerOptions(features, sysroot);
   }
 
+  public ImmutableList<String> getUnfilteredCompilerOptions(Iterable<String> features) {
+    return cppConfiguration.getUnfilteredCompilerOptions(features, null);
+  }
+
   @SkylarkCallable(
     name = "link_options_do_not_use",
     structField = true,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java
index 3e1eaf6..db43758 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.cpp;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -22,10 +23,10 @@
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables;
 import com.google.devtools.build.lib.rules.cpp.CppCompileAction.DotdFile;
 import com.google.devtools.build.lib.util.FileType;
+import com.google.devtools.build.lib.util.Pair;
 import com.google.devtools.build.lib.util.Preconditions;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Nullable;
@@ -37,7 +38,6 @@
   private final Artifact outputFile;
   private final Label sourceLabel;
   private final Predicate<String> coptsFilter;
-  private final Collection<String> features;
   private final FeatureConfiguration featureConfiguration;
   private final CcToolchainFeatures.Variables variables;
   private final String actionName;
@@ -50,7 +50,6 @@
       Artifact outputFile,
       Label sourceLabel,
       Predicate<String> coptsFilter,
-      Collection<String> features,
       FeatureConfiguration featureConfiguration,
       CppConfiguration cppConfiguration,
       CcToolchainFeatures.Variables variables,
@@ -61,7 +60,6 @@
     this.outputFile = Preconditions.checkNotNull(outputFile);
     this.sourceLabel = Preconditions.checkNotNull(sourceLabel);
     this.coptsFilter = coptsFilter;
-    this.features = Preconditions.checkNotNull(features);
     this.featureConfiguration = Preconditions.checkNotNull(featureConfiguration);
     this.cppConfiguration = Preconditions.checkNotNull(cppConfiguration);
     this.variables = variables;
@@ -111,34 +109,10 @@
     return commandLine;
   }
 
-  private boolean isObjcCompile(String actionName) {
-    return (actionName.equals(CppCompileAction.OBJC_COMPILE)
-        || actionName.equals(CppCompileAction.OBJCPP_COMPILE));
-  }
-
   public List<String> getCompilerOptions(
       @Nullable CcToolchainFeatures.Variables overwrittenVariables) {
     List<String> options = new ArrayList<>();
-    CppConfiguration toolchain = cppConfiguration;
 
-    addFilteredOptions(options, toolchain.getCompilerOptions(features));
-
-    String sourceFilename = sourceFile.getExecPathString();
-    if (CppFileTypes.C_SOURCE.matches(sourceFilename)) {
-      addFilteredOptions(options, toolchain.getCOptions());
-    }
-    if (CppFileTypes.CPP_SOURCE.matches(sourceFilename)
-        || CppFileTypes.CPP_HEADER.matches(sourceFilename)
-        || CppFileTypes.CPP_MODULE_MAP.matches(sourceFilename)
-        || CppFileTypes.CLIF_INPUT_PROTO.matches(sourceFilename)) {
-      addFilteredOptions(options, toolchain.getCxxOptions(features));
-    }
-
-    // TODO(bazel-team): This needs to be before adding getUnfilteredCompilerOptions() and after
-    // adding the warning flags until all toolchains are migrated; currently toolchains use the
-    // unfiltered compiler options to inject include paths, which is superseded by the feature
-    // configuration; on the other hand toolchains switch off warnings for the layering check
-    // that will be re-added by the feature flags.
     CcToolchainFeatures.Variables updatedVariables = variables;
     if (variables != null && overwrittenVariables != null) {
       CcToolchainFeatures.Variables.Builder variablesBuilder =
@@ -147,18 +121,14 @@
       variablesBuilder.addAndOverwriteAll(overwrittenVariables);
       updatedVariables = variablesBuilder.build();
     }
-    addFilteredOptions(options, featureConfiguration.getCommandLine(actionName, updatedVariables));
+    addFilteredOptions(
+        options, featureConfiguration.getPerFeatureExpansions(actionName, updatedVariables));
 
-    // Unfiltered compiler options contain system include paths. These must be added after
-    // the user provided options, otherwise users adding include paths will not pick up their
-    // own include paths first.
     if (isObjcCompile(actionName)) {
       PathFragment sysroot = cppProvider.getSysroot();
       if (sysroot != null) {
-        options.add(toolchain.getSysrootCompilerOption(sysroot));
+        options.add(cppConfiguration.getSysrootCompilerOption(sysroot));
       }
-    } else {
-      options.addAll(cppProvider.getUnfilteredCompilerOptions(features));
     }
 
     // Add the options of --per_file_copt, if the label or the base name of the source file
@@ -186,9 +156,22 @@
     return options;
   }
 
+  private boolean isObjcCompile(String actionName) {
+    return (actionName.equals(CppCompileAction.OBJC_COMPILE)
+        || actionName.equals(CppCompileAction.OBJCPP_COMPILE));
+  }
+
   // For each option in 'in', add it to 'out' unless it is matched by the 'coptsFilter' regexp.
-  private void addFilteredOptions(List<String> out, List<String> in) {
-    in.stream().filter(coptsFilter).forEachOrdered(out::add);
+  private void addFilteredOptions(
+      List<String> out, List<Pair<String, List<String>>> expandedFeatures) {
+    for (Pair<String, List<String>> pair : expandedFeatures) {
+      if (pair.getFirst().equals(CppRuleClasses.UNFILTERED_COMPILE_FLAGS_FEATURE_NAME)) {
+        out.addAll(pair.getSecond());
+        continue;
+      }
+
+      pair.getSecond().stream().filter(coptsFilter).forEachOrdered(out::add);
+    }
   }
 
   public Artifact getSourceFile() {
@@ -211,8 +194,8 @@
    * explicit attribute, not using platform-dependent garbage bag that copts is).
    */
   public ImmutableList<String> getCopts() {
-    if (variables.isAvailable(CppModel.COPTS_VARIABLE_VALUE)) {
-      return Variables.toStringList(variables, CppModel.COPTS_VARIABLE_VALUE);
+    if (variables.isAvailable(CppModel.USER_COMPILE_FLAGS_VARIABLE_NAME)) {
+      return Variables.toStringList(variables, CppModel.USER_COMPILE_FLAGS_VARIABLE_NAME);
     } else {
       return ImmutableList.of();
     }
@@ -223,7 +206,6 @@
       Artifact outputFile,
       Label sourceLabel,
       Predicate<String> coptsFilter,
-      ImmutableList<String> features,
       String actionName,
       CppConfiguration cppConfiguration,
       DotdFile dotdFile,
@@ -233,7 +215,6 @@
         outputFile,
         sourceLabel,
         coptsFilter,
-        features,
         actionName,
         cppConfiguration,
         dotdFile,
@@ -245,8 +226,7 @@
     private final Artifact sourceFile;
     private final Artifact outputFile;
     private final Label sourceLabel;
-    private final Predicate<String> coptsFilter;
-    private final Collection<String> features;
+    private Predicate<String> coptsFilter;
     private FeatureConfiguration featureConfiguration;
     private CcToolchainFeatures.Variables variables = Variables.EMPTY;
     private final String actionName;
@@ -260,7 +240,6 @@
           Preconditions.checkNotNull(outputFile),
           Preconditions.checkNotNull(sourceLabel),
           Preconditions.checkNotNull(coptsFilter),
-          Preconditions.checkNotNull(features),
           Preconditions.checkNotNull(featureConfiguration),
           Preconditions.checkNotNull(cppConfiguration),
           Preconditions.checkNotNull(variables),
@@ -274,7 +253,6 @@
         Artifact outputFile,
         Label sourceLabel,
         Predicate<String> coptsFilter,
-        Collection<String> features,
         String actionName,
         CppConfiguration cppConfiguration,
         DotdFile dotdFile,
@@ -283,7 +261,6 @@
       this.outputFile = outputFile;
       this.sourceLabel = sourceLabel;
       this.coptsFilter = coptsFilter;
-      this.features = features;
       this.actionName = actionName;
       this.cppConfiguration = cppConfiguration;
       this.dotdFile = dotdFile;
@@ -300,5 +277,11 @@
       this.variables = variables;
       return this;
     }
+
+    @VisibleForTesting
+    Builder setCoptsFilter(Predicate<String> filter) {
+      this.coptsFilter = Preconditions.checkNotNull(filter);
+      return this;
+    }
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
index 8ed59a2..958b26f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
@@ -15,7 +15,7 @@
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
-import java.util.Set;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * A helper class for creating action_configs for the c++ actions.
@@ -33,7 +33,7 @@
 
   public static String getCppActionConfigs(
       CppPlatform platform,
-      Set<String> features,
+      ImmutableSet<String> existingFeatureNames,
       String gccToolPath,
       String cppLinkDynamicLibraryToolPath,
       String arToolPath,
@@ -41,7 +41,8 @@
       boolean supportsEmbeddedRuntimes,
       boolean supportsInterfaceSharedLibraries) {
     String cppDynamicLibraryLinkerTool = "";
-    if (!features.contains("dynamic_library_linker_tool") && supportsInterfaceSharedLibraries) {
+    if (!existingFeatureNames.contains("dynamic_library_linker_tool")
+        && supportsInterfaceSharedLibraries) {
       cppDynamicLibraryLinkerTool =
           ""
               + "feature {"
@@ -65,7 +66,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'preprocess-assemble'",
@@ -73,7 +76,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'c-compile'",
@@ -81,7 +86,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'c++-compile'",
@@ -89,7 +96,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'c++-header-parsing'",
@@ -97,7 +106,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'c++-header-preprocessing'",
@@ -105,7 +116,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'c++-module-compile'",
@@ -113,7 +126,9 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
                 "action_config {",
                 "  config_name: 'c++-module-codegen'",
@@ -121,8 +136,33 @@
                 "  tool {",
                 "    tool_path: '" + gccToolPath + "'",
                 "  }",
-                "  implies: 'copts'",
+                "  implies: 'legacy_compile_flags'",
+                "  implies: 'user_compile_flags'",
+                "  implies: 'unfiltered_compile_flags'",
                 "}",
+                ifTrue(
+                    !existingFeatureNames.contains(CppRuleClasses.LEGACY_COMPILE_FLAGS),
+                    "feature {",
+                    "  name: 'legacy_compile_flags'",
+                    "  enabled: true",
+                    "  flag_set {",
+                    "    expand_if_all_available: 'legacy_compile_flags'",
+                    "    action: 'assemble'",
+                    "    action: 'preprocess-assemble'",
+                    "    action: 'c-compile'",
+                    "    action: 'c++-compile'",
+                    "    action: 'c++-header-parsing'",
+                    "    action: 'c++-header-preprocessing'",
+                    "    action: 'c++-module-compile'",
+                    "    action: 'c++-module-codegen'",
+                    "    action: 'lto-backend'",
+                    "    action: 'clif-match'",
+                    "    flag_group {",
+                    "      iterate_over: 'legacy_compile_flags'",
+                    "      flag: '%{legacy_compile_flags}'",
+                    "    }",
+                    "  }",
+                    "}"),
                 // Gcc options:
                 //  -MD turns on .d file output as a side-effect (doesn't imply -E)
                 //  -MM[D] enables user includes only, not system includes
@@ -133,7 +173,7 @@
                 // This combination gets user and system includes with specified name:
                 //  -MD -MF <name>
                 ifTrue(
-                    !features.contains(CppRuleClasses.DEPENDENCY_FILE),
+                    !existingFeatureNames.contains(CppRuleClasses.DEPENDENCY_FILE),
                     "feature {",
                     "  name: 'dependency_file'",
                     "  flag_set {",
@@ -162,7 +202,7 @@
                 // any value which differs for all translation units; we use the
                 // path to the object file.
                 ifTrue(
-                    !features.contains(CppRuleClasses.RANDOM_SEED),
+                    !existingFeatureNames.contains(CppRuleClasses.RANDOM_SEED),
                     "feature {",
                     "  name: 'random_seed'",
                     "  flag_set {",
@@ -175,7 +215,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.PIC),
+                    !existingFeatureNames.contains(CppRuleClasses.PIC),
                     "feature {",
                     "  name: 'pic'",
                     "  flag_set {",
@@ -192,7 +232,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.PER_OBJECT_DEBUG_INFO),
+                    !existingFeatureNames.contains(CppRuleClasses.PER_OBJECT_DEBUG_INFO),
                     "feature {",
                     "  name: 'per_object_debug_info'",
                     "  flag_set {",
@@ -208,7 +248,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.PREPROCESSOR_DEFINES),
+                    !existingFeatureNames.contains(CppRuleClasses.PREPROCESSOR_DEFINES),
                     "feature {",
                     "  name: 'preprocessor_defines'",
                     "  flag_set {",
@@ -226,7 +266,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.INCLUDE_PATHS),
+                    !existingFeatureNames.contains(CppRuleClasses.INCLUDE_PATHS),
                     "feature {",
                     "  name: 'include_paths'",
                     "  flag_set {",
@@ -256,7 +296,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.FDO_INSTRUMENT),
+                    !existingFeatureNames.contains(CppRuleClasses.FDO_INSTRUMENT),
                     "feature {",
                     "  name: 'fdo_instrument'",
                     "  provides: 'profile'",
@@ -273,7 +313,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.FDO_OPTIMIZE),
+                    !existingFeatureNames.contains(CppRuleClasses.FDO_OPTIMIZE),
                     "feature {",
                     "  name: 'fdo_optimize'",
                     "  provides: 'profile'",
@@ -290,7 +330,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.AUTOFDO),
+                    !existingFeatureNames.contains(CppRuleClasses.AUTOFDO),
                     "feature {",
                     "  name: 'autofdo'",
                     "  provides: 'profile'",
@@ -305,7 +345,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.LIPO),
+                    !existingFeatureNames.contains(CppRuleClasses.LIPO),
                     "feature {",
                     "  name: 'lipo'",
                     "  requires { feature: 'autofdo' }",
@@ -418,7 +458,7 @@
                     // follow right after build_interface_libraries.
                     cppDynamicLibraryLinkerTool),
                 ifTrue(
-                    !features.contains("symbol_counts"),
+                    !existingFeatureNames.contains("symbol_counts"),
                     "feature {",
                     "  name: 'symbol_counts'",
                     "  flag_set {",
@@ -431,7 +471,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("shared_flag"),
+                    !existingFeatureNames.contains("shared_flag"),
                     "feature {",
                     "  name: 'shared_flag'",
                     "  flag_set {",
@@ -442,7 +482,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("linkstamps"),
+                    !existingFeatureNames.contains("linkstamps"),
                     "feature {",
                     "  name: 'linkstamps'",
                     "  flag_set {",
@@ -456,7 +496,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("output_execpath_flags"),
+                    !existingFeatureNames.contains("output_execpath_flags"),
                     "feature {",
                     "  name: 'output_execpath_flags'",
                     "  flag_set {",
@@ -469,7 +509,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("output_execpath_flags_executable"),
+                    !existingFeatureNames.contains("output_execpath_flags_executable"),
                     "feature {",
                     "  name: 'output_execpath_flags_executable'",
                     "  flag_set {",
@@ -498,7 +538,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("runtime_library_search_directories"),
+                    !existingFeatureNames.contains("runtime_library_search_directories"),
                     "feature {",
                     "  name: 'runtime_library_search_directories',",
                     "  flag_set {",
@@ -523,7 +563,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("library_search_directories"),
+                    !existingFeatureNames.contains("library_search_directories"),
                     "feature {",
                     "  name: 'library_search_directories'",
                     "  flag_set {",
@@ -537,7 +577,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("archiver_flags"),
+                    !existingFeatureNames.contains("archiver_flags"),
                     "feature {",
                     "  name: 'archiver_flags'",
                     "  flag_set {",
@@ -558,7 +598,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("libraries_to_link"),
+                    !existingFeatureNames.contains("libraries_to_link"),
                     "feature {",
                     "  name: 'libraries_to_link'",
                     "  flag_set {",
@@ -719,7 +759,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("force_pic_flags"),
+                    !existingFeatureNames.contains("force_pic_flags"),
                     "feature {",
                     "  name: 'force_pic_flags'",
                     "  flag_set {",
@@ -731,7 +771,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("legacy_link_flags"),
+                    !existingFeatureNames.contains("legacy_link_flags"),
                     "feature {",
                     "  name: 'legacy_link_flags'",
                     "  flag_set {",
@@ -745,7 +785,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("fission_support"),
+                    !existingFeatureNames.contains("fission_support"),
                     "feature {",
                     "  name: 'fission_support'",
                     "  flag_set {",
@@ -759,7 +799,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("strip_debug_symbols"),
+                    !existingFeatureNames.contains("strip_debug_symbols"),
                     "feature {",
                     "  name: 'strip_debug_symbols'",
                     "  flag_set {",
@@ -773,7 +813,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains("linker_param_file"),
+                    !existingFeatureNames.contains("linker_param_file"),
                     "feature {",
                     "  name: 'linker_param_file'",
                     "  flag_set {",
@@ -796,7 +836,7 @@
                     "  }",
                     "}"),
                 ifTrue(
-                    !features.contains(CppRuleClasses.COVERAGE),
+                    !existingFeatureNames.contains(CppRuleClasses.COVERAGE),
                     "feature {",
                     "  name: 'coverage'",
                     "}",
@@ -859,28 +899,6 @@
                     "    feature: 'coverage'",
                     "  }",
                     "}"),
-                ifTrue(
-                    !features.contains(CppRuleClasses.COPTS),
-                    "feature {",
-                    "  name: 'copts'",
-                    "  flag_set {",
-                    "    expand_if_all_available: 'copts'",
-                    "    action: 'assemble'",
-                    "    action: 'preprocess-assemble'",
-                    "    action: 'c-compile'",
-                    "    action: 'c++-compile'",
-                    "    action: 'c++-header-parsing'",
-                    "    action: 'c++-header-preprocessing'",
-                    "    action: 'c++-module-compile'",
-                    "    action: 'c++-module-codegen'",
-                    "    action: 'lto-backend'",
-                    "    action: 'clif-match'",
-                    "    flag_group {",
-                    "      iterate_over: 'copts'",
-                    "      flag: '%{copts}'",
-                    "    }",
-                    "  }",
-                    "}"),
                 "action_config {",
                 "  config_name: 'strip'",
                 "  action_name: 'strip'",
@@ -923,6 +941,63 @@
                 "}"));
   }
 
+  public static String getFeaturesToAppearLastInToolchain(
+      ImmutableSet<String> existingFeatureNames) {
+    return Joiner.on("\n")
+        .join(
+            ImmutableList.of(
+                ifTrue(
+                    !existingFeatureNames.contains("user_compile_flags"),
+                    "feature {",
+                    "  name: 'user_compile_flags'",
+                    "  enabled: true",
+                    "  flag_set {",
+                    "    expand_if_all_available: 'user_compile_flags'",
+                    "    action: 'assemble'",
+                    "    action: 'preprocess-assemble'",
+                    "    action: 'c-compile'",
+                    "    action: 'c++-compile'",
+                    "    action: 'c++-header-parsing'",
+                    "    action: 'c++-header-preprocessing'",
+                    "    action: 'c++-module-compile'",
+                    "    action: 'c++-module-codegen'",
+                    "    action: 'lto-backend'",
+                    "    action: 'clif-match'",
+                    "    flag_group {",
+                    "      iterate_over: 'user_compile_flags'",
+                    "      flag: '%{user_compile_flags}'",
+                    "    }",
+                    "  }",
+                    "}"),
+                // unfiltered_compile_flags contain system include paths. These must be added
+                // after the user provided options (present in legacy_compile_flags build
+                // variable above), otherwise users adding include paths will not pick up their own
+                // include paths first.
+                ifTrue(
+                    !existingFeatureNames.contains("unfiltered_compile_flags"),
+                    "feature {",
+                    "  name: 'unfiltered_compile_flags'",
+                    "  enabled: true",
+                    "  flag_set {",
+                    "    expand_if_all_available: 'unfiltered_compile_flags'",
+                    "    action: 'assemble'",
+                    "    action: 'preprocess-assemble'",
+                    "    action: 'c-compile'",
+                    "    action: 'c++-compile'",
+                    "    action: 'c++-header-parsing'",
+                    "    action: 'c++-header-preprocessing'",
+                    "    action: 'c++-module-compile'",
+                    "    action: 'c++-module-codegen'",
+                    "    action: 'lto-backend'",
+                    "    action: 'clif-match'",
+                    "    flag_group {",
+                    "      iterate_over: 'unfiltered_compile_flags'",
+                    "      flag: '%{unfiltered_compile_flags}'",
+                    "    }",
+                    "  }",
+                    "}")));
+  }
+
   private static String ifLinux(CppPlatform platform, String... lines) {
     return ifTrue(platform == CppPlatform.LINUX, lines);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index ed46336..a8d3a38 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -250,7 +250,6 @@
    *
    * @param owner the owner of the action, usually the configured target that emitted it
    * @param allInputs the list of all action inputs.
-   * @param features TODO(bazel-team): Add parameter description.
    * @param featureConfiguration TODO(bazel-team): Add parameter description.
    * @param variables TODO(bazel-team): Add parameter description.
    * @param sourceFile the source file that should be compiled. {@code mandatoryInputs} must contain
@@ -285,9 +284,6 @@
   protected CppCompileAction(
       ActionOwner owner,
       NestedSet<Artifact> allInputs,
-      // TODO(bazel-team): Eventually we will remove 'features'; all functionality in 'features'
-      // will be provided by 'featureConfiguration'.
-      ImmutableList<String> features,
       FeatureConfiguration featureConfiguration,
       CcToolchainFeatures.Variables variables,
       Artifact sourceFile,
@@ -352,7 +348,6 @@
                 outputFile,
                 sourceLabel,
                 coptsFilter,
-                features,
                 actionName,
                 cppConfiguration,
                 dotdFile,
@@ -802,7 +797,7 @@
    */
   @VisibleForTesting
   public List<String> getCompilerOptions() {
-    return compileCommandLine.getCompilerOptions(/*updatedVariables=*/ null);
+    return compileCommandLine.getCompilerOptions(/* overwrittenVariables= */ null);
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
index 6020ae9..1db66ca 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
@@ -38,14 +38,11 @@
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
 import java.util.function.Consumer;
-import java.util.regex.Pattern;
 
 /**
  * Builder class to construct C++ compile actions.
@@ -55,7 +52,6 @@
 
   private final ActionOwner owner;
   private final BuildConfiguration configuration;
-  private final List<String> features = new ArrayList<>();
   private CcToolchainFeatures.FeatureConfiguration featureConfiguration;
   private CcToolchainFeatures.Variables variables = Variables.EMPTY;
   private Artifact sourceFile;
@@ -70,7 +66,7 @@
   private Artifact gcnoFile;
   private CppCompilationContext context = CppCompilationContext.EMPTY;
   private final List<String> pluginOpts = new ArrayList<>();
-  private final List<Pattern> nocopts = new ArrayList<>();
+  private Predicate<String> coptsFilter = Predicates.alwaysTrue();
   private ImmutableList<PathFragment> extraSystemIncludePrefixes = ImmutableList.of();
   private boolean usePic;
   private boolean allowUsingHeaderModules;
@@ -101,7 +97,6 @@
         sourceLabel,
         ruleContext.getConfiguration(),
         getLipoScannableMap(ruleContext),
-        ruleContext.getFeatures(),
         ccToolchain);
   }
 
@@ -116,7 +111,6 @@
         sourceLabel,
         configuration,
         getLipoScannableMap(ruleContext),
-        ruleContext.getFeatures(),
         ccToolchain);
   }
 
@@ -126,14 +120,12 @@
       Label sourceLabel,
       BuildConfiguration configuration,
       Map<Artifact, IncludeScannable> lipoScannableMap,
-      Set<String> features,
       CcToolchainProvider ccToolchain) {
     this.owner = actionOwner;
     this.sourceLabel = sourceLabel;
     this.configuration = configuration;
     this.cppConfiguration = configuration.getFragment(CppConfiguration.class);
     this.lipoScannableMap = ImmutableMap.copyOf(lipoScannableMap);
-    this.features.addAll(features);
     this.mandatoryInputsBuilder = NestedSetBuilder.stableOrder();
     this.allowUsingHeaderModules = true;
     this.localShellEnvironment = configuration.getLocalShellEnvironment();
@@ -161,7 +153,6 @@
    */
   public CppCompileActionBuilder(CppCompileActionBuilder other) {
     this.owner = other.owner;
-    this.features.addAll(other.features);
     this.featureConfiguration = other.featureConfiguration;
     this.sourceFile = other.sourceFile;
     this.sourceLabel = other.sourceLabel;
@@ -176,7 +167,7 @@
     this.gcnoFile = other.gcnoFile;
     this.context = other.context;
     this.pluginOpts.addAll(other.pluginOpts);
-    this.nocopts.addAll(other.nocopts);
+    this.coptsFilter = other.coptsFilter;
     this.extraSystemIncludePrefixes = ImmutableList.copyOf(other.extraSystemIncludePrefixes);
     this.specialInputsHandler = other.specialInputsHandler;
     this.actionClassId = other.actionClassId;
@@ -216,23 +207,6 @@
     return mandatoryInputsBuilder.build();
   }
 
-  private static Predicate<String> getNocoptPredicate(Collection<Pattern> patterns) {
-    final ImmutableList<Pattern> finalPatterns = ImmutableList.copyOf(patterns);
-    if (finalPatterns.isEmpty()) {
-      return Predicates.alwaysTrue();
-    } else {
-      return option -> {
-        for (Pattern pattern : finalPatterns) {
-          if (pattern.matcher(option).matches()) {
-            return false;
-          }
-        }
-
-        return true;
-      };
-    }
-  }
-
   private Iterable<IncludeScannable> getLipoScannables(NestedSet<Artifact> realMandatoryInputs) {
     boolean fake = tempOutputFile != null;
 
@@ -385,7 +359,6 @@
           new FakeCppCompileAction(
               owner,
               allInputs,
-              ImmutableList.copyOf(features),
               featureConfiguration,
               variables,
               sourceFile,
@@ -403,7 +376,7 @@
               cppConfiguration,
               context,
               actionContext,
-              getNocoptPredicate(nocopts),
+              coptsFilter,
               getLipoScannables(realMandatoryInputs),
               cppSemantics,
               ccToolchain,
@@ -413,7 +386,6 @@
           new CppCompileAction(
               owner,
               allInputs,
-              ImmutableList.copyOf(features),
               featureConfiguration,
               variables,
               sourceFile,
@@ -434,7 +406,7 @@
               cppConfiguration,
               context,
               actionContext,
-              getNocoptPredicate(nocopts),
+              coptsFilter,
               specialInputsHandler,
               getLipoScannables(realMandatoryInputs),
               additionalIncludeFiles.build(),
@@ -535,10 +507,8 @@
     return this;
   }
 
-  /**
-   * Returns the build variables to be used for the action.
-   */
-  CcToolchainFeatures.Variables getVariables() {
+  /** Returns the build variables to be used for the action. */
+  public CcToolchainFeatures.Variables getVariables() {
     return variables;
   }
 
@@ -674,11 +644,6 @@
     return this;
   }
 
-  public CppCompileActionBuilder addNocopts(Pattern nocopts) {
-    this.nocopts.add(nocopts);
-    return this;
-  }
-
   public CppCompileActionBuilder setContext(CppCompilationContext context) {
     this.context = context;
     return this;
@@ -714,4 +679,7 @@
     return ccToolchain;
   }
 
+  public void setCoptsFilter(Predicate<String> coptsFilter) {
+    this.coptsFilter = Preconditions.checkNotNull(coptsFilter);
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index a367817..539883b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -55,6 +55,7 @@
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LinkingModeFlags;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath;
+import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.TextFormat;
 import com.google.protobuf.TextFormat.ParseException;
 import java.io.Serializable;
@@ -631,12 +632,13 @@
       }
     }
 
-    ImmutableSet.Builder<String> featuresBuilder = ImmutableSet.builder();
-    for (CToolchain.Feature feature : toolchain.getFeatureList()) {
-      featuresBuilder.add(feature.getName());
-    }
-    Set<String> features = featuresBuilder.build();
-    if (!features.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
+    ImmutableSet<String> featureNames =
+        toolchain
+            .getFeatureList()
+            .stream()
+            .map(feature -> feature.getName())
+            .collect(ImmutableSet.toImmutableSet());
+    if (!featureNames.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
       try {
         String gccToolPath = "DUMMY_GCC_TOOL";
         String linkerToolPath = "DUMMY_LINKER_TOOL";
@@ -657,10 +659,28 @@
             stripToolPath = tool.getPath();
           }
         }
+
+        // TODO(b/30109612): Remove fragile legacyCompileFlags shuffle once there are no legacy
+        // crosstools.
+        // Existing projects depend on flags from legacy toolchain fields appearing first on the
+        // compile command line. 'legacy_compile_flags' feature contains all these flags, and so it
+        // needs to appear before other features from {@link CppActionConfigs}.
+        CToolchain.Feature legacyCompileFlagsFeature =
+            toolchain
+                .getFeatureList()
+                .stream()
+                .filter(feature -> feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
+                .findFirst()
+                .orElse(null);
+        if (legacyCompileFlagsFeature != null) {
+          toolchainBuilder.addFeature(legacyCompileFlagsFeature);
+          toolchain = removeLegacyCompileFlagsFeatureFromToolchain(toolchain);
+        }
+
         TextFormat.merge(
             CppActionConfigs.getCppActionConfigs(
                 getTargetLibc().equals("macosx") ? CppPlatform.MAC : CppPlatform.LINUX,
-                features,
+                featureNames,
                 gccToolPath,
                 linkerToolPath,
                 arToolPath,
@@ -676,9 +696,34 @@
     }
 
     toolchainBuilder.mergeFrom(toolchain);
+
+    if (!featureNames.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
+      try {
+        TextFormat.merge(
+            CppActionConfigs.getFeaturesToAppearLastInToolchain(featureNames), toolchainBuilder);
+      } catch (ParseException e) {
+        // Can only happen if we change the proto definition without changing our
+        // configuration above.
+        throw new RuntimeException(e);
+      }
+    }
     return toolchainBuilder.build();
   }
 
+  private CToolchain removeLegacyCompileFlagsFeatureFromToolchain(CToolchain toolchain) {
+    FieldDescriptor featuresFieldDescriptor = CToolchain.getDescriptor().findFieldByName("feature");
+    return toolchain
+        .toBuilder()
+        .setField(
+            featuresFieldDescriptor,
+            toolchain
+                .getFeatureList()
+                .stream()
+                .filter(feature -> !feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS))
+                .collect(ImmutableList.toImmutableList()))
+        .build();
+  }
+
   @VisibleForTesting
   static CompilationMode importCompilationMode(CrosstoolConfig.CompilationMode mode) {
     return CompilationMode.valueOf(mode.name());
@@ -1963,6 +2008,22 @@
     return requestedFeatures.build();
   }
 
+  public ImmutableList<String> collectLegacyCompileFlags(
+      String sourceFilename, ImmutableSet<String> features) {
+    ImmutableList.Builder<String> legacyCompileFlags = ImmutableList.builder();
+    legacyCompileFlags.addAll(getCompilerOptions(features));
+    if (CppFileTypes.C_SOURCE.matches(sourceFilename)) {
+      legacyCompileFlags.addAll(getCOptions());
+    }
+    if (CppFileTypes.CPP_SOURCE.matches(sourceFilename)
+        || CppFileTypes.CPP_HEADER.matches(sourceFilename)
+        || CppFileTypes.CPP_MODULE_MAP.matches(sourceFilename)
+        || CppFileTypes.CLIF_INPUT_PROTO.matches(sourceFilename)) {
+      legacyCompileFlags.addAll(getCxxOptions(features));
+    }
+    return legacyCompileFlags.build();
+  }
+
   public static PathFragment computeDefaultSysroot(CToolchain toolchain) {
     PathFragment defaultSysroot =
         toolchain.getBuiltinSysroot().length() == 0
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
index 8e1d578..07a3f41 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
@@ -14,6 +14,9 @@
 
 package com.google.devtools.build.lib.rules.cpp;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
@@ -50,8 +53,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.regex.Pattern;
-import javax.annotation.Nullable;
 
 /**
  * Representation of a C/C++ compilation. Its purpose is to share the code that creates compilation
@@ -121,6 +122,9 @@
    */
   public static final String SYSTEM_INCLUDE_PATHS_VARIABLE_NAME = "system_include_paths";
 
+  /** Name of the build variable for the dependency file path */
+  public static final String DEPENDENCY_FILE_VARIABLE_NAME = "dependency_file";
+
   /** Name of the build variable for the collection of macros defined for preprocessor. */
   public static final String PREPROCESSOR_DEFINES_VARIABLE_NAME = "preprocessor_defines";
 
@@ -137,12 +141,24 @@
   /** Name of the build variable for the LTO indexing bitcode file. */
   public static final String LTO_INDEXING_BITCODE_FILE_VARIABLE_NAME = "lto_indexing_bitcode_file";
 
-  /** Build variable for all user provided copt flags. */
-  public static final String COPTS_VARIABLE_VALUE = "copts";
-
   /** Name of the build variable for stripopts for the strip action. */
   public static final String STRIPOPTS_VARIABLE_NAME = "stripopts";
 
+  /**
+   * Build variable for all flags coming from legacy crosstool fields, such as compiler_flag,
+   * optional_compiler_flag, cxx_flag, optional_cxx_flag.
+   */
+  public static final String LEGACY_COMPILE_FLAGS_VARIABLE_NAME = "legacy_compile_flags";
+
+  /**
+   * Build variable for all flags coming from copt rule attribute, and from --copt, --cxxopt, or
+   * --conlyopt options.
+   */
+  public static final String USER_COMPILE_FLAGS_VARIABLE_NAME = "user_compile_flags";
+
+  /** Build variable for flags coming from unfiltered_cxx_flag CROSSTOOL fields. */
+  public static final String UNFILTERED_COMPILE_FLAGS_VARIABLE_NAME = "unfiltered_compile_flags";
+
   private final CppSemantics semantics;
   private final RuleContext ruleContext;
   private final BuildConfiguration configuration;
@@ -153,7 +169,7 @@
   private final Set<CppSource> sourceFiles = new LinkedHashSet<>();
   private final List<Artifact> mandatoryInputs = new ArrayList<>();
   private final ImmutableList<String> copts;
-  @Nullable private Pattern nocopts;
+  private final Predicate<String> coptsFilter;
   private boolean fake;
   private boolean maySaveTemps;
   private boolean onlySingleOutput;
@@ -172,6 +188,7 @@
   private final CcToolchainProvider ccToolchain;
   private final FdoSupportProvider fdoSupport;
   private String linkedArtifactNameSuffix = "";
+  private final ImmutableSet<String> features;
 
   public CppModel(
       RuleContext ruleContext,
@@ -179,7 +196,31 @@
       CcToolchainProvider ccToolchain,
       FdoSupportProvider fdoSupport,
       ImmutableList<String> copts) {
-    this(ruleContext, semantics, ccToolchain, fdoSupport, ruleContext.getConfiguration(), copts);
+    this(
+        ruleContext,
+        semantics,
+        ccToolchain,
+        fdoSupport,
+        ruleContext.getConfiguration(),
+        copts,
+        Predicates.alwaysTrue());
+  }
+
+  public CppModel(
+      RuleContext ruleContext,
+      CppSemantics semantics,
+      CcToolchainProvider ccToolchain,
+      FdoSupportProvider fdoSupport,
+      ImmutableList<String> copts,
+      Predicate<String> coptsFilter) {
+    this(
+        ruleContext,
+        semantics,
+        ccToolchain,
+        fdoSupport,
+        ruleContext.getConfiguration(),
+        copts,
+        coptsFilter);
  }
 
   public CppModel(
@@ -188,14 +229,17 @@
       CcToolchainProvider ccToolchain,
       FdoSupportProvider fdoSupport,
       BuildConfiguration configuration,
-      ImmutableList<String> copts) {
+      ImmutableList<String> copts,
+      Predicate<String> coptsFilter) {
     this.ruleContext = Preconditions.checkNotNull(ruleContext);
     this.semantics = semantics;
     this.ccToolchain = Preconditions.checkNotNull(ccToolchain);
     this.fdoSupport = Preconditions.checkNotNull(fdoSupport);
     this.configuration = configuration;
     this.copts = copts;
+    this.coptsFilter = Preconditions.checkNotNull(coptsFilter);
     cppConfiguration = ruleContext.getFragment(CppConfiguration.class);
+    features = ruleContext.getFeatures();
   }
 
   private Artifact getDwoFile(Artifact outputFile) {
@@ -273,15 +317,6 @@
   }
 
   /**
-   * Sets the nocopts pattern. This is used to filter out flags from the system defined set of
-   * flags. By default no filter is applied.
-   */
-  public CppModel setNoCopts(@Nullable Pattern nocopts) {
-    this.nocopts = nocopts;
-    return this;
-  }
-
-  /**
    * Adds the given linkopts to the optional dynamic library link command.
    */
   public CppModel addLinkopts(Collection<String> linkopts) {
@@ -432,10 +467,6 @@
   private CppCompileActionBuilder initializeCompileAction(
       Artifact sourceArtifact, Label sourceLabel) {
     CppCompileActionBuilder builder = createCompileActionBuilder(sourceArtifact, sourceLabel);
-    if (nocopts != null) {
-      builder.addNocopts(nocopts);
-    }
-
     builder.setFeatureConfiguration(featureConfiguration);
 
     return builder;
@@ -450,6 +481,30 @@
     return result.build();
   }
 
+  /**
+   * Supplier that computes unfiltered_compile_flags lazily at the execution phase.
+   *
+   * <p>Dear friends of the lambda, this method exists to limit the scope of captured variables
+   * only to arguments (to prevent accidental capture of enclosing instance which could regress
+   * memory).
+   */
+  public static Supplier<ImmutableList<String>> getUnfilteredCompileFlagsSupplier(
+      CcToolchainProvider ccToolchain, ImmutableSet<String> features) {
+    return () -> ccToolchain.getUnfilteredCompilerOptionsWithSysroot(features);
+  }
+
+  /**
+   * Supplier that computes legacy_compile_flags lazily at the execution phase.
+   *
+   * <p>Dear friends of the lambda, this method exists to limit the scope of captured variables
+   * only to arguments (to prevent accidental capture of enclosing instance which could regress
+   * memory).
+   */
+  public static Supplier<ImmutableList<String>> getLegacyCompileFlagsSupplier(
+      CppConfiguration cppConfiguration, String sourceFilename, ImmutableSet<String> features) {
+    return () -> cppConfiguration.collectLegacyCompileFlags(sourceFilename, features);
+  }
+
   private void setupCompileBuildVariables(
       CppCompileActionBuilder builder,
       boolean usePic,
@@ -463,8 +518,6 @@
     CcToolchainFeatures.Variables.Builder buildVariables =
         new CcToolchainFeatures.Variables.Builder();
 
-    // TODO(bazel-team): Pull out string constants for all build variables.
-
     CppCompilationContext builderContext = builder.getContext();
     Artifact sourceFile = builder.getSourceFile();
     Artifact outputFile = builder.getOutputFile();
@@ -472,7 +525,19 @@
 
     buildVariables.addStringVariable(SOURCE_FILE_VARIABLE_NAME, sourceFile.getExecPathString());
     buildVariables.addStringVariable(OUTPUT_FILE_VARIABLE_NAME, outputFile.getExecPathString());
-    buildVariables.addStringSequenceVariable(COPTS_VARIABLE_VALUE, copts);
+    buildVariables.addStringSequenceVariable(USER_COMPILE_FLAGS_VARIABLE_NAME, copts);
+
+    String sourceFilename = sourceFile.getExecPathString();
+    buildVariables.addLazyStringSequenceVariable(
+        LEGACY_COMPILE_FLAGS_VARIABLE_NAME,
+        getLegacyCompileFlagsSupplier(cppConfiguration, sourceFilename, features));
+
+    if (!CppFileTypes.OBJC_SOURCE.matches(sourceFilename)
+        && !CppFileTypes.OBJCPP_SOURCE.matches(sourceFilename)) {
+      buildVariables.addLazyStringSequenceVariable(
+          UNFILTERED_COMPILE_FLAGS_VARIABLE_NAME,
+          getUnfilteredCompileFlagsSupplier(ccToolchain, features));
+    }
 
     if (builder.getTempOutputFile() != null) {
       realOutputFilePath = builder.getTempOutputFile().getPathString();
@@ -495,7 +560,7 @@
     // Set dependency_file to enable <object>.d file generation.
     if (dotdFile != null) {
       buildVariables.addStringVariable(
-          "dependency_file", dotdFile.getSafeExecPath().getPathString());
+          DEPENDENCY_FILE_VARIABLE_NAME, dotdFile.getSafeExecPath().getPathString());
     }
 
     if (featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAPS) && cppModuleMap != null) {
@@ -706,7 +771,11 @@
         builder.getContext().getCppModuleMap(),
         ImmutableMap.of());
     semantics.finalizeCompileActionBuilder(
-        ruleContext, builder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        builder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     CppCompileAction compileAction = builder.buildOrThrowRuleError(ruleContext);
     env.registerAction(compileAction);
     Artifact tokenFile = compileAction.getOutputFile();
@@ -768,7 +837,11 @@
     builder.setDwoFile(dwoFile);
 
     semantics.finalizeCompileActionBuilder(
-        ruleContext, builder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        builder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     CppCompileAction compileAction = builder.buildOrThrowRuleError(ruleContext);
     AnalysisEnvironment env = ruleContext.getAnalysisEnvironment();
     env.registerAction(compileAction);
@@ -830,7 +903,11 @@
         builder.getContext().getCppModuleMap(),
         /* sourceSpecificBuildVariables= */ ImmutableMap.of());
     semantics.finalizeCompileActionBuilder(
-        ruleContext, builder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        builder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     CppCompileAction compileAction = builder.buildOrThrowRuleError(ruleContext);
     env.registerAction(compileAction);
     Artifact tokenFile = compileAction.getOutputFile();
@@ -916,7 +993,11 @@
         picBuilder.setLtoIndexingFile(ltoIndexingFile);
 
         semantics.finalizeCompileActionBuilder(
-            ruleContext, picBuilder, featureConfiguration.getFeatureSpecification());
+            ruleContext,
+            picBuilder,
+            featureConfiguration.getFeatureSpecification(),
+            coptsFilter,
+            features);
         CppCompileAction picAction = picBuilder.buildOrThrowRuleError(ruleContext);
         env.registerAction(picAction);
         directOutputs.add(picAction.getOutputFile());
@@ -983,7 +1064,11 @@
         builder.setLtoIndexingFile(ltoIndexingFile);
 
         semantics.finalizeCompileActionBuilder(
-            ruleContext, builder, featureConfiguration.getFeatureSpecification());
+            ruleContext,
+            builder,
+            featureConfiguration.getFeatureSpecification(),
+            coptsFilter,
+            features);
         CppCompileAction compileAction = builder.buildOrThrowRuleError(ruleContext);
         env.registerAction(compileAction);
         Artifact objectFile = compileAction.getOutputFile();
@@ -1024,7 +1109,11 @@
         builder.getContext().getCppModuleMap(),
         source.getBuildVariables());
     semantics.finalizeCompileActionBuilder(
-        ruleContext, builder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        builder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     // Make sure this builder doesn't reference ruleContext outside of analysis phase.
     CppCompileActionTemplate actionTemplate = new CppCompileActionTemplate(
         sourceArtifact,
@@ -1080,7 +1169,11 @@
         builder.getContext().getCppModuleMap(),
         ImmutableMap.of());
     semantics.finalizeCompileActionBuilder(
-        ruleContext, builder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        builder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     CppCompileAction action = builder.buildOrThrowRuleError(ruleContext);
     env.registerAction(action);
     if (addObject) {
@@ -1421,7 +1514,11 @@
         builder.getContext().getCppModuleMap(),
         ImmutableMap.of());
     semantics.finalizeCompileActionBuilder(
-        ruleContext, dBuilder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        dBuilder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     CppCompileAction dAction = dBuilder.buildOrThrowRuleError(ruleContext);
     ruleContext.registerAction(dAction);
 
@@ -1439,7 +1536,11 @@
         builder.getContext().getCppModuleMap(),
         ImmutableMap.of());
     semantics.finalizeCompileActionBuilder(
-        ruleContext, sdBuilder, featureConfiguration.getFeatureSpecification());
+        ruleContext,
+        sdBuilder,
+        featureConfiguration.getFeatureSpecification(),
+        coptsFilter,
+        features);
     CppCompileAction sdAction = sdBuilder.buildOrThrowRuleError(ruleContext);
     ruleContext.registerAction(sdAction);
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
index 06e4c9b..b099854 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -176,8 +176,8 @@
   public static final SafeImplicitOutputsFunction CC_BINARY_DEBUG_PACKAGE =
       fromTemplates("%{name}.dwp");
 
-  /** A string constant for the copts feature. */
-  public static final String COPTS = "copts";
+  /** Name of the feature that will be exempt from flag filtering when nocopts are used */
+  public static final String UNFILTERED_COMPILE_FLAGS_FEATURE_NAME = "unfiltered_compile_flags";
 
   /**
    * A string constant for the parse_headers feature.
@@ -289,6 +289,13 @@
   public static final String NO_LEGACY_FEATURES = "no_legacy_features";
 
   /**
+   * A string constant for the legacy_compile_flags feature. If this feature is present in the
+   * toolchain, and the toolchain doesn't specify no_legacy_features, bazel will move
+   * legacy_compile_flags before other features from {@link CppActionConfigs}.
+   */
+  public static final String LEGACY_COMPILE_FLAGS = "legacy_compile_flags";
+
+  /**
    * A string constant for the feature that makes us build per-object debug info files.
    */
   public static final String PER_OBJECT_DEBUG_INFO = "per_object_debug_info";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java
index dfdafb6..3331cb1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.rules.cpp;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -40,7 +42,9 @@
   void finalizeCompileActionBuilder(
       RuleContext ruleContext,
       CppCompileActionBuilder actionBuilder,
-      FeatureSpecification featureSpecification);
+      FeatureSpecification featureSpecification,
+      Predicate<String> coptsFilter,
+      ImmutableSet<String> features);
 
   /**
    * Called before {@link CppCompilationContext}s are finalized.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
index bf6b9fd..3ca8100 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
@@ -56,7 +56,6 @@
   FakeCppCompileAction(
       ActionOwner owner,
       NestedSet<Artifact> allInputs,
-      ImmutableList<String> features,
       FeatureConfiguration featureConfiguration,
       CcToolchainFeatures.Variables variables,
       Artifact sourceFile,
@@ -82,7 +81,6 @@
     super(
         owner,
         allInputs,
-        features,
         featureConfiguration,
         variables,
         sourceFile,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
index 27f920b..54aa46e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
@@ -18,6 +18,7 @@
 import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER;
 import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE;
 
+import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -97,13 +98,16 @@
   public void finalizeCompileActionBuilder(
       RuleContext ruleContext,
       CppCompileActionBuilder actionBuilder,
-      FeatureSpecification featureSpecification) {
+      FeatureSpecification featureSpecification,
+      Predicate<String> coptsFilter,
+      ImmutableSet<String> features) {
     actionBuilder.setCppConfiguration(ruleContext.getFragment(CppConfiguration.class));
     actionBuilder.setActionContext(CppCompileActionContext.class);
     // Because Bazel does not support include scanning, we need the entire crosstool filegroup,
     // including header files, as opposed to just the "compile" filegroup.
     actionBuilder.addTransitiveMandatoryInputs(actionBuilder.getToolchain().getCrosstool());
     actionBuilder.setShouldScanIncludes(false);
+    actionBuilder.setCoptsFilter(coptsFilter);
 
     actionBuilder.addTransitiveMandatoryInputs(objcProvider.get(STATIC_FRAMEWORK_FILE));
     actionBuilder.addTransitiveMandatoryInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE));
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/MOCK_OSX_CROSSTOOL b/src/test/java/com/google/devtools/build/lib/packages/util/MOCK_OSX_CROSSTOOL
index 86e7e7c..f01c9e1 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/MOCK_OSX_CROSSTOOL
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/MOCK_OSX_CROSSTOOL
@@ -208,6 +208,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -1158,7 +1179,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -1168,13 +1189,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -1259,7 +1302,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -1279,7 +1324,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -1294,7 +1341,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -1309,7 +1358,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -1324,7 +1375,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -1348,7 +1401,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -1373,7 +1428,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -1386,7 +1443,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -1401,7 +1460,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -1841,6 +1902,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -2791,7 +2873,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -2801,13 +2883,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -2892,7 +2996,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -2912,7 +3018,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -2927,7 +3035,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -2942,7 +3052,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -2957,7 +3069,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -2981,7 +3095,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -3006,7 +3122,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -3019,7 +3137,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -3034,7 +3154,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -3474,6 +3596,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -4424,7 +4567,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -4434,13 +4577,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -4525,7 +4690,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -4545,7 +4712,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -4560,7 +4729,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -4575,7 +4746,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -4590,7 +4763,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -4614,7 +4789,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -4639,7 +4816,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -4652,7 +4831,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -4667,7 +4848,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -5107,6 +5290,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -6057,7 +6261,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -6067,13 +6271,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -6158,7 +6384,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -6178,7 +6406,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -6193,7 +6423,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -6208,7 +6440,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -6223,7 +6457,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -6247,7 +6483,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -6272,7 +6510,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -6285,7 +6525,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -6300,7 +6542,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -6744,6 +6988,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -7698,7 +7963,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -7708,13 +7973,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -7799,7 +8086,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -7819,7 +8108,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -7834,7 +8125,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -7849,7 +8142,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -7864,7 +8159,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -7888,7 +8185,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -7914,7 +8213,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -7928,7 +8229,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -7943,7 +8246,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -8387,6 +8692,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -9343,7 +9669,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -9353,13 +9679,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -9444,7 +9792,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -9464,7 +9814,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -9479,7 +9831,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -9494,7 +9848,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -9509,7 +9865,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -9533,7 +9891,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -9559,7 +9919,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -9573,7 +9935,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -9588,7 +9952,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -10033,6 +10399,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -11013,7 +11400,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -11023,13 +11410,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -11114,7 +11523,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11135,7 +11546,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11151,7 +11564,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11167,7 +11582,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11183,7 +11600,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11208,7 +11627,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -11234,7 +11655,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -11248,7 +11671,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11264,7 +11689,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11709,6 +12136,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -12663,7 +13111,7 @@
     name: "bitcode_embedded"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -12673,13 +13121,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -12764,7 +13234,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -12784,7 +13256,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -12799,7 +13273,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -12814,7 +13290,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -12829,7 +13307,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -12853,7 +13333,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -12879,7 +13361,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -12893,7 +13377,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -12908,7 +13394,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -13352,6 +13840,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -14328,7 +14837,7 @@
     }
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -14338,13 +14847,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -14429,7 +14960,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -14449,7 +14982,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -14464,7 +14999,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -14479,7 +15016,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -14494,7 +15033,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -14518,7 +15059,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -14543,7 +15086,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -14556,7 +15101,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -14571,7 +15118,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -15015,6 +15564,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -15993,7 +16563,7 @@
     }
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -16003,13 +16573,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -16094,7 +16686,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -16114,7 +16708,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -16129,7 +16725,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -16144,7 +16742,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -16159,7 +16759,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -16183,7 +16785,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -16208,7 +16812,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -16221,7 +16827,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -16236,7 +16844,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -16681,6 +17291,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -17683,7 +18314,7 @@
     }
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -17693,13 +18324,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -17784,7 +18437,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -17805,7 +18460,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -17821,7 +18478,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -17837,7 +18496,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -17853,7 +18514,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -17878,7 +18541,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -17903,7 +18568,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -17916,7 +18583,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -17932,7 +18601,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -18377,6 +19048,27 @@
     name: "is_not_test_target"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "generate_dsym_file"
     flag_set {
       action: "c-compile"
@@ -19353,7 +20045,7 @@
     }
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -19363,13 +20055,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   feature {
@@ -19454,7 +20168,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -19474,7 +20190,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -19489,7 +20207,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -19504,7 +20224,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -19519,7 +20241,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -19543,7 +20267,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -19568,7 +20294,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -19581,7 +20309,9 @@
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -19596,7 +20326,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
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 9e80434..52d33e2 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
@@ -282,6 +282,18 @@
         .contains("Invalid toolchain configuration: Cannot find variable named 'v'");
   }
 
+  @Test
+  public void testLazySequenceExpansion() throws Exception {
+    assertThat(
+            getCommandLineForFlagGroups(
+                "flag_group { iterate_over: 'lazy' flag: '-lazy-%{lazy}' }",
+                new Variables.Builder()
+                    .addLazyStringSequenceVariable("lazy", () -> ImmutableList.of("a", "b", "c"))
+                    .build()))
+        .containsExactly("-lazy-a", "-lazy-b", "-lazy-c")
+        .inOrder();
+  }
+
   private Variables createStructureSequenceVariables(String name, StructureBuilder... values) {
     SequenceBuilder builder = new SequenceBuilder();
     for (StructureBuilder value : values) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java
index 67b9f8a..469e51d 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java
@@ -20,6 +20,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.util.AnalysisMock;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables;
 import org.junit.Test;
@@ -65,15 +66,49 @@
   }
 
   @Test
-  public void testPresenceOfCoptsVariable() throws Exception {
-    scratch.file(
-        "x/BUILD", "cc_binary(name = 'bin', srcs = ['bin.cc'], copts = ['-foo', '-bar'])");
+  public void testPresenceOfLegacyCompileFlags() throws Exception {
+    AnalysisMock.get().ccSupport().setupCrosstool(mockToolsConfig, "cxx_flag: '-foo'");
+    useConfiguration();
+
+    scratch.file("x/BUILD", "cc_binary(name = 'bin', srcs = ['bin.cc'])");
     scratch.file("x/bin.cc");
 
     Variables variables = getCompileBuildVariables("//x:bin", "bin");
 
     ImmutableList<String> copts =
-        Variables.toStringList(variables, CppModel.COPTS_VARIABLE_VALUE);
-    assertThat(copts).containsExactly("-foo", "-bar").inOrder();
+        Variables.toStringList(variables, CppModel.LEGACY_COMPILE_FLAGS_VARIABLE_NAME);
+    assertThat(copts).contains("-foo");
+  }
+
+  @Test
+  public void testPresenceOfUserCompileFlags() throws Exception {
+    AnalysisMock.get().ccSupport().setupCrosstool(mockToolsConfig);
+    useConfiguration();
+
+    scratch.file("x/BUILD", "cc_binary(name = 'bin', srcs = ['bin.cc'], copts = ['-foo'])");
+    scratch.file("x/bin.cc");
+
+    Variables variables = getCompileBuildVariables("//x:bin", "bin");
+
+    ImmutableList<String> copts =
+        Variables.toStringList(variables, CppModel.USER_COMPILE_FLAGS_VARIABLE_NAME);
+    assertThat(copts).contains("-foo");
+  }
+
+  @Test
+  public void testPresenceOfUnfilteredCompileFlags() throws Exception {
+    AnalysisMock.get()
+        .ccSupport()
+        .setupCrosstool(mockToolsConfig, "unfiltered_cxx_flag: '--i_ll_live_forever'");
+    useConfiguration();
+
+    scratch.file("x/BUILD", "cc_binary(name = 'bin', srcs = ['bin.cc'])");
+    scratch.file("x/bin.cc");
+
+    Variables variables = getCompileBuildVariables("//x:bin", "bin");
+
+    ImmutableList<String> unfilteredCompileFlags =
+        Variables.toStringList(variables, CppModel.UNFILTERED_COMPILE_FLAGS_VARIABLE_NAME);
+    assertThat(unfilteredCompileFlags).contains("--i_ll_live_forever");
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java
index 97abeeb..f481f0a 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLineTest.java
@@ -16,7 +16,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Root;
@@ -26,6 +25,7 @@
 import com.google.devtools.build.lib.rules.cpp.CompileCommandLine.Builder;
 import com.google.devtools.build.lib.rules.cpp.CppCompileAction.DotdFile;
 import java.io.IOException;
+import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -97,6 +97,47 @@
         .contains("-some_foo_flag");
   }
 
+  @Test
+  public void testUnfilteredFlagsAreNotFiltered() throws Exception {
+    List<String> actualCommandLine =
+        getCompileCommandLineWithCoptsFilter(CppRuleClasses.UNFILTERED_COMPILE_FLAGS_FEATURE_NAME);
+    assertThat(actualCommandLine).contains("-i_am_a_flag");
+  }
+
+  @Test
+  public void testNonUnfilteredFlagsAreFiltered() throws Exception {
+    List<String> actualCommandLine = getCompileCommandLineWithCoptsFilter("filtered_flags");
+    assertThat(actualCommandLine).doesNotContain("-i_am_a_flag");
+  }
+
+  private List<String> getCompileCommandLineWithCoptsFilter(String featureName) throws Exception {
+    CompileCommandLine compileCommandLine =
+        makeCompileCommandLineBuilder()
+            .setFeatureConfiguration(
+                getMockFeatureConfiguration(
+                    "",
+                    "action_config {",
+                    "  config_name: 'c++-compile'",
+                    "  action_name: 'c++-compile'",
+                    "  implies: '" + featureName + "'",
+                    "  tool {",
+                    "    tool_path: 'foo/bar/DUMMY_COMPILER'",
+                    "  }",
+                    "}",
+                    "feature {",
+                    "  name: '" + featureName + "'",
+                    "  flag_set {",
+                    "     action: 'c++-compile'",
+                    "     flag_group {",
+                    "       flag: '-i_am_a_flag'",
+                    "    }",
+                    "  }",
+                    "}"))
+            .setCoptsFilter(flag -> !flag.contains("i_am_a_flag"))
+            .build();
+    return compileCommandLine.getArgv(scratchArtifact("a/FakeOutput").getExecPath(), null);
+  }
+
   private Builder makeCompileCommandLineBuilder() throws Exception {
     ConfiguredTarget dummyTarget =
         scratchConfiguredTarget("a", "a", "cc_binary(name='a', srcs=['a.cc'])");
@@ -110,7 +151,6 @@
             return true;
           }
         },
-        ImmutableList.<String>of(),
         "c++-compile",
         getTargetConfiguration().getFragment(CppConfiguration.class),
         new DotdFile(scratchArtifact("a/dotD")),
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
index bc2e57f..19f4392 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
@@ -84,13 +84,14 @@
     return CcToolchainFeaturesTest.buildFeatures(
             CppActionConfigs.getCppActionConfigs(
                 CppPlatform.LINUX,
-                ImmutableSet.<String>of(),
+                ImmutableSet.of(),
                 "gcc_tool",
                 "dynamic_library_linker_tool",
                 "ar_tool",
                 "strip_tool",
-                true,
-                false))
+                /* supportsEmbeddedRuntimes= */ true,
+                /* supportsInterfaceSharedLibraries= */ false),
+            CppActionConfigs.getFeaturesToAppearLastInToolchain(ImmutableSet.of()))
         .getFeatureConfiguration(
             FeatureSpecification.create(
                 ImmutableSet.of(
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java
index c0a2457..f2df3dd4 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CrosstoolConfigurationLoaderTest.java
@@ -527,7 +527,7 @@
             "cxx-flag-A-1", "cxx-flag-A-2", "cxx-fastbuild-flag-A-1", "cxx-fastbuild-flag-A-2")
         .inOrder();
     assertThat(ccProviderA.getUnfilteredCompilerOptions(NO_FEATURES))
-        .containsExactly("--sysroot=some", "unfiltered-flag-A-1", "unfiltered-flag-A-2")
+        .containsExactly("unfiltered-flag-A-1", "unfiltered-flag-A-2")
         .inOrder();
     assertThat(toolchainA.getDynamicLinkOptions(NO_FEATURES, true))
         .containsExactly(
diff --git a/tools/cpp/CROSSTOOL b/tools/cpp/CROSSTOOL
index 1219054..b9b78f5 100644
--- a/tools/cpp/CROSSTOOL
+++ b/tools/cpp/CROSSTOOL
@@ -668,6 +668,108 @@
   compiler_flag: "/wd4996"
 
   linker_flag: "-m64"
+  # Stop passing -frandom-seed option
+  feature {
+    name: 'random_seed'
+  }
+
+  # This feature is just for enabling flag_set in action_config for -c and -o options during the transitional period
+  feature {
+    name: 'compile_action_flags_in_flag_set'
+  }
+
+  action_config {
+    config_name: 'c-compile'
+    action_name: 'c-compile'
+    tool {
+      tool_path: 'wrapper/bin/msvc_cl.bat'
+    }
+    flag_set {
+      flag_group {
+        flag: '/c'
+        flag: '%{source_file}'
+      }
+    }
+    flag_set {
+      expand_if_all_available: 'output_object_file'
+      flag_group {
+        flag: '/Fo%{output_object_file}'
+      }
+    }
+    flag_set {
+      expand_if_all_available: 'output_assembly_file'
+      flag_group {
+        flag: '/Fa%{output_assembly_file}'
+      }
+    }
+    flag_set {
+      expand_if_all_available: 'output_preprocess_file'
+      flag_group {
+        flag: '/P'
+        flag: '/Fi%{output_preprocess_file}'
+      }
+    }
+    implies: 'legacy_compile_flags'
+    implies: 'user_compile_flags'
+    implies: 'unfiltered_compile_flags'
+  }
+
+  action_config {
+    config_name: 'c++-compile'
+    action_name: 'c++-compile'
+    tool {
+      tool_path: 'wrapper/bin/msvc_cl.bat'
+    }
+    flag_set {
+      flag_group {
+        flag: '/c'
+        flag: '%{source_file}'
+      }
+    }
+    flag_set {
+      expand_if_all_available: 'output_object_file'
+      flag_group {
+        flag: '/Fo%{output_object_file}'
+      }
+    }
+    flag_set {
+      expand_if_all_available: 'output_assembly_file'
+      flag_group {
+        flag: '/Fa%{output_assembly_file}'
+      }
+    }
+    flag_set {
+      expand_if_all_available: 'output_preprocess_file'
+      flag_group {
+        flag: '/P'
+        flag: '/Fi%{output_preprocess_file}'
+      }
+    }
+    implies: 'legacy_compile_flags'
+    implies: 'user_compile_flags'
+    implies: 'unfiltered_compile_flags'
+  }
+
+  # TODO(b/65151735): Remove legacy_compile_flags feature when legacy fields are
+  # not used in this crosstool
+  feature {
+    name: 'legacy_compile_flags'
+    flag_set {
+      expand_if_all_available: 'legacy_compile_flags'
+      action: 'assemble'
+      action: 'preprocess-assemble'
+      action: 'c-compile'
+      action: 'c++-compile'
+      action: 'c++-header-parsing'
+      action: 'c++-header-preprocessing'
+      action: 'c++-module-compile'
+      action: 'c++-module-codegen'
+      flag_group {
+        iterate_over: 'legacy_compile_flags'
+        flag: '%{legacy_compile_flags}'
+      }
+    }
+  }
 
   feature {
     name: 'include_paths'
@@ -711,88 +813,10 @@
     }
   }
 
-  # Stop passing -frandom-seed option
   feature {
-    name: 'random_seed'
-  }
-
-  # This feature is just for enabling flag_set in action_config for -c and -o options during the transitional period
-  feature {
-    name: 'compile_action_flags_in_flag_set'
-  }
-
-  action_config {
-    config_name: 'c-compile'
-    action_name: 'c-compile'
-    tool {
-      tool_path: 'wrapper/bin/msvc_cl.bat'
-    }
+    name: 'user_compile_flags'
     flag_set {
-      flag_group {
-        flag: '/c'
-        flag: '%{source_file}'
-      }
-    }
-    flag_set {
-      expand_if_all_available: 'output_object_file'
-      flag_group {
-        flag: '/Fo%{output_object_file}'
-      }
-    }
-    flag_set {
-      expand_if_all_available: 'output_assembly_file'
-      flag_group {
-        flag: '/Fa%{output_assembly_file}'
-      }
-    }
-    flag_set {
-      expand_if_all_available: 'output_preprocess_file'
-      flag_group {
-        flag: '/P'
-        flag: '/Fi%{output_preprocess_file}'
-      }
-    }
-    implies: 'copts'
-  }
-
-  action_config {
-    config_name: 'c++-compile'
-    action_name: 'c++-compile'
-    tool {
-      tool_path: 'wrapper/bin/msvc_cl.bat'
-    }
-    flag_set {
-      flag_group {
-        flag: '/c'
-        flag: '%{source_file}'
-      }
-    }
-    flag_set {
-      expand_if_all_available: 'output_object_file'
-      flag_group {
-        flag: '/Fo%{output_object_file}'
-      }
-    }
-    flag_set {
-      expand_if_all_available: 'output_assembly_file'
-      flag_group {
-        flag: '/Fa%{output_assembly_file}'
-      }
-    }
-    flag_set {
-      expand_if_all_available: 'output_preprocess_file'
-      flag_group {
-        flag: '/P'
-        flag: '/Fi%{output_preprocess_file}'
-      }
-    }
-    implies: 'copts'
-  }
-
-  feature {
-    name: 'copts'
-    flag_set {
-      expand_if_all_available: 'copts'
+      expand_if_all_available: 'user_compile_flags'
       action: 'assemble'
       action: 'preprocess-assemble'
       action: 'c-compile'
@@ -802,8 +826,27 @@
       action: 'c++-module-compile'
       action: 'c++-module-codegen'
       flag_group {
-        iterate_over: 'copts'
-        flag: '%{copts}'
+        iterate_over: 'user_compile_flags'
+        flag: '%{user_compile_flags}'
+      }
+    }
+  }
+
+  feature {
+    name: 'unfiltered_compile_flags'
+    flag_set {
+      expand_if_all_available: 'unfiltered_compile_flags'
+      action: 'assemble'
+      action: 'preprocess-assemble'
+      action: 'c-compile'
+      action: 'c++-compile'
+      action: 'c++-header-parsing'
+      action: 'c++-header-preprocessing'
+      action: 'c++-module-compile'
+      action: 'c++-module-codegen'
+      flag_group {
+        iterate_over: 'unfiltered_compile_flags'
+        flag: '%{unfiltered_compile_flags}'
       }
     }
   }
diff --git a/tools/cpp/CROSSTOOL.tpl b/tools/cpp/CROSSTOOL.tpl
index c27a117..7b7630b 100644
--- a/tools/cpp/CROSSTOOL.tpl
+++ b/tools/cpp/CROSSTOOL.tpl
@@ -238,120 +238,11 @@
     }
   }
 
-  feature {
-    name: "msvc_env"
-    env_set {
-      action: "c-compile"
-      action: "c++-compile"
-      action: "c++-module-compile"
-      action: "c++-module-codegen"
-      action: "c++-header-parsing"
-      action: "c++-header-preprocessing"
-      action: "assemble"
-      action: "preprocess-assemble"
-      action: "c++-link-executable"
-      action: "c++-link-dynamic-library"
-      action: "c++-link-static-library"
-      action: "c++-link-alwayslink-static-library"
-      action: "c++-link-pic-static-library"
-      action: "c++-link-alwayslink-pic-static-library"
-      env_entry {
-        key: "PATH"
-        value: "%{msvc_env_path}"
-      }
-      env_entry {
-        key: "INCLUDE"
-        value: "%{msvc_env_include}"
-      }
-      env_entry {
-        key: "LIB"
-        value: "%{msvc_env_lib}"
-      }
-      env_entry {
-        key: "TMP"
-        value: "%{msvc_env_tmp}"
-      }
-      env_entry {
-        key: "TEMP"
-        value: "%{msvc_env_tmp}"
-      }
-    }
-  }
-
-  feature {
-    name: "use_linker"
-    env_set {
-      action: "c++-link-executable"
-      action: "c++-link-dynamic-library"
-      env_entry {
-        key: "USE_LINKER"
-        value: "1"
-      }
-    }
-  }
-
-  feature {
-    name: 'include_paths'
-    flag_set {
-      action: 'preprocess-assemble'
-      action: 'c-compile'
-      action: 'c++-compile'
-      action: 'c++-header-parsing'
-      action: 'c++-header-preprocessing'
-      action: 'c++-module-compile'
-      flag_group {
-        iterate_over: 'quote_include_paths'
-        flag: '/I%{quote_include_paths}'
-      }
-      flag_group {
-        iterate_over: 'include_paths'
-        flag: '/I%{include_paths}'
-      }
-      flag_group {
-        iterate_over: 'system_include_paths'
-        flag: '/I%{system_include_paths}'
-      }
-    }
-  }
-
-  # Tell Bazel to parse the output of /showIncludes
-  feature {
-    name: 'parse_showincludes'
-    flag_set {
-      action: 'assemble'
-      action: 'preprocess-assemble'
-      action: 'c-compile'
-      action: 'c++-compile'
-      action: 'c++-module-compile'
-      action: 'c++-header-preprocessing'
-      action: 'c++-header-parsing'
-      flag_group {
-        flag: "/showIncludes"
-      }
-    }
-  }
-
   # This feature is just for enabling flag_set in action_config for -c and -o options during the transitional period
   feature {
     name: 'compile_action_flags_in_flag_set'
   }
 
-  feature {
-    name: "preprocessor_defines"
-    flag_set {
-      action: "preprocess-assemble"
-      action: "c-compile"
-      action: "c++-compile"
-      action: "c++-header-parsing"
-      action: "c++-header-preprocessing"
-      action: "c++-module-compile"
-      flag_group {
-        flag: "/D%{preprocessor_defines}"
-        iterate_over: "preprocessor_defines"
-      }
-    }
-  }
-
   # This feature indicates strip is not supported, building stripped binary will just result a copy of orignial binary
   feature {
     name: 'no_stripping'
@@ -388,10 +279,12 @@
         flag: '/Fi%{output_preprocess_file}'
       }
     }
+    implies: 'legacy_compile_flags'
     implies: 'nologo'
     implies: 'msvc_env'
     implies: 'parse_showincludes'
-    implies: 'copts'
+    implies: 'user_compile_flags'
+    implies: 'unfiltered_compile_flags'
   }
 
   action_config {
@@ -425,10 +318,12 @@
         flag: '/Fi%{output_preprocess_file}'
       }
     }
+    implies: 'legacy_compile_flags'
     implies: 'nologo'
     implies: 'msvc_env'
     implies: 'parse_showincludes'
-    implies: 'copts'
+    implies: 'user_compile_flags'
+    implies: 'unfiltered_compile_flags'
   }
 
   action_config {
@@ -533,6 +428,137 @@
     implies: 'msvc_env'
   }
 
+  # TODO(b/65151735): Remove legacy_compile_flags feature when legacy fields are
+  # not used in this crosstool
+  feature {
+    name: 'legacy_compile_flags'
+    flag_set {
+      expand_if_all_available: 'legacy_compile_flags'
+      action: 'assemble'
+      action: 'preprocess-assemble'
+      action: 'c-compile'
+      action: 'c++-compile'
+      action: 'c++-header-parsing'
+      action: 'c++-header-preprocessing'
+      action: 'c++-module-compile'
+      action: 'c++-module-codegen'
+      flag_group {
+        iterate_over: 'legacy_compile_flags'
+        flag: '%{legacy_compile_flags}'
+      }
+    }
+  }
+
+  feature {
+    name: "msvc_env"
+    env_set {
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c++-link-executable"
+      action: "c++-link-dynamic-library"
+      action: "c++-link-static-library"
+      action: "c++-link-alwayslink-static-library"
+      action: "c++-link-pic-static-library"
+      action: "c++-link-alwayslink-pic-static-library"
+      env_entry {
+        key: "PATH"
+        value: "%{msvc_env_path}"
+      }
+      env_entry {
+        key: "INCLUDE"
+        value: "%{msvc_env_include}"
+      }
+      env_entry {
+        key: "LIB"
+        value: "%{msvc_env_lib}"
+      }
+      env_entry {
+        key: "TMP"
+        value: "%{msvc_env_tmp}"
+      }
+      env_entry {
+        key: "TEMP"
+        value: "%{msvc_env_tmp}"
+      }
+    }
+  }
+
+  feature {
+    name: "use_linker"
+    env_set {
+      action: "c++-link-executable"
+      action: "c++-link-dynamic-library"
+      env_entry {
+        key: "USE_LINKER"
+        value: "1"
+      }
+    }
+  }
+
+  feature {
+    name: 'include_paths'
+    flag_set {
+      action: 'preprocess-assemble'
+      action: 'c-compile'
+      action: 'c++-compile'
+      action: 'c++-header-parsing'
+      action: 'c++-header-preprocessing'
+      action: 'c++-module-compile'
+      flag_group {
+        iterate_over: 'quote_include_paths'
+        flag: '/I%{quote_include_paths}'
+      }
+      flag_group {
+        iterate_over: 'include_paths'
+        flag: '/I%{include_paths}'
+      }
+      flag_group {
+        iterate_over: 'system_include_paths'
+        flag: '/I%{system_include_paths}'
+      }
+    }
+  }
+
+  feature {
+    name: "preprocessor_defines"
+    flag_set {
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      flag_group {
+        flag: "/D%{preprocessor_defines}"
+        iterate_over: "preprocessor_defines"
+      }
+    }
+  }
+
+  # Tell Bazel to parse the output of /showIncludes
+  feature {
+    name: 'parse_showincludes'
+    flag_set {
+      action: 'assemble'
+      action: 'preprocess-assemble'
+      action: 'c-compile'
+      action: 'c++-compile'
+      action: 'c++-module-compile'
+      action: 'c++-header-preprocessing'
+      action: 'c++-header-parsing'
+      flag_group {
+        flag: "/showIncludes"
+      }
+    }
+  }
+
+
   feature {
     name: 'generate_pdb_file'
     requires: {
@@ -852,9 +878,9 @@
   }
 
   feature {
-    name: 'copts'
+    name: 'user_compile_flags'
     flag_set {
-      expand_if_all_available: 'copts'
+      expand_if_all_available: 'user_compile_flags'
       action: 'assemble'
       action: 'preprocess-assemble'
       action: 'c-compile'
@@ -864,12 +890,32 @@
       action: 'c++-module-compile'
       action: 'c++-module-codegen'
       flag_group {
-        iterate_over: 'copts'
-        flag: '%{copts}'
+        iterate_over: 'user_compile_flags'
+        flag: '%{user_compile_flags}'
       }
     }
   }
 
+  feature {
+    name: 'unfiltered_compile_flags'
+    flag_set {
+      expand_if_all_available: 'unfiltered_compile_flags'
+      action: 'assemble'
+      action: 'preprocess-assemble'
+      action: 'c-compile'
+      action: 'c++-compile'
+      action: 'c++-header-parsing'
+      action: 'c++-header-preprocessing'
+      action: 'c++-module-compile'
+      action: 'c++-module-codegen'
+      flag_group {
+        iterate_over: 'unfiltered_compile_flags'
+        flag: '%{unfiltered_compile_flags}'
+      }
+    }
+  }
+
+
 %{compilation_mode_content}
 
 }
diff --git a/tools/osx/crosstool/CROSSTOOL.tpl b/tools/osx/crosstool/CROSSTOOL.tpl
index 5870195..c246576 100644
--- a/tools/osx/crosstool/CROSSTOOL.tpl
+++ b/tools/osx/crosstool/CROSSTOOL.tpl
@@ -184,6 +184,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -1044,7 +1065,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -1054,13 +1075,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -1107,13 +1150,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -1122,13 +1167,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -1137,13 +1184,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -1152,13 +1201,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -1167,13 +1218,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -1198,7 +1251,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -1224,7 +1279,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -1233,11 +1290,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -1246,13 +1305,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -1680,6 +1741,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -2545,7 +2627,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -2555,13 +2637,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -2608,13 +2712,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -2623,13 +2729,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -2638,13 +2746,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -2653,13 +2763,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -2668,13 +2780,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -2699,7 +2813,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -2726,7 +2842,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -2736,11 +2854,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -2749,13 +2869,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -3183,6 +3305,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -4050,7 +4193,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -4060,13 +4203,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -4113,13 +4278,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -4128,13 +4295,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -4143,13 +4312,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -4158,13 +4329,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -4173,13 +4346,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -4204,7 +4379,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -4231,7 +4408,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -4241,11 +4420,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -4254,13 +4435,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -4689,6 +4872,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -5577,7 +5781,7 @@
     }
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -5587,13 +5791,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -5640,13 +5866,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -5656,13 +5884,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -5672,13 +5902,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -5688,13 +5920,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -5704,13 +5938,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -5736,7 +5972,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -5763,7 +6001,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -5773,11 +6013,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -5787,13 +6029,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -6224,6 +6468,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -7089,7 +7354,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -7099,13 +7364,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -7152,13 +7439,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -7167,13 +7456,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -7182,13 +7473,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -7197,13 +7490,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -7212,13 +7507,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -7243,7 +7540,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -7270,7 +7569,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "apply_simulator_compiler_flags"
   }
   action_config {
@@ -7280,11 +7581,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -7293,13 +7596,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -7727,6 +8032,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -8582,7 +8908,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -8592,13 +8918,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -8645,13 +8993,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -8660,13 +9010,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -8675,13 +9027,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -8690,13 +9044,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -8705,13 +9061,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -8736,7 +9094,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -8762,7 +9122,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -8771,11 +9133,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -8784,13 +9148,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -9218,6 +9584,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -10075,7 +10462,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -10085,13 +10472,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -10138,13 +10547,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -10153,13 +10564,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -10168,13 +10581,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -10183,13 +10598,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -10198,13 +10615,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -10229,7 +10648,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -10255,7 +10676,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -10264,11 +10687,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -10277,13 +10702,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -10712,6 +11139,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -11590,7 +12038,7 @@
     }
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -11600,13 +12048,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -11653,13 +12123,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11669,13 +12141,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11685,13 +12159,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11701,13 +12177,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11717,13 +12195,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11749,7 +12229,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -11775,7 +12257,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -11784,11 +12268,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -11798,13 +12284,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
     implies: "unfiltered_cxx_flags"
   }
   action_config {
@@ -12235,6 +12723,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -13090,7 +13599,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -13100,13 +13609,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -13153,13 +13684,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -13168,13 +13701,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -13183,13 +13718,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -13198,13 +13735,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -13213,13 +13752,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -13244,7 +13785,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -13270,7 +13813,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -13279,11 +13824,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -13292,13 +13839,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"
@@ -13732,6 +14281,27 @@
     name: "only_doth_headers_in_module_maps"
   }
   feature {
+    name: "legacy_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{legacy_compile_flags}"
+        iterate_over: "legacy_compile_flags"
+      }
+      expand_if_all_available: "legacy_compile_flags"
+    }
+  }
+  feature {
     name: "objc_actions"
     implies: "objc-compile"
     implies: "objc++-compile"
@@ -14587,7 +15157,7 @@
     name: "unfiltered_cxx_flags"
   }
   feature {
-    name: "copts"
+    name: "user_compile_flags"
     flag_set {
       action: "assemble"
       action: "preprocess-assemble"
@@ -14597,13 +15167,35 @@
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
       action: "c++-module-codegen"
+      action: "lto-backend"
       action: "objc-compile"
       action: "objc++-compile"
       flag_group {
-        flag: "%{copts}"
-        iterate_over: "copts"
+        flag: "%{user_compile_flags}"
+        iterate_over: "user_compile_flags"
       }
-      expand_if_all_available: "copts"
+      expand_if_all_available: "user_compile_flags"
+    }
+  }
+  feature {
+    name: "unfiltered_compile_flags"
+    flag_set {
+      action: "assemble"
+      action: "preprocess-assemble"
+      action: "c-compile"
+      action: "c++-compile"
+      action: "c++-header-parsing"
+      action: "c++-header-preprocessing"
+      action: "c++-module-compile"
+      action: "c++-module-codegen"
+      action: "lto-backend"
+      action: "objc-compile"
+      action: "objc++-compile"
+      flag_group {
+        flag: "%{unfiltered_compile_flags}"
+        iterate_over: "unfiltered_compile_flags"
+      }
+      expand_if_all_available: "unfiltered_compile_flags"
     }
   }
   action_config {
@@ -14650,13 +15242,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-compile"
@@ -14665,13 +15259,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-module-compile"
@@ -14680,13 +15276,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-parsing"
@@ -14695,13 +15293,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "c++-header-preprocessing"
@@ -14710,13 +15310,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-compile"
@@ -14741,7 +15343,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc++-compile"
@@ -14767,7 +15371,9 @@
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
-    implies: "copts"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "assemble"
@@ -14776,11 +15382,13 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "include_system_dirs"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "preprocess-assemble"
@@ -14789,13 +15397,15 @@
       tool_path: "wrapped_clang"
       execution_requirement: "requires-darwin"
     }
-    implies: "copts"
     implies: "preprocessor_defines"
     implies: "include_system_dirs"
     implies: "version_min"
     implies: "objc_arc"
     implies: "no_objc_arc"
     implies: "apple_env"
+    implies: "legacy_compile_flags"
+    implies: "user_compile_flags"
+    implies: "unfiltered_compile_flags"
   }
   action_config {
     config_name: "objc-archive"