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.

llvm-svn: 333653
This commit is contained in:
Aaron Ballman 2018-05-31 13:57:09 +00:00
parent d657c25649
commit 16ed8dd823
9 changed files with 342 additions and 207 deletions

View File

@ -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

View File

@ -563,6 +563,8 @@ def rewrite_macros : Flag<["-"], "rewrite-macros">,
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">,

View File

@ -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
//===----------------------------------------------------------------------===//

View File

@ -43,6 +43,9 @@ enum ActionKind {
/// Parse ASTs and view them in Graphviz.
ASTView,
/// Dump the compiler configuration.
DumpCompilerOptions,
/// Dump out raw tokens.
DumpRawTokens,

View File

@ -1396,6 +1396,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
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(frontend::ActionKind Action) {
case frontend::MigrateSource:
return false;
case frontend::DumpCompilerOptions:
case frontend::DumpRawTokens:
case frontend::DumpTokens:
case frontend::InitOnly:

View File

@ -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 << "}";
}

View File

@ -45,6 +45,8 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
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>();

View File

@ -1099,187 +1099,11 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
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 Preprocessor &PP, StringRef Extension) {
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")'

View File

@ -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