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

Reply via email to