Teach Bazel to accept assembler-without-preprocessor source files.

Adding the accepted file extensions was a minor issue.
The bulk of this change was to weaken the assertion
that all cxx compiler actions produce a '.d' file.

RELNOTES[NEW]: a cc_binary rule may list '.s' and '.asm' files in the srcs

--
MOS_MIGRATED_REVID=103196242
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
index 43e4209..1437192 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
@@ -27,6 +27,7 @@
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ALWAYS_LINK_LIBRARY;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ALWAYS_LINK_PIC_LIBRARY;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ARCHIVE;
+import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ASSEMBLER;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.CPP_HEADER;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.CPP_SOURCE;
@@ -78,6 +79,7 @@
       C_SOURCE,
       CPP_HEADER,
       ASSEMBLER_WITH_C_PREPROCESSOR,
+      ASSEMBLER,
       ARCHIVE,
       PIC_ARCHIVE,
       ALWAYS_LINK_LIBRARY,
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 aff5dd7..8028abd 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
@@ -63,6 +63,7 @@
       CppFileTypes.CPP_SOURCE,
       CppFileTypes.CPP_HEADER,
       CppFileTypes.C_SOURCE,
+      CppFileTypes.ASSEMBLER,
       CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR);
 
   /**
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 d2f2b6a..dc79e25 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
@@ -133,8 +133,9 @@
   public static final String CPP_MODULE_COMPILE = "c++-module-compile";
 
   /**
-   * A string constant for the preprocessing assembler action.
+   * A string constant for the assembler actions.
    */
+  public static final String ASSEMBLE = "assemble";
   public static final String PREPROCESS_ASSEMBLE = "preprocess-assemble";
 
 
@@ -227,7 +228,8 @@
       RuleContext ruleContext) {
     super(owner,
           createInputs(mandatoryInputs, context.getCompilationPrerequisites(), optionalSourceFile),
-          CollectionUtils.asListWithoutNulls(outputFile, dotdFile.artifact(),
+          CollectionUtils.asListWithoutNulls(outputFile,
+              (dotdFile == null ? null : dotdFile.artifact()),
               gcnoFile, dwoFile));
     this.configuration = configuration;
     this.sourceLabel = sourceLabel;
@@ -829,13 +831,14 @@
 
   private DependencySet processDepset(Path execRoot, CppCompileActionContext.Reply reply)
       throws IOException {
+    DotdFile dotdFile = getDotdFile();
+    Preconditions.checkNotNull(dotdFile);
     DependencySet depSet = new DependencySet(execRoot);
-
-    // artifact() is null if we are not using in-memory .d files. We also want to prepare for the
+    // artifact() is null if we are using in-memory .d files. We also want to prepare for the
     // case where we expected an in-memory .d file, but we did not get an appropriate response.
     // Perhaps we produced the file locally.
-    if (getDotdFile().artifact() != null || reply == null) {
-      return depSet.read(getDotdFile().getPath());
+    if (dotdFile.artifact() != null || reply == null) {
+      return depSet.read(dotdFile.getPath());
     } else {
       // This is an in-memory .d file.
       return depSet.process(reply.getContents());
@@ -854,14 +857,17 @@
    *
    * @param reply the reply from the compilation.
    * @param inputs the ordered collection of inputs to append to
-   * @throws ActionExecutionException iff the .d is missing, malformed or has
-   *         unresolvable included artifacts.
+   * @throws ActionExecutionException iff the .d is missing (when required),
+   *         malformed, or has unresolvable included artifacts.
    */
   @ThreadCompatible
   private void populateActionInputs(Path execRoot,
       ArtifactResolver artifactResolver, CppCompileActionContext.Reply reply,
       NestedSetBuilder<Artifact> inputs)
       throws ActionExecutionException {
+    if (getDotdFile() == null) {
+      return;
+    }
     try {
       // Read .d file.
       DependencySet depSet = processDepset(execRoot, reply);
@@ -1193,7 +1199,8 @@
         CcToolchainFeatures.Variables variables,
         @Nullable String fdoBuildStamp) {
       this.sourceFile = Preconditions.checkNotNull(sourceFile);
-      this.dotdFile = Preconditions.checkNotNull(dotdFile);
+      this.dotdFile = CppFileTypes.mustProduceDotdFile(sourceFile.getPath().toString())
+                      ? Preconditions.checkNotNull(dotdFile) : null;
       this.copts = Preconditions.checkNotNull(copts);
       this.coptsFilter = coptsFilter;
       this.pluginOpts = Preconditions.checkNotNull(pluginOpts);
@@ -1243,6 +1250,8 @@
         return C_COMPILE;
       } else if (CppFileTypes.CPP_SOURCE.matches(sourcePath)) {
         return CPP_COMPILE;
+      } else if (CppFileTypes.ASSEMBLER.matches(sourcePath)) {
+        return ASSEMBLE;
       } else if (CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR.matches(sourcePath)) {
         return PREPROCESS_ASSEMBLE;
       }
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 a943057..ab1196c 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
@@ -382,13 +382,17 @@
   }
 
   public CppCompileActionBuilder setDotdFile(PathFragment outputName, String extension) {
-    if (configuration.getFragment(CppConfiguration.class).getInmemoryDotdFiles()) {
-      // Just set the path, no artifact is constructed
-      PathFragment file = FileSystemUtils.replaceExtension(outputName, extension);
-      Root root = configuration.getBinDirectory();
-      dotdFile = new DotdFile(root.getExecPath().getRelative(file));
+    if (CppFileTypes.mustProduceDotdFile(outputName.toString())) {
+      if (configuration.getFragment(CppConfiguration.class).getInmemoryDotdFiles()) {
+        // Just set the path, no artifact is constructed
+        PathFragment file = FileSystemUtils.replaceExtension(outputName, extension);
+        Root root = configuration.getBinDirectory();
+        dotdFile = new DotdFile(root.getExecPath().getRelative(file));
+      } else {
+        dotdFile = new DotdFile(ruleContext.getRelatedArtifact(outputName, extension));
+      }
     } else {
-      dotdFile = new DotdFile(ruleContext.getRelatedArtifact(outputName, extension));
+      dotdFile = null;
     }
     return this;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
index 655dcd5..a7e3a1a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
@@ -59,11 +59,12 @@
       final String ext = ".s";
       @Override
       public boolean apply(String filename) {
-        return filename.endsWith(ext) && !PIC_ASSEMBLER.matches(filename);
+        return (filename.endsWith(ext) && !PIC_ASSEMBLER.matches(filename))
+               || filename.endsWith(".asm");
       }
       @Override
       public List<String> getExtensions() {
-        return ImmutableList.of(ext);
+        return ImmutableList.of(ext, ".asm");
       }
     };
 
@@ -139,4 +140,8 @@
 
   // Output of the dwp tool
   public static final FileType DEBUG_INFO_PACKAGE = FileType.of(".dwp");
+
+  public static final boolean mustProduceDotdFile(String source) {
+    return !(ASSEMBLER.matches(source) || PIC_ASSEMBLER.matches(source));
+  }
 }
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 de1c92c..f651f62 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
@@ -18,6 +18,7 @@
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ALWAYS_LINK_LIBRARY;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ALWAYS_LINK_PIC_LIBRARY;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ARCHIVE;
+import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ASSEMBLER;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.CPP_HEADER;
 import static com.google.devtools.build.lib.rules.cpp.CppFileTypes.CPP_SOURCE;
@@ -54,7 +55,8 @@
    * those.
    */
   static final InstrumentationSpec INSTRUMENTATION_SPEC = new InstrumentationSpec(
-      FileTypeSet.of(CPP_SOURCE, C_SOURCE, CPP_HEADER, ASSEMBLER_WITH_C_PREPROCESSOR),
+      FileTypeSet.of(CPP_SOURCE, C_SOURCE, CPP_HEADER, ASSEMBLER_WITH_C_PREPROCESSOR,
+          ASSEMBLER),
       "srcs", "deps", "data", "hdrs");
 
   public static final LibraryLanguage LANGUAGE = new LibraryLanguage("C++");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LocalGccStrategy.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LocalGccStrategy.java
index 7b1cd6f..d9be59b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LocalGccStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LocalGccStrategy.java
@@ -46,7 +46,11 @@
   public static void updateEnv(CppCompileAction action, Map<String, String> env) {
     // We cannot locally execute an action that does not expect to output a .d file, since we would
     // have no way to tell what files that it included were used during compilation.
-    env.put("INTERCEPT_LOCALLY_EXECUTABLE", action.getDotdFile().artifact() == null ? "0" : "1");
+    // The exception to this is that if no .d file can be produced (as indicated by
+    // dotdfile == null), then the assumption is that there are truly no depencies,
+    // and therefore we don't care whether the step executes locally or remotely.
+    env.put("INTERCEPT_LOCALLY_EXECUTABLE",
+        (action.getDotdFile() != null && action.getDotdFile().artifact() == null) ? "0" : "1");
   }
 
   @Override