[cfe-commits] r159892 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Driver/Options.td lib/Driver/Tools.cpp lib/Frontend/TextDiagnosticPrinter.cpp test/Driver/warning-options_pedantic.cpp test/Misc/show-diag-options.c test/Misc/warning-flags.c tools/libclang/CXStoredDiagnostic.cpp utils/TableGen/ClangDiagnosticsEmitter.cpp
Ted Kremenek
kremenek at apple.com
Fri Jul 6 22:53:30 PDT 2012
Author: kremenek
Date: Sat Jul 7 00:53:30 2012
New Revision: 159892
URL: http://llvm.org/viewvc/llvm-project?rev=159892&view=rev
Log:
Re-apply r159875 with fixes.
- Split pedantic driver flag test into separate test file, and XFAIL on cygwin,mingw32
- Fix bug in tablegen logic where a missing '{' caused errors to be included in -Wpedantic.
Added:
cfe/trunk/test/Driver/warning-options_pedantic.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
cfe/trunk/test/Misc/show-diag-options.c
cfe/trunk/test/Misc/warning-flags.c
cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp
cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Sat Jul 7 00:53:30 2012
@@ -380,6 +380,9 @@
// DefaultIgnore in addition to putting it here.
def : DiagGroup<"all", [Most, Parentheses, Switch]>;
+// Warnings enabled by -pedantic. This is magically filled in by TableGen.
+def Pedantic : DiagGroup<"pedantic">;
+
// Aliases.
def : DiagGroup<"", [Extra]>; // -W = -Wextra
def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wendif-tokens
Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Sat Jul 7 00:53:30 2012
@@ -868,6 +868,7 @@
def no_cpp_precomp : Flag<"-no-cpp-precomp">, Group<clang_ignored_f_Group>;
def no_integrated_as : Flag<"-no-integrated-as">, Flags<[DriverOption]>;
def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
+def no_pedantic : Flag<"-no-pedantic">, Group<pedantic_Group>;
def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
def nobuiltininc : Flag<"-nobuiltininc">, Flags<[CC1Option]>,
HelpText<"Disable builtin #include directories">;
@@ -1070,6 +1071,7 @@
def _machine : Separate<"--machine">, Alias<m_Joined>;
def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>;
def _no_line_commands : Flag<"--no-line-commands">, Alias<P>;
+def _no_pedantic : Flag<"--no-pedantic">, Alias<no_pedantic>;
def _no_standard_includes : Flag<"--no-standard-includes">, Alias<nostdinc>;
def _no_standard_libraries : Flag<"--no-standard-libraries">, Alias<nostdlib>;
def _no_undefined : Flag<"--no-undefined">, Flags<[LinkerInput]>;
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Sat Jul 7 00:53:30 2012
@@ -2093,7 +2093,8 @@
}
Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
- Args.AddLastArg(CmdArgs, options::OPT_pedantic);
+ if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
+ CmdArgs.push_back("-pedantic");
Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
Args.AddLastArg(CmdArgs, options::OPT_w);
Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Sat Jul 7 00:53:30 2012
@@ -79,16 +79,6 @@
Started = true;
}
- // If the diagnostic is an extension diagnostic and not enabled by default
- // then it must have been turned on with -pedantic.
- bool EnabledByDefault;
- if (DiagnosticIDs::isBuiltinExtensionDiag(Info.getID(),
- EnabledByDefault) &&
- !EnabledByDefault) {
- OS << (Started ? "," : " [") << "-pedantic";
- Started = true;
- }
-
StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID());
if (!Opt.empty()) {
OS << (Started ? "," : " [") << "-W" << Opt;
Added: cfe/trunk/test/Driver/warning-options_pedantic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/warning-options_pedantic.cpp?rev=159892&view=auto
==============================================================================
--- cfe/trunk/test/Driver/warning-options_pedantic.cpp (added)
+++ cfe/trunk/test/Driver/warning-options_pedantic.cpp Sat Jul 7 00:53:30 2012
@@ -0,0 +1,7 @@
+// RUN: %clang -### -pedantic -no-pedantic %s 2>&1 | FileCheck -check-prefix=NO_PEDANTIC %s
+// RUN: %clang -### -pedantic -Wno-pedantic %s 2>&1 | FileCheck -check-prefix=PEDANTIC %s
+// NO_PEDANTIC-NOT: -pedantic
+// RUN: %clang -### -pedantic -pedantic -no-pedantic -pedantic %s 2>&1 | FileCheck -check-prefix=PEDANTIC %s
+// RUN: %clang -### -pedantic -pedantic -no-pedantic -Wpedantic %s 2>&1 | FileCheck -check-prefix=NO_PEDANTIC %s
+// PEDANTIC: -pedantic
+// XFAIL: cygwin,mingw32
Modified: cfe/trunk/test/Misc/show-diag-options.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/show-diag-options.c?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/test/Misc/show-diag-options.c (original)
+++ cfe/trunk/test/Misc/show-diag-options.c Sat Jul 7 00:53:30 2012
@@ -23,5 +23,5 @@
// OPTION_ERROR_CATEGORY: {{.*}}: error: {{[a-z ]+}} [-Werror,-Wparentheses,Semantic Issue]
// Leverage the fact that all these '//'s get warned about in C89 pedantic.
- // OPTION_PEDANTIC: {{.*}}: warning: {{[/a-z ]+}} [-pedantic,-Wcomment]
+ // OPTION_PEDANTIC: {{.*}}: warning: {{[/a-z ]+}} [-Wcomment]
}
Modified: cfe/trunk/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/test/Misc/warning-flags.c (original)
+++ cfe/trunk/test/Misc/warning-flags.c Sat Jul 7 00:53:30 2012
@@ -17,66 +17,7 @@
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (229):
-CHECK-NEXT: ext_anonymous_struct_union_qualified
-CHECK-NEXT: ext_binary_literal
-CHECK-NEXT: ext_cast_fn_obj
-CHECK-NEXT: ext_delete_void_ptr_operand
-CHECK-NEXT: ext_designated_init
-CHECK-NEXT: ext_duplicate_declspec
-CHECK-NEXT: ext_ellipsis_exception_spec
-CHECK-NEXT: ext_enum_friend
-CHECK-NEXT: ext_enum_value_not_int
-CHECK-NEXT: ext_enumerator_list_comma
-CHECK-NEXT: ext_expected_semi_decl_list
-CHECK-NEXT: ext_explicit_instantiation_without_qualified_id
-CHECK-NEXT: ext_explicit_specialization_storage_class
-CHECK-NEXT: ext_forward_ref_enum
-CHECK-NEXT: ext_freestanding_complex
-CHECK-NEXT: ext_hexconstant_invalid
-CHECK-NEXT: ext_ident_list_in_param
-CHECK-NEXT: ext_imaginary_constant
-CHECK-NEXT: ext_implicit_lib_function_decl
-CHECK-NEXT: ext_in_class_initializer_non_constant
-CHECK-NEXT: ext_integer_complement_complex
-CHECK-NEXT: ext_integer_complex
-CHECK-NEXT: ext_integer_increment_complex
-CHECK-NEXT: ext_invalid_sign_spec
-CHECK-NEXT: ext_missing_declspec
-CHECK-NEXT: ext_missing_whitespace_after_macro_name
-CHECK-NEXT: ext_new_paren_array_nonconst
-CHECK-NEXT: ext_nonstandard_escape
-CHECK-NEXT: ext_param_not_declared
-CHECK-NEXT: ext_plain_complex
-CHECK-NEXT: ext_pp_bad_vaargs_use
-CHECK-NEXT: ext_pp_comma_expr
-CHECK-NEXT: ext_pp_ident_directive
-CHECK-NEXT: ext_pp_include_next_directive
-CHECK-NEXT: ext_pp_line_too_big
-CHECK-NEXT: ext_pp_macro_redef
-CHECK-NEXT: ext_pp_warning_directive
-CHECK-NEXT: ext_return_has_void_expr
-CHECK-NEXT: ext_subscript_non_lvalue
-CHECK-NEXT: ext_template_arg_extra_parens
-CHECK-NEXT: ext_thread_before
-CHECK-NEXT: ext_typecheck_addrof_void
-CHECK-NEXT: ext_typecheck_cast_nonscalar
-CHECK-NEXT: ext_typecheck_cast_to_union
-CHECK-NEXT: ext_typecheck_comparison_of_distinct_pointers
-CHECK-NEXT: ext_typecheck_comparison_of_distinct_pointers_nonstandard
-CHECK-NEXT: ext_typecheck_comparison_of_fptr_to_void
-CHECK-NEXT: ext_typecheck_comparison_of_pointer_integer
-CHECK-NEXT: ext_typecheck_cond_incompatible_operands
-CHECK-NEXT: ext_typecheck_cond_incompatible_operands_nonstandard
-CHECK-NEXT: ext_typecheck_cond_one_void
-CHECK-NEXT: ext_typecheck_convert_pointer_void_func
-CHECK-NEXT: ext_typecheck_ordered_comparison_of_function_pointers
-CHECK-NEXT: ext_typecheck_ordered_comparison_of_pointer_and_zero
-CHECK-NEXT: ext_typecheck_ordered_comparison_of_pointer_integer
-CHECK-NEXT: ext_typecheck_zero_array_size
-CHECK-NEXT: ext_unknown_escape
-CHECK-NEXT: ext_using_undefined_std
-CHECK-NEXT: ext_vla_folded_to_constant
+CHECK: Warnings without flags (158):
CHECK-NEXT: pp_include_next_absolute_path
CHECK-NEXT: pp_include_next_in_primary
CHECK-NEXT: pp_invalid_string_literal
@@ -138,9 +79,6 @@
CHECK-NEXT: warn_enum_value_overflow
CHECK-NEXT: warn_enumerator_too_large
CHECK-NEXT: warn_exception_caught_by_earlier_handler
-CHECK-NEXT: warn_excess_initializers
-CHECK-NEXT: warn_excess_initializers_in_char_array_initializer
-CHECK-NEXT: warn_expected_qualified_after_typename
CHECK-NEXT: warn_extraneous_char_constant
CHECK-NEXT: warn_fe_cc_log_diagnostics_failure
CHECK-NEXT: warn_fe_cc_print_header_failure
@@ -149,23 +87,17 @@
CHECK-NEXT: warn_function_attribute_wrong_type
CHECK-NEXT: warn_gc_attribute_weak_on_local
CHECK-NEXT: warn_gnu_inline_attribute_requires_inline
-CHECK-NEXT: warn_hex_escape_too_large
CHECK-NEXT: warn_ignoring_ftabstop_value
-CHECK-NEXT: warn_illegal_constant_array_size
CHECK-NEXT: warn_implements_nscopying
CHECK-NEXT: warn_incompatible_qualified_id
-CHECK-NEXT: warn_initializer_string_for_char_array_too_long
CHECK-NEXT: warn_inline_namespace_reopened_noninline
CHECK-NEXT: warn_integer_too_large
CHECK-NEXT: warn_integer_too_large_for_signed
CHECK-NEXT: warn_invalid_asm_cast_lvalue
-CHECK-NEXT: warn_many_braces_around_scalar_init
CHECK-NEXT: warn_maynot_respond
CHECK-NEXT: warn_member_extra_qualification
CHECK-NEXT: warn_method_param_redefinition
-CHECK-NEXT: warn_mismatched_exception_spec
CHECK-NEXT: warn_missing_case_for_condition
-CHECK-NEXT: warn_missing_dependent_template_keyword
CHECK-NEXT: warn_missing_exception_specification
CHECK-NEXT: warn_missing_whitespace_after_macro_name
CHECK-NEXT: warn_multiple_method_decl
@@ -177,10 +109,8 @@
CHECK-NEXT: warn_objc_object_attribute_wrong_type
CHECK-NEXT: warn_objc_property_copy_missing_on_block
CHECK-NEXT: warn_objc_protocol_qualifier_missing_id
-CHECK-NEXT: warn_octal_escape_too_large
CHECK-NEXT: warn_odr_tag_type_inconsistent
CHECK-NEXT: warn_on_superclass_use
-CHECK-NEXT: warn_param_default_argument_redefinition
CHECK-NEXT: warn_partial_specs_not_deducible
CHECK-NEXT: warn_pointer_attribute_wrong_type
CHECK-NEXT: warn_pp_convert_lhs_to_positive
@@ -228,7 +158,6 @@
CHECK-NEXT: warn_second_parameter_to_va_arg_never_compatible
CHECK-NEXT: warn_standalone_specifier
CHECK-NEXT: warn_static_inline_explicit_inst_ignored
-CHECK-NEXT: warn_static_non_static
CHECK-NEXT: warn_template_export_unsupported
CHECK-NEXT: warn_template_spec_extra_headers
CHECK-NEXT: warn_tentative_incomplete_array
@@ -247,3 +176,4 @@
CHECK-NEXT: warn_use_out_of_scope_declaration
CHECK-NEXT: warn_weak_identifier_undeclared
CHECK-NEXT: warn_weak_import
+
Modified: cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp (original)
+++ cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp Sat Jul 7 00:53:30 2012
@@ -66,13 +66,8 @@
*Disable = createCXString("-ferror-limit=0");
return createCXString("-ferror-limit=");
}
-
- bool EnabledByDefault;
- if (DiagnosticIDs::isBuiltinExtensionDiag(ID, EnabledByDefault) &&
- !EnabledByDefault)
- return createCXString("-pedantic");
- return createCXString("");
+ return createCXString("");
}
unsigned CXStoredDiagnostic::getCategory() const {
Modified: cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=159892&r1=159891&r2=159892&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Sat Jul 7 00:53:30 2012
@@ -11,9 +11,11 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/TableGen/Record.h"
@@ -78,7 +80,7 @@
DiagGroupParents);
if (!CatName.empty()) return CatName;
}
-
+
// If the diagnostic itself has a category, get it.
return R->getValueAsString("CategoryName");
}
@@ -160,6 +162,180 @@
}
//===----------------------------------------------------------------------===//
+// Infer members of -Wpedantic.
+//===----------------------------------------------------------------------===//
+
+typedef std::vector<const Record *> RecordVec;
+typedef llvm::DenseSet<const Record *> RecordSet;
+typedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet;
+
+namespace {
+class InferPedantic {
+ typedef llvm::DenseMap<const Record*,
+ std::pair<unsigned, llvm::Optional<unsigned> > > GMap;
+
+ DiagGroupParentMap &DiagGroupParents;
+ const std::vector<Record*> &Diags;
+ const std::vector<Record*> DiagGroups;
+ std::map<std::string, GroupInfo> &DiagsInGroup;
+ llvm::DenseSet<const Record*> DiagsSet;
+ GMap GroupCount;
+public:
+ InferPedantic(DiagGroupParentMap &DiagGroupParents,
+ const std::vector<Record*> &Diags,
+ const std::vector<Record*> &DiagGroups,
+ std::map<std::string, GroupInfo> &DiagsInGroup)
+ : DiagGroupParents(DiagGroupParents),
+ Diags(Diags),
+ DiagGroups(DiagGroups),
+ DiagsInGroup(DiagsInGroup) {}
+
+ /// Compute the set of diagnostics and groups that are immediately
+ /// in -Wpedantic.
+ void compute(VecOrSet DiagsInPedantic,
+ VecOrSet GroupsInPedantic);
+
+private:
+ /// Determine whether a group is a subgroup of another group.
+ bool isSubGroupOfGroup(const Record *Group,
+ llvm::StringRef RootGroupName);
+
+ /// Determine if the diagnostic is an extension.
+ bool isExtension(const Record *Diag);
+
+ /// Increment the count for a group, and transitively marked
+ /// parent groups when appropriate.
+ void markGroup(const Record *Group);
+
+ /// Return true if the diagnostic is in a pedantic group.
+ bool groupInPedantic(const Record *Group, bool increment = false);
+};
+} // end anonymous namespace
+
+bool InferPedantic::isSubGroupOfGroup(const Record *Group,
+ llvm::StringRef GName) {
+
+ const std::string &GroupName = Group->getValueAsString("GroupName");
+ if (GName == GroupName)
+ return true;
+
+ const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
+ for (unsigned i = 0, e = Parents.size(); i != e; ++i)
+ if (isSubGroupOfGroup(Parents[i], GName))
+ return true;
+
+ return false;
+}
+
+/// Determine if the diagnostic is an extension.
+bool InferPedantic::isExtension(const Record *Diag) {
+ const std::string &ClsName = Diag->getValueAsDef("Class")->getName();
+ return ClsName == "CLASS_EXTENSION";
+}
+
+bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
+ GMap::mapped_type &V = GroupCount[Group];
+ // Lazily compute the threshold value for the group count.
+ if (!V.second.hasValue()) {
+ const GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
+ V.second = GI.SubGroups.size() + GI.DiagsInGroup.size();
+ }
+
+ if (increment)
+ ++V.first;
+
+ // Consider a group in -Wpendatic IFF if has at least one diagnostic
+ // or subgroup AND all of those diagnostics and subgroups are covered
+ // by -Wpedantic via our computation.
+ return V.first != 0 && V.first == V.second.getValue();
+}
+
+void InferPedantic::markGroup(const Record *Group) {
+ // If all the diagnostics and subgroups have been marked as being
+ // covered by -Wpedantic, increment the count of parent groups. Once the
+ // group's count is equal to the number of subgroups and diagnostics in
+ // that group, we can safely add this group to -Wpedantic.
+ if (groupInPedantic(Group, /* increment */ true)) {
+ const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
+ for (unsigned i = 0, e = Parents.size(); i != e; ++i)
+ markGroup(Parents[i]);
+ }
+}
+
+void InferPedantic::compute(VecOrSet DiagsInPedantic,
+ VecOrSet GroupsInPedantic) {
+ // All extensions are implicitly in the "pedantic" group. For those that
+ // aren't explicitly included in -Wpedantic, mark them for consideration
+ // to be included in -Wpedantic directly.
+ for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
+ Record *R = Diags[i];
+ if (isExtension(R)) {
+ DiagsSet.insert(R);
+ if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) {
+ const Record *GroupRec = Group->getDef();
+ if (!isSubGroupOfGroup(GroupRec, "pedantic")) {
+ markGroup(GroupRec);
+ }
+ }
+ }
+ }
+
+ // Compute the set of diagnostics that are directly in -Wpedantic. We
+ // march through Diags a second time to ensure the results are emitted
+ // in deterministic order.
+ for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
+ Record *R = Diags[i];
+ if (!DiagsSet.count(R))
+ continue;
+ // Check if the group is implicitly in -Wpedantic. If so,
+ // the diagnostic should not be directly included in the -Wpedantic
+ // diagnostic group.
+ if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group")))
+ if (groupInPedantic(Group->getDef()))
+ continue;
+
+ // The diagnostic is not included in a group that is (transitively) in
+ // -Wpedantic. Include it in -Wpedantic directly.
+ if (RecordVec *V = DiagsInPedantic.dyn_cast<RecordVec*>())
+ V->push_back(R);
+ else {
+ DiagsInPedantic.get<RecordSet*>()->insert(R);
+ }
+ }
+
+ if (!GroupsInPedantic)
+ return;
+
+ // Compute the set of groups that are directly in -Wpedantic. We
+ // march through the groups to ensure the results are emitted
+ /// in a deterministc order.
+ for (unsigned i = 0, ei = DiagGroups.size(); i != ei; ++i) {
+ Record *Group = DiagGroups[i];
+ if (!groupInPedantic(Group))
+ continue;
+
+ unsigned ParentsInPedantic = 0;
+ const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
+ for (unsigned j = 0, ej = Parents.size(); j != ej; ++j) {
+ if (groupInPedantic(Parents[j]))
+ ++ParentsInPedantic;
+ }
+ // If all the parents are in -Wpedantic, this means that this diagnostic
+ // group will be indirectly included by -Wpedantic already. In that
+ // case, do not add it directly to -Wpedantic. If the group has no
+ // parents, obviously it should go into -Wpedantic.
+ if (Parents.size() > 0 && ParentsInPedantic == Parents.size())
+ continue;
+
+ if (RecordVec *V = GroupsInPedantic.dyn_cast<RecordVec*>())
+ V->push_back(Group);
+ else {
+ GroupsInPedantic.get<RecordSet*>()->insert(Group);
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
// Warning Tables (.inc file) generation.
//===----------------------------------------------------------------------===//
@@ -190,6 +366,11 @@
DiagCategoryIDMap CategoryIDs(Records);
DiagGroupParentMap DGParentMap(Records);
+ // Compute the set of diagnostics that are in -Wpedantic.
+ RecordSet DiagsInPedantic;
+ InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
+ inferPedantic.compute(&DiagsInPedantic, (RecordVec*)0);
+
for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
const Record &R = *Diags[i];
// Filter by component.
@@ -211,6 +392,11 @@
DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName"));
assert(I != DiagsInGroup.end());
OS << ", " << I->second.IDNo;
+ } else if (DiagsInPedantic.count(&R)) {
+ std::map<std::string, GroupInfo>::iterator I =
+ DiagsInGroup.find("pedantic");
+ assert(I != DiagsInGroup.end() && "pedantic group not defined");
+ OS << ", " << I->second.IDNo;
} else {
OS << ", 0";
}
@@ -262,12 +448,12 @@
enumName += isalnum(*I) ? *I : '_';
return enumName.str();
}
-
+
namespace clang {
void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) {
// Compute a mapping from a DiagGroup to all of its parents.
DiagGroupParentMap DGParentMap(Records);
-
+
std::vector<Record*> Diags =
Records.getAllDerivedDefinitions("Diagnostic");
@@ -276,7 +462,15 @@
std::map<std::string, GroupInfo> DiagsInGroup;
groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
-
+
+ // All extensions are implicitly in the "pedantic" group. Record the
+ // implicit set of groups in the "pedantic" group, and use this information
+ // later when emitting the group information for Pedantic.
+ RecordVec DiagsInPedantic;
+ RecordVec GroupsInPedantic;
+ InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
+ inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic);
+
// Walk through the groups emitting an array for each diagnostic of the diags
// that are mapped to.
OS << "\n#ifdef GET_DIAG_ARRAYS\n";
@@ -284,17 +478,23 @@
for (std::map<std::string, GroupInfo>::iterator
I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
MaxLen = std::max(MaxLen, (unsigned)I->first.size());
-
+ const bool IsPedantic = I->first == "pedantic";
+
std::vector<const Record*> &V = I->second.DiagsInGroup;
- if (!V.empty()) {
+ if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
OS << "static const short DiagArray" << I->second.IDNo << "[] = { ";
for (unsigned i = 0, e = V.size(); i != e; ++i)
OS << "diag::" << V[i]->getName() << ", ";
+ // Emit the diagnostics implicitly in "pedantic".
+ if (IsPedantic) {
+ for (unsigned i = 0, e = DiagsInPedantic.size(); i != e; ++i)
+ OS << "diag::" << DiagsInPedantic[i]->getName() << ", ";
+ }
OS << "-1 };\n";
}
const std::vector<std::string> &SubGroups = I->second.SubGroups;
- if (!SubGroups.empty()) {
+ if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { ";
for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) {
std::map<std::string, GroupInfo>::iterator RI =
@@ -302,6 +502,18 @@
assert(RI != DiagsInGroup.end() && "Referenced without existing?");
OS << RI->second.IDNo << ", ";
}
+ // Emit the groups implicitly in "pedantic".
+ if (IsPedantic) {
+ for (unsigned i = 0, e = GroupsInPedantic.size(); i != e; ++i) {
+ const std::string &GroupName =
+ GroupsInPedantic[i]->getValueAsString("GroupName");
+ std::map<std::string, GroupInfo>::iterator RI =
+ DiagsInGroup.find(GroupName);
+ assert(RI != DiagsInGroup.end() && "Referenced without existing?");
+ OS << RI->second.IDNo << ", ";
+ }
+ }
+
OS << "-1 };\n";
}
}
@@ -321,15 +533,22 @@
throw "Invalid character in diagnostic group '" + I->first + "'";
OS.write_escaped(I->first) << "\","
<< std::string(MaxLen-I->first.size()+1, ' ');
-
+
+ // Special handling for 'pedantic'.
+ const bool IsPedantic = I->first == "pedantic";
+
// Diagnostics in the group.
- if (I->second.DiagsInGroup.empty())
+ const bool hasDiags = !I->second.DiagsInGroup.empty() ||
+ (IsPedantic && !DiagsInPedantic.empty());
+ if (!hasDiags)
OS << "0, ";
else
OS << "DiagArray" << I->second.IDNo << ", ";
// Subgroups.
- if (I->second.SubGroups.empty())
+ const bool hasSubGroups = !I->second.SubGroups.empty() ||
+ (IsPedantic && !GroupsInPedantic.empty());
+ if (!hasSubGroups)
OS << 0;
else
OS << "DiagSubGroup" << I->second.IDNo;
More information about the cfe-commits
mailing list