Reland "[clang-cl] Accept `#pragma warning(disable : N)` for some N"
This reverts commit 0cd9d8a48b
and
adds the changes described in https://reviews.llvm.org/D110668#3034461.
This commit is contained in:
parent
b989211d7d
commit
e31899c708
|
@ -0,0 +1,26 @@
|
|||
//===--- 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
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace diag {
|
||||
enum class Group;
|
||||
}
|
||||
|
||||
/// For cl.exe warning IDs that cleany map to clang diagnostic groups,
|
||||
/// returns the corresponding group. Else, returns an empty Optional.
|
||||
llvm::Optional<diag::Group> diagGroupFromCLWarningID(unsigned);
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_CLWARNINGS_H
|
|
@ -807,6 +807,9 @@ public:
|
|||
bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
|
||||
diag::Severity Map,
|
||||
SourceLocation Loc = SourceLocation());
|
||||
bool setSeverityForGroup(diag::Flavor Flavor, diag::Group Group,
|
||||
diag::Severity Map,
|
||||
SourceLocation Loc = SourceLocation());
|
||||
|
||||
/// Set the warning-as-error flag for the given diagnostic group.
|
||||
///
|
||||
|
|
|
@ -19,6 +19,13 @@ namespace clang {
|
|||
#undef GET_CATEGORY_TABLE
|
||||
DiagCat_NUM_CATEGORIES
|
||||
};
|
||||
|
||||
enum class Group {
|
||||
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups) GroupName,
|
||||
#include "clang/Basic/DiagnosticGroups.inc"
|
||||
#undef CATEGORY
|
||||
#undef DIAG_ENTRY
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
|
|
|
@ -396,6 +396,7 @@ def Dangling : DiagGroup<"dangling", [DanglingField,
|
|||
DanglingGsl,
|
||||
ReturnStackAddress]>;
|
||||
def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
|
||||
def DllexportExplicitInstantiationDecl : DiagGroup<"dllexport-explicit-instantiation-decl">;
|
||||
def ExcessInitializers : DiagGroup<"excess-initializers">;
|
||||
def ExpansionToDefined : DiagGroup<"expansion-to-defined">;
|
||||
def FlagEnum : DiagGroup<"flag-enum">;
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace clang {
|
|||
|
||||
// Import the diagnostic enums themselves.
|
||||
namespace diag {
|
||||
enum class Group;
|
||||
|
||||
// Size of each of the diagnostic categories.
|
||||
enum {
|
||||
DIAG_SIZE_COMMON = 300,
|
||||
|
@ -224,6 +226,10 @@ public:
|
|||
///
|
||||
static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
|
||||
|
||||
/// Given a group ID, returns the flag that toggles the group.
|
||||
/// For example, for Group::DeprecatedDeclarations, returns
|
||||
/// "deprecated-declarations".
|
||||
static StringRef getWarningOptionForGroup(diag::Group);
|
||||
|
||||
/// Return the lowest-level warning option that enables the specified
|
||||
/// diagnostic.
|
||||
|
|
|
@ -3396,7 +3396,7 @@ def warn_attribute_dllimport_static_field_definition : Warning<
|
|||
InGroup<DiagGroup<"dllimport-static-field-def">>;
|
||||
def warn_attribute_dllexport_explicit_instantiation_decl : Warning<
|
||||
"explicit instantiation declaration should not be 'dllexport'">,
|
||||
InGroup<DiagGroup<"dllexport-explicit-instantiation-decl">>;
|
||||
InGroup<DllexportExplicitInstantiationDecl>;
|
||||
def warn_attribute_dllexport_explicit_instantiation_def : Warning<
|
||||
"'dllexport' attribute ignored on explicit instantiation definition">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
|
|
|
@ -6106,16 +6106,7 @@ def _SLASH_WX_ : CLFlag<"WX-">,
|
|||
HelpText<"Do not treat warnings as errors (default)">,
|
||||
Alias<W_Joined>, AliasArgs<["no-error"]>;
|
||||
def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>;
|
||||
def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
|
||||
AliasArgs<["no-macro-redefined"]>;
|
||||
def _SLASH_wd4018 : CLFlag<"wd4018">, Alias<W_Joined>,
|
||||
AliasArgs<["no-sign-compare"]>;
|
||||
def _SLASH_wd4100 : CLFlag<"wd4100">, Alias<W_Joined>,
|
||||
AliasArgs<["no-unused-parameter"]>;
|
||||
def _SLASH_wd4910 : CLFlag<"wd4910">, Alias<W_Joined>,
|
||||
AliasArgs<["no-dllexport-explicit-instantiation-decl"]>;
|
||||
def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>,
|
||||
AliasArgs<["no-deprecated-declarations"]>;
|
||||
def _SLASH_wd : CLCompileJoined<"wd">;
|
||||
def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
|
||||
Alias<vtordisp_mode_EQ>;
|
||||
def _SLASH_X : CLFlag<"X">,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//===--- 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"
|
||||
#include "clang/Basic/DiagnosticCategories.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
llvm::Optional<diag::Group>
|
||||
clang::diagGroupFromCLWarningID(unsigned CLWarningID) {
|
||||
switch (CLWarningID) {
|
||||
case 4005: return diag::Group::MacroRedefined;
|
||||
case 4018: return diag::Group::SignCompare;
|
||||
case 4100: return diag::Group::UnusedParameter;
|
||||
case 4910: return diag::Group::DllexportExplicitInstantiationDecl;
|
||||
case 4996: return diag::Group::DeprecatedDeclarations;
|
||||
}
|
||||
return {};
|
||||
}
|
|
@ -39,6 +39,7 @@ endif()
|
|||
add_clang_library(clangBasic
|
||||
Attributes.cpp
|
||||
Builtins.cpp
|
||||
CLWarnings.cpp
|
||||
CharInfo.cpp
|
||||
CodeGenOptions.cpp
|
||||
Cuda.cpp
|
||||
|
|
|
@ -408,6 +408,14 @@ bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
|
||||
diag::Group Group,
|
||||
diag::Severity Map,
|
||||
SourceLocation Loc) {
|
||||
return setSeverityForGroup(Flavor, Diags->getWarningOptionForGroup(Group),
|
||||
Map, Loc);
|
||||
}
|
||||
|
||||
bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
|
||||
bool Enabled) {
|
||||
// If we are enabling this feature, just set the diagnostic mappings to map to
|
||||
|
|
|
@ -609,17 +609,23 @@ namespace {
|
|||
|
||||
// Second the table of options, sorted by name for fast binary lookup.
|
||||
static const WarningOption OptionTable[] = {
|
||||
#define GET_DIAG_TABLE
|
||||
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups) \
|
||||
{FlagNameOffset, Members, SubGroups},
|
||||
#include "clang/Basic/DiagnosticGroups.inc"
|
||||
#undef GET_DIAG_TABLE
|
||||
#undef DIAG_ENTRY
|
||||
};
|
||||
|
||||
StringRef DiagnosticIDs::getWarningOptionForGroup(diag::Group Group) {
|
||||
return OptionTable[static_cast<int>(Group)].getName();
|
||||
}
|
||||
|
||||
/// getWarningOptionForDiag - Return the lowest-level warning option that
|
||||
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
|
||||
/// the diagnostic, this returns null.
|
||||
StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
|
||||
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
|
||||
return OptionTable[Info->getOptionGroupIndex()].getName();
|
||||
return getWarningOptionForGroup(
|
||||
static_cast<diag::Group>(Info->getOptionGroupIndex()));
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -5438,7 +5439,26 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
|
||||
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 (auto Group = diagGroupFromCLWarningID(WarningNumber)) {
|
||||
CmdArgs.push_back(Args.MakeArgString(
|
||||
"-Wno-" + DiagnosticIDs::getWarningOptionForGroup(*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);
|
||||
|
|
|
@ -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 @@ struct PragmaWarningHandler : public PragmaHandler {
|
|||
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,22 @@ struct PragmaWarningHandler : public PragmaHandler {
|
|||
}
|
||||
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 (auto 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);
|
||||
|
||||
|
|
|
@ -353,12 +353,13 @@
|
|||
// 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"
|
||||
// Wno: "-Wno-dllexport-explicit-instantiation-decl"
|
||||
// Wno: "-Wno-deprecated-declarations"
|
||||
// Wno-NOT: "-wd
|
||||
|
||||
// Ignored options. Check that we don't get "unused during compilation" errors.
|
||||
// RUN: %clang_cl /c \
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -66,9 +66,10 @@ const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) {
|
|||
|
||||
// Second the table of options, sorted by name for fast binary lookup.
|
||||
static const GroupRecord OptionTable[] = {
|
||||
#define GET_DIAG_TABLE
|
||||
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups) \
|
||||
{FlagNameOffset, Members, SubGroups},
|
||||
#include "clang/Basic/DiagnosticGroups.inc"
|
||||
#undef GET_DIAG_TABLE
|
||||
#undef DIAG_ENTRY
|
||||
};
|
||||
|
||||
llvm::StringRef GroupRecord::getName() const {
|
||||
|
|
|
@ -129,6 +129,7 @@ namespace {
|
|||
};
|
||||
|
||||
struct GroupInfo {
|
||||
llvm::StringRef GroupName;
|
||||
std::vector<const Record*> DiagsInGroup;
|
||||
std::vector<std::string> SubGroups;
|
||||
unsigned IDNo;
|
||||
|
@ -174,6 +175,7 @@ static void groupDiagnostics(const std::vector<Record*> &Diags,
|
|||
Record *Group = DiagGroups[i];
|
||||
GroupInfo &GI =
|
||||
DiagsInGroup[std::string(Group->getValueAsString("GroupName"))];
|
||||
GI.GroupName = Group->getName();
|
||||
GI.Defs.push_back(Group);
|
||||
|
||||
std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups");
|
||||
|
@ -1279,8 +1281,8 @@ void clang::EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS,
|
|||
OS << ", \"";
|
||||
OS.write_escaped(DiagTextBuilder.buildForDefinition(&R)) << '"';
|
||||
|
||||
// Warning associated with the diagnostic. This is stored as an index into
|
||||
// the alphabetically sorted warning table.
|
||||
// Warning group associated with the diagnostic. This is stored as an index
|
||||
// into the alphabetically sorted warning group table.
|
||||
if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
|
||||
std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.find(
|
||||
std::string(DI->getDef()->getValueAsString("GroupName")));
|
||||
|
@ -1487,18 +1489,20 @@ static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
|
|||
for (auto const &I: DiagsInGroup)
|
||||
MaxLen = std::max(MaxLen, (unsigned)I.first.size());
|
||||
|
||||
OS << "\n#ifdef GET_DIAG_TABLE\n";
|
||||
OS << "\n#ifdef DIAG_ENTRY\n";
|
||||
unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
|
||||
for (auto const &I: DiagsInGroup) {
|
||||
// Group option string.
|
||||
OS << " { /* ";
|
||||
OS << "DIAG_ENTRY(";
|
||||
OS << I.second.GroupName << " /* ";
|
||||
|
||||
if (I.first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789!@#$%^*-+=:?") !=
|
||||
std::string::npos)
|
||||
PrintFatalError("Invalid character in diagnostic group '" + I.first +
|
||||
"'");
|
||||
OS << I.first << " */ " << std::string(MaxLen - I.first.size(), ' ');
|
||||
OS << I.first << " */, ";
|
||||
// Store a pascal-style length byte at the beginning of the string.
|
||||
std::string Name = char(I.first.size()) + I.first;
|
||||
OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
|
||||
|
@ -1517,7 +1521,7 @@ static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
|
|||
DiagArrayIndex += DiagsInPedantic.size();
|
||||
DiagArrayIndex += V.size() + 1;
|
||||
} else {
|
||||
OS << "/* Empty */ 0, ";
|
||||
OS << "0, ";
|
||||
}
|
||||
|
||||
// Subgroups.
|
||||
|
@ -1530,12 +1534,12 @@ static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
|
|||
SubGroupIndex += GroupsInPedantic.size();
|
||||
SubGroupIndex += SubGroups.size() + 1;
|
||||
} else {
|
||||
OS << "/* Empty */ 0";
|
||||
OS << "0";
|
||||
}
|
||||
|
||||
OS << " },\n";
|
||||
OS << ")\n";
|
||||
}
|
||||
OS << "#endif // GET_DIAG_TABLE\n\n";
|
||||
OS << "#endif // DIAG_ENTRY\n\n";
|
||||
}
|
||||
|
||||
/// Emit the table of diagnostic categories.
|
||||
|
|
|
@ -55,6 +55,7 @@ static_library("Basic") {
|
|||
sources = [
|
||||
"Attributes.cpp",
|
||||
"Builtins.cpp",
|
||||
"CLWarnings.cpp",
|
||||
"CharInfo.cpp",
|
||||
"CodeGenOptions.cpp",
|
||||
"Cuda.cpp",
|
||||
|
|
Loading…
Reference in New Issue