146 lines
3.0 KiB
C++
146 lines
3.0 KiB
C++
/*
|
|
* 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,
|
|
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
|