Mordante created this revision. Mordante added a project: clang. Herald added a subscriber: mgorny.
This is a proof-of-concept patch to be discussed on the dev ml. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D72053 Files: clang/docs/ImplementationQuantities.rst clang/docs/UsersManual.rst clang/include/clang/AST/Decl.h clang/include/clang/AST/Type.h clang/include/clang/Basic/CMakeLists.txt clang/include/clang/Basic/ImplementationQuantities.h clang/include/clang/Basic/ImplementationQuantities.inc clang/include/clang/Basic/ImplementationQuantities.td clang/lib/CodeGen/CGRecordLayout.h clang/lib/Frontend/CompilerInvocation.cpp clang/utils/TableGen/CMakeLists.txt clang/utils/TableGen/ClangImplementationQuantitiesEmitter.cpp clang/utils/TableGen/TableGen.cpp clang/utils/TableGen/TableGenBackends.h
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); 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/ClangImplementationQuantitiesEmitter.cpp =================================================================== --- /dev/null +++ clang/utils/TableGen/ClangImplementationQuantitiesEmitter.cpp @@ -0,0 +1,105 @@ +//===--- 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 <vector> + +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 WriteValue = [&OS](Record *Tag) { + if (Tag->getValueAsBit("isBitLimit")) { + int Bits = Tag->getValueAsInt("Bits"); + OS << ((1 << Bits) - 1) << " (" << Bits << " bits)\n\n"; + } else if (Tag->getValueAsBit("isValueLimit")) + OS << Tag->getValueAsInt("Value") << "\n\n"; + else if (Tag->getValueAsBit("isCompilerFlagLimit")) + OS << "Controlled by option '" + << Tag->getValueAsString("CompilerFlagOrDescription") << "' default " + << Tag->getValueAsInt("Value") << "\n\n"; + else if (Tag->getValueAsBit("isDescriptionLimit")) + OS << Tag->getValueAsString("CompilerFlagOrDescription") << "\n\n"; + else + OS << "*Unknown*\n\n"; + }; + + OS << Documentation->getValueAsString("Intro") << "\n"; + + std::vector<Record *> NonStandard; + for (auto Tag : Records.getAllDerivedDefinitions("IQ")) { + int Recommended = Tag->getValueAsInt("Recommended"); + if (Recommended == 0) { + NonStandard.push_back(Tag); + continue; + } + + OS << Tag->getValueAsString("Description") + << "\n* Recommended: " << Recommended << "\n* Clang: "; + + WriteValue(Tag); + } + + if (NonStandard.empty()) + return; + + OS << "Non standard defined quantities\n" + << "-------------------------------\n\n"; + + for (auto Tag : NonStandard) { + OS << Tag->getValueAsString("Description") << "\n* Clang: "; + + WriteValue(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/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/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/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/include/clang/Basic/ImplementationQuantities.td =================================================================== --- /dev/null +++ clang/include/clang/Basic/ImplementationQuantities.td @@ -0,0 +1,147 @@ +//==--- 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 Implementation Quantities of Clang as required by Annex B +of the C++ standard. + +Standard defined quantities +--------------------------- +}]; +} + +class IQ<string N, string T, int R> { + // The variable base name + string Name = N; + + // The description of the limit, often a copy from [implimits] + string Description = T; + + // 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 = ""; + + // The recommended value of [implimits]. If the quantity is not a standard + // quantity it is set to 0. + int Recommended = R; + + // 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'. + bit isBitLimit = 0; + bit isValueLimit = 0; + bit isCompilerFlagLimit = 0; + bit isDescriptionLimit = 0; +} + +class IQBits<string N, string T, int R, int B> : IQ<N, T, R> { + let Bits = B; + let isBitLimit = 1; +} + +class IQValue<string N, string T, int R, int V> : IQ<N, T, R> { + let Value = V; + let isValueLimit = 1; +} + +class IQCompilerFlag<string N, string T, int R, string CF, int V> + : IQ<N, T, R> { + let CompilerFlagOrDescription = CF; + let Value = V; + let isCompilerFlagLimit = 1; +} + +class IQDescription<string N, string T, int R, string D> + : IQ<N, T, R> { + let CompilerFlagOrDescription = D; + let isDescriptionLimit = 1; +} + +// +// Standard defined quantities +// + +def : IQ<"", "Nesting levels of conditional inclusion.", 256>; + +def : IQBits<"NumParams", "Parameters in one function definition.", 256, 16>; + +def : IQCompilerFlag<"InstantiationDepth", + "Recursively nested template instantiations, including " + "substitution during template argumentdeduction.", + 1024, "-ftemplate-depth=N", 1024>; + +// +// +// 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>; + +def NestedFunctionPrototypes : IQBits<"NumScopeDepthOrObjCQuals", + "Maximum number of nested function " + "prototypes.", 0, 7>; + + +// +// +// Examples not to be committed +// +// + +// Example of a value based limit +def : IQValue<"Answer", + "Answer to the Ultimate Question of Life, the Universe, and " + "Everything.", + 0, 42>; + +def : IQValue<"Wrong_answer", + "Answer to the Ultimate Question of Life, the Universe, and " + "Everything.", + 42, 54>; + +// Example of a description based limit +def : IQDescription<"", "The maximum number of recursive function calls.", 0, +"Depends on the stack size">; + +def : IQDescription<"", "The maximum number of recursive function calls.", 1, +"Depends on the stack size">; Index: clang/include/clang/Basic/ImplementationQuantities.inc =================================================================== --- /dev/null +++ clang/include/clang/Basic/ImplementationQuantities.inc @@ -0,0 +1,27 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* A list of commands useable in documentation comments *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +// +// +// Example generated file. DO NOT COMMIT +// +// + + +namespace IQ { +constexpr unsigned BitFieldBits = 15; +constexpr unsigned MaxBitField = 32767; +constexpr unsigned NumScopeDepthOrObjCQualsBits = 7; +constexpr unsigned MaxNumScopeDepthOrObjCQuals = 127; +constexpr unsigned NumParamsBits = 16; +constexpr unsigned MaxNumParams = 65535; +constexpr unsigned InstantiationDepthDefault = 1024; +constexpr unsigned MaxAnswer = 42; +constexpr unsigned MaxWrong_answer = 54; +} // IQ namespace + 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/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/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 <cassert> #include <cstddef> #include <cstdint> 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/docs/UsersManual.rst =================================================================== --- clang/docs/UsersManual.rst +++ clang/docs/UsersManual.rst @@ -2586,6 +2586,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/docs/ImplementationQuantities.rst =================================================================== --- /dev/null +++ clang/docs/ImplementationQuantities.rst @@ -0,0 +1,50 @@ +.. + ------------------------------------------------------------------- + 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 Implementation Quantities of Clang as required by Annex B +of the C++ standard. + +Standard defined quantities +--------------------------- + +Nesting levels of conditional inclusion. +* Recommended: 256 +* Clang: *Unknown* + +Parameters in one function definition. +* Recommended: 256 +* Clang: 65535 (16 bits) + +Recursively nested template instantiations, including substitution during template argumentdeduction. +* Recommended: 1024 +* Clang: Controlled by option '-ftemplate-depth=N' default 1024 + +Answer to the Ultimate Question of Life, the Universe, and Everything. +* Recommended: 42 +* Clang: 54 + +The maximum number of recursive function calls. +* Recommended: 1 +* Clang: Depends on the stack size + +Non standard defined quantities +------------------------------- + +Maximum width of a bit-field. +* Clang: 32767 (15 bits) + +Maximum number of nested function prototypes. +* Clang: 127 (7 bits) + +Answer to the Ultimate Question of Life, the Universe, and Everything. +* Clang: 42 + +The maximum number of recursive function calls. +* Clang: Depends on the stack size +
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits