Index: clang/include/clang/Basic/CLWarnings.h =================================================================== --- /dev/null +++ clang/include/clang/Basic/CLWarnings.h @@ -0,0 +1,20 @@ +//===--- CLWarnings.h - Maps some cl.exe warning ids -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_CLWARNINGS_H +#define LLVM_CLANG_BASIC_CLWARNINGS_H + +namespace clang { + +/// For cl.exe warning IDs that cleany map to clang diagnostic groups, +/// returns the corresponding group name. Else, returns nullptr. +const char *diagGroupFromCLWarningID(unsigned); + +} // end namespace clang + +#endif // LLVM_CLANG_BASIC_CLWARNINGS_H Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -6106,16 +6106,7 @@ HelpText<"Do not treat warnings as errors (default)">, Alias, AliasArgs<["no-error"]>; def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias; -def _SLASH_wd4005 : CLFlag<"wd4005">, Alias, - AliasArgs<["no-macro-redefined"]>; -def _SLASH_wd4018 : CLFlag<"wd4018">, Alias, - AliasArgs<["no-sign-compare"]>; -def _SLASH_wd4100 : CLFlag<"wd4100">, Alias, - AliasArgs<["no-unused-parameter"]>; -def _SLASH_wd4910 : CLFlag<"wd4910">, Alias, - AliasArgs<["no-dllexport-explicit-instantiation-decl"]>; -def _SLASH_wd4996 : CLFlag<"wd4996">, Alias, - AliasArgs<["no-deprecated-declarations"]>; +def _SLASH_wd : CLCompileJoined<"wd">; def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, Alias; def _SLASH_X : CLFlag<"X">, Index: clang/lib/Basic/CLWarnings.cpp =================================================================== --- /dev/null +++ clang/lib/Basic/CLWarnings.cpp @@ -0,0 +1,24 @@ +//===--- CLWarnings.h - Maps some cl.exe warning ids -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the Diagnostic-related interfaces. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/CLWarnings.h" + +const char *clang::diagGroupFromCLWarningID(unsigned CLWarningID) { + switch (CLWarningID) { + case 4005: return "macro-redefined"; + case 4018: return "sign-compare"; + case 4100: return "unused-parameter"; + case 4910: return "dllexport-explicit-instantiation-decl"; + case 4996: return "deprecated-declarations"; + } + return nullptr; +} Index: clang/lib/Basic/CMakeLists.txt =================================================================== --- clang/lib/Basic/CMakeLists.txt +++ clang/lib/Basic/CMakeLists.txt @@ -39,6 +39,7 @@ add_clang_library(clangBasic Attributes.cpp Builtins.cpp + CLWarnings.cpp CharInfo.cpp CodeGenOptions.cpp Cuda.cpp Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -22,6 +22,7 @@ #include "Hexagon.h" #include "MSP430.h" #include "PS4CPU.h" +#include "clang/Basic/CLWarnings.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LangOptions.h" @@ -5443,7 +5444,24 @@ Args.AddAllArgs(CmdArgs, options::OPT_R_Group); - Args.AddAllArgs(CmdArgs, options::OPT_W_Group); + for (const Arg *A : + Args.filtered(options::OPT_W_Group, options::OPT__SLASH_wd)) { + A->claim(); + if (A->getOption().getID() == options::OPT__SLASH_wd) { + unsigned WarningNumber; + if (StringRef(A->getValue()).getAsInteger(10, WarningNumber)) { + D.Diag(diag::err_drv_invalid_int_value) + << A->getAsString(Args) << A->getValue(); + continue; + } + + if (const char *Group = diagGroupFromCLWarningID(WarningNumber)) + CmdArgs.push_back(Args.MakeArgString(Twine("-Wno-") + Group)); + continue; + } + A->render(Args, CmdArgs); + } + if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false)) CmdArgs.push_back("-pedantic"); Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors); Index: clang/lib/Lex/Pragma.cpp =================================================================== --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/Pragma.h" +#include "clang/Basic/CLWarnings.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/FileManager.h" @@ -1413,12 +1414,15 @@ return; } } + PP.getDiagnostics().pushMappings(DiagLoc); if (Callbacks) Callbacks->PragmaWarningPush(DiagLoc, Level); } else if (II && II->isStr("pop")) { // #pragma warning( pop ) PP.Lex(Tok); - if (Callbacks) + if (!PP.getDiagnostics().popMappings(DiagLoc)) + PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop); + else if (Callbacks) Callbacks->PragmaWarningPop(DiagLoc); } else { // #pragma warning( warning-specifier : warning-number-list @@ -1482,6 +1486,21 @@ } Ids.push_back(int(Value)); } + + // Only act on disable for now. + diag::Severity SV = diag::Severity(); + if (Specifier == PPCallbacks::PWS_Disable) + SV = diag::Severity::Ignored; + if (SV != diag::Severity()) + for (int Id : Ids) + if (const char *Group = diagGroupFromCLWarningID(Id)) { + bool unknownDiag = PP.getDiagnostics().setSeverityForGroup( + diag::Flavor::WarningOrError, Group, SV, DiagLoc); + assert(!unknownDiag && + "wd table should only contain known diags"); + (void)unknownDiag; + } + if (Callbacks) Callbacks->PragmaWarning(DiagLoc, Specifier, Ids); Index: clang/test/Driver/cl-options.c =================================================================== --- clang/test/Driver/cl-options.c +++ clang/test/Driver/cl-options.c @@ -353,7 +353,7 @@ // CHECK-C11: -std=c11 // For some warning ids, we can map from MSVC warning to Clang warning. -// RUN: %clang_cl -wd4005 -wd4100 -wd4910 -wd4996 -### -- %s 2>&1 | FileCheck -check-prefix=Wno %s +// RUN: %clang_cl -wd4005 -wd4100 -wd4910 -wd4996 -wd12345678 -### -- %s 2>&1 | FileCheck -check-prefix=Wno %s // Wno: "-cc1" // Wno: "-Wno-macro-redefined" // Wno: "-Wno-unused-parameter" Index: clang/test/Sema/pragma-warning.cpp =================================================================== --- /dev/null +++ clang/test/Sema/pragma-warning.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fms-extensions -fsyntax-only -verify %s + +[[deprecated]] void f() {} // expected-note 2 {{marked deprecated here}} + +#define From__pragma() \ + __pragma(warning(push)) \ + __pragma(warning(disable:4996)) \ + f(); \ + __pragma(warning(pop)) + +void g() { + f(); // expected-warning {{deprecated}} + +#pragma warning(push) +#pragma warning(disable: 4996) + f(); // no diag + +#pragma warning(disable: 49960000) +#pragma warning(pop) + + f(); // expected-warning {{deprecated}} + + From__pragma(); // no diag +} Index: llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -55,6 +55,7 @@ sources = [ "Attributes.cpp", "Builtins.cpp", + "CLWarnings.cpp", "CharInfo.cpp", "CodeGenOptions.cpp", "Cuda.cpp",