Index: clang/docs/ImplementationQuantities.rst =================================================================== --- /dev/null +++ clang/docs/ImplementationQuantities.rst @@ -0,0 +1,99 @@ +.. + ------------------------------------------------------------------- + NOTE: This file is automatically generated by running clang-tblgen-gen + -clang-implementation-quantities-docs.Do not edit this file by hand !! + ------------------------------------------------------------------- + +Introduction +============ + +This page lists the limits implemented in the Clang compiler. The available +resources on the system running Clang may imposse other limits. For example, +the system may have insufficient memory to compile the translation unit before +the limits imposed by Clang are reached. + + +C Standard defined quantities +----------------------------- + +This is the list of limits as defined in the C standard's 'Translation limits'. + +Nesting levels of parenthesized declarators within a full declarator +* Required: 63 +* Clang: *Unknown* + +Characters in a string literal (after concatenation). +* Required: 509 +* Clang: 509 +* Remark: The limit is only enforced when the source is compiled in C89 mode with the compiler flag -Wpedantic. +* Design choices: The value is required by the C89 standard. + +Characters in a string literal (after concatenation). +* Required: 4095 +* Clang: 4095 +* Remark: The limit is only enforced when the source is compiled in C99 mode (or newer) with the compiler flag -Wpedantic. +* Design choices: The value is required by the C99 and later standards. + +Nesting levels of conditional inclusion. +* Required: 63 +* Clang: *Unknown* + +Nesting levels of parenthesized declarators within a full expression +* Required: 63 +* Clang: *Unknown* + +Parameters in one function definition. +* Required: 127 +* Clang: 65535 (16 bits) +* Design choices: Unknown +* Status: At least partially implemented. + + +C++ Standard defined quantities +------------------------------- + +This contains the Implementation Quantities of Clang as required by Annex B of +the C++ standard. + +Nesting levels of conditional inclusion. +* Recommended: 256 +* Clang: *Unknown* + +Nesting levels of parenthesized declarators within a full-expression. +* Recommended: 256 +* Clang: *Unknown* + +Parameters in one function definition. +* Recommended: 256 +* Clang: 65535 (16 bits) +* Design choices: Unknown +* Status: At least partially implemented. + +Recursively nested template instantiations, including substitution during template argumentdeduction. +* Recommended: 1024 +* Clang: Controlled by option '-ftemplate-depth=N' default 1024 +* Design choices: Unknown +* Status: At least partially implemented. + +Characters in a string literal (after concatenation). +* Recommended: 65536 +* Clang: 65536 +* Remark: The limit is only enforced when the source is with the compiler flag -Wpedantic. +* Design choices: The value is recommened by the C++ standard. + + +Non standard defined quantities +------------------------------- + +These limits are not defined in the standards, but are imposed in Clang. + +Maximum width of a bit-field. +* Clang: 32767 (15 bits) +* Design choices: This value avoids padding in `CodeGen::CGBitFieldInfo::CGBitFieldInfo`. +* Status: Enforced by an assertion failure. + +Maximum number of nested function prototypes. +* Clang: 127 (7 bits) +* Design choices: Unknown +* Status: Unknown + Index: clang/docs/UsersManual.rst =================================================================== --- clang/docs/UsersManual.rst +++ clang/docs/UsersManual.rst @@ -2389,7 +2389,8 @@ =================== The support for standard C in clang is feature-complete except for the -C99 floating-point pragmas. +C99 floating-point pragmas. For detailed information about implemented limits +of C features please refer to :doc:`ImplementationQuantities`. Extensions supported by clang ----------------------------- @@ -2586,6 +2587,9 @@ Sets the limit for iterative calls to 'operator->' functions to N. The default is 256. +For detailed information about implemented limits of C++ features please +refer to :doc:`ImplementationQuantities`. + .. _objc: Objective-C Language Features Index: clang/include/clang/AST/Decl.h =================================================================== --- clang/include/clang/AST/Decl.h +++ clang/include/clang/AST/Decl.h @@ -25,6 +25,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/ImplementationQuantities.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/OperatorKinds.h" @@ -873,8 +874,6 @@ DAK_Normal }; - enum { NumScopeDepthOrObjCQualsBits = 7 }; - class ParmVarDeclBitfields { friend class ASTDeclReader; friend class ParmVarDecl; @@ -901,7 +900,7 @@ /// Otherwise, the number of function parameter scopes enclosing /// the function parameter scope in which this parameter was /// declared. - unsigned ScopeDepthOrObjCQuals : NumScopeDepthOrObjCQualsBits; + unsigned ScopeDepthOrObjCQuals : IQ::NumScopeDepthOrObjCQualsBits; /// The number of parameters preceding this parameter in the /// function parameter scope in which it was declared. @@ -1627,7 +1626,7 @@ } static constexpr unsigned getMaxFunctionScopeDepth() { - return (1u << NumScopeDepthOrObjCQualsBits) - 1; + return IQ::MaxNumScopeDepthOrObjCQuals; } /// Returns the index of this parameter in its prototype or method scope. Index: clang/include/clang/AST/Type.h =================================================================== --- clang/include/clang/AST/Type.h +++ clang/include/clang/AST/Type.h @@ -23,6 +23,7 @@ #include "clang/Basic/AttrKinds.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/ImplementationQuantities.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" @@ -44,8 +45,8 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/PointerLikeTypeTraits.h" -#include "llvm/Support/type_traits.h" #include "llvm/Support/TrailingObjects.h" +#include "llvm/Support/type_traits.h" #include #include #include Index: clang/include/clang/Basic/CMakeLists.txt =================================================================== --- clang/include/clang/Basic/CMakeLists.txt +++ clang/include/clang/Basic/CMakeLists.txt @@ -41,6 +41,12 @@ TARGET ClangAttrHasAttributeImpl ) +clang_tablegen(ImplementationQuantities.inc -gen-clang-implementation-quantities + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ImplementationQuantities.td + TARGET ClangImplementationQuantities +) + # ARM NEON and MVE clang_tablegen(arm_neon.inc -gen-arm-neon-sema SOURCE arm_neon.td Index: clang/include/clang/Basic/ImplementationQuantities.h =================================================================== --- /dev/null +++ clang/include/clang/Basic/ImplementationQuantities.h @@ -0,0 +1,18 @@ +//===--- ImplementationQuantities.h ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_IMPLEMENTATIONQUANTITIES_H +#define LLVM_CLANG_BASIC_IMPLEMENTATIONQUANTITIES_H + +namespace clang { + +#include "clang/Basic/ImplementationQuantities.inc" + +} // end namespace clang + +#endif Index: clang/include/clang/Basic/ImplementationQuantities.td =================================================================== --- /dev/null +++ clang/include/clang/Basic/ImplementationQuantities.td @@ -0,0 +1,239 @@ +//==--- ImplementationQuantities.td - Implementation quantities ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +def GlobalDocumentation { + code Intro = [{.. + ------------------------------------------------------------------- + NOTE: This file is automatically generated by running clang-tblgen-gen + -clang-implementation-quantities-docs.Do not edit this file by hand !! + ------------------------------------------------------------------- + +Introduction +============ + +This page lists the limits implemented in the Clang compiler. The available +resources on the system running Clang may imposse other limits. For example, +the system may have insufficient memory to compile the translation unit before +the limits imposed by Clang are reached. + +}]; + + code C = [{ +C Standard defined quantities +----------------------------- + +This is the list of limits as defined in the C standard's 'Translation limits'. + +}]; + + code CXX = [{ +C++ Standard defined quantities +------------------------------- + +This contains the Implementation Quantities of Clang as required by Annex B of +the C++ standard. + +}]; + +code Non_standard = [{ +Non standard defined quantities +------------------------------- + +These limits are not defined in the standards, but are imposed in Clang. + +}]; +} + +class IQ { + // The variable base name + string Name = N; + + // The description of the limit, often a copy from [implimits] + string Description = T; + + // The description of the limit as documented in the C standard. If the value + // is the same as C++ leave it empty. + string Description_C_standard = ""; + + // If the limit is controlled by a compiler flag this field contains the name + // of the flag. + // If the limit is controlled by a description this field contains the + // description of the limit. + string CompilerFlagOrDescription = ""; + + // Explains the the design choices made in Clang. This should aid developers + // to determine why the current limit has been choosen so they can determine + // the impact of changing the value. + string DesignChoices = ""; + + // The status of the implementation and enforcing of the limit in Clang. + string Status = ""; + + // The recommended value of [implimits]. If the quantity is not a standard + // quantity it is set to 0. + int Recommended = R; + + // The required number of Translation limits. + int Required = 0; + + // The number of bits of the limit. + int Bits = 0; + + // The numeric value of the limit. + int Value = 0; + + // The type of limit used is determined by one of these bits: + // * isBitLimit The quantity is limited by a number of bits: + // * Bits Is the number of bits used + // * Value Contains maximum value based on the number of Bits as an unsigned + // bit-field. + // * isValueLimit The quantity is limited by a value: + // * Bits Unused. + // * Value The maximum value of the limit. + // * isCompilerFlagLimit The quantity is limited by a value based on a + // compiler flag: + // * Bits Unused. + // * Value The default value of the limit. + // * isDescriptionLimit The quantity's limit is described by a text. For + // exmple 'limited by the size of the stack'. + // * hasRemark if the limit is controlled by isBitLimit or isValueLimit + // the CompilerFlagOrDescription can have an additional remark which is + // stored in this field + bit isBitLimit = 0; + bit isValueLimit = 0; + bit isCompilerFlagLimit = 0; + bit isDescriptionLimit = 0; + bit hasRemark = 0; +} + +class IQImpl : IQ { + let DesignChoices = DC; + let Status = S; +} + +class IQBits + : IQImpl { + let Bits = B; + let isBitLimit = 1; +} + +class IQValue + : IQImpl { + let Value = V; + let isValueLimit = 1; +} + +class IQValueWithRemark : IQImpl { + let Value = V; + let isValueLimit = 1; + let CompilerFlagOrDescription = D; + let hasRemark = 1; +} + +class IQCompilerFlag : IQImpl { + let CompilerFlagOrDescription = CF; + let Value = V; + let isCompilerFlagLimit = 1; +} + +class IQDescription + : IQImpl { + let CompilerFlagOrDescription = D; + let isDescriptionLimit = 1; +} + +// +// C only standard defined limits +// + +let Required = 63 in +def : IQ<"", + "Nesting levels of parenthesized declarators within a " + "full declarator", 0>; + +let Required = 509 in +def : IQValueWithRemark<"StringLiteralLengthC89", + "Characters in a string literal (after concatenation).", + 0, + 509, + "The value is required by the C89 standard.", + "", + "The limit is only enforced when the source is " + "compiled in C89 mode with the compiler flag " + "-Wpedantic.">; + +let Required = 4095 in +def : IQValueWithRemark<"StringLiteralLengthC99", + "Characters in a string literal (after concatenation).", + 0, + 4095, + "The value is required by the C99 and later standards.", + "", + "The limit is only enforced when the source is " + "compiled in C99 mode (or newer) with the compiler " + "flag -Wpedantic.">; + +// +// C/C++ Standard defined quantities +// + + +let Required = 63 in +def : IQ<"", "Nesting levels of conditional inclusion.", 256>; + + +let Required = 63, +Description_C_standard = "Nesting levels of parenthesized declarators within " + "a full expression" in +def : IQ<"", + "Nesting levels of parenthesized declarators within a " + "full-expression.", 256>; + + +let Required = 127 in +def : IQBits<"NumParams", "Parameters in one function definition.", 256, 16, + "Unknown", "At least partially implemented.">; + +def : IQCompilerFlag<"InstantiationDepth", + "Recursively nested template instantiations, including " + "substitution during template argumentdeduction.", + 1024, "-ftemplate-depth=N", 1024, "Unknown", + "At least partially implemented.">; + +def : IQValueWithRemark< + "StringLiteralLengthCXX", + "Characters in a string literal (after concatenation).", + 65536, + 65536, + "The value is recommened by the C++ standard.", + "", + "The limit is only enforced when the source is with the compiler " + "flag -Wpedantic.">; + +// +// +// TODO copy the other quantities of the Standard's Annex B. +// +// + + +// +// Non standard defined quantities +// + +def BitFieldWidth : IQBits<"BitField", "Maximum width of a bit-field.", 0, 15, + "This value avoids padding in " + "`CodeGen::CGBitFieldInfo::CGBitFieldInfo`.", + "Enforced by an assertion failure.">; + +def NestedFunctionPrototypes + : IQBits<"NumScopeDepthOrObjCQuals", + "Maximum number of nested function prototypes.", 0, 7, + "Unknown", "Unknown">; Index: clang/lib/CodeGen/CGRecordLayout.h =================================================================== --- clang/lib/CodeGen/CGRecordLayout.h +++ clang/lib/CodeGen/CGRecordLayout.h @@ -11,6 +11,7 @@ #include "clang/AST/CharUnits.h" #include "clang/AST/DeclCXX.h" +#include "clang/Basic/ImplementationQuantities.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/IR/DerivedTypes.h" @@ -68,7 +69,7 @@ unsigned Offset : 16; /// The total size of the bit-field, in bits. - unsigned Size : 15; + unsigned Size : IQ::BitFieldBits; /// Whether the bit-field is signed. unsigned IsSigned : 1; Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/ImplementationQuantities.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/LangStandard.h" @@ -2847,8 +2848,8 @@ Opts.AccessControl = !Args.hasArg(OPT_fno_access_control); Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors); Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno); - Opts.InstantiationDepth = - getLastArgIntValue(Args, OPT_ftemplate_depth, 1024, Diags); + Opts.InstantiationDepth = getLastArgIntValue( + Args, OPT_ftemplate_depth, IQ::InstantiationDepthDefault, Diags); Opts.ArrowDepth = getLastArgIntValue(Args, OPT_foperator_arrow_depth, 256, Diags); Opts.ConstexprCallDepth = Index: clang/lib/Lex/LiteralSupport.cpp =================================================================== --- clang/lib/Lex/LiteralSupport.cpp +++ clang/lib/Lex/LiteralSupport.cpp @@ -13,6 +13,7 @@ #include "clang/Lex/LiteralSupport.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/ImplementationQuantities.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" @@ -1732,7 +1733,10 @@ } } else if (Diags) { // Complain if this string literal has too many characters. - unsigned MaxChars = Features.CPlusPlus? 65536 : Features.C99 ? 4095 : 509; + unsigned MaxChars = Features.CPlusPlus + ? IQ::MaxStringLiteralLengthCXX + : Features.C99 ? IQ::MaxStringLiteralLengthC99 + : IQ::MaxStringLiteralLengthC89; if (GetNumStringChars() > MaxChars) Diags->Report(StringToks.front().getLocation(), Index: clang/utils/TableGen/CMakeLists.txt =================================================================== --- clang/utils/TableGen/CMakeLists.txt +++ clang/utils/TableGen/CMakeLists.txt @@ -11,6 +11,7 @@ ClangDataCollectorsEmitter.cpp ClangDiagnosticsEmitter.cpp ClangOpcodesEmitter.cpp + ClangImplementationQuantitiesEmitter.cpp ClangOpenCLBuiltinEmitter.cpp ClangOptionDocEmitter.cpp ClangSACheckersEmitter.cpp Index: clang/utils/TableGen/ClangImplementationQuantitiesEmitter.cpp =================================================================== --- /dev/null +++ clang/utils/TableGen/ClangImplementationQuantitiesEmitter.cpp @@ -0,0 +1,135 @@ +//===--- ClangCommentCommandInfoEmitter.cpp - Generate command lists -----====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" +#include + +using namespace llvm; + +namespace clang { + +void EmitClangImplementationQuantitiesDocs(RecordKeeper &Records, + raw_ostream &OS) { + // Get the documentation introduction paragraph. + const Record *Documentation = Records.getDef("GlobalDocumentation"); + if (!Documentation) { + llvm::PrintFatalError("The Documentation top-level definition is missing, " + "no documentation will be generated."); + return; + } + + auto WriteValueAndSuffix = [&OS](Record *Tag) { + if (Tag->getValueAsBit("isBitLimit")) { + int Bits = Tag->getValueAsInt("Bits"); + OS << ((1 << Bits) - 1) << " (" << Bits << " bits)"; + } else if (Tag->getValueAsBit("isValueLimit")) + OS << Tag->getValueAsInt("Value"); + else if (Tag->getValueAsBit("isCompilerFlagLimit")) + OS << "Controlled by option '" + << Tag->getValueAsString("CompilerFlagOrDescription") << "' default " + << Tag->getValueAsInt("Value"); + else if (Tag->getValueAsBit("isDescriptionLimit")) + OS << Tag->getValueAsString("CompilerFlagOrDescription"); + else + OS << "*Unknown*"; + + if (Tag->getValueAsBit("hasRemark")) + OS << "\n* Remark: " + << Tag->getValueAsString("CompilerFlagOrDescription"); + + std::string DC = Tag->getValueAsString("DesignChoices"); + if (!DC.empty()) + OS << "\n* Design choices: " << DC; + + std::string Status = Tag->getValueAsString("Status"); + if (!Status.empty()) + OS << "\n* Status: " << Status; + + OS << "\n\n"; + }; + + OS << Documentation->getValueAsString("Intro"); + std::vector NonStandard; + + OS << Documentation->getValueAsString("C"); + for (auto Tag : Records.getAllDerivedDefinitions("IQ")) { + int Required = Tag->getValueAsInt("Required"); + if (Required == 0) { + if (Tag->getValueAsInt("Recommended") == 0) + NonStandard.push_back(Tag); + continue; + } + + std::string Decription = Tag->getValueAsString("Description_C_standard"); + if (Decription.empty()) + Decription = Tag->getValueAsString("Description"); + + OS << Decription << "\n* Required: " << Required << "\n* Clang: "; + + WriteValueAndSuffix(Tag); + } + + OS << Documentation->getValueAsString("CXX"); + for (auto Tag : Records.getAllDerivedDefinitions("IQ")) { + int Recommended = Tag->getValueAsInt("Recommended"); + if (Recommended == 0) + continue; + + OS << Tag->getValueAsString("Description") + << "\n* Recommended: " << Recommended << "\n* Clang: "; + + WriteValueAndSuffix(Tag); + } + + if (NonStandard.empty()) + return; + + OS << Documentation->getValueAsString("Non_standard"); + + for (auto Tag : NonStandard) { + OS << Tag->getValueAsString("Description") << "\n* Clang: "; + + WriteValueAndSuffix(Tag); + } +} + +void EmitClangImplementationQuantities(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("A list of commands useable in documentation comments", + OS); + + OS << "namespace IQ {\n"; + + for (auto Tag : Records.getAllDerivedDefinitions("IQ")) { + if (Tag->getValueAsBit("isDescriptionLimit")) + continue; + + auto Name = Tag->getValueAsString("Name"); + if (Name.empty()) + continue; + + if (Tag->getValueAsBit("isBitLimit")) { + int Bits = Tag->getValueAsInt("Bits"); + OS << "constexpr unsigned " << Name << "Bits = " << Bits << ";\n"; + OS << "constexpr unsigned Max" << Name << " = " << ((1u << Bits) - 1) + << ";\n"; + } else if (Tag->getValueAsBit("isValueLimit")) + OS << "constexpr unsigned Max" << Name << " = " + << Tag->getValueAsInt("Value") << ";\n"; + else if (Tag->getValueAsBit("isCompilerFlagLimit")) + OS << "constexpr unsigned " << Name + << "Default = " << Tag->getValueAsInt("Value") << ";\n"; + else + PrintWarning("No tag set for \"" + Name + "\" no output is generated."); + } + OS << "} // IQ namespace\n\n"; +} + +} // end namespace clang Index: clang/utils/TableGen/TableGen.cpp =================================================================== --- clang/utils/TableGen/TableGen.cpp +++ clang/utils/TableGen/TableGen.cpp @@ -60,6 +60,8 @@ GenClangCommentHTMLNamedCharacterReferences, GenClangCommentCommandInfo, GenClangCommentCommandList, + GenClangImplementationQuantitiesDocs, + GenClangImplementationQuantities, GenClangOpenCLBuiltins, GenArmNeon, GenArmFP16, @@ -172,6 +174,14 @@ clEnumValN(GenClangCommentCommandList, "gen-clang-comment-command-list", "Generate list of commands that are used in " "documentation comments"), + clEnumValN(GenClangImplementationQuantitiesDocs, + "gen-clang-implementation-quantities-docs", + "Generate documentation of the implementation quantities " + "as defined in the C++ standard"), + clEnumValN(GenClangImplementationQuantities, + "gen-clang-implementation-quantities", + "Generate of the implementation quantities " + "as defined in the C++ standard"), clEnumValN(GenClangOpenCLBuiltins, "gen-clang-opencl-builtins", "Generate OpenCL builtin declaration handlers"), clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"), @@ -321,6 +331,12 @@ case GenClangCommentCommandList: EmitClangCommentCommandList(Records, OS); break; + case GenClangImplementationQuantitiesDocs: + EmitClangImplementationQuantitiesDocs(Records, OS); + break; + case GenClangImplementationQuantities: + EmitClangImplementationQuantities(Records, OS); + break; case GenClangOpenCLBuiltins: EmitClangOpenCLBuiltins(Records, OS); break; Index: clang/utils/TableGen/TableGenBackends.h =================================================================== --- clang/utils/TableGen/TableGenBackends.h +++ clang/utils/TableGen/TableGenBackends.h @@ -81,8 +81,14 @@ llvm::raw_ostream &OS); void EmitClangCommentCommandList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); + void EmitClangOpcodes(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitClangImplementationQuantitiesDocs(llvm::RecordKeeper &Records, + llvm::raw_ostream &OS); +void EmitClangImplementationQuantities(llvm::RecordKeeper &Records, + llvm::raw_ostream &OS); + void EmitNeon(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitFP16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitNeonSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);