r333653 - Add a new driver mode to dump compiler feature and extension options.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu May 31 06:57:09 PDT 2018


Author: aaronballman
Date: Thu May 31 06:57:09 2018
New Revision: 333653

URL: http://llvm.org/viewvc/llvm-project?rev=333653&view=rev
Log:
Add a new driver mode to dump compiler feature and extension options.

Add the ability to dump compiler option-related information to a JSON file via the -compiler-options-dump option. Specifically, it dumps the features/extensions lists -- however, this output could be extended to other information should it be useful. In order to support features and extensions, I moved them into a .def file so that we could build the various lists we care about from them without a significant increase in maintenance burden.

Added:
    cfe/trunk/include/clang/Basic/Features.def
    cfe/trunk/test/Frontend/compiler-options-dump.cpp
Modified:
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Frontend/FrontendActions.h
    cfe/trunk/include/clang/Frontend/FrontendOptions.h
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp

Added: cfe/trunk/include/clang/Basic/Features.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Features.def?rev=333653&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/Features.def (added)
+++ cfe/trunk/include/clang/Basic/Features.def Thu May 31 06:57:09 2018
@@ -0,0 +1,238 @@
+//===--- Features.def - Features and Extensions database --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines features exposed via __has_feature and extensions exposed
+// via __has_extension. Users of this file must either define the FEATURE or
+// EXTENSION macros (or both) to make use of this information. Note that these
+// macros expect the following declarations to be available for the Predicate:
+//
+//   const LangOptions &LangOpts;
+//   const Preprocessor &PP;
+//
+// The Predicate field dictates the conditions under which the feature or
+// extension will be made available.
+//===----------------------------------------------------------------------===//
+
+#if !defined(FEATURE) && !defined(EXTENSION)
+#  error Define either the FEATURE or EXTENSION macro to handle features
+#endif
+
+#ifndef FEATURE
+#define FEATURE(Name, Predicate)
+#endif
+
+#ifndef EXTENSION
+#define EXTENSION(Name, Predicate)
+#endif
+
+FEATURE(address_sanitizer,
+        LangOpts.Sanitize.hasOneOf(SanitizerKind::Address |
+                                   SanitizerKind::KernelAddress))
+FEATURE(hwaddress_sanitizer,
+        LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
+                                   SanitizerKind::KernelHWAddress))
+FEATURE(assume_nonnull, true)
+FEATURE(attribute_analyzer_noreturn, true)
+FEATURE(attribute_availability, true)
+FEATURE(attribute_availability_with_message, true)
+FEATURE(attribute_availability_app_extension, true)
+FEATURE(attribute_availability_with_version_underscores, true)
+FEATURE(attribute_availability_tvos, true)
+FEATURE(attribute_availability_watchos, true)
+FEATURE(attribute_availability_with_strict, true)
+FEATURE(attribute_availability_with_replacement, true)
+FEATURE(attribute_availability_in_templates, true)
+FEATURE(attribute_cf_returns_not_retained, true)
+FEATURE(attribute_cf_returns_retained, true)
+FEATURE(attribute_cf_returns_on_parameters, true)
+FEATURE(attribute_deprecated_with_message, true)
+FEATURE(attribute_deprecated_with_replacement, true)
+FEATURE(attribute_ext_vector_type, true)
+FEATURE(attribute_ns_returns_not_retained, true)
+FEATURE(attribute_ns_returns_retained, true)
+FEATURE(attribute_ns_consumes_self, true)
+FEATURE(attribute_ns_consumed, true)
+FEATURE(attribute_cf_consumed, true)
+FEATURE(attribute_objc_ivar_unused, true)
+FEATURE(attribute_objc_method_family, true)
+FEATURE(attribute_overloadable, true)
+FEATURE(attribute_unavailable_with_message, true)
+FEATURE(attribute_unused_on_fields, true)
+FEATURE(attribute_diagnose_if_objc, true)
+FEATURE(blocks, LangOpts.Blocks)
+FEATURE(c_thread_safety_attributes, true)
+FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
+FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
+FEATURE(enumerator_attributes, true)
+FEATURE(nullability, true)
+FEATURE(nullability_on_arrays, true)
+FEATURE(memory_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Memory))
+FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
+FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
+FEATURE(efficiency_sanitizer,
+        LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
+FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
+// Objective-C features
+FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
+FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
+FEATURE(objc_arc_fields, true)
+FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
+FEATURE(objc_default_synthesize_properties, LangOpts.ObjC2)
+FEATURE(objc_fixed_enum, LangOpts.ObjC2)
+FEATURE(objc_instancetype, LangOpts.ObjC2)
+FEATURE(objc_kindof, LangOpts.ObjC2)
+FEATURE(objc_modules, LangOpts.ObjC2 &&LangOpts.Modules)
+FEATURE(objc_nonfragile_abi, LangOpts.ObjCRuntime.isNonFragile())
+FEATURE(objc_property_explicit_atomic, true)
+FEATURE(objc_protocol_qualifier_mangling, true)
+FEATURE(objc_weak_class, LangOpts.ObjCRuntime.hasWeakClassImport())
+FEATURE(ownership_holds, true)
+FEATURE(ownership_returns, true)
+FEATURE(ownership_takes, true)
+FEATURE(objc_bool, true)
+FEATURE(objc_subscripting, LangOpts.ObjCRuntime.isNonFragile())
+FEATURE(objc_array_literals, LangOpts.ObjC2)
+FEATURE(objc_dictionary_literals, LangOpts.ObjC2)
+FEATURE(objc_boxed_expressions, LangOpts.ObjC2)
+FEATURE(objc_boxed_nsvalue_expressions, LangOpts.ObjC2)
+FEATURE(arc_cf_code_audited, true)
+FEATURE(objc_bridge_id, true)
+FEATURE(objc_bridge_id_on_typedefs, true)
+FEATURE(objc_generics, LangOpts.ObjC2)
+FEATURE(objc_generics_variance, LangOpts.ObjC2)
+FEATURE(objc_class_property, LangOpts.ObjC2)
+// C11 features
+FEATURE(c_alignas, LangOpts.C11)
+FEATURE(c_alignof, LangOpts.C11)
+FEATURE(c_atomic, LangOpts.C11)
+FEATURE(c_generic_selections, LangOpts.C11)
+FEATURE(c_static_assert, LangOpts.C11)
+FEATURE(c_thread_local, LangOpts.C11 &&PP.getTargetInfo().isTLSSupported())
+// C++11 features
+FEATURE(cxx_access_control_sfinae, LangOpts.CPlusPlus11)
+FEATURE(cxx_alias_templates, LangOpts.CPlusPlus11)
+FEATURE(cxx_alignas, LangOpts.CPlusPlus11)
+FEATURE(cxx_alignof, LangOpts.CPlusPlus11)
+FEATURE(cxx_atomic, LangOpts.CPlusPlus11)
+FEATURE(cxx_attributes, LangOpts.CPlusPlus11)
+FEATURE(cxx_auto_type, LangOpts.CPlusPlus11)
+FEATURE(cxx_constexpr, LangOpts.CPlusPlus11)
+FEATURE(cxx_constexpr_string_builtins, LangOpts.CPlusPlus11)
+FEATURE(cxx_decltype, LangOpts.CPlusPlus11)
+FEATURE(cxx_decltype_incomplete_return_types, LangOpts.CPlusPlus11)
+FEATURE(cxx_default_function_template_args, LangOpts.CPlusPlus11)
+FEATURE(cxx_defaulted_functions, LangOpts.CPlusPlus11)
+FEATURE(cxx_delegating_constructors, LangOpts.CPlusPlus11)
+FEATURE(cxx_deleted_functions, LangOpts.CPlusPlus11)
+FEATURE(cxx_explicit_conversions, LangOpts.CPlusPlus11)
+FEATURE(cxx_generalized_initializers, LangOpts.CPlusPlus11)
+FEATURE(cxx_implicit_moves, LangOpts.CPlusPlus11)
+FEATURE(cxx_inheriting_constructors, LangOpts.CPlusPlus11)
+FEATURE(cxx_inline_namespaces, LangOpts.CPlusPlus11)
+FEATURE(cxx_lambdas, LangOpts.CPlusPlus11)
+FEATURE(cxx_local_type_template_args, LangOpts.CPlusPlus11)
+FEATURE(cxx_nonstatic_member_init, LangOpts.CPlusPlus11)
+FEATURE(cxx_noexcept, LangOpts.CPlusPlus11)
+FEATURE(cxx_nullptr, LangOpts.CPlusPlus11)
+FEATURE(cxx_override_control, LangOpts.CPlusPlus11)
+FEATURE(cxx_range_for, LangOpts.CPlusPlus11)
+FEATURE(cxx_raw_string_literals, LangOpts.CPlusPlus11)
+FEATURE(cxx_reference_qualified_functions, LangOpts.CPlusPlus11)
+FEATURE(cxx_rvalue_references, LangOpts.CPlusPlus11)
+FEATURE(cxx_strong_enums, LangOpts.CPlusPlus11)
+FEATURE(cxx_static_assert, LangOpts.CPlusPlus11)
+FEATURE(cxx_thread_local,
+        LangOpts.CPlusPlus11 &&PP.getTargetInfo().isTLSSupported())
+FEATURE(cxx_trailing_return, LangOpts.CPlusPlus11)
+FEATURE(cxx_unicode_literals, LangOpts.CPlusPlus11)
+FEATURE(cxx_unrestricted_unions, LangOpts.CPlusPlus11)
+FEATURE(cxx_user_literals, LangOpts.CPlusPlus11)
+FEATURE(cxx_variadic_templates, LangOpts.CPlusPlus11)
+// C++14 features
+FEATURE(cxx_aggregate_nsdmi, LangOpts.CPlusPlus14)
+FEATURE(cxx_binary_literals, LangOpts.CPlusPlus14)
+FEATURE(cxx_contextual_conversions, LangOpts.CPlusPlus14)
+FEATURE(cxx_decltype_auto, LangOpts.CPlusPlus14)
+FEATURE(cxx_generic_lambdas, LangOpts.CPlusPlus14)
+FEATURE(cxx_init_captures, LangOpts.CPlusPlus14)
+FEATURE(cxx_relaxed_constexpr, LangOpts.CPlusPlus14)
+FEATURE(cxx_return_type_deduction, LangOpts.CPlusPlus14)
+FEATURE(cxx_variable_templates, LangOpts.CPlusPlus14)
+// NOTE: For features covered by SD-6, it is preferable to provide *only*
+// the SD-6 macro and not a __has_feature check.
+
+// C++ TSes
+// FEATURE(cxx_runtime_arrays, LangOpts.CPlusPlusTSArrays)
+// FEATURE(cxx_concepts, LangOpts.CPlusPlusTSConcepts)
+// FIXME: Should this be __has_feature or __has_extension?
+// FEATURE(raw_invocation_type, LangOpts.CPlusPlus)
+// Type traits
+// N.B. Additional type traits should not be added to the following list.
+// Instead, they should be detected by has_extension.
+FEATURE(has_nothrow_assign, LangOpts.CPlusPlus)
+FEATURE(has_nothrow_copy, LangOpts.CPlusPlus)
+FEATURE(has_nothrow_constructor, LangOpts.CPlusPlus)
+FEATURE(has_trivial_assign, LangOpts.CPlusPlus)
+FEATURE(has_trivial_copy, LangOpts.CPlusPlus)
+FEATURE(has_trivial_constructor, LangOpts.CPlusPlus)
+FEATURE(has_trivial_destructor, LangOpts.CPlusPlus)
+FEATURE(has_virtual_destructor, LangOpts.CPlusPlus)
+FEATURE(is_abstract, LangOpts.CPlusPlus)
+FEATURE(is_base_of, LangOpts.CPlusPlus)
+FEATURE(is_class, LangOpts.CPlusPlus)
+FEATURE(is_constructible, LangOpts.CPlusPlus)
+FEATURE(is_convertible_to, LangOpts.CPlusPlus)
+FEATURE(is_empty, LangOpts.CPlusPlus)
+FEATURE(is_enum, LangOpts.CPlusPlus)
+FEATURE(is_final, LangOpts.CPlusPlus)
+FEATURE(is_literal, LangOpts.CPlusPlus)
+FEATURE(is_standard_layout, LangOpts.CPlusPlus)
+FEATURE(is_pod, LangOpts.CPlusPlus)
+FEATURE(is_polymorphic, LangOpts.CPlusPlus)
+FEATURE(is_sealed, LangOpts.CPlusPlus &&LangOpts.MicrosoftExt)
+FEATURE(is_trivial, LangOpts.CPlusPlus)
+FEATURE(is_trivially_assignable, LangOpts.CPlusPlus)
+FEATURE(is_trivially_constructible, LangOpts.CPlusPlus)
+FEATURE(is_trivially_copyable, LangOpts.CPlusPlus)
+FEATURE(is_union, LangOpts.CPlusPlus)
+FEATURE(modules, LangOpts.Modules)
+FEATURE(safe_stack, LangOpts.Sanitize.has(SanitizerKind::SafeStack))
+FEATURE(shadow_call_stack,
+        LangOpts.Sanitize.has(SanitizerKind::ShadowCallStack))
+FEATURE(tls, PP.getTargetInfo().isTLSSupported())
+FEATURE(underlying_type, LangOpts.CPlusPlus)
+
+// C11 features supported by other languages as extensions.
+EXTENSION(c_alignas, true)
+EXTENSION(c_alignof, true)
+EXTENSION(c_atomic, true)
+EXTENSION(c_generic_selections, true)
+EXTENSION(c_static_assert, true)
+EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported())
+// C++11 features supported by other languages as extensions.
+EXTENSION(cxx_atomic, LangOpts.CPlusPlus)
+EXTENSION(cxx_deleted_functions, LangOpts.CPlusPlus)
+EXTENSION(cxx_explicit_conversions, LangOpts.CPlusPlus)
+EXTENSION(cxx_inline_namespaces, LangOpts.CPlusPlus)
+EXTENSION(cxx_local_type_template_args, LangOpts.CPlusPlus)
+EXTENSION(cxx_nonstatic_member_init, LangOpts.CPlusPlus)
+EXTENSION(cxx_override_control, LangOpts.CPlusPlus)
+EXTENSION(cxx_range_for, LangOpts.CPlusPlus)
+EXTENSION(cxx_reference_qualified_functions, LangOpts.CPlusPlus)
+EXTENSION(cxx_rvalue_references, LangOpts.CPlusPlus)
+EXTENSION(cxx_variadic_templates, LangOpts.CPlusPlus)
+// C++14 features supported by other languages as extensions.
+EXTENSION(cxx_binary_literals, true)
+EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
+EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
+// Miscellaneous language extensions
+EXTENSION(overloadable_unmarked, true)
+
+#undef EXTENSION
+#undef FEATURE

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Thu May 31 06:57:09 2018
@@ -563,6 +563,8 @@ def rewrite_macros : Flag<["-"], "rewrit
   HelpText<"Expand macros without full preprocessing">;
 def migrate : Flag<["-"], "migrate">,
   HelpText<"Migrate source code">;
+def compiler_options_dump : Flag<["-"], "compiler-options-dump">,
+  HelpText<"Dump the compiler configuration options">;
 }
 
 def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">,

Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendActions.h Thu May 31 06:57:09 2018
@@ -35,6 +35,18 @@ public:
   bool usesPreprocessorOnly() const override { return false; }
 };
 
+class DumpCompilerOptionsAction : public FrontendAction {
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override {
+    return nullptr;
+  }
+
+  void ExecuteAction() override;
+
+public:
+  bool usesPreprocessorOnly() const override { return true; }
+};
+
 //===----------------------------------------------------------------------===//
 // AST Consumer Actions
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Thu May 31 06:57:09 2018
@@ -43,6 +43,9 @@ enum ActionKind {
   /// Parse ASTs and view them in Graphviz.
   ASTView,
 
+  /// Dump the compiler configuration.
+  DumpCompilerOptions,
+
   /// Dump out raw tokens.
   DumpRawTokens,
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu May 31 06:57:09 2018
@@ -1396,6 +1396,8 @@ static InputKind ParseFrontendArgs(Front
       Opts.ProgramAction = frontend::ASTPrint; break;
     case OPT_ast_view:
       Opts.ProgramAction = frontend::ASTView; break;
+    case OPT_compiler_options_dump:
+      Opts.ProgramAction = frontend::DumpCompilerOptions; break;
     case OPT_dump_raw_tokens:
       Opts.ProgramAction = frontend::DumpRawTokens; break;
     case OPT_dump_tokens:
@@ -2788,6 +2790,7 @@ static bool isStrictlyPreprocessorAction
   case frontend::MigrateSource:
     return false;
 
+  case frontend::DumpCompilerOptions:
   case frontend::DumpRawTokens:
   case frontend::DumpTokens:
   case frontend::InitOnly:

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Thu May 31 06:57:09 2018
@@ -756,3 +756,51 @@ void PrintPreambleAction::ExecuteAction(
     llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
   }
 }
+
+void DumpCompilerOptionsAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  std::unique_ptr<raw_ostream> OSP =
+      CI.createDefaultOutputFile(false, getCurrentFile());
+  if (!OSP)
+    return;
+
+  raw_ostream &OS = *OSP;
+  const Preprocessor &PP = CI.getPreprocessor();
+  const LangOptions &LangOpts = PP.getLangOpts();
+
+  // FIXME: Rather than manually format the JSON (which is awkward due to
+  // needing to remove trailing commas), this should make use of a JSON library.
+  // FIXME: Instead of printing enums as an integral value and specifying the
+  // type as a separate field, use introspection to print the enumerator.
+
+  OS << "{\n";
+  OS << "\n\"features\" : [\n";
+  {
+    llvm::SmallString<128> Str;
+#define FEATURE(Name, Predicate)                                               \
+  ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
+      .toVector(Str);
+#include "clang/Basic/Features.def"
+#undef FEATURE
+    // Remove the newline and comma from the last entry to ensure this remains
+    // valid JSON.
+    OS << Str.substr(0, Str.size() - 2);
+  }
+  OS << "\n],\n";
+
+  OS << "\n\"extensions\" : [\n";
+  {
+    llvm::SmallString<128> Str;
+#define EXTENSION(Name, Predicate)                                             \
+  ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
+      .toVector(Str);
+#include "clang/Basic/Features.def"
+#undef EXTENSION
+    // Remove the newline and comma from the last entry to ensure this remains
+    // valid JSON.
+    OS << Str.substr(0, Str.size() - 2);
+  }
+  OS << "\n]\n";
+
+  OS << "}";
+}

Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Thu May 31 06:57:09 2018
@@ -45,6 +45,8 @@ CreateFrontendBaseAction(CompilerInstanc
   case ASTDump:                return llvm::make_unique<ASTDumpAction>();
   case ASTPrint:               return llvm::make_unique<ASTPrintAction>();
   case ASTView:                return llvm::make_unique<ASTViewAction>();
+  case DumpCompilerOptions:
+    return llvm::make_unique<DumpCompilerOptionsAction>();
   case DumpRawTokens:          return llvm::make_unique<DumpRawTokensAction>();
   case DumpTokens:             return llvm::make_unique<DumpTokensAction>();
   case EmitAssembly:           return llvm::make_unique<EmitAssemblyAction>();

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=333653&r1=333652&r2=333653&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu May 31 06:57:09 2018
@@ -1099,187 +1099,11 @@ static bool HasFeature(const Preprocesso
   if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4)
     Feature = Feature.substr(2, Feature.size() - 4);
 
+#define FEATURE(Name, Predicate) .Case(#Name, Predicate)
   return llvm::StringSwitch<bool>(Feature)
-      .Case("address_sanitizer",
-            LangOpts.Sanitize.hasOneOf(SanitizerKind::Address |
-                                       SanitizerKind::KernelAddress))
-      .Case("hwaddress_sanitizer",
-            LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
-                                       SanitizerKind::KernelHWAddress))
-      .Case("assume_nonnull", true)
-      .Case("attribute_analyzer_noreturn", true)
-      .Case("attribute_availability", true)
-      .Case("attribute_availability_with_message", true)
-      .Case("attribute_availability_app_extension", true)
-      .Case("attribute_availability_with_version_underscores", true)
-      .Case("attribute_availability_tvos", true)
-      .Case("attribute_availability_watchos", true)
-      .Case("attribute_availability_with_strict", true)
-      .Case("attribute_availability_with_replacement", true)
-      .Case("attribute_availability_in_templates", true)
-      .Case("attribute_cf_returns_not_retained", true)
-      .Case("attribute_cf_returns_retained", true)
-      .Case("attribute_cf_returns_on_parameters", true)
-      .Case("attribute_deprecated_with_message", true)
-      .Case("attribute_deprecated_with_replacement", true)
-      .Case("attribute_ext_vector_type", true)
-      .Case("attribute_ns_returns_not_retained", true)
-      .Case("attribute_ns_returns_retained", true)
-      .Case("attribute_ns_consumes_self", true)
-      .Case("attribute_ns_consumed", true)
-      .Case("attribute_cf_consumed", true)
-      .Case("attribute_objc_ivar_unused", true)
-      .Case("attribute_objc_method_family", true)
-      .Case("attribute_overloadable", true)
-      .Case("attribute_unavailable_with_message", true)
-      .Case("attribute_unused_on_fields", true)
-      .Case("attribute_diagnose_if_objc", true)
-      .Case("blocks", LangOpts.Blocks)
-      .Case("c_thread_safety_attributes", true)
-      .Case("cxx_exceptions", LangOpts.CXXExceptions)
-      .Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData)
-      .Case("enumerator_attributes", true)
-      .Case("nullability", true)
-      .Case("nullability_on_arrays", true)
-      .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
-      .Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread))
-      .Case("dataflow_sanitizer",
-            LangOpts.Sanitize.has(SanitizerKind::DataFlow))
-      .Case("efficiency_sanitizer",
-            LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
-      .Case("scudo", LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
-      // Objective-C features
-      .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
-      .Case("objc_arc", LangOpts.ObjCAutoRefCount)
-      .Case("objc_arc_fields", true)
-      .Case("objc_arc_weak", LangOpts.ObjCWeak)
-      .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
-      .Case("objc_fixed_enum", LangOpts.ObjC2)
-      .Case("objc_instancetype", LangOpts.ObjC2)
-      .Case("objc_kindof", LangOpts.ObjC2)
-      .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
-      .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
-      .Case("objc_property_explicit_atomic",
-            true) // Does clang support explicit "atomic" keyword?
-      .Case("objc_protocol_qualifier_mangling", true)
-      .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
-      .Case("ownership_holds", true)
-      .Case("ownership_returns", true)
-      .Case("ownership_takes", true)
-      .Case("objc_bool", true)
-      .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
-      .Case("objc_array_literals", LangOpts.ObjC2)
-      .Case("objc_dictionary_literals", LangOpts.ObjC2)
-      .Case("objc_boxed_expressions", LangOpts.ObjC2)
-      .Case("objc_boxed_nsvalue_expressions", LangOpts.ObjC2)
-      .Case("arc_cf_code_audited", true)
-      .Case("objc_bridge_id", true)
-      .Case("objc_bridge_id_on_typedefs", true)
-      .Case("objc_generics", LangOpts.ObjC2)
-      .Case("objc_generics_variance", LangOpts.ObjC2)
-      .Case("objc_class_property", LangOpts.ObjC2)
-      // C11 features
-      .Case("c_alignas", LangOpts.C11)
-      .Case("c_alignof", LangOpts.C11)
-      .Case("c_atomic", LangOpts.C11)
-      .Case("c_generic_selections", LangOpts.C11)
-      .Case("c_static_assert", LangOpts.C11)
-      .Case("c_thread_local",
-            LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
-      // C++11 features
-      .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
-      .Case("cxx_alias_templates", LangOpts.CPlusPlus11)
-      .Case("cxx_alignas", LangOpts.CPlusPlus11)
-      .Case("cxx_alignof", LangOpts.CPlusPlus11)
-      .Case("cxx_atomic", LangOpts.CPlusPlus11)
-      .Case("cxx_attributes", LangOpts.CPlusPlus11)
-      .Case("cxx_auto_type", LangOpts.CPlusPlus11)
-      .Case("cxx_constexpr", LangOpts.CPlusPlus11)
-      .Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11)
-      .Case("cxx_decltype", LangOpts.CPlusPlus11)
-      .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
-      .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
-      .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11)
-      .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11)
-      .Case("cxx_deleted_functions", LangOpts.CPlusPlus11)
-      .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11)
-      .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11)
-      .Case("cxx_implicit_moves", LangOpts.CPlusPlus11)
-      .Case("cxx_inheriting_constructors", LangOpts.CPlusPlus11)
-      .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11)
-      .Case("cxx_lambdas", LangOpts.CPlusPlus11)
-      .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11)
-      .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11)
-      .Case("cxx_noexcept", LangOpts.CPlusPlus11)
-      .Case("cxx_nullptr", LangOpts.CPlusPlus11)
-      .Case("cxx_override_control", LangOpts.CPlusPlus11)
-      .Case("cxx_range_for", LangOpts.CPlusPlus11)
-      .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11)
-      .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11)
-      .Case("cxx_rvalue_references", LangOpts.CPlusPlus11)
-      .Case("cxx_strong_enums", LangOpts.CPlusPlus11)
-      .Case("cxx_static_assert", LangOpts.CPlusPlus11)
-      .Case("cxx_thread_local",
-            LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported())
-      .Case("cxx_trailing_return", LangOpts.CPlusPlus11)
-      .Case("cxx_unicode_literals", LangOpts.CPlusPlus11)
-      .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
-      .Case("cxx_user_literals", LangOpts.CPlusPlus11)
-      .Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
-      // C++14 features
-      .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14)
-      .Case("cxx_binary_literals", LangOpts.CPlusPlus14)
-      .Case("cxx_contextual_conversions", LangOpts.CPlusPlus14)
-      .Case("cxx_decltype_auto", LangOpts.CPlusPlus14)
-      .Case("cxx_generic_lambdas", LangOpts.CPlusPlus14)
-      .Case("cxx_init_captures", LangOpts.CPlusPlus14)
-      .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
-      .Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
-      .Case("cxx_variable_templates", LangOpts.CPlusPlus14)
-      // NOTE: For features covered by SD-6, it is preferable to provide *only*
-      // the SD-6 macro and not a __has_feature check.
-
-      // C++ TSes
-      //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
-      //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
-      // FIXME: Should this be __has_feature or __has_extension?
-      //.Case("raw_invocation_type", LangOpts.CPlusPlus)
-      // Type traits
-      // N.B. Additional type traits should not be added to the following list.
-      // Instead, they should be detected by has_extension.
-      .Case("has_nothrow_assign", LangOpts.CPlusPlus)
-      .Case("has_nothrow_copy", LangOpts.CPlusPlus)
-      .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
-      .Case("has_trivial_assign", LangOpts.CPlusPlus)
-      .Case("has_trivial_copy", LangOpts.CPlusPlus)
-      .Case("has_trivial_constructor", LangOpts.CPlusPlus)
-      .Case("has_trivial_destructor", LangOpts.CPlusPlus)
-      .Case("has_virtual_destructor", LangOpts.CPlusPlus)
-      .Case("is_abstract", LangOpts.CPlusPlus)
-      .Case("is_base_of", LangOpts.CPlusPlus)
-      .Case("is_class", LangOpts.CPlusPlus)
-      .Case("is_constructible", LangOpts.CPlusPlus)
-      .Case("is_convertible_to", LangOpts.CPlusPlus)
-      .Case("is_empty", LangOpts.CPlusPlus)
-      .Case("is_enum", LangOpts.CPlusPlus)
-      .Case("is_final", LangOpts.CPlusPlus)
-      .Case("is_literal", LangOpts.CPlusPlus)
-      .Case("is_standard_layout", LangOpts.CPlusPlus)
-      .Case("is_pod", LangOpts.CPlusPlus)
-      .Case("is_polymorphic", LangOpts.CPlusPlus)
-      .Case("is_sealed", LangOpts.CPlusPlus && LangOpts.MicrosoftExt)
-      .Case("is_trivial", LangOpts.CPlusPlus)
-      .Case("is_trivially_assignable", LangOpts.CPlusPlus)
-      .Case("is_trivially_constructible", LangOpts.CPlusPlus)
-      .Case("is_trivially_copyable", LangOpts.CPlusPlus)
-      .Case("is_union", LangOpts.CPlusPlus)
-      .Case("modules", LangOpts.Modules)
-      .Case("safe_stack", LangOpts.Sanitize.has(SanitizerKind::SafeStack))
-      .Case("shadow_call_stack",
-            LangOpts.Sanitize.has(SanitizerKind::ShadowCallStack))
-      .Case("tls", PP.getTargetInfo().isTLSSupported())
-      .Case("underlying_type", LangOpts.CPlusPlus)
+#include "clang/Basic/Features.def"
       .Default(false);
+#undef FEATURE
 }
 
 /// HasExtension - Return true if we recognize and implement the feature
@@ -1302,35 +1126,13 @@ static bool HasExtension(const Preproces
       Extension.size() >= 4)
     Extension = Extension.substr(2, Extension.size() - 4);
 
-  // Because we inherit the feature list from HasFeature, this string switch
-  // must be less restrictive than HasFeature's.
+    // Because we inherit the feature list from HasFeature, this string switch
+    // must be less restrictive than HasFeature's.
+#define EXTENSION(Name, Predicate) .Case(#Name, Predicate)
   return llvm::StringSwitch<bool>(Extension)
-           // C11 features supported by other languages as extensions.
-           .Case("c_alignas", true)
-           .Case("c_alignof", true)
-           .Case("c_atomic", true)
-           .Case("c_generic_selections", true)
-           .Case("c_static_assert", true)
-           .Case("c_thread_local", PP.getTargetInfo().isTLSSupported())
-           // C++11 features supported by other languages as extensions.
-           .Case("cxx_atomic", LangOpts.CPlusPlus)
-           .Case("cxx_deleted_functions", LangOpts.CPlusPlus)
-           .Case("cxx_explicit_conversions", LangOpts.CPlusPlus)
-           .Case("cxx_inline_namespaces", LangOpts.CPlusPlus)
-           .Case("cxx_local_type_template_args", LangOpts.CPlusPlus)
-           .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus)
-           .Case("cxx_override_control", LangOpts.CPlusPlus)
-           .Case("cxx_range_for", LangOpts.CPlusPlus)
-           .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
-           .Case("cxx_rvalue_references", LangOpts.CPlusPlus)
-           .Case("cxx_variadic_templates", LangOpts.CPlusPlus)
-           // C++14 features supported by other languages as extensions.
-           .Case("cxx_binary_literals", true)
-           .Case("cxx_init_captures", LangOpts.CPlusPlus11)
-           .Case("cxx_variable_templates", LangOpts.CPlusPlus)
-           // Miscellaneous language extensions
-           .Case("overloadable_unmarked", true)
-           .Default(false);
+#include "clang/Basic/Features.def"
+      .Default(false);
+#undef EXTENSION
 }
 
 /// EvaluateHasIncludeCommon - Process a '__has_include("path")'

Added: cfe/trunk/test/Frontend/compiler-options-dump.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/compiler-options-dump.cpp?rev=333653&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/compiler-options-dump.cpp (added)
+++ cfe/trunk/test/Frontend/compiler-options-dump.cpp Thu May 31 06:57:09 2018
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -compiler-options-dump -std=c++03 %s -o - | FileCheck %s --check-prefix=CXX03
+// RUN: %clang_cc1 -compiler-options-dump -std=c++17 %s -o - | FileCheck %s --check-prefix=CXX17
+// RUN: %clang_cc1 -compiler-options-dump -std=c99 -x c %s -o - | FileCheck %s --check-prefix=C99
+
+// CXX03: "features"
+// CXX03: "cxx_auto_type" : false
+// CXX03: "cxx_range_for" : false
+// CXX03: "extensions"
+// CXX03: "cxx_range_for" : true
+
+// CXX17: "features"
+// CXX17: "cxx_auto_type" : true
+// CXX17: "cxx_range_for" : true
+// CXX17: "extensions"
+// CXX17: "cxx_range_for" : true
+
+// C99: "features"
+// C99: "c_alignas" : false
+// C99: "c_atomic" : false
+// C99: "cxx_auto_type" : false
+// C99: "cxx_range_for" : false
+// C99: "extensions"
+// C99: "c_alignas" : true
+// C99: "c_atomic" : true
+// C99: "cxx_range_for" : false




More information about the cfe-commits mailing list