Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1308)

Unified Diff: src/sksl/SkSLIRGenerator.cpp

Issue 2405383003: added basic dataflow analysis to skslc (Closed)
Patch Set: various fixes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/sksl/SkSLIRGenerator.cpp
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index d64684e62dc3312ed3c885c46f9d064026799664..eff1e7ff06fcc5fcf08a290ca2f6653ac7f2d695 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -42,8 +42,8 @@
#include "ir/SkSLTernaryExpression.h"
#include "ir/SkSLUnresolvedFunction.h"
#include "ir/SkSLVariable.h"
-#include "ir/SkSLVarDeclaration.h"
-#include "ir/SkSLVarDeclarationStatement.h"
+#include "ir/SkSLVarDeclarations.h"
+#include "ir/SkSLVarDeclarationsStatement.h"
#include "ir/SkSLVariableReference.h"
#include "ir/SkSLWhileStatement.h"
@@ -66,11 +66,26 @@ public:
std::shared_ptr<SymbolTable> fPrevious;
};
+class AutoLoopLevel {
+public:
+ AutoLoopLevel(IRGenerator* ir)
+ : fIR(ir) {
+ fIR->fLoopLevel++;
+ }
+
+ ~AutoLoopLevel() {
+ fIR->fLoopLevel--;
+ }
+
+ IRGenerator* fIR;
+};
+
IRGenerator::IRGenerator(const Context* context, std::shared_ptr<SymbolTable> symbolTable,
ErrorReporter& errorReporter)
: fContext(*context)
, fCurrentFunction(nullptr)
, fSymbolTable(std::move(symbolTable))
+, fLoopLevel(0)
, fErrors(errorReporter) {}
void IRGenerator::pushSymbolTable() {
@@ -235,21 +250,36 @@ std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
}
std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) {
+ AutoLoopLevel level(this);
AutoSymbolTable table(this);
- std::unique_ptr<Statement> initializer = this->convertStatement(*f.fInitializer);
- if (!initializer) {
- return nullptr;
+ std::unique_ptr<Statement> initializer;
+ if (f.fInitializer) {
+ initializer = this->convertStatement(*f.fInitializer);
+ if (!initializer) {
+ return nullptr;
+ }
+ } else {
+ initializer = nullptr;
dogben 2016/10/13 03:55:43 nit: unneeded x3
ethannicholas 2016/10/13 17:41:27 Fixed.
}
- std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*f.fTest),
- *fContext.fBool_Type);
- if (!test) {
- return nullptr;
+ std::unique_ptr<Expression> test;
+ if (f.fTest) {
+ test = this->coerce(this->convertExpression(*f.fTest), *fContext.fBool_Type);
+ if (!test) {
+ return nullptr;
+ }
+ } else {
+ test = nullptr;
}
- std::unique_ptr<Expression> next = this->convertExpression(*f.fNext);
- if (!next) {
- return nullptr;
+ std::unique_ptr<Expression> next;
+ if (f.fNext) {
+ next = this->convertExpression(*f.fNext);
+ if (!next) {
+ return nullptr;
+ }
+ this->checkValid(*next);
+ } else {
+ next = nullptr;
}
- this->checkValid(*next);
std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement);
if (!statement) {
return nullptr;
@@ -260,6 +290,7 @@ std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) {
}
std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w) {
+ AutoLoopLevel level(this);
std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.fTest),
*fContext.fBool_Type);
if (!test) {
@@ -274,6 +305,7 @@ std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w)
}
std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) {
+ AutoLoopLevel level(this);
std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.fTest),
*fContext.fBool_Type);
if (!test) {
@@ -323,11 +355,21 @@ std::unique_ptr<Statement> IRGenerator::convertReturn(const ASTReturnStatement&
}
std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b) {
- return std::unique_ptr<Statement>(new BreakStatement(b.fPosition));
+ if (fLoopLevel > 0) {
+ return std::unique_ptr<Statement>(new BreakStatement(b.fPosition));
+ } else {
+ fErrors.error(b.fPosition, "break statement must be inside a loop");
+ return nullptr;
+ }
}
std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStatement& c) {
- return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition));
+ if (fLoopLevel > 0) {
+ return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition));
+ } else {
+ fErrors.error(c.fPosition, "continue statement must be inside a loop");
+ return nullptr;
+ }
}
std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement& d) {

Powered by Google App Engine
This is Rietveld 408576698