C++: IR generation for repeated initializers.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-04-04 10:08:32 +01:00
parent a0df7d22cd
commit bef0a159c0
3 changed files with 65 additions and 18 deletions

View File

@@ -190,10 +190,23 @@ class ClassAggregateLiteral extends AggregateLiteral {
* Gets the expression within the aggregate literal that is used to initialize
* field `field`, if present.
*/
Expr getFieldExpr(Field field) {
Expr getFieldExpr(Field field) { result = this.getFieldExpr(field, _) }
/**
* Gets the expression within the aggregate literal that is used to initialize
* field `field` the `repitition`'th time in the initializer list, if present.
*
* For example, if `aggr` represents the initialization literal `{.x = 1234, .x = 5678}` in
* ```cpp
* struct Foo { int x; };
* struct Foo foo = {.x = 1234, .x = 5678};
* ```
* then `aggr.getFieldExpr(x, 0)` gives `1234`, and `aggr.getFieldExpr(x, 1)` gives `5678`.
*/
Expr getFieldExpr(Field field, int repitition) {
field = classType.getAField() and
aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field),
_)
repitition)
}
/**
@@ -264,8 +277,20 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
* Gets the expression within the aggregate literal that is used to initialize
* element `elementIndex`, if present.
*/
Expr getElementExpr(int elementIndex) {
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, _)
Expr getElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) }
/**
* Gets the expression within the aggregate literal that is used to initialize
* element `elementIndex` the `repitition`'th time in the initializer list, if present.
*
* For example, if `a` represents the initialization literal `{[0] = 1234, [0] = 5678}` in
* ```cpp
* int x[1] = {[0] = 1234, [0] = 5678};
* ```
* then `a.getElementExpr(0, 0)` gives `1234`, and `a.getElementExpr(0, 1)` gives `5678`.
*/
Expr getElementExpr(int elementIndex, int repitition) {
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, repitition)
}
/**

View File

@@ -619,18 +619,19 @@ newtype TTranslatedElement =
)
} or
// The initialization of a field via a member of an initializer list.
TTranslatedExplicitFieldInitialization(Expr ast, Field field, Expr expr) {
TTranslatedExplicitFieldInitialization(Expr ast, Field field, Expr expr, int repitition) {
exists(ClassAggregateLiteral initList |
not ignoreExpr(initList) and
ast = initList and
expr = initList.getFieldExpr(field).getFullyConverted()
expr = initList.getFieldExpr(field, repitition).getFullyConverted()
)
or
exists(ConstructorFieldInit init |
not ignoreExpr(init) and
ast = init and
field = init.getTarget() and
expr = init.getExpr().getFullyConverted()
expr = init.getExpr().getFullyConverted() and
repitition = 0
)
} or
// The value initialization of a field due to an omitted member of an
@@ -643,9 +644,11 @@ newtype TTranslatedElement =
)
} or
// The initialization of an array element via a member of an initializer list.
TTranslatedExplicitElementInitialization(ArrayOrVectorAggregateLiteral initList, int elementIndex) {
TTranslatedExplicitElementInitialization(
ArrayOrVectorAggregateLiteral initList, int elementIndex, int repitition
) {
not ignoreExpr(initList) and
exists(initList.getElementExpr(elementIndex))
exists(initList.getElementExpr(elementIndex, repitition))
} or
// The value initialization of a range of array elements that were omitted
// from an initializer list.

View File

@@ -201,10 +201,12 @@ class TranslatedClassListInitialization extends TranslatedListInitialization {
override ClassAggregateLiteral expr;
override TranslatedElement getChild(int id) {
exists(TranslatedFieldInitialization fieldInit |
result = fieldInit and
result =
rank[id + 1](TranslatedFieldInitialization fieldInit, int ord |
fieldInit = getTranslatedFieldInitialization(expr, _) and
fieldInit.getOrder() = id
fieldInit.getOrder() = ord
|
fieldInit order by ord, fieldInit.getRepetitionIndex()
)
}
}
@@ -222,7 +224,7 @@ class TranslatedArrayListInitialization extends TranslatedListInitialization {
rank[id + 1](TranslatedElementInitialization init |
init.getInitList() = expr
|
init order by init.getElementIndex()
init order by init.getElementIndex(), init.getRepetitionIndex()
)
}
}
@@ -522,6 +524,12 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
final Field getField() { result = field }
/**
* Gets the index of this initialization, if the field is mentioned
* multiple times in the initializer.
*/
int getRepetitionIndex() { result = 0 }
}
/**
@@ -532,9 +540,10 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
InitializationContext, TTranslatedExplicitFieldInitialization
{
Expr expr;
int repitition;
TranslatedExplicitFieldInitialization() {
this = TTranslatedExplicitFieldInitialization(ast, field, expr)
this = TTranslatedExplicitFieldInitialization(ast, field, expr, repitition)
}
override Instruction getTargetAddress() { result = getInstruction(getFieldAddressTag()) }
@@ -556,6 +565,8 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
private TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(expr)
}
override int getRepetitionIndex() { result = repitition }
}
private string getZeroValue(Type type) {
@@ -689,6 +700,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
abstract int getElementIndex();
int getRepetitionIndex() { result = 0 }
final InstructionTag getElementAddressTag() { result = InitializerElementAddressTag() }
final InstructionTag getElementIndexTag() { result = InitializerElementIndexTag() }
@@ -706,9 +719,10 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
TTranslatedExplicitElementInitialization, InitializationContext
{
int elementIndex;
int repetition;
TranslatedExplicitElementInitialization() {
this = TTranslatedExplicitElementInitialization(initList, elementIndex)
this = TTranslatedExplicitElementInitialization(initList, elementIndex, repetition)
}
override Instruction getTargetAddress() { result = getInstruction(getElementAddressTag()) }
@@ -731,8 +745,13 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
override int getElementIndex() { result = elementIndex }
override int getRepetitionIndex() { result = repetition }
TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(initList.getElementExpr(elementIndex).getFullyConverted())
result =
getTranslatedInitialization(initList
.getElementExpr(elementIndex, repetition)
.getFullyConverted())
}
}