-
Notifications
You must be signed in to change notification settings - Fork 8k
gen_stub: Add support for generation C #include statements
#19869
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1299,6 +1299,19 @@ public function generateVersionDependentFlagCode( | |
| } | ||
| } | ||
|
|
||
| class IncludeInfo { | ||
| public /* readonly */ ?string $cond; | ||
| public /* readonly */ string $include; | ||
|
|
||
| public function __construct( | ||
| string $include, | ||
| ?string $cond, | ||
| ) { | ||
| $this->include = $include; | ||
| $this->cond = $cond; | ||
| } | ||
| } | ||
|
|
||
| class FuncInfo { | ||
| public /* readonly */ FunctionOrMethodName $name; | ||
| private /* readonly */ int $classFlags; | ||
|
|
@@ -4189,6 +4202,8 @@ class FileInfo { | |
| public array $funcInfos = []; | ||
| /** @var ClassInfo[] */ | ||
| public array $classInfos = []; | ||
| /** @var IncludeInfo[] */ | ||
| public array $includeInfos = []; | ||
| public bool $generateFunctionEntries = false; | ||
| public string $declarationPrefix = ""; | ||
| public bool $generateClassEntries = false; | ||
|
|
@@ -4337,6 +4352,16 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri | |
| $conds = []; | ||
| foreach ($stmts as $stmt) { | ||
| $cond = self::handlePreprocessorConditions($conds, $stmt); | ||
|
|
||
| if ($stmt instanceof Stmt\Declare_) { | ||
| foreach ($stmt->declares as $declare) { | ||
| if ($declare->key->name !== 'c_include') { | ||
| throw new Exception("Unexpected declare {$declare->key->name}"); | ||
| } | ||
| $this->includeInfos[] = new IncludeInfo((string)EvaluatedValue::createFromExpression($declare->value, null, null, [])->value, $cond); | ||
| } | ||
| continue; | ||
| } | ||
|
|
||
| if ($stmt instanceof Stmt\Nop) { | ||
| continue; | ||
|
|
@@ -5111,7 +5136,7 @@ function generateCodeWithConditions( | |
| continue; | ||
| } | ||
|
|
||
| if ($info->cond && $info->cond !== $parentCond) { | ||
| if ($info->cond !== null && $info->cond !== $parentCond) { | ||
| if ($openCondition !== null | ||
| && $info->cond !== $openCondition | ||
| ) { | ||
|
|
@@ -5162,6 +5187,17 @@ function generateArgInfoCode( | |
|
|
||
| $generatedFuncInfos = []; | ||
|
|
||
| $argInfoCode = generateCodeWithConditions( | ||
| $fileInfo->includeInfos, "\n", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need both a "\n" at the end of each line and a "\n" when combining them, that leads to blank lines between the inclusions |
||
| static function (IncludeInfo $includeInfo) { | ||
| return sprintf("#include %s\n", $includeInfo->include); | ||
| } | ||
| ); | ||
|
|
||
| if ($argInfoCode !== "") { | ||
| $code .= "$argInfoCode\n"; | ||
| } | ||
|
|
||
| $argInfoCode = generateCodeWithConditions( | ||
| $fileInfo->getAllFuncInfos(), "\n", | ||
| static function (FuncInfo $funcInfo) use (&$generatedFuncInfos, $fileInfo) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,14 @@ | |
| * @generate-legacy-arginfo 80000 | ||
| * @undocumentable | ||
| */ | ||
|
|
||
| #if 0 | ||
| declare( | ||
| c_include='<stdint.h>', | ||
| c_include='"zend_attributes.h"' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My 2 cents: why I'm not enthusiastic about this feature is that it would add even more C code in stubs. For ifdefs and a few constant values it was unavoidable, but these includes are different: one should decide if they need a particular include or not, or which includes they want to use.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one in
|
||
| ); | ||
| #endif | ||
|
|
||
| namespace { | ||
| require "Zend/zend_attributes.stub.php"; | ||
|
|
||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think using
declare()is the right approach here, it adds a new declaration in stubs that isn't valid in normal PHP code, meaning that stubs would no longer be valid PHP:can I suggest instead just using a C preprocessor macro,
#include <stdint.h>this would be a comment, so it would get skipped in the next block, and you would just add handling to
handlePreprocessorConditionsto ensure that for#includea new IncludeInfo is added (make thehandlePreprocessorConditionsmethod non-static)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree that this is somewhat abusing the existing PHP syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a warning. It's valid PHP code.
I initially tried that, but it got pretty ugly: The existing logic to handle
#if/#endifis “statement-based”. Since the#includewould not be a statement, special handling would be required.Also the
declarenicely forces the#includeto appear at the top of the file, avoiding random includes from appearing somewhere in the middle of the stub.