Code cleanup: Add isMain() accessor to FunctionDeclaration.
This returns true if the function name is `main`. We have special treatment for functions named `main` in various places throughout the compiler, so this accessor comes in handy fairly often. Change-Id: I9da17648800f0385875e1e7d66aacb5f3dea3817 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/388443 Commit-Queue: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
3f5bee1a7a
commit
e8da4d2757
@ -230,7 +230,7 @@ SkRuntimeEffect::Result SkRuntimeEffect::Make(SkString sksl, const Options& opti
|
||||
else if (elem->is<SkSL::FunctionDefinition>()) {
|
||||
const auto& func = elem->as<SkSL::FunctionDefinition>();
|
||||
const SkSL::FunctionDeclaration& decl = func.declaration();
|
||||
if (decl.name() == "main") {
|
||||
if (decl.isMain()) {
|
||||
main = &func;
|
||||
}
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ static const char* glsltype_string(const Context& context, const Type& type) {
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::prepareHelperFunction(const FunctionDeclaration& decl) {
|
||||
if (decl.isBuiltin() || decl.name() == "main") {
|
||||
if (decl.isBuiltin() || decl.isMain()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -557,7 +557,7 @@ void CPPCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
OutputStream* oldOut = fOut;
|
||||
StringStream buffer;
|
||||
fOut = &buffer;
|
||||
if (decl.name() == "main") {
|
||||
if (decl.isMain()) {
|
||||
fInMain = true;
|
||||
for (const std::unique_ptr<Statement>& s : f.body()->as<Block>().children()) {
|
||||
this->writeStatement(*s);
|
||||
|
@ -541,7 +541,7 @@ bool Compiler::removeDeadFunctions(Program& program, ProgramUsage* usage) {
|
||||
return false;
|
||||
}
|
||||
const FunctionDefinition& fn = element->as<FunctionDefinition>();
|
||||
if (fn.declaration().name() == "main" || usage->get(fn.declaration()) > 0) {
|
||||
if (fn.declaration().isMain() || usage->get(fn.declaration()) > 0) {
|
||||
return false;
|
||||
}
|
||||
usage->remove(*element);
|
||||
|
@ -907,7 +907,7 @@ void IRGenerator::finalizeFunction(const FunctionDeclaration& funcDecl, Statemen
|
||||
// will probably never actually be necessary.
|
||||
SkASSERT(fIRGenerator->programKind() != ProgramKind::kVertex ||
|
||||
!fIRGenerator->fRTAdjust ||
|
||||
fFunction->name() != "main");
|
||||
!fFunction->isMain());
|
||||
|
||||
// Verify that the return statement matches the function's return type.
|
||||
ReturnStatement& returnStmt = stmt.as<ReturnStatement>();
|
||||
@ -1010,6 +1010,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
return;
|
||||
}
|
||||
const ASTNode::FunctionData& funcData = f.getFunctionData();
|
||||
bool isMain = (funcData.fName == "main");
|
||||
|
||||
// Check function modifiers.
|
||||
this->checkModifiers(
|
||||
@ -1053,7 +1054,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
}
|
||||
|
||||
Modifiers m = pd.fModifiers;
|
||||
if (funcData.fName == "main" && (this->programKind() == ProgramKind::kRuntimeEffect ||
|
||||
if (isMain && (this->programKind() == ProgramKind::kRuntimeEffect ||
|
||||
this->programKind() == ProgramKind::kFragmentProcessor)) {
|
||||
if (i == 0) {
|
||||
// We verify that the type is correct later, for now, if there is a parameter to
|
||||
@ -1075,7 +1076,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
};
|
||||
|
||||
// Check the function signature of `main`.
|
||||
if (funcData.fName == "main") {
|
||||
if (isMain) {
|
||||
switch (this->programKind()) {
|
||||
case ProgramKind::kRuntimeEffect: {
|
||||
// (half4|float4) main() -or- (half4|float4) main(float2)
|
||||
@ -1212,7 +1213,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
for (const Variable* param : decl->parameters()) {
|
||||
fSymbolTable->addWithoutOwnership(param);
|
||||
}
|
||||
bool needInvocationIDWorkaround = fInvocations != -1 && funcData.fName == "main" &&
|
||||
bool needInvocationIDWorkaround = fInvocations != -1 && isMain &&
|
||||
!this->caps().gsInvocationsSupport();
|
||||
std::unique_ptr<Block> body = this->convertBlock(*iter);
|
||||
if (!body) {
|
||||
@ -1221,7 +1222,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
if (needInvocationIDWorkaround) {
|
||||
body = this->applyInvocationIDWorkaround(std::move(body));
|
||||
}
|
||||
if (ProgramKind::kVertex == this->programKind() && funcData.fName == "main" && fRTAdjust) {
|
||||
if (ProgramKind::kVertex == this->programKind() && isMain && fRTAdjust) {
|
||||
body->children().push_back(this->getNormalizeSkPositionCode());
|
||||
}
|
||||
this->finalizeFunction(*decl, body.get());
|
||||
@ -2023,7 +2024,7 @@ void IRGenerator::findAndDeclareBuiltinVariables() {
|
||||
const FunctionDefinition& funcDef = pe.as<FunctionDefinition>();
|
||||
// We synthesize writes to sk_FragColor if main() returns a color, even if it's
|
||||
// otherwise unreferenced. Check main's return type to see if it's half4.
|
||||
if (funcDef.declaration().name() == "main" &&
|
||||
if (funcDef.declaration().isMain() &&
|
||||
funcDef.declaration().returnType() == *fGenerator->fContext.fTypes.fHalf4) {
|
||||
fPreserveFragColor = true;
|
||||
}
|
||||
|
@ -1457,7 +1457,7 @@ int MetalCodeGenerator::getUniformSet(const Modifiers& m) {
|
||||
bool MetalCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& f) {
|
||||
fRTHeightName = fProgram.fInputs.fRTHeight ? "_globals._anonInterface0->u_skRTHeight" : "";
|
||||
const char* separator = "";
|
||||
if ("main" == f.name()) {
|
||||
if (f.isMain()) {
|
||||
switch (fProgram.fConfig->fKind) {
|
||||
case ProgramKind::kFragment:
|
||||
this->write("fragment Outputs fragmentMain");
|
||||
@ -1587,7 +1587,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
|
||||
this->writeLine(" {");
|
||||
|
||||
if (f.declaration().name() == "main") {
|
||||
if (f.declaration().isMain()) {
|
||||
this->writeGlobalInit();
|
||||
this->writeLine(" Outputs _out;");
|
||||
this->writeLine(" (void)_out;");
|
||||
@ -1604,7 +1604,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
this->finishLine();
|
||||
}
|
||||
}
|
||||
if (f.declaration().name() == "main") {
|
||||
if (f.declaration().isMain()) {
|
||||
// If the main function doesn't end with a return, we need to synthesize one here.
|
||||
if (!is_block_ending_with_return(f.body().get())) {
|
||||
this->writeReturnStatementFromMain();
|
||||
@ -1891,7 +1891,7 @@ void MetalCodeGenerator::writeReturnStatementFromMain() {
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
|
||||
if (fCurrentFunction && fCurrentFunction->name() == "main") {
|
||||
if (fCurrentFunction && fCurrentFunction->isMain()) {
|
||||
if (r.expression()) {
|
||||
if (r.expression()->type() == *fContext.fTypes.fHalf4) {
|
||||
this->write("_out.sk_FragColor = ");
|
||||
|
@ -282,9 +282,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
// if the return type is float4 - injecting it unconditionally reduces the risk of an
|
||||
// obscure bug.
|
||||
const FunctionDeclaration& decl = f.declaration();
|
||||
bool isMain = decl.name() == "main";
|
||||
|
||||
if (isMain) {
|
||||
if (decl.isMain()) {
|
||||
fCastReturnsToHalf = true;
|
||||
}
|
||||
|
||||
@ -293,11 +291,12 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
this->writeLine();
|
||||
}
|
||||
|
||||
if (isMain) {
|
||||
if (decl.isMain()) {
|
||||
fCastReturnsToHalf = false;
|
||||
}
|
||||
|
||||
String fnName = isMain ? "main" : fCallbacks->getMangledName(String(decl.name()).c_str());
|
||||
String fnName = decl.isMain() ? decl.name()
|
||||
: fCallbacks->getMangledName(String(decl.name()).c_str());
|
||||
|
||||
// This is similar to decl.description(), but substitutes a mangled name, and handles modifiers
|
||||
// on the function (e.g. `inline`) and its parameters (e.g. `inout`).
|
||||
@ -320,7 +319,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
declString.append(")");
|
||||
|
||||
fFunctionNames.insert({&decl, std::move(fnName)});
|
||||
fCallbacks->defineFunction(declString.c_str(), body.fBuffer.str().c_str(), isMain);
|
||||
fCallbacks->defineFunction(declString.c_str(), body.fBuffer.str().c_str(), decl.isMain());
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeGlobalVarDeclaration(const GlobalVarDeclaration& g) {
|
||||
|
@ -2713,7 +2713,7 @@ SpvId SPIRVCodeGenerator::writeFunction(const FunctionDefinition& f, OutputStrea
|
||||
StringStream bodyBuffer;
|
||||
this->writeBlock(f.body()->as<Block>(), bodyBuffer);
|
||||
write_stringstream(fVariableBuffer, out);
|
||||
if (f.declaration().name() == "main") {
|
||||
if (f.declaration().isMain()) {
|
||||
write_stringstream(fGlobalInitializersBuffer, out);
|
||||
}
|
||||
write_stringstream(bodyBuffer, out);
|
||||
@ -3314,7 +3314,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
const FunctionDefinition& funcDef = e->as<FunctionDefinition>();
|
||||
const FunctionDeclaration& funcDecl = funcDef.declaration();
|
||||
fFunctionMap[&funcDecl] = this->nextId(nullptr);
|
||||
if (funcDecl.name() == "main") {
|
||||
if (funcDecl.isMain()) {
|
||||
main = &funcDecl;
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ public:
|
||||
, fModifiers(modifiers)
|
||||
, fParameters(std::move(parameters))
|
||||
, fReturnType(returnType)
|
||||
, fBuiltin(builtin) {}
|
||||
, fBuiltin(builtin)
|
||||
, fIsMain(name == "main") {}
|
||||
|
||||
const Modifiers& modifiers() const {
|
||||
return *fModifiers;
|
||||
@ -61,8 +62,12 @@ public:
|
||||
return fBuiltin;
|
||||
}
|
||||
|
||||
bool isMain() const {
|
||||
return fIsMain;
|
||||
}
|
||||
|
||||
String mangledName() const {
|
||||
if ((this->isBuiltin() && !this->definition()) || this->name() == "main") {
|
||||
if ((this->isBuiltin() && !this->definition()) || this->isMain()) {
|
||||
// Builtins without a definition (like `sin` or `sqrt`) must use their real names.
|
||||
return this->name();
|
||||
}
|
||||
@ -175,6 +180,7 @@ private:
|
||||
std::vector<const Variable*> fParameters;
|
||||
const Type* fReturnType;
|
||||
bool fBuiltin;
|
||||
bool fIsMain;
|
||||
|
||||
using INHERITED = Symbol;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user