Made IRNode smaller

This backs off a bit on the "stuff everything into IRNode" push, moving
the data of the big nodes back into them and significantly cutting the
size of IRNode. This isn't a complete revert of the changes to these
nodes - now that all of the fields have been hidden behind accessor
methods, it's merely an implementation detail where the data actually
lives, so these changes are much smaller and more targeted.

Change-Id: I84c770245f26dfe36651d0f482543505bd7f71ef
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329629
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2020-10-26 15:06:46 -04:00 committed by Skia Commit-Bot
parent 7737a5bd25
commit 6f87de7c27
13 changed files with 117 additions and 361 deletions

View File

@ -18,7 +18,7 @@ namespace SkSL {
class ErrorReporter;
class Expression;
class FunctionDeclaration;
struct FunctionDefinition;
class FunctionDefinition;
struct Program;
class ProgramElement;
class ProgramUsage;

View File

@ -20,7 +20,7 @@ class Block;
class Context;
class Expression;
class FunctionCall;
struct FunctionDefinition;
class FunctionDefinition;
struct InlineCandidate;
struct InlineCandidateList;
class ModifiersPool;

View File

@ -26,22 +26,26 @@ public:
Enum(int offset, StringFragment typeName, std::shared_ptr<SymbolTable> symbols,
bool isSharedWithCpp, bool isBuiltin = true)
: INHERITED(offset, EnumData{typeName, std::move(symbols), isSharedWithCpp, isBuiltin}) {}
: INHERITED(offset, kProgramElementKind)
, fTypeName(typeName)
, fSymbols(std::move(symbols))
, fIsSharedWithCpp(isSharedWithCpp)
, fIsBuiltin(isBuiltin) {}
StringFragment typeName() const {
return this->enumData().fTypeName;
return fTypeName;
}
std::shared_ptr<SymbolTable> symbols() const {
return this->enumData().fSymbols;
return fSymbols;
}
bool isBuiltin() const {
return this->enumData().fIsBuiltin;
return fIsBuiltin;
}
bool isSharedWithCpp() const {
return this->enumData().fIsSharedWithCpp;
return fIsSharedWithCpp;
}
std::unique_ptr<ProgramElement> clone() const override {
@ -77,6 +81,11 @@ private:
return symbol->as<Variable>().initialValue()->as<IntLiteral>().value();
}
StringFragment fTypeName;
std::shared_ptr<SymbolTable> fSymbols;
bool fIsSharedWithCpp;
bool fIsBuiltin;
using INHERITED = ProgramElement;
};

View File

@ -26,25 +26,17 @@ public:
static constexpr Kind kSymbolKind = Kind::kField;
Field(int offset, const Variable* owner, int fieldIndex)
: INHERITED(offset, FieldData{owner->type().fields()[fieldIndex].fName,
owner->type().fields()[fieldIndex].fType,
owner,
fieldIndex}) {}
const Type& type() const override {
return *this->fieldData().fType;
}
StringFragment name() const override {
return this->fieldData().fName;
}
: INHERITED(offset, kSymbolKind, owner->type().fields()[fieldIndex].fName,
owner->type().fields()[fieldIndex].fType)
, fOwner(owner)
, fFieldIndex(fieldIndex) {}
int fieldIndex() const {
return this->fieldData().fFieldIndex;
return fFieldIndex;
}
const Variable& owner() const {
return *this->fieldData().fOwner;
return *fOwner;
}
String description() const override {
@ -52,6 +44,9 @@ public:
}
private:
const Variable* fOwner;
int fFieldIndex;
using INHERITED = Symbol;
};

View File

@ -18,7 +18,7 @@
namespace SkSL {
struct FunctionDefinition;
class FunctionDefinition;
/**
* A function declaration (not a definition -- does not contain a body).
@ -30,35 +30,35 @@ public:
FunctionDeclaration(int offset, ModifiersPool::Handle modifiers, StringFragment name,
std::vector<const Variable*> parameters, const Type* returnType,
bool builtin)
: INHERITED(offset, FunctionDeclarationData{name, /*fDefiniition=*/nullptr, modifiers,
std::move(parameters), returnType, builtin}) {}
: INHERITED(offset, kSymbolKind, name, /*type=*/nullptr)
, fDefinition(nullptr)
, fModifiersHandle(modifiers)
, fParameters(std::move(parameters))
, fReturnType(returnType)
, fBuiltin(builtin) {}
const Modifiers& modifiers() const {
return *this->functionDeclarationData().fModifiersHandle;
}
StringFragment name() const override {
return this->functionDeclarationData().fName;
return *fModifiersHandle;
}
const FunctionDefinition* definition() const {
return this->functionDeclarationData().fDefinition;
return fDefinition;
}
void setDefinition(const FunctionDefinition* definition) const {
this->functionDeclarationData().fDefinition = definition;
fDefinition = definition;
}
const std::vector<const Variable*>& parameters() const {
return this->functionDeclarationData().fParameters;
return fParameters;
}
const Type& returnType() const {
return *this->functionDeclarationData().fReturnType;
return *fReturnType;
}
bool isBuiltin() const {
return this->functionDeclarationData().fBuiltin;
return fBuiltin;
}
String description() const override {
@ -146,6 +146,12 @@ public:
}
private:
mutable const FunctionDefinition* fDefinition;
ModifiersPool::Handle fModifiersHandle;
std::vector<const Variable*> fParameters;
const Type* fReturnType;
bool fBuiltin;
using INHERITED = Symbol;
};

View File

@ -19,25 +19,28 @@ struct ASTNode;
/**
* A function definition (a declaration plus an associated block of code).
*/
struct FunctionDefinition : public ProgramElement {
class FunctionDefinition : public ProgramElement {
public:
static constexpr Kind kProgramElementKind = Kind::kFunction;
FunctionDefinition(int offset,
const FunctionDeclaration* declaration, bool builtin,
std::unique_ptr<Statement> body,
std::unordered_set<const FunctionDeclaration*> referencedIntrinsics = {})
: INHERITED(offset,
FunctionDefinitionData{declaration, builtin, std::move(referencedIntrinsics),
/*fSource=*/nullptr}) {
: INHERITED(offset, kProgramElementKind)
, fDeclaration(declaration)
, fBuiltin(builtin)
, fReferencedIntrinsics(std::move(referencedIntrinsics))
, fSource(nullptr) {
fStatementChildren.push_back(std::move(body));
}
const FunctionDeclaration& declaration() const {
return *this->functionDefinitionData().fDeclaration;
return *fDeclaration;
}
bool isBuiltin() const {
return this->functionDefinitionData().fBuiltin;
return fBuiltin;
}
std::unique_ptr<Statement>& body() {
@ -49,15 +52,15 @@ struct FunctionDefinition : public ProgramElement {
}
const std::unordered_set<const FunctionDeclaration*>& referencedIntrinsics() const {
return this->functionDefinitionData().fReferencedIntrinsics;
return fReferencedIntrinsics;
}
const ASTNode* source() const {
return this->functionDefinitionData().fSource;
return fSource;
}
void setSource(const ASTNode* source) {
this->functionDefinitionData().fSource = source;
fSource = source;
}
std::unique_ptr<ProgramElement> clone() const override {
@ -70,6 +73,18 @@ struct FunctionDefinition : public ProgramElement {
return this->declaration().description() + " " + this->body()->description();
}
private:
const FunctionDeclaration* fDeclaration;
bool fBuiltin;
// We track intrinsic functions we reference so that we can ensure that all of them end up
// copied into the final output.
std::unordered_set<const FunctionDeclaration*> fReferencedIntrinsics;
// This pointer may be null, and even when non-null is not guaranteed to remain valid for
// the entire lifespan of this object. The parse tree's lifespan is normally controlled by
// IRGenerator, so the IRGenerator being destroyed or being used to compile another file
// will invalidate this pointer.
const ASTNode* fSource;
using INHERITED = ProgramElement;
};

View File

@ -22,21 +22,11 @@ IRNode::IRNode(int offset, int kind, const BoolLiteralData& data)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const EnumData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const ExternalValueData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const FieldData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const FieldAccessData& data)
: fOffset(offset)
, fKind(kind)
@ -57,16 +47,6 @@ IRNode::IRNode(int offset, int kind, const FunctionCallData& data)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const FunctionDeclarationData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const FunctionDefinitionData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const FunctionReferenceData& data)
: fOffset(offset)
, fKind(kind)
@ -82,11 +62,6 @@ IRNode::IRNode(int offset, int kind, const InlineMarkerData& data)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const InterfaceBlockData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const IntLiteralData& data)
: fOffset(offset)
, fKind(kind)
@ -97,11 +72,6 @@ IRNode::IRNode(int offset, int kind, const ModifiersDeclarationData& data)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const SectionData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const SettingData& data)
: fOffset(offset)
, fKind(kind)
@ -157,11 +127,6 @@ IRNode::IRNode(int offset, int kind, const VarDeclarationData& data)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const VariableData& data)
: fOffset(offset)
, fKind(kind)
, fData(data) {}
IRNode::IRNode(int offset, int kind, const VariableReferenceData& data)
: fOffset(offset)
, fKind(kind)

View File

@ -25,7 +25,7 @@ namespace SkSL {
class Expression;
class ExternalValue;
class FunctionDeclaration;
struct FunctionDefinition;
class FunctionDefinition;
class Statement;
class Symbol;
class SymbolTable;
@ -67,8 +67,6 @@ public:
// Override operator new and delete to allow us to control allocation behavior.
static void* operator new(const size_t size) {
// TODO: once all IRNodes hold their data in fData, everything should come out of the pool,
// and this check should become an assertion.
if (size == sizeof(IRNode)) {
return Pool::AllocIRNode();
}
@ -93,25 +91,11 @@ protected:
bool fValue;
};
struct EnumData {
StringFragment fTypeName;
std::shared_ptr<SymbolTable> fSymbols;
bool fIsSharedWithCpp;
bool fIsBuiltin;
};
struct ExternalValueData {
const Type* fType;
const ExternalValue* fValue;
};
struct FieldData {
StringFragment fName;
const Type* fType;
const Variable* fOwner;
int fFieldIndex;
};
struct FieldAccessData {
const Type* fType;
int fFieldIndex;
@ -132,40 +116,6 @@ protected:
const FunctionDeclaration* fFunction;
};
struct FunctionDeclarationData {
StringFragment fName;
mutable const FunctionDefinition* fDefinition;
ModifiersPool::Handle fModifiersHandle;
// FIXME after killing fExpressionChildren / fStatementChildren in favor of just fChildren,
// the parameters should move into that vector
std::vector<const Variable*> fParameters;
const Type* fReturnType;
bool fBuiltin;
FunctionDeclarationData& operator=(const FunctionDeclarationData& other) {
fName = other.fName;
fDefinition = other.fDefinition;
fModifiersHandle = other.fModifiersHandle;
fParameters = other.fParameters;
fReturnType = other.fReturnType;
fBuiltin = other.fBuiltin;
return *this;
}
};
struct FunctionDefinitionData {
const FunctionDeclaration* fDeclaration;
bool fBuiltin;
// We track intrinsic functions we reference so that we can ensure that all of them end up
// copied into the final output.
std::unordered_set<const FunctionDeclaration*> fReferencedIntrinsics;
// This pointer may be null, and even when non-null is not guaranteed to remain valid for
// the entire lifespan of this object. The parse tree's lifespan is normally controlled by
// IRGenerator, so the IRGenerator being destroyed or being used to compile another file
// will invalidate this pointer.
const ASTNode* fSource;
};
struct FunctionReferenceData {
const Type* fType;
std::vector<const FunctionDeclaration*> fFunctions;
@ -175,13 +125,6 @@ protected:
bool fIsStatic;
};
struct InterfaceBlockData {
const Variable* fVariable;
String fTypeName;
String fInstanceName;
std::shared_ptr<SymbolTable> fTypeOwner;
};
struct IntLiteralData {
const Type* fType;
int64_t fValue;
@ -195,12 +138,6 @@ protected:
ModifiersPool::Handle fModifiersHandle;
};
struct SectionData {
String fName;
String fArgument;
String fText;
};
struct SettingData {
String fName;
const Type* fType;
@ -247,15 +184,6 @@ protected:
const Variable* fVar;
};
struct VariableData {
StringFragment fName;
const Type* fType;
const Expression* fInitialValue = nullptr;
ModifiersPool::Handle fModifiersHandle;
VariableStorage fStorage;
bool fBuiltin;
};
struct VariableReferenceData {
const Variable* fVariable;
VariableRefKind fRefKind;
@ -265,22 +193,16 @@ protected:
enum class Kind {
kBlock,
kBoolLiteral,
kEnum,
kExternalValue,
kField,
kFieldAccess,
kFloatLiteral,
kForStatement,
kFunctionCall,
kFunctionDeclaration,
kFunctionDefinition,
kFunctionReference,
kIfStatement,
kInlineMarker,
kInterfaceBlock,
kIntLiteral,
kModifiersDeclaration,
kSection,
kSetting,
kString,
kSwitchStatement,
@ -292,7 +214,6 @@ protected:
kTypeToken,
kUnresolvedFunction,
kVarDeclaration,
kVariable,
kVariableReference,
} fKind = Kind::kType;
// it doesn't really matter what kind we default to, as long as it's a POD type
@ -300,22 +221,16 @@ protected:
union Contents {
BlockData fBlock;
BoolLiteralData fBoolLiteral;
EnumData fEnum;
ExternalValueData fExternalValue;
FieldData fField;
FieldAccessData fFieldAccess;
FloatLiteralData fFloatLiteral;
ForStatementData fForStatement;
FunctionCallData fFunctionCall;
FunctionDeclarationData fFunctionDeclaration;
FunctionDefinitionData fFunctionDefinition;
FunctionReferenceData fFunctionReference;
IfStatementData fIfStatement;
InlineMarkerData fInlineMarker;
InterfaceBlockData fInterfaceBlock;
IntLiteralData fIntLiteral;
ModifiersDeclarationData fModifiersDeclaration;
SectionData fSection;
SettingData fSetting;
String fString;
SwitchStatementData fSwitchStatement;
@ -327,7 +242,6 @@ protected:
TypeTokenData fTypeToken;
UnresolvedFunctionData fUnresolvedFunction;
VarDeclarationData fVarDeclaration;
VariableData fVariable;
VariableReferenceData fVariableReference;
Contents() {}
@ -345,21 +259,11 @@ protected:
*(new(&fContents) BoolLiteralData) = data;
}
NodeData(const EnumData& data)
: fKind(Kind::kEnum) {
*(new(&fContents) EnumData) = data;
}
NodeData(const ExternalValueData& data)
: fKind(Kind::kExternalValue) {
*(new(&fContents) ExternalValueData) = data;
}
NodeData(const FieldData& data)
: fKind(Kind::kField) {
*(new(&fContents) FieldData) = data;
}
NodeData(const FieldAccessData& data)
: fKind(Kind::kFieldAccess) {
*(new(&fContents) FieldAccessData) = data;
@ -380,16 +284,6 @@ protected:
*(new(&fContents) FunctionCallData) = data;
}
NodeData(const FunctionDeclarationData& data)
: fKind(Kind::kFunctionDeclaration) {
*(new(&fContents) FunctionDeclarationData) = data;
}
NodeData(const FunctionDefinitionData& data)
: fKind(Kind::kFunctionDefinition) {
*(new(&fContents) FunctionDefinitionData) = data;
}
NodeData(const FunctionReferenceData& data)
: fKind(Kind::kFunctionReference) {
*(new(&fContents) FunctionReferenceData) = data;
@ -405,11 +299,6 @@ protected:
*(new(&fContents) InlineMarkerData) = data;
}
NodeData(InterfaceBlockData data)
: fKind(Kind::kInterfaceBlock) {
*(new(&fContents) InterfaceBlockData) = data;
}
NodeData(IntLiteralData data)
: fKind(Kind::kIntLiteral) {
*(new(&fContents) IntLiteralData) = data;
@ -420,11 +309,6 @@ protected:
*(new(&fContents) ModifiersDeclarationData) = data;
}
NodeData(const SectionData& data)
: fKind(Kind::kSection) {
*(new(&fContents) SectionData) = data;
}
NodeData(const SettingData& data)
: fKind(Kind::kSetting) {
*(new(&fContents) SettingData) = data;
@ -480,11 +364,6 @@ protected:
*(new(&fContents) VarDeclarationData) = data;
}
NodeData(const VariableData& data)
: fKind(Kind::kVariable) {
*(new(&fContents) VariableData) = data;
}
NodeData(const VariableReferenceData& data)
: fKind(Kind::kVariableReference) {
*(new(&fContents) VariableReferenceData) = data;
@ -504,15 +383,9 @@ protected:
case Kind::kBoolLiteral:
*(new(&fContents) BoolLiteralData) = other.fContents.fBoolLiteral;
break;
case Kind::kEnum:
*(new(&fContents) EnumData) = other.fContents.fEnum;
break;
case Kind::kExternalValue:
*(new(&fContents) ExternalValueData) = other.fContents.fExternalValue;
break;
case Kind::kField:
*(new(&fContents) FieldData) = other.fContents.fField;
break;
case Kind::kFieldAccess:
*(new(&fContents) FieldAccessData) = other.fContents.fFieldAccess;
break;
@ -525,13 +398,6 @@ protected:
case Kind::kFunctionCall:
*(new(&fContents) FunctionCallData) = other.fContents.fFunctionCall;
break;
case Kind::kFunctionDeclaration:
*(new(&fContents) FunctionDeclarationData) =
other.fContents.fFunctionDeclaration;
break;
case Kind::kFunctionDefinition:
*(new(&fContents) FunctionDefinitionData) = other.fContents.fFunctionDefinition;
break;
case Kind::kFunctionReference:
*(new(&fContents) FunctionReferenceData) = other.fContents.fFunctionReference;
break;
@ -541,9 +407,6 @@ protected:
case Kind::kInlineMarker:
*(new(&fContents) InlineMarkerData) = other.fContents.fInlineMarker;
break;
case Kind::kInterfaceBlock:
*(new(&fContents) InterfaceBlockData) = other.fContents.fInterfaceBlock;
break;
case Kind::kIntLiteral:
*(new(&fContents) IntLiteralData) = other.fContents.fIntLiteral;
break;
@ -551,9 +414,6 @@ protected:
*(new(&fContents) ModifiersDeclarationData) =
other.fContents.fModifiersDeclaration;
break;
case Kind::kSection:
*(new(&fContents) SectionData) = other.fContents.fSection;
break;
case Kind::kSetting:
*(new(&fContents) SettingData) = other.fContents.fSetting;
break;
@ -587,9 +447,6 @@ protected:
case Kind::kVarDeclaration:
*(new(&fContents) VarDeclarationData) = other.fContents.fVarDeclaration;
break;
case Kind::kVariable:
*(new(&fContents) VariableData) = other.fContents.fVariable;
break;
case Kind::kVariableReference:
*(new(&fContents) VariableReferenceData) = other.fContents.fVariableReference;
break;
@ -610,15 +467,9 @@ protected:
case Kind::kBoolLiteral:
fContents.fBoolLiteral.~BoolLiteralData();
break;
case Kind::kEnum:
fContents.fEnum.~EnumData();
break;
case Kind::kExternalValue:
fContents.fExternalValue.~ExternalValueData();
break;
case Kind::kField:
fContents.fField.~FieldData();
break;
case Kind::kFieldAccess:
fContents.fFieldAccess.~FieldAccessData();
break;
@ -631,12 +482,6 @@ protected:
case Kind::kFunctionCall:
fContents.fFunctionCall.~FunctionCallData();
break;
case Kind::kFunctionDeclaration:
fContents.fFunctionDeclaration.~FunctionDeclarationData();
break;
case Kind::kFunctionDefinition:
fContents.fFunctionDefinition.~FunctionDefinitionData();
break;
case Kind::kFunctionReference:
fContents.fFunctionReference.~FunctionReferenceData();
break;
@ -646,18 +491,12 @@ protected:
case Kind::kInlineMarker:
fContents.fInlineMarker.~InlineMarkerData();
break;
case Kind::kInterfaceBlock:
fContents.fInterfaceBlock.~InterfaceBlockData();
break;
case Kind::kIntLiteral:
fContents.fIntLiteral.~IntLiteralData();
break;
case Kind::kModifiersDeclaration:
fContents.fModifiersDeclaration.~ModifiersDeclarationData();
break;
case Kind::kSection:
fContents.fSection.~SectionData();
break;
case Kind::kSetting:
fContents.fSetting.~SettingData();
break;
@ -690,9 +529,6 @@ protected:
case Kind::kVarDeclaration:
fContents.fVarDeclaration.~VarDeclarationData();
break;
case Kind::kVariable:
fContents.fVariable.~VariableData();
break;
case Kind::kVariableReference:
fContents.fVariableReference.~VariableReferenceData();
break;
@ -704,12 +540,8 @@ protected:
IRNode(int offset, int kind, const BoolLiteralData& data);
IRNode(int offset, int kind, const EnumData& data);
IRNode(int offset, int kind, const ExternalValueData& data);
IRNode(int offset, int kind, const FieldData& data);
IRNode(int offset, int kind, const FieldAccessData& data);
IRNode(int offset, int kind, const FloatLiteralData& data);
@ -718,24 +550,16 @@ protected:
IRNode(int offset, int kind, const FunctionCallData& data);
IRNode(int offset, int kind, const FunctionDeclarationData& data);
IRNode(int offset, int kind, const FunctionDefinitionData& data);
IRNode(int offset, int kind, const FunctionReferenceData& data);
IRNode(int offset, int kind, const IfStatementData& data);
IRNode(int offset, int kind, const InlineMarkerData& data);
IRNode(int offset, int kind, const InterfaceBlockData& data);
IRNode(int offset, int kind, const IntLiteralData& data);
IRNode(int offset, int kind, const ModifiersDeclarationData& data);
IRNode(int offset, int kind, const SectionData& data);
IRNode(int offset, int kind, const SettingData& data);
IRNode(int offset, int kind, const String& data);
@ -758,8 +582,6 @@ protected:
IRNode(int offset, int kind, const VarDeclarationData& data);
IRNode(int offset, int kind, const VariableData& data);
IRNode(int offset, int kind, const VariableReferenceData& data);
Expression& expressionChild(int index) const {
@ -816,21 +638,11 @@ protected:
return fData.fContents.fBoolLiteral;
}
const EnumData& enumData() const {
SkASSERT(fData.fKind == NodeData::Kind::kEnum);
return fData.fContents.fEnum;
}
const ExternalValueData& externalValueData() const {
SkASSERT(fData.fKind == NodeData::Kind::kExternalValue);
return fData.fContents.fExternalValue;
}
const FieldData& fieldData() const {
SkASSERT(fData.fKind == NodeData::Kind::kField);
return fData.fContents.fField;
}
const FieldAccessData& fieldAccessData() const {
SkASSERT(fData.fKind == NodeData::Kind::kFieldAccess);
return fData.fContents.fFieldAccess;
@ -851,26 +663,6 @@ protected:
return fData.fContents.fFunctionCall;
}
FunctionDeclarationData& functionDeclarationData() {
SkASSERT(fData.fKind == NodeData::Kind::kFunctionDeclaration);
return fData.fContents.fFunctionDeclaration;
}
const FunctionDeclarationData& functionDeclarationData() const {
SkASSERT(fData.fKind == NodeData::Kind::kFunctionDeclaration);
return fData.fContents.fFunctionDeclaration;
}
FunctionDefinitionData& functionDefinitionData() {
SkASSERT(fData.fKind == NodeData::Kind::kFunctionDefinition);
return fData.fContents.fFunctionDefinition;
}
const FunctionDefinitionData& functionDefinitionData() const {
SkASSERT(fData.fKind == NodeData::Kind::kFunctionDefinition);
return fData.fContents.fFunctionDefinition;
}
const FunctionReferenceData& functionReferenceData() const {
SkASSERT(fData.fKind == NodeData::Kind::kFunctionReference);
return fData.fContents.fFunctionReference;
@ -886,16 +678,6 @@ protected:
return fData.fContents.fInlineMarker;
}
InterfaceBlockData& interfaceBlockData() {
SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlock);
return fData.fContents.fInterfaceBlock;
}
const InterfaceBlockData& interfaceBlockData() const {
SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlock);
return fData.fContents.fInterfaceBlock;
}
const IntLiteralData& intLiteralData() const {
SkASSERT(fData.fKind == NodeData::Kind::kIntLiteral);
return fData.fContents.fIntLiteral;
@ -906,11 +688,6 @@ protected:
return fData.fContents.fModifiersDeclaration;
}
const SectionData& sectionData() const {
SkASSERT(fData.fKind == NodeData::Kind::kSection);
return fData.fContents.fSection;
}
const SettingData& settingData() const {
SkASSERT(fData.fKind == NodeData::Kind::kSetting);
return fData.fContents.fSetting;
@ -986,16 +763,6 @@ protected:
return fData.fContents.fVarDeclaration;
}
VariableData& variableData() {
SkASSERT(fData.fKind == NodeData::Kind::kVariable);
return fData.fContents.fVariable;
}
const VariableData& variableData() const {
SkASSERT(fData.fKind == NodeData::Kind::kVariable);
return fData.fContents.fVariable;
}
VariableReferenceData& variableReferenceData() {
SkASSERT(fData.fKind == NodeData::Kind::kVariableReference);
return fData.fContents.fVariableReference;

View File

@ -24,34 +24,38 @@ namespace SkSL {
*
* At the IR level, this is represented by a single variable of struct type.
*/
struct InterfaceBlock : public ProgramElement {
class InterfaceBlock : public ProgramElement {
public:
static constexpr Kind kProgramElementKind = Kind::kInterfaceBlock;
InterfaceBlock(int offset, const Variable* var, String typeName, String instanceName,
ExpressionArray sizes, std::shared_ptr<SymbolTable> typeOwner)
: INHERITED(offset, InterfaceBlockData{var, std::move(typeName), std::move(instanceName),
std::move(typeOwner)}) {
: INHERITED(offset, kProgramElementKind)
, fVariable(var)
, fTypeName(std::move(typeName))
, fInstanceName(std::move(instanceName))
, fTypeOwner(std::move(typeOwner)) {
fExpressionChildren.move_back_n(sizes.size(), sizes.data());
}
const Variable& variable() const {
return *this->interfaceBlockData().fVariable;
return *fVariable;
}
void setVariable(const Variable* var) {
this->interfaceBlockData().fVariable = var;
fVariable = var;
}
const String& typeName() const {
return this->interfaceBlockData().fTypeName;
return fTypeName;
}
const String& instanceName() const {
return this->interfaceBlockData().fInstanceName;
return fInstanceName;
}
const std::shared_ptr<SymbolTable>& typeOwner() const {
return this->interfaceBlockData().fTypeOwner;
return fTypeOwner;
}
ExpressionArray& sizes() {
@ -96,6 +100,12 @@ struct InterfaceBlock : public ProgramElement {
return result + ";";
}
private:
const Variable* fVariable;
String fTypeName;
String fInstanceName;
std::shared_ptr<SymbolTable> fTypeOwner;
using INHERITED = ProgramElement;
};

View File

@ -37,15 +37,6 @@ public:
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
ProgramElement(int offset, const EnumData& data)
: INHERITED(offset, (int) Kind::kEnum, data) {}
ProgramElement(int offset, const FunctionDefinitionData& data)
: INHERITED(offset, (int) Kind::kFunction, data) {}
ProgramElement(int offset, const InterfaceBlockData& data)
: INHERITED(offset, (int) Kind::kInterfaceBlock, data) {}
ProgramElement(int offset, const ModifiersDeclarationData& data)
: INHERITED(offset, (int) Kind::kModifiers, data) {}
@ -54,9 +45,6 @@ public:
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
ProgramElement(int offset, const SectionData& data)
: INHERITED(offset, (int) Kind::kSection, data) {}
Kind kind() const {
return (Kind) fKind;
}

View File

@ -15,22 +15,26 @@ namespace SkSL {
/**
* A section declaration (e.g. @body { body code here })..
*/
struct Section : public ProgramElement {
class Section : public ProgramElement {
public:
static constexpr Kind kProgramElementKind = Kind::kSection;
Section(int offset, String name, String arg, String text)
: INHERITED(offset, SectionData{std::move(name), std::move(arg), std::move(text)}) {}
: INHERITED(offset, kProgramElementKind)
, fName(std::move(name))
, fArgument(std::move(arg))
, fText(std::move(text)) {}
const String& name() const {
return this->sectionData().fName;
return fName;
}
const String& argument() const {
return this->sectionData().fArgument;
return fArgument;
}
const String& text() const {
return this->sectionData().fText;
return fText;
}
std::unique_ptr<ProgramElement> clone() const override {
@ -47,6 +51,11 @@ struct Section : public ProgramElement {
return result;
}
private:
String fName;
String fArgument;
String fText;
using INHERITED = ProgramElement;
};

View File

@ -36,21 +36,12 @@ public:
SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
}
Symbol(int offset, const FieldData& data)
: INHERITED(offset, (int) Kind::kField, data) {}
Symbol(int offset, const FunctionDeclarationData& data)
: INHERITED(offset, (int) Kind::kFunctionDeclaration, data) {}
Symbol(int offset, const SymbolAliasData& data)
: INHERITED(offset, (int) Kind::kSymbolAlias, data) {}
Symbol(int offset, const UnresolvedFunctionData& data)
: INHERITED(offset, (int) Kind::kUnresolvedFunction, data) {}
Symbol(int offset, const VariableData& data)
: INHERITED(offset, (int) Kind::kVariable, data) {}
Symbol& operator=(const Symbol&) = default;
~Symbol() override {}

View File

@ -38,39 +38,35 @@ public:
Variable(int offset, ModifiersPool::Handle modifiers, StringFragment name, const Type* type,
bool builtin, Storage storage, const Expression* initialValue = nullptr)
: INHERITED(offset, VariableData{name, type, initialValue, modifiers, storage, builtin}) {}
const Type& type() const override {
return *this->variableData().fType;
}
: INHERITED(offset, kSymbolKind, name, type)
, fInitialValue(initialValue)
, fModifiersHandle(modifiers)
, fStorage(storage)
, fBuiltin(builtin) {}
const Modifiers& modifiers() const {
return *this->variableData().fModifiersHandle;
return *fModifiersHandle;
}
const ModifiersPool::Handle& modifiersHandle() const {
return this->variableData().fModifiersHandle;
return fModifiersHandle;
}
bool isBuiltin() const {
return this->variableData().fBuiltin;
return fBuiltin;
}
Storage storage() const {
return (Storage) this->variableData().fStorage;
return (Storage) fStorage;
}
const Expression* initialValue() const {
return this->variableData().fInitialValue;
return fInitialValue;
}
void setInitialValue(const Expression* initialValue) {
SkASSERT(!this->initialValue());
this->variableData().fInitialValue = initialValue;
}
StringFragment name() const override {
return this->variableData().fName;
fInitialValue = initialValue;
}
String description() const override {
@ -78,6 +74,11 @@ public:
}
private:
const Expression* fInitialValue = nullptr;
ModifiersPool::Handle fModifiersHandle;
VariableStorage fStorage;
bool fBuiltin;
using INHERITED = Symbol;
friend class VariableReference;