# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This file is meant to be included into an target to create a unittest that
# invokes a set of no-compile tests.  A no-compile test is a test that asserts
# a particular construct will not compile.
#
# Usage:
#
# 1. Create a GN target:
#
#    import("//build/nocompile.gni")
#
#    nocompile_source_set("base_nocompile_tests") {
#      sources = [
#        "functional/one_not_equal_two_nocompile.nc",
#      ]
#      deps = [
#        ":base"
#      ]
#    }
#
#    Note that by convention, nocompile tests use the `.nc` extension rather
#    than the standard `.cc` extension: this is because the expectation lines
#    often exceed 80 characters, which would make clang-format unhappy.
#
# 2. Add a dep from a related test binary to the nocompile source set:
#
#    test("base_unittests") {
#      ...
#      deps += [ ":base_nocompile_tests" ]
#    }
#
# 3. Populate the .nc file with test cases. Expected compile failures should be
#    annotated with a comment of the form:
#
#    // expected-error {{<expected error string here>}}
#
#    For example:
#
#    void OneDoesNotEqualTwo() {
#      static_assert(1 == 2);  // expected-error {{static assertion failed due to requirement '1 == 2'}}
#    }
#
#    The verification logic is built as part of clang; full documentation is at
#    https://clang.llvm.org/docs/InternalsManual.html#specifying-diagnostics.
#
# Also see:
#   http://dev.chromium.org/developers/testing/no-compile-tests
#
import("//build/config/clang/clang.gni")
if (is_win) {
  import("//build/toolchain/win/win_toolchain_data.gni")
}

declare_args() {
  enable_nocompile_tests = is_clang && !is_nacl
}

if (enable_nocompile_tests) {
  template("nocompile_source_set") {
    action_foreach(target_name) {
      testonly = true

      script = "//tools/nocompile/wrapper.py"
      sources = invoker.sources
      if (defined(invoker.deps)) {
        deps = invoker.deps
      }

      # An action is not a compiler, so configs is empty until it is explicitly
      # set.
      configs = default_compiler_configs
      if (defined(invoker.configs)) {
        configs += invoker.configs
      }

      configs -= [
        # Disable the checks that the Chrome style plugin normally enforces to
        # reduce the amount of boilerplate needed in nocompile tests.
        "//build/config/clang:find_bad_constructs",

        # Disable modules in this target to keep config for this action simple.
        "//build/config/compiler:libcxx_module",
      ]

      if (is_win) {
        result_path =
            "$target_out_dir/$target_name/{{source_name_part}}_placeholder.obj"
      } else {
        result_path =
            "$target_out_dir/$target_name/{{source_name_part}}_placeholder.o"
      }
      rebased_obj_path = rebase_path(result_path, root_build_dir)

      depfile = "${result_path}.d"
      rebased_depfile_path = rebase_path(depfile, root_build_dir)
      outputs = [ result_path ]

      if (is_win) {
        if (host_os == "win") {
          cxx = "clang-cl.exe"
        } else {
          cxx = "clang-cl"
        }
      } else {
        cxx = "clang++"
      }

      args = []

      if (is_win) {
        # ninja normally parses /showIncludes output, but the depsformat
        # variable can only be set in compiler tools, not for custom actions.
        # Unfortunately, this means the clang wrapper needs to generate the
        # depfile itself.
        args += [ "--generate-depfile" ]
      }

      args += [
        rebase_path("$clang_base_path/bin/$cxx", root_build_dir),
        "{{source}}",
        rebased_obj_path,
        rebased_depfile_path,
        "--",
        "{{cflags}}",
        "{{cflags_cc}}",
        "{{defines}}",
        "{{include_dirs}}",

        # No need to generate an object file for nocompile tests.
        "-Xclang",
        "-fsyntax-only",

        # Enable clang's VerifyDiagnosticConsumer:
        # https://clang.llvm.org/doxygen/classclang_1_1VerifyDiagnosticConsumer.html
        "-Xclang",
        "-verify",

        # But don't require expected-note comments since that is not the
        # primary point of the nocompile tests.
        "-Xclang",
        "-verify-ignore-unexpected=note",

        # Disable the error limit so that nocompile tests do not need to be
        # arbitrarily split up when they hit the default error limit.
        "-ferror-limit=0",

        # So funny characters don't show up in error messages.
        "-fno-color-diagnostics",

        # Always treat warnings as errors.
        "-Werror",
      ]

      if (!is_win) {
        args += [
          # On non-Windows platforms, clang can generate the depfile.
          "-MMD",
          "-MF",
          rebased_depfile_path,
          "-MT",
          rebased_obj_path,

          # Non-Windows clang uses file extensions to determine how to treat
          # various inputs, so explicitly tell it to treat all inputs (even
          # those with weird extensions like .nc) as C++ source files.
          "-x",
          "c++",
        ]
      } else {
        # For some reason, the Windows includes are not part of the default
        # compiler configs. Set it explicitly here, since things like libc++
        # depend on the VC runtime.
        if (target_cpu == "x86") {
          win_toolchain_data = win_toolchain_data_x86
        } else if (target_cpu == "x64") {
          win_toolchain_data = win_toolchain_data_x64
        } else if (target_cpu == "arm64") {
          win_toolchain_data = win_toolchain_data_arm64
        } else {
          error("Unsupported target_cpu, add it to win_toolchain_data.gni")
        }
        args += win_toolchain_data.include_flags_imsvc_list
        args += [ "/showIncludes:user" ]
      }

      # Note: for all platforms, the depfile only lists user includes, and not
      # system includes. If system includes change, the compiler flags are
      # expected to artificially change in some way to invalidate and force the
      # nocompile tests to run again.
    }
  }
}
