-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17918 from hvitved/rust/cfg-codegen
Rust: Add (auto-generated) CFG node wrapper classes
- Loading branch information
Showing
29 changed files
with
5,008 additions
and
616 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
// generated by {{generator}}, do not edit | ||
/** | ||
* This module provides generated wrappers around the `CfgNode` type. | ||
* | ||
* INTERNAL: Do not import directly. | ||
*/ | ||
|
||
private import codeql.util.Location | ||
private import codeql.util.Unit | ||
private import {{include_file_import}} | ||
|
||
/** Provides the input to `MakeCfgNodes` */ | ||
signature module InputSig<LocationSig Loc> { | ||
class CfgNode { | ||
AstNode getAstNode(); | ||
string toString(); | ||
Loc getLocation(); | ||
} | ||
|
||
AstNode getDesugared(AstNode n); | ||
} | ||
|
||
/** | ||
* Given a `CfgNode` implementation, provides the module `Nodes` that | ||
* contains wrappers around `CfgNode` for relevant classes. | ||
*/ | ||
module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> { | ||
private import Input | ||
final private class AstNodeFinal = AstNode; | ||
final private class CfgNodeFinal = CfgNode; | ||
/** | ||
* INTERNAL: Do not expose. | ||
*/ | ||
abstract class ParentAstNode extends AstNodeFinal { | ||
/** | ||
* Holds if `child` is a (possibly nested) child of this AST node | ||
* for which we would like to find a matching CFG child. | ||
*/ | ||
abstract predicate relevantChild(AstNode child); | ||
} | ||
|
||
/** | ||
* INTERNAL: Do not expose. | ||
*/ | ||
abstract class ChildMapping extends Unit { | ||
/** | ||
* Holds if `child` is a (possibly nested) child of AST node `parent` | ||
* for which we would like to find a matching CFG child. | ||
*/ | ||
final predicate relevantChild(AstNode parent, AstNode child) { | ||
parent.(ParentAstNode).relevantChild(child) | ||
} | ||
|
||
/** | ||
* Holds if there is a control flow path from `cfn` to `cfnChild`, where `cfn` | ||
* is a control flow node for this AST node, and `cfnChild` is a control flow | ||
* node for `child`. | ||
* | ||
* This predicate should be implemented at the place where `MakeCfgNodes` is | ||
* invoked. Ideally, `MakeCfgNodes` should be a higher-order parameterized | ||
* module, but since that is currently not supported, we achieve the "callback" | ||
* effect using this `abstract` class instead. | ||
*/ | ||
cached | ||
abstract predicate hasCfgChild(AstNode parent, AstNode child, CfgNode cfn, CfgNode cfnChild); | ||
} | ||
|
||
/** Provides sub classes of `CfgNode`. */ | ||
module Nodes { | ||
{{#classes}} | ||
private final class Parent{{name}} extends ParentAstNode, {{name}} { | ||
override predicate relevantChild(AstNode child) { | ||
none() | ||
{{#properties}} | ||
{{#cfg}} | ||
or | ||
child = this.{{getter}}({{#is_indexed}}_{{/is_indexed}}) | ||
{{/cfg}} | ||
{{/properties}} | ||
} | ||
} | ||
|
||
/** | ||
{{#doc}} | ||
* {{.}} | ||
{{/doc}} | ||
*/ | ||
final class {{name}}CfgNode extends CfgNodeFinal{{#bases}}, {{.}}CfgNode{{/bases}} { | ||
private {{name}} node; | ||
|
||
{{name}}CfgNode() { | ||
node = this.getAstNode() | ||
} | ||
|
||
/** Gets the underlying `{{name}}`. */ | ||
{{name}} get{{name}}() { result = node } | ||
|
||
{{#properties}} | ||
/** | ||
* {{>ql_property_doc}} * | ||
{{#description}} | ||
* {{.}} | ||
{{/description}} | ||
{{#internal}} | ||
* INTERNAL: Do not use. | ||
{{/internal}} | ||
*/ | ||
{{type}}{{#cfg}}CfgNode{{/cfg}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { | ||
{{#cfg}} | ||
any(ChildMapping mapping).hasCfgChild(node, node.{{getter}}({{#is_indexed}}index{{/is_indexed}}), this, result) | ||
{{/cfg}} | ||
{{^cfg}} | ||
{{^is_predicate}}result = {{/is_predicate}}node.{{getter}}({{#is_indexed}}index{{/is_indexed}}) | ||
{{/cfg}} | ||
} | ||
|
||
{{#is_optional}} | ||
/** | ||
* Holds if `{{getter}}({{#is_repeated}}index{{/is_repeated}})` exists. | ||
{{#internal}} | ||
* INTERNAL: Do not use. | ||
{{/internal}} | ||
*/ | ||
predicate has{{singular}}({{#is_repeated}}int index{{/is_repeated}}) { | ||
exists(this.{{getter}}({{#is_repeated}}index{{/is_repeated}})) | ||
} | ||
{{/is_optional}} | ||
{{#is_indexed}} | ||
|
||
/** | ||
* Gets any of the {{doc_plural}}. | ||
{{#internal}} | ||
* INTERNAL: Do not use. | ||
{{/internal}} | ||
*/ | ||
{{type}}{{#cfg}}CfgNode{{/cfg}} {{indefinite_getter}}() { | ||
result = this.{{getter}}(_) | ||
} | ||
{{^is_optional}} | ||
|
||
/** | ||
* Gets the number of {{doc_plural}}. | ||
{{#internal}} | ||
* INTERNAL: Do not use. | ||
{{/internal}} | ||
*/ | ||
int getNumberOf{{plural}}() { | ||
result = count(int i | exists(this.{{getter}}(i))) | ||
} | ||
{{/is_optional}} | ||
{{/is_indexed}} | ||
{{#is_unordered}} | ||
/** | ||
* Gets the number of {{doc_plural}}. | ||
{{#internal}} | ||
* INTERNAL: Do not use. | ||
{{/internal}} | ||
*/ | ||
int getNumberOf{{plural}}() { | ||
result = count(this.{{getter}}()) | ||
} | ||
{{/is_unordered}} | ||
{{/properties}} | ||
} | ||
{{/classes}} | ||
} | ||
|
||
module Consistency { | ||
private predicate hasCfgNode(AstNode astNode) { | ||
astNode = any(CfgNode cfgNode).getAstNode() | ||
} | ||
|
||
query predicate missingCfgChild(CfgNode parent, string pred, int i, AstNode child) { | ||
none() | ||
{{#classes}} | ||
{{#properties}} | ||
{{#cfg}} | ||
or | ||
pred = "{{getter}}" and | ||
parent = any(Nodes::{{name}}CfgNode cfgNode, {{name}} astNode | | ||
astNode = cfgNode.get{{name}}() and | ||
child = getDesugared(astNode.{{getter}}({{#is_indexed}}i{{/is_indexed}})) | ||
{{^is_indexed}}and i = -1{{/is_indexed}} and | ||
hasCfgNode(child) and | ||
not child = cfgNode.{{getter}}({{#is_indexed}}i{{/is_indexed}}).getAstNode() | ||
| | ||
cfgNode | ||
) | ||
{{/cfg}} | ||
{{/properties}} | ||
{{/classes}} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.