forked from OSchip/llvm-project
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:
parent
d657c25649
commit
16ed8dd823
|
@ -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
|
|
@ -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">,
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -43,6 +43,9 @@ enum ActionKind {
|
|||
/// Parse ASTs and view them in Graphviz.
|
||||
ASTView,
|
||||
|
||||
/// Dump the compiler configuration.
|
||||
DumpCompilerOptions,
|
||||
|
||||
/// Dump out raw tokens.
|
||||
DumpRawTokens,
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 << "}";
|
||||
}
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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")'
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue