Ted, excuse me, I have reverted it in r159886. I suspect -Wpedantic would not work as you expected.
I would be happier if you consider in the next commit, thank you; - Split PEDANTIC tests to other test. - Mark it as XFAIL: cygwin,mingw32 . They still use gcc-as driver. ...Takumi 2012/7/7 Ted Kremenek <[email protected]>: > Author: kremenek > Date: Fri Jul 6 18:07:31 2012 > New Revision: 159875 > > URL: http://llvm.org/viewvc/llvm-project?rev=159875&view=rev > Log: > Implement -Wpedantic and --no-pedantic to complement -Weverything. > > This patch introduces some magic in tablegen to create a "Pedantic" diagnostic > group which automagically includes all warnings that are extensions. This > allows a user to suppress specific warnings traditionally under -pedantic used > an ordinary warning flag. This also allows users to use #pragma to silence > specific -pedantic warnings, or promote them to errors, within blocks of text > (just like any other warning). > > -Wpedantic is NOT an alias for -pedantic. Instead, it provides another way > to (a) activate -pedantic warnings and (b) disable them. Where they differ > is that -pedantic changes the behavior of the preprocessor slightly, whereas > -Wpedantic does not (it just turns on the warnings). > > The magic in the tablegen diagnostic emitter has to do with computing the > minimal > set of diagnostic groups and diagnostics that should go into -Wpedantic, as > those > diagnostics that already members of groups that themselves are (transitively) > members > of -Wpedantic do not need to be included in the Pedantic group directly. I > went > back and forth on whether or not to magically generate this group, and the > invariant > was that we always wanted extension warnings to be included in -Wpedantic > "some how", > but the bookkeeping would be very onerous to manage by hand. > > -no-pedantic (and --no-pedantic) is included for completeness, and matches > many of the > same kind of flags the compiler already supports. It does what it says: > cancels out > -pedantic. One discrepancy is that if one specifies --no-pedantic and > -Weverything or > -Wpedantic the pedantic warnings are still enabled (essentially the -W flags > win). We > can debate the correct behavior here. > > Along the way, this patch nukes some code in TextDiagnosticPrinter.cpp and > CXStoredDiagnostic.cpp > that determine whether to include the "-pedantic" flag in the warning output. > This is > no longer needed, as all extensions now have a -W flag. > > This patch also significantly reduces the number of warnings not under flags > from 229 > to 158 (all extension warnings). That's a 31% reduction. > > 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/Driver/warning-options.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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jul 6 18:07:31 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Driver/Options.td (original) > +++ cfe/trunk/include/clang/Driver/Options.td Fri Jul 6 18:07:31 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/lib/Driver/Tools.cpp (original) > +++ cfe/trunk/lib/Driver/Tools.cpp Fri Jul 6 18:07:31 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original) > +++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Fri Jul 6 18:07:31 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; > > Modified: cfe/trunk/test/Driver/warning-options.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/warning-options.cpp?rev=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/test/Driver/warning-options.cpp (original) > +++ cfe/trunk/test/Driver/warning-options.cpp Fri Jul 6 18:07:31 2012 > @@ -8,3 +8,11 @@ > // CHECK: unknown warning option '-Wmonkey' > // CHECK: unknown warning option '-Wno-monkey' > // CHECK: unknown warning option '-Wno-unused-command-line-arguments'; did > you mean '-Wno-unused-command-line-argument'? > + > +// 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=PEDANTIC %s > +// PEDANTIC: -pedantic > + > > 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/test/Misc/show-diag-options.c (original) > +++ cfe/trunk/test/Misc/show-diag-options.c Fri Jul 6 18:07:31 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/test/Misc/warning-flags.c (original) > +++ cfe/trunk/test/Misc/warning-flags.c Fri Jul 6 18:07:31 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp (original) > +++ cfe/trunk/tools/libclang/CXStoredDiagnostic.cpp Fri Jul 6 18:07:31 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=159875&r1=159874&r2=159875&view=diff > ============================================================================== > --- cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) > +++ cfe/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Fri Jul 6 18:07:31 > 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,179 @@ > } > > > //===----------------------------------------------------------------------===// > +// 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 +365,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 +391,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 +447,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 +461,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 +477,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 +501,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 +532,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; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
