blob: 35ba68114fa59d0afb35d89b7ba5ad74a1fc4c19 [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_IRNODE
#define SKSL_IRNODE
#include "include/sksl/SkSLPosition.h"
#include "src/sksl/SkSLPool.h"
#include <string>
namespace SkSL {
// The fKind field of IRNode could contain any of these values.
enum class ProgramElementKind {
kExtension = 0,
kFunction,
kFunctionPrototype,
kGlobalVar,
kInterfaceBlock,
kModifiers,
kStructDefinition,
kFirst = kExtension,
kLast = kStructDefinition
};
enum class SymbolKind {
kExternal = (int) ProgramElementKind::kLast + 1,
kField,
kFunctionDeclaration,
kType,
kVariable,
kFirst = kExternal,
kLast = kVariable
};
enum class StatementKind {
kBlock = (int) SymbolKind::kLast + 1,
kBreak,
kContinue,
kDiscard,
kDo,
kExpression,
kFor,
kIf,
kNop,
kReturn,
kSwitch,
kSwitchCase,
kVarDeclaration,
kFirst = kBlock,
kLast = kVarDeclaration,
};
enum class ExpressionKind {
kBinary = (int) StatementKind::kLast + 1,
kChildCall,
kConstructorArray,
kConstructorArrayCast,
kConstructorCompound,
kConstructorCompoundCast,
kConstructorDiagonalMatrix,
kConstructorMatrixResize,
kConstructorScalarCast,
kConstructorSplat,
kConstructorStruct,
kExternalFunctionCall,
kExternalFunctionReference,
kFieldAccess,
kFunctionReference,
kFunctionCall,
kIndex,
kLiteral,
kMethodReference,
kPoison,
kPostfix,
kPrefix,
kSetting,
kSwizzle,
kTernary,
kTypeReference,
kVariableReference,
kFirst = kBinary,
kLast = kVariableReference
};
/**
* Represents a node in the intermediate representation (IR) tree. The IR is a fully-resolved
* version of the program (all types determined, everything validated), ready for code generation.
*/
class IRNode : public Poolable {
public:
virtual ~IRNode() {}
virtual std::string description() const = 0;
// No copy construction or assignment
IRNode(const IRNode&) = delete;
IRNode& operator=(const IRNode&) = delete;
// position of this element within the program being compiled, for error reporting purposes
Position fPosition;
/**
* Use is<T> to check the type of an IRNode.
* e.g. replace `s.kind() == Statement::Kind::kReturn` with `s.is<ReturnStatement>()`.
*/
template <typename T>
bool is() const {
return this->fKind == (int)T::kIRNodeKind;
}
/**
* Use as<T> to downcast IRNodes.
* e.g. replace `(ReturnStatement&) s` with `s.as<ReturnStatement>()`.
*/
template <typename T>
const T& as() const {
SkASSERT(this->is<T>());
return static_cast<const T&>(*this);
}
template <typename T>
T& as() {
SkASSERT(this->is<T>());
return static_cast<T&>(*this);
}
protected:
IRNode(Position position, int kind)
: fPosition(position)
, fKind(kind) {}
int fKind;
};
} // namespace SkSL
#endif