Commit fd285a85fdc for php.net

commit fd285a85fdc1bbb8705c89ced513535e8a50d23f
Merge: 4cc691ae46a e826bf80363
Author: Máté Kocsis <kocsismate@woohoolabs.com>
Date:   Sun Apr 5 07:36:16 2026 +0200

    Merge branch 'PHP-8.5'

    * PHP-8.5:
      Add support for generating enum pages for the manual (#21469)

diff --cc build/gen_stub.php
index 31b10ada50b,67be5c2f7b9..70265c40cb9
--- a/build/gen_stub.php
+++ b/build/gen_stub.php
@@@ -3118,23 -3302,28 +3134,23 @@@ class PropertyInfo extends VariableLik
  }

  class EnumCaseInfo {
 -    private /* readonly */ EnumCaseName $name;
 -    private /* readonly */ ?Expr $value;
 -    private /* readonly */ ?string $valueString;
--
 -    public function __construct(EnumCaseName $name, ?Expr $value, ?string $valueString) {
 -        $this->name = $name;
 -        $this->value = $value;
 -        $this->valueString = $valueString;
 -    }
 +    public function __construct(
-         public readonly string $name,
++        public readonly EnumCaseName $name,
 +        private readonly ?Expr $value,
++        private readonly ?string $valueString
 +    ) {}

      /** @param array<string, ConstInfo> $allConstInfos */
      public function getDeclaration(array $allConstInfos): string {
-         $escapedName = addslashes($this->name);
+         $escapedName = addslashes($this->name->case);
          if ($this->value === null) {
 -            $code = "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
 -        } else {
 -            $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
 -
 -            $zvalName = "enum_case_{$escapedName}_value";
 -            $code = "\n" . $value->initializeZval($zvalName);
 -            $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
 +            return "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
          }
 +        $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
 +
 +        $zvalName = "enum_case_{$escapedName}_value";
 +        $code = "\n" . $value->initializeZval($zvalName);
 +        $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";

          return $code;
      }
@@@ -4351,147 -4650,6 +4435,147 @@@ class FileInfo

          return $code;
      }
 +
 +    public function generateCDeclarations(): string {
 +        $code = "";
 +
 +        if (!$this->generateCEnums) {
 +            return $code;
 +        }
 +
 +        foreach ($this->classInfos as $class) {
 +            $cdecl = $class->getCDeclarations();
 +            if ($cdecl !== '') {
 +                $code .= "\n" . $cdecl;
 +            }
 +        }
 +
 +        return $code;
 +    }
 +
-
++
 +    /**
 +     * @param array<string, ConstInfo> $allConstInfos
 +     * @return array{string, string}
 +     */
 +    public function generateArgInfoCode(
 +        string $stubFilenameWithoutExtension,
 +        array $allConstInfos,
 +        string $stubHash
 +    ): array {
 +        $code = "";
 +
 +        $generatedFuncInfos = [];
 +
 +        $argInfoCode = generateCodeWithConditions(
 +            $this->getAllFuncInfos(), "\n",
 +            function (FuncInfo $funcInfo) use (&$generatedFuncInfos) {
 +                /* If there already is an equivalent arginfo structure, only emit a #define */
 +                if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
 +                    $code = sprintf(
 +                        "#define %s %s\n",
 +                        $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
 +                    );
 +                } else {
 +                    $code = $funcInfo->toArgInfoCode($this->getMinimumPhpVersionIdCompatibility());
 +                }
 +
 +                $generatedFuncInfos[] = $funcInfo;
 +                return $code;
 +            }
 +        );
 +
 +        if ($argInfoCode !== "") {
 +            $code .= "$argInfoCode\n";
 +        }
 +
 +        if ($this->generateFunctionEntries) {
 +            $framelessFunctionCode = generateCodeWithConditions(
 +                $this->getAllFuncInfos(), "\n",
 +                static function (FuncInfo $funcInfo) {
 +                    return $funcInfo->getFramelessDeclaration();
 +                }
 +            );
 +
 +            if ($framelessFunctionCode !== "") {
 +                $code .= "$framelessFunctionCode\n";
 +            }
 +
 +            $generatedFunctionDeclarations = [];
 +            $code .= generateCodeWithConditions(
 +                $this->getAllFuncInfos(), "",
 +                function (FuncInfo $funcInfo) use (&$generatedFunctionDeclarations) {
 +                    $key = $funcInfo->getDeclarationKey();
 +                    if (isset($generatedFunctionDeclarations[$key])) {
 +                        return null;
 +                    }
 +
 +                    $generatedFunctionDeclarations[$key] = true;
 +                    return $this->declarationPrefix . $funcInfo->getDeclaration();
 +                }
 +            );
 +
 +            $code .= generateFunctionEntries(null, $this->funcInfos);
 +
 +            foreach ($this->classInfos as $classInfo) {
 +                $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
 +            }
 +        }
 +
 +        $php80MinimumCompatibility = $this->getMinimumPhpVersionIdCompatibility() === null || $this->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
 +
 +        if ($this->generateClassEntries) {
 +            $declaredStrings = [];
 +            $attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
 +            $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
 +            if ($attributeInitializationCode) {
 +                if (!$php80MinimumCompatibility) {
 +                    $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
 +                }
 +            }
 +
 +            if ($attributeInitializationCode !== "" || !empty($this->constInfos)) {
 +                $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
 +                $code .= "{\n";
 +
 +                $code .= generateCodeWithConditions(
 +                    $this->constInfos,
 +                    '',
 +                    static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
 +                );
 +
 +                if ($attributeInitializationCode !== "" && $this->constInfos) {
 +                    $code .= "\n";
 +                }
 +
 +                $code .= $attributeInitializationCode;
 +                $code .= "}\n";
 +            }
 +
 +            $code .= $this->generateClassEntryCode($allConstInfos);
 +        }
 +
 +        $hasDeclFile = false;
 +        $declCode = $this->generateCDeclarations();
 +        if ($declCode !== '') {
 +            $hasDeclFile = true;
 +            $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
 +            $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
 +                . " * Stub hash: $stubHash */\n"
 +                . "\n"
 +                . "#ifndef {$headerName}\n"
 +                . "#define {$headerName}\n"
 +                . $declCode . "\n"
 +                . "#endif /* {$headerName} */\n";
 +        }
 +
 +        $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
 +            . " * Stub hash: $stubHash"
 +            . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
 +            . $code;
 +
 +        return [$code, $declCode];
 +    }
  }

  class DocCommentTag {