Stop cloning elements that declare builtin enums
Instead, add them to the shared element list (like functions and variables). Bug: skia:10905 Change-Id: Ib52b4c5eaca9a3023532c5f7021d0ac263ab64ac Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345476 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
c819bb16ee
commit
e0049aac38
@ -2719,46 +2719,51 @@ std::unique_ptr<Expression> IRGenerator::valueForSetting(int offset, String name
|
|||||||
|
|
||||||
std::unique_ptr<Expression> IRGenerator::convertTypeField(int offset, const Type& type,
|
std::unique_ptr<Expression> IRGenerator::convertTypeField(int offset, const Type& type,
|
||||||
StringFragment field) {
|
StringFragment field) {
|
||||||
// Find the Enum element that this type refers to (if any)
|
|
||||||
const ProgramElement* enumElement = nullptr;
|
const ProgramElement* enumElement = nullptr;
|
||||||
for (const auto& e : *fProgramElements) {
|
// Find the Enum element that this type refers to, start by searching our elements
|
||||||
|
for (const std::unique_ptr<ProgramElement>& e : *fProgramElements) {
|
||||||
if (e->is<Enum>() && type.name() == e->as<Enum>().typeName()) {
|
if (e->is<Enum>() && type.name() == e->as<Enum>().typeName()) {
|
||||||
enumElement = e.get();
|
enumElement = e.get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ... if that fails, look in our shared elements
|
||||||
if (enumElement) {
|
if (!enumElement) {
|
||||||
// We found the Enum element. Look for 'field' as a member.
|
for (const ProgramElement* e : *fSharedElements) {
|
||||||
std::shared_ptr<SymbolTable> old = fSymbolTable;
|
if (e->is<Enum>() && type.name() == e->as<Enum>().typeName()) {
|
||||||
fSymbolTable = enumElement->as<Enum>().symbols();
|
enumElement = e;
|
||||||
std::unique_ptr<Expression> result = convertIdentifier(
|
break;
|
||||||
ASTNode(&fFile->fNodes, offset, ASTNode::Kind::kIdentifier, field));
|
|
||||||
if (result) {
|
|
||||||
const Variable& v = *result->as<VariableReference>().variable();
|
|
||||||
SkASSERT(v.initialValue());
|
|
||||||
result = std::make_unique<IntLiteral>(
|
|
||||||
offset, v.initialValue()->as<IntLiteral>().value(), &type);
|
|
||||||
} else {
|
|
||||||
fErrors.error(offset,
|
|
||||||
"type '" + type.name() + "' does not have a member named '" + field +
|
|
||||||
"'");
|
|
||||||
}
|
|
||||||
fSymbolTable = old;
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
// No Enum element? Check the intrinsics, clone it into the program, try again.
|
|
||||||
if (!fIsBuiltinCode && fIntrinsics) {
|
|
||||||
if (const ProgramElement* found = fIntrinsics->findAndInclude(type.name())) {
|
|
||||||
fProgramElements->push_back(found->clone());
|
|
||||||
return this->convertTypeField(offset, type, field);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fErrors.error(offset,
|
}
|
||||||
"type '" + type.displayName() + "' does not have a member named '" + field +
|
// ... and if that fails, check the intrinsics, add it to our shared elements
|
||||||
"'");
|
if (!enumElement && !fIsBuiltinCode && fIntrinsics) {
|
||||||
|
if (const ProgramElement* found = fIntrinsics->findAndInclude(type.name())) {
|
||||||
|
fSharedElements->push_back(found);
|
||||||
|
enumElement = found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!enumElement) {
|
||||||
|
fErrors.error(offset, "type '" + type.displayName() + "' is not a known enum");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We found the Enum element. Look for 'field' as a member.
|
||||||
|
std::shared_ptr<SymbolTable> old = fSymbolTable;
|
||||||
|
fSymbolTable = enumElement->as<Enum>().symbols();
|
||||||
|
std::unique_ptr<Expression> result =
|
||||||
|
convertIdentifier(ASTNode(&fFile->fNodes, offset, ASTNode::Kind::kIdentifier, field));
|
||||||
|
if (result) {
|
||||||
|
const Variable& v = *result->as<VariableReference>().variable();
|
||||||
|
SkASSERT(v.initialValue());
|
||||||
|
result = std::make_unique<IntLiteral>(offset, v.initialValue()->as<IntLiteral>().value(),
|
||||||
|
&type);
|
||||||
|
} else {
|
||||||
|
fErrors.error(offset,
|
||||||
|
"type '" + type.name() + "' does not contain enumerator '" + field + "'");
|
||||||
|
}
|
||||||
|
fSymbolTable = old;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Expression> IRGenerator::convertIndexExpression(const ASTNode& index) {
|
std::unique_ptr<Expression> IRGenerator::convertIndexExpression(const ASTNode& index) {
|
||||||
|
Loading…
Reference in New Issue
Block a user