Added line numbers to DSLParser errors
Change-Id: I895c3d94c9a49cc0350b287d3aa722050b91295e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/443036
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/include/sksl/DSLCore.h b/include/sksl/DSLCore.h
index 8bbbb21..d6ebf85 100644
--- a/include/sksl/DSLCore.h
+++ b/include/sksl/DSLCore.h
@@ -78,12 +78,12 @@
/**
* break;
*/
-DSLStatement Break();
+DSLStatement Break(PositionInfo pos = PositionInfo::Capture());
/**
* continue;
*/
-DSLStatement Continue();
+DSLStatement Continue(PositionInfo pos = PositionInfo::Capture());
/**
* Creates a local variable declaration statement.
diff --git a/include/sksl/DSLExpression.h b/include/sksl/DSLExpression.h
index 837c5b4..d7ed8ea 100644
--- a/include/sksl/DSLExpression.h
+++ b/include/sksl/DSLExpression.h
@@ -43,45 +43,47 @@
/**
* Creates an expression representing a literal float.
*/
- DSLExpression(float value);
+ DSLExpression(float value, PositionInfo pos = PositionInfo::Capture());
/**
* Creates an expression representing a literal float.
*/
- DSLExpression(double value)
+ DSLExpression(double value, PositionInfo pos = PositionInfo::Capture())
: DSLExpression((float) value) {}
/**
* Creates an expression representing a literal int.
*/
- DSLExpression(int value);
+ DSLExpression(int value, PositionInfo pos = PositionInfo::Capture());
/**
* Creates an expression representing a literal int.
*/
- DSLExpression(int64_t value);
+ DSLExpression(int64_t value, PositionInfo pos = PositionInfo::Capture());
/**
* Creates an expression representing a literal uint.
*/
- DSLExpression(unsigned int value);
+ DSLExpression(unsigned int value, PositionInfo pos = PositionInfo::Capture());
/**
* Creates an expression representing a literal bool.
*/
- DSLExpression(bool value);
+ DSLExpression(bool value, PositionInfo pos = PositionInfo::Capture());
/**
* Creates an expression representing a variable reference.
*/
- DSLExpression(DSLVarBase& var);
+ DSLExpression(DSLVarBase& var, PositionInfo pos = PositionInfo::Capture());
- DSLExpression(DSLVarBase&& var);
+ DSLExpression(DSLVarBase&& var, PositionInfo pos = PositionInfo::Capture());
DSLExpression(DSLPossibleExpression expr, PositionInfo pos = PositionInfo::Capture());
explicit DSLExpression(std::unique_ptr<SkSL::Expression> expression);
+ static DSLExpression Poison(PositionInfo pos = PositionInfo::Capture());
+
~DSLExpression();
DSLType type();
@@ -117,7 +119,8 @@
*/
DSLPossibleExpression operator[](DSLExpression index);
- DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args);
+ DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args,
+ PositionInfo pos = PositionInfo::Capture());
/**
* Returns true if this object contains an expression. DSLExpressions which were created with
@@ -258,7 +261,8 @@
DSLPossibleExpression operator[](DSLExpression index);
- DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args);
+ DSLPossibleExpression operator()(SkTArray<DSLWrapper<DSLExpression>> args,
+ PositionInfo pos = PositionInfo::Capture());
DSLPossibleExpression operator++();
diff --git a/include/sksl/DSLFunction.h b/include/sksl/DSLFunction.h
index 475a791..452d743 100644
--- a/include/sksl/DSLFunction.h
+++ b/include/sksl/DSLFunction.h
@@ -40,17 +40,19 @@
// (parameterArray.push_back(¶meters), ...);
int unused[] = {0, (static_cast<void>(parameterArray.push_back(¶meters)), 0)...};
static_cast<void>(unused);
- this->init(modifiers, returnType, name, std::move(parameterArray));
+ // We can't have a default parameter and a template parameter pack at the same time, so
+ // unfortunately we can't capture position info from this overload.
+ this->init(modifiers, returnType, name, std::move(parameterArray), PositionInfo());
}
DSLFunction(const DSLType& returnType, skstd::string_view name,
- SkTArray<DSLParameter*> parameters) {
- this->init(DSLModifiers(), returnType, name, std::move(parameters));
+ SkTArray<DSLParameter*> parameters, PositionInfo pos = PositionInfo::Capture()) {
+ this->init(DSLModifiers(), returnType, name, std::move(parameters), pos);
}
DSLFunction(const DSLModifiers& modifiers, const DSLType& returnType, skstd::string_view name,
- SkTArray<DSLParameter*> parameters) {
- this->init(modifiers, returnType, name, std::move(parameters));
+ SkTArray<DSLParameter*> parameters, PositionInfo pos = PositionInfo::Capture()) {
+ this->init(modifiers, returnType, name, std::move(parameters), pos);
}
DSLFunction(const SkSL::FunctionDeclaration* decl)
@@ -100,7 +102,7 @@
}
void init(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
- SkTArray<DSLParameter*> params);
+ SkTArray<DSLParameter*> params, PositionInfo pos);
const SkSL::FunctionDeclaration* fDecl = nullptr;
};
diff --git a/include/sksl/DSLModifiers.h b/include/sksl/DSLModifiers.h
index 66d622b..e0a9689 100644
--- a/include/sksl/DSLModifiers.h
+++ b/include/sksl/DSLModifiers.h
@@ -49,7 +49,7 @@
private:
SkSL::Modifiers fModifiers;
- friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields);
+ friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
friend class DSLCore;
friend class DSLFunction;
friend class DSLType;
diff --git a/include/sksl/DSLSymbols.h b/include/sksl/DSLSymbols.h
index 0281ba2..93e32ad 100644
--- a/include/sksl/DSLSymbols.h
+++ b/include/sksl/DSLSymbols.h
@@ -47,7 +47,7 @@
/**
* Returns an expression referring to the named symbol.
*/
-DSLPossibleExpression Symbol(skstd::string_view name);
+DSLPossibleExpression Symbol(skstd::string_view name, PositionInfo pos = PositionInfo::Capture());
/**
* Returns true if the name refers to a type.
diff --git a/include/sksl/DSLType.h b/include/sksl/DSLType.h
index 73c601c..e8f2e2b 100644
--- a/include/sksl/DSLType.h
+++ b/include/sksl/DSLType.h
@@ -166,8 +166,8 @@
TypeConstant fTypeConstant = kPoison_Type;
- friend DSLType Array(const DSLType& base, int count);
- friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields);
+ friend DSLType Array(const DSLType& base, int count, PositionInfo pos);
+ friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
friend class DSLCore;
friend class DSLFunction;
friend class DSLVarBase;
@@ -212,7 +212,7 @@
#undef VECTOR_TYPE
#undef MATRIX_TYPE
-DSLType Array(const DSLType& base, int count);
+DSLType Array(const DSLType& base, int count, PositionInfo pos = PositionInfo::Capture());
class DSLField {
public:
@@ -230,15 +230,16 @@
skstd::string_view fName;
friend class DSLCore;
- friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields);
+ friend DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos);
};
-DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields);
+DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields,
+ PositionInfo pos = PositionInfo::Capture());
template<typename... Field>
DSLType Struct(skstd::string_view name, Field... fields) {
DSLField fieldTypes[] = {std::move(fields)...};
- return Struct(name, SkMakeSpan(fieldTypes));
+ return Struct(name, SkMakeSpan(fieldTypes), PositionInfo());
}
} // namespace dsl
diff --git a/include/sksl/DSLVar.h b/include/sksl/DSLVar.h
index 1b9250b..cfac770 100644
--- a/include/sksl/DSLVar.h
+++ b/include/sksl/DSLVar.h
@@ -34,14 +34,15 @@
* name conflicts and the variable's name is only important when debugging shaders, the name
* parameter is optional.
*/
- DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue);
+ DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue, PositionInfo pos);
- DSLVarBase(DSLType type, DSLExpression initialValue);
+ DSLVarBase(DSLType type, DSLExpression initialValue, PositionInfo pos);
DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::string_view name,
- DSLExpression initialValue);
+ DSLExpression initialValue, PositionInfo pos);
- DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue);
+ DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue,
+ PositionInfo pos);
DSLVarBase(DSLVarBase&&) = default;
@@ -131,6 +132,7 @@
// true if we have attempted to create the SkSL var
bool fInitialized = false;
bool fDeclared = false;
+ PositionInfo fPosition;
friend class DSLCore;
friend class DSLExpression;
@@ -148,22 +150,24 @@
DSLVar() = default;
DSLVar(DSLType type, skstd::string_view name = "var",
- DSLExpression initialValue = DSLExpression())
- : INHERITED(type, name, std::move(initialValue)) {}
+ DSLExpression initialValue = DSLExpression(),
+ PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(type, name, std::move(initialValue), pos) {}
- DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
- : DSLVar(type, skstd::string_view(name), std::move(initialValue)) {}
+ DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression(),
+ PositionInfo pos = PositionInfo::Capture())
+ : DSLVar(type, skstd::string_view(name), std::move(initialValue), pos) {}
- DSLVar(DSLType type, DSLExpression initialValue)
- : INHERITED(type, std::move(initialValue)) {}
+ DSLVar(DSLType type, DSLExpression initialValue, PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(type, std::move(initialValue), pos) {}
DSLVar(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var",
- DSLExpression initialValue = DSLExpression())
- : INHERITED(modifiers, type, name, std::move(initialValue)) {}
+ DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(modifiers, type, name, std::move(initialValue), pos) {}
DSLVar(const DSLModifiers& modifiers, DSLType type, const char* name,
- DSLExpression initialValue = DSLExpression())
- : DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}
+ DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
+ : DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue), pos) {}
DSLVar(DSLVar&&) = default;
@@ -194,22 +198,24 @@
DSLGlobalVar() = default;
DSLGlobalVar(DSLType type, skstd::string_view name = "var",
- DSLExpression initialValue = DSLExpression())
- : INHERITED(type, name, std::move(initialValue)) {}
+ DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(type, name, std::move(initialValue), pos) {}
- DSLGlobalVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
- : DSLGlobalVar(type, skstd::string_view(name), std::move(initialValue)) {}
+ DSLGlobalVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression(),
+ PositionInfo pos = PositionInfo::Capture())
+ : DSLGlobalVar(type, skstd::string_view(name), std::move(initialValue), pos) {}
- DSLGlobalVar(DSLType type, DSLExpression initialValue)
- : INHERITED(type, std::move(initialValue)) {}
+ DSLGlobalVar(DSLType type, DSLExpression initialValue,
+ PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(type, std::move(initialValue), pos) {}
DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var",
- DSLExpression initialValue = DSLExpression())
- : INHERITED(modifiers, type, name, std::move(initialValue)) {}
+ DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(modifiers, type, name, std::move(initialValue), pos) {}
DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, const char* name,
- DSLExpression initialValue = DSLExpression())
- : DSLGlobalVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}
+ DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture())
+ : DSLGlobalVar(modifiers, type, skstd::string_view(name), std::move(initialValue), pos) {}
DSLGlobalVar(const char* name);
@@ -241,17 +247,20 @@
public:
DSLParameter() = default;
- DSLParameter(DSLType type, skstd::string_view name = "var")
- : INHERITED(type, name, DSLExpression()) {}
+ DSLParameter(DSLType type, skstd::string_view name = "var",
+ PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(type, name, DSLExpression(), pos) {}
- DSLParameter(DSLType type, const char* name)
- : DSLParameter(type, skstd::string_view(name)) {}
+ DSLParameter(DSLType type, const char* name, PositionInfo pos = PositionInfo::Capture())
+ : DSLParameter(type, skstd::string_view(name), pos) {}
- DSLParameter(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var")
- : INHERITED(modifiers, type, name, DSLExpression()) {}
+ DSLParameter(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var",
+ PositionInfo pos = PositionInfo::Capture())
+ : INHERITED(modifiers, type, name, DSLExpression(), pos) {}
- DSLParameter(const DSLModifiers& modifiers, DSLType type, const char* name)
- : DSLParameter(modifiers, type, skstd::string_view(name)) {}
+ DSLParameter(const DSLModifiers& modifiers, DSLType type, const char* name,
+ PositionInfo pos = PositionInfo::Capture())
+ : DSLParameter(modifiers, type, skstd::string_view(name), pos) {}
DSLParameter(DSLParameter&&) = default;
diff --git a/include/sksl/SkSLErrorReporter.h b/include/sksl/SkSLErrorReporter.h
index 5ee35e5..4a3de92 100644
--- a/include/sksl/SkSLErrorReporter.h
+++ b/include/sksl/SkSLErrorReporter.h
@@ -33,17 +33,42 @@
static PositionInfo Capture() { return PositionInfo(); }
#endif // __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
+ static PositionInfo Offset(const char* file, const char* text, int offset) {
+ PositionInfo result(file, -1);
+ result.fText = text;
+ result.fOffset = offset;
+ return result;
+ }
+
const char* file_name() const {
return fFile;
}
int line() {
+ if (fLine == -1) {
+ if (fOffset == -1 || !fText) {
+ return -1;
+ }
+ fLine = 1;
+ for (int i = 0; i < fOffset; i++) {
+ SkASSERT(fText[i]);
+ if (fText[i] == '\n') {
+ ++fLine;
+ }
+ }
+ }
return fLine;
}
+ int offset() {
+ return fOffset;
+ }
+
private:
- const char* fFile;
- int fLine;
+ const char* fFile = nullptr;
+ const char* fText = nullptr;
+ int32_t fOffset = -1;
+ int32_t fLine = -1;
};
/**
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index ab3bc8e..602f755 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -990,10 +990,6 @@
#endif // defined(SKSL_STANDALONE) || SK_SUPPORT_GPU
void Compiler::handleError(const char* msg, PositionInfo pos) {
- if (strstr(msg, POISON_TAG)) {
- // don't report errors on poison values
- return;
- }
fErrorText += "error: " + (pos.line() >= 1 ? to_string(pos.line()) + ": " : "") + msg + "\n";
}
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index b50fd80..deb772b 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -276,6 +276,7 @@
friend class AutoSource;
friend class ::SkSLCompileBench;
+ friend class DSLParser;
friend class dsl::DSLCore;
friend class dsl::DSLWriter;
};
diff --git a/src/sksl/SkSLDSLParser.cpp b/src/sksl/SkSLDSLParser.cpp
index 55320a5..c4477d6 100644
--- a/src/sksl/SkSLDSLParser.cpp
+++ b/src/sksl/SkSLDSLParser.cpp
@@ -100,14 +100,13 @@
String text)
: fCompiler(*compiler)
, fSettings(settings)
- , fErrorReporter(&compiler->errorReporter())
, fKind(kind)
- , fText(std::move(text))
+ , fText(std::make_unique<String>(std::move(text)))
, fPushback(Token::Kind::TK_NONE, -1, -1) {
// We don't want to have to worry about manually releasing all of the objects in the event that
// an error occurs
fSettings.fAssertDSLObjectsReleased = false;
- fLexer.start(fText);
+ fLexer.start(*fText);
static const bool layoutMapInitialized = []{ InitLayoutMap(); return true; }();
(void) layoutMapInitialized;
}
@@ -187,7 +186,15 @@
}
skstd::string_view DSLParser::text(Token token) {
- return skstd::string_view(fText.data() + token.fOffset, token.fLength);
+ return skstd::string_view(fText->data() + token.fOffset, token.fLength);
+}
+
+PositionInfo DSLParser::position(Token t) {
+ return this->position(t.fOffset);
+}
+
+PositionInfo DSLParser::position(int offset) {
+ return PositionInfo::Offset("<unknown>", fText->c_str(), offset);
}
void DSLParser::error(Token token, String msg) {
@@ -195,7 +202,7 @@
}
void DSLParser::error(int offset, String msg) {
- GetErrorReporter().error(msg.c_str(), PositionInfo());
+ GetErrorReporter().error(msg.c_str(), this->position(offset));
}
/* declaration* END_OF_FILE */
@@ -203,6 +210,7 @@
ErrorReporter* errorReporter = &fCompiler.errorReporter();
Start(&fCompiler, fKind, fSettings);
SetErrorReporter(errorReporter);
+ errorReporter->setSource(fText->c_str());
fEncounteredFatalError = false;
std::unique_ptr<Program> result;
bool done = false;
@@ -211,12 +219,12 @@
case Token::Kind::TK_END_OF_FILE:
done = true;
if (!errorReporter->errorCount()) {
- result = dsl::ReleaseProgram(std::make_unique<String>(std::move(fText)));
+ result = dsl::ReleaseProgram(std::move(fText));
}
break;
case Token::Kind::TK_INVALID: {
+ this->nextToken();
this->error(this->peek(), String("invalid token"));
- done = true;
break;
}
default:
@@ -225,6 +233,7 @@
}
}
End();
+ errorReporter->setSource(nullptr);
return result;
}
@@ -234,6 +243,7 @@
Token lookahead = this->peek();
switch (lookahead.fKind) {
case Token::Kind::TK_SEMICOLON:
+ this->nextToken();
this->error(lookahead.fOffset, "expected a declaration, but found ';'");
return false;
default:
@@ -264,7 +274,8 @@
if (this->checkNext(Token::Kind::TK_LPAREN)) {
return this->functionDeclarationEnd(modifiers, *type, name);
} else {
- SkTArray<DSLGlobalVar> result = this->varDeclarationEnd<DSLGlobalVar>(modifiers, *type,
+ SkTArray<DSLGlobalVar> result = this->varDeclarationEnd<DSLGlobalVar>(this->position(name),
+ modifiers, *type,
this->text(name));
Declare(result);
return true;
@@ -301,7 +312,7 @@
for (DSLWrapper<DSLParameter>& param : parameters) {
parameterPointers.push_back(¶m.get());
}
- DSLFunction result(modifiers, type, this->text(name), parameterPointers);
+ DSLFunction result(modifiers, type, this->text(name), parameterPointers, this->position(name));
if (!this->checkNext(Token::Kind::TK_SEMICOLON)) {
AutoDSLSymbolTable symbols;
for (DSLParameter* var : parameterPointers) {
@@ -324,26 +335,45 @@
return Declare(vars);
}
+SKSL_INT DSLParser::arraySize() {
+ Token next = this->peek();
+ if (next.fKind == Token::Kind::TK_INT_LITERAL) {
+ SKSL_INT size;
+ if (this->intLiteral(&size)) {
+ if (size > INT32_MAX) {
+ this->error(next, "array size out of bounds");
+ return 1;
+ }
+ if (size <= 0) {
+ this->error(next, "array size must be positive");
+ return 1;
+ }
+ return size;
+ }
+ return 1;
+ } else if (this->checkNext(Token::Kind::TK_MINUS) &&
+ this->checkNext(Token::Kind::TK_INT_LITERAL)) {
+ this->error(next, "array size must be positive");
+ return 1;
+ } else {
+ this->expression();
+ this->error(next, "expected int literal");
+ return 1;
+ }
+}
+
template<class T>
-SkTArray<T> DSLParser::varDeclarationEnd(const dsl::DSLModifiers& mods, dsl::DSLType baseType,
- skstd::string_view name) {
+SkTArray<T> DSLParser::varDeclarationEnd(PositionInfo pos, const dsl::DSLModifiers& mods,
+ dsl::DSLType baseType, skstd::string_view name) {
using namespace dsl;
SkTArray<T> result;
int offset = this->peek().fOffset;
auto parseArrayDimensions = [&](DSLType* type) -> bool {
while (this->checkNext(Token::Kind::TK_LBRACKET)) {
- if (type->isArray()) {
- this->error(this->peek(), "multi-dimensional arrays are not supported");
- return {};
- }
if (this->checkNext(Token::Kind::TK_RBRACKET)) {
this->error(offset, "expected array dimension");
} else {
- SKSL_INT size;
- if (!this->intLiteral(&size)) {
- return {};
- }
- *type = Array(*type, size);
+ *type = Array(*type, this->arraySize(), pos);
if (!this->expect(Token::Kind::TK_RBRACKET, "']'")) {
return {};
}
@@ -367,10 +397,8 @@
if (!parseArrayDimensions(&type)) {
return {};
}
- if (!parseInitializer(&initializer)) {
- return {};
- }
- result.push_back(T(mods, type, name, std::move(initializer)));
+ parseInitializer(&initializer);
+ result.push_back(T(mods, type, name, std::move(initializer), pos));
AddToSymbolTable(result.back());
while (this->checkNext(Token::Kind::TK_COMMA)) {
@@ -414,9 +442,10 @@
VarDeclarationsPrefix prefix;
if (this->varDeclarationsPrefix(&prefix)) {
checkpoint.accept();
- return declaration_statements(this->varDeclarationEnd<DSLVar>(prefix.modifiers,
- prefix.type,
- this->text(prefix.name)),
+ return declaration_statements(this->varDeclarationEnd<DSLVar>(prefix.fPosition,
+ prefix.fModifiers,
+ prefix.fType,
+ this->text(prefix.fName)),
this->symbols());
}
@@ -430,13 +459,14 @@
// Helper function for varDeclarations(). If this function succeeds, we assume that the rest of the
// statement is a variable-declaration statement, not an expression-statement.
bool DSLParser::varDeclarationsPrefix(VarDeclarationsPrefix* prefixData) {
- prefixData->modifiers = this->modifiers();
- skstd::optional<DSLType> type = this->type(prefixData->modifiers);
+ prefixData->fPosition = this->position(this->peek());
+ prefixData->fModifiers = this->modifiers();
+ skstd::optional<DSLType> type = this->type(prefixData->fModifiers);
if (!type) {
return false;
}
- prefixData->type = *type;
- return this->expectIdentifier(&prefixData->name);
+ prefixData->fType = *type;
+ return this->expectIdentifier(&prefixData->fName);
}
/* modifiers type IDENTIFIER varDeclarationEnd */
@@ -445,8 +475,10 @@
if (!this->varDeclarationsPrefix(&prefix)) {
return skstd::nullopt;
}
- return declaration_statements(this->varDeclarationEnd<DSLVar>(prefix.modifiers, prefix.type,
- this->text(prefix.name)),
+ return declaration_statements(this->varDeclarationEnd<DSLVar>(prefix.fPosition,
+ prefix.fModifiers,
+ prefix.fType,
+ this->text(prefix.fName)),
this->symbols());
}
@@ -486,18 +518,8 @@
return skstd::nullopt;
}
- if (this->checkNext(Token::Kind::TK_LBRACKET)) {
- SKSL_INT arraySize;
- Token sizeToken = this->peek();
- if (!this->DSLParser::intLiteral(&arraySize)) {
- this->error(sizeToken.fOffset, "expected an integer array size");
- return skstd::nullopt;
- }
- if (arraySize <= 0 || arraySize > INT_MAX) {
- this->error(sizeToken.fOffset, "array size is invalid");
- return skstd::nullopt;
- }
- actualType = dsl::Array(actualType, arraySize);
+ while (this->checkNext(Token::Kind::TK_LBRACKET)) {
+ actualType = dsl::Array(actualType, this->arraySize(), this->position(memberName));
if (!this->expect(Token::Kind::TK_RBRACKET, "']'")) {
return skstd::nullopt;
}
@@ -513,18 +535,20 @@
"struct '" + this->text(name) + "' must contain at least one field");
return skstd::nullopt;
}
- return dsl::Struct(this->text(name), SkMakeSpan(fields));
+ return dsl::Struct(this->text(name), SkMakeSpan(fields), this->position(name));
}
/* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
SkTArray<dsl::DSLGlobalVar> DSLParser::structVarDeclaration(const DSLModifiers& modifiers) {
+ PositionInfo pos = this->position(this->peek());
skstd::optional<DSLType> type = this->structDeclaration();
if (!type) {
return {};
}
Token name;
if (this->checkNext(Token::Kind::TK_IDENTIFIER, &name)) {
- return this->varDeclarationEnd<DSLGlobalVar>(modifiers, std::move(*type), this->text(name));
+ return this->varDeclarationEnd<DSLGlobalVar>(pos, modifiers, std::move(*type),
+ this->text(name));
}
this->expect(Token::Kind::TK_SEMICOLON, "';'");
return {};
@@ -542,10 +566,6 @@
return skstd::nullopt;
}
while (this->checkNext(Token::Kind::TK_LBRACKET)) {
- if (type->isArray()) {
- this->error(this->peek(), "multi-dimensional arrays are not supported");
- return skstd::nullopt;
- }
Token sizeToken;
if (!this->expect(Token::Kind::TK_INT_LITERAL, "a positive integer", &sizeToken)) {
return skstd::nullopt;
@@ -556,12 +576,12 @@
this->error(sizeToken, "array size is too large: " + arraySizeFrag);
return skstd::nullopt;
}
- type = Array(*type, arraySize);
+ type = Array(*type, arraySize, this->position(name));
if (!this->expect(Token::Kind::TK_RBRACKET, "']'")) {
return skstd::nullopt;
}
}
- return {{DSLParameter(modifiers, *type, this->text(name))}};
+ return {{DSLParameter(modifiers, *type, this->text(name), this->position(name))}};
}
/** EQ INT_LITERAL */
@@ -743,17 +763,8 @@
}
DSLType result(this->text(type), modifiers);
while (this->checkNext(Token::Kind::TK_LBRACKET)) {
- if (result.isArray()) {
- this->error(this->peek(), "multi-dimensional arrays are not supported");
- return skstd::nullopt;
- }
if (this->peek().fKind != Token::Kind::TK_RBRACKET) {
- SKSL_INT i;
- if (this->intLiteral(&i)) {
- result = Array(result, i);
- } else {
- return skstd::nullopt;
- }
+ result = Array(result, this->arraySize(), this->position(type));
} else {
this->error(this->peek(), "expected array dimension");
}
@@ -794,15 +805,8 @@
if (this->checkNext(Token::Kind::TK_LBRACKET)) {
Token sizeToken = this->peek();
if (sizeToken.fKind != Token::Kind::TK_RBRACKET) {
- SKSL_INT arraySize = 0;
- if (this->DSLParser::intLiteral(&arraySize)) {
- if (arraySize <= 0) {
- this->error(sizeToken, "array size must be positive");
- }
- actualType = Array(std::move(actualType), arraySize);
- } else {
- return false;
- }
+ actualType = Array(std::move(actualType), this->arraySize(),
+ this->position(typeName));
} else {
this->error(sizeToken, "unsized arrays are not permitted");
}
@@ -826,19 +830,7 @@
if (this->checkNext(Token::Kind::TK_IDENTIFIER, &instanceNameToken)) {
instanceName = this->text(instanceNameToken);
if (this->checkNext(Token::Kind::TK_LBRACKET)) {
- Token sizeToken = this->peek();
- if (sizeToken.fKind != Token::Kind::TK_RBRACKET) {
- if (this->DSLParser::intLiteral(&arraySize)) {
- if (arraySize <= 0) {
- this->error(sizeToken, "array size must be positive");
- }
- } else {
- return false;
- }
- } else {
- this->error(sizeToken, "unsized arrays are not permitted");
- return false;
- }
+ arraySize = this->arraySize();
this->expect(Token::Kind::TK_RBRACKET, "']'");
}
}
@@ -880,10 +872,10 @@
}
if (isStatic) {
return StaticIf(std::move(**test), std::move(*ifTrue),
- ifFalse ? std::move(*ifFalse) : DSLStatement());
+ ifFalse ? std::move(*ifFalse) : DSLStatement(), this->position(start));
} else {
return If(std::move(**test), std::move(*ifTrue),
- ifFalse ? std::move(*ifFalse) : DSLStatement());
+ ifFalse ? std::move(*ifFalse) : DSLStatement(), this->position(start));
}
}
@@ -1102,7 +1094,7 @@
if (!this->expect(Token::Kind::TK_SEMICOLON, "';'")) {
return skstd::nullopt;
}
- return Break();
+ return Break(this->position(start));
}
/* CONTINUE SEMICOLON */
@@ -1114,7 +1106,7 @@
if (!this->expect(Token::Kind::TK_SEMICOLON, "';'")) {
return skstd::nullopt;
}
- return Continue();
+ return Continue(this->position(start));
}
/* DISCARD SEMICOLON */
@@ -1503,7 +1495,7 @@
skstd::string_view swizzleMask) {
SkASSERT(swizzleMask.length() > 0);
if (!base.type().isVector() && !base.type().isScalar()) {
- return base.field(swizzleMask);
+ return base.field(swizzleMask, this->position(offset));
}
int length = swizzleMask.length();
if (length > 4) {
@@ -1549,7 +1541,7 @@
skstd::optional<dsl::Wrapper<dsl::DSLExpression>> DSLParser::call(int offset,
dsl::DSLExpression base, SkTArray<Wrapper<DSLExpression>> args) {
- return {{base(std::move(args))}};
+ return {{DSLExpression(base(std::move(args), this->position(offset)), this->position(offset))}};
}
/* LBRACKET expression? RBRACKET | DOT IDENTIFIER | LPAREN arguments RPAREN |
@@ -1562,17 +1554,20 @@
}
switch (next.fKind) {
case Token::Kind::TK_LBRACKET: {
+ if (this->checkNext(Token::Kind::TK_RBRACKET)) {
+ this->error(next, "missing index in '[]'");
+ return {{DSLExpression::Poison()}};
+ }
skstd::optional<DSLWrapper<DSLExpression>> index = this->expression();
if (!index) {
return skstd::nullopt;
}
this->expect(Token::Kind::TK_RBRACKET, "']' to complete array access expression");
DSLPossibleExpression result = base[std::move(**index)];
- if (result.valid()) {
- return {{std::move(result)}};
+ if (!result.valid()) {
+ result.reportErrors(this->position(next));
}
- result.reportErrors(PositionInfo());
- return skstd::nullopt;
+ return {{std::move(result)}};
}
case Token::Kind::TK_DOT: {
int offset = this->peek().fOffset;
@@ -1633,21 +1628,21 @@
case Token::Kind::TK_IDENTIFIER: {
skstd::string_view text;
if (this->identifier(&text)) {
- return dsl::Symbol(text);
+ return dsl::Symbol(text, this->position(t));
}
break;
}
case Token::Kind::TK_INT_LITERAL: {
SKSL_INT i;
if (this->intLiteral(&i)) {
- return {{i}};
+ return {{DSLExpression(i, this->position(t))}};
}
break;
}
case Token::Kind::TK_FLOAT_LITERAL: {
SKSL_FLOAT f;
if (this->floatLiteral(&f)) {
- return {{f}};
+ return {{DSLExpression(f, this->position(t))}};
}
break;
}
@@ -1655,7 +1650,7 @@
case Token::Kind::TK_FALSE_LITERAL: {
bool b;
if (this->boolLiteral(&b)) {
- return {{b}};
+ return {{DSLExpression(b, this->position(t))}};
}
break;
}
diff --git a/src/sksl/SkSLDSLParser.h b/src/sksl/SkSLDSLParser.h
index 11b9f60..d9e9b62 100644
--- a/src/sksl/SkSLDSLParser.h
+++ b/src/sksl/SkSLDSLParser.h
@@ -68,7 +68,9 @@
skstd::string_view text(Token token);
- Position position(Token token);
+ PositionInfo position(Token token);
+
+ PositionInfo position(int offset);
private:
static void InitLayoutMap();
@@ -121,9 +123,6 @@
*/
bool expectIdentifier(Token* result);
- ErrorReporter& errors() {
- return *fErrorReporter;
- }
void error(Token token, String msg);
void error(int offset, String msg);
@@ -137,6 +136,8 @@
ASTNode::ID precision();
+ SKSL_INT arraySize();
+
bool declaration();
bool functionDeclarationEnd(const dsl::DSLModifiers& modifiers,
@@ -144,9 +145,10 @@
const Token& name);
struct VarDeclarationsPrefix {
- dsl::DSLModifiers modifiers;
- dsl::DSLType type = dsl::DSLType(dsl::kVoid_Type);
- Token name;
+ PositionInfo fPosition;
+ dsl::DSLModifiers fModifiers;
+ dsl::DSLType fType = dsl::DSLType(dsl::kVoid_Type);
+ Token fName;
};
bool varDeclarationsPrefix(VarDeclarationsPrefix* prefixData);
@@ -162,8 +164,8 @@
/* (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)? (COMMA IDENTIFER
(LBRACKET expression? RBRACKET)* (EQ assignmentExpression)?)* SEMICOLON */
template<class T>
- SkTArray<T> varDeclarationEnd(const dsl::DSLModifiers& mods, dsl::DSLType baseType,
- skstd::string_view name);
+ SkTArray<T> varDeclarationEnd(PositionInfo position, const dsl::DSLModifiers& mods,
+ dsl::DSLType baseType, skstd::string_view name);
SkTArray<dsl::DSLGlobalVar> globalVarDeclarationEnd(const dsl::DSLModifiers& modifiers,
dsl::DSLType type, skstd::string_view name);
@@ -335,7 +337,7 @@
ErrorReporter* fErrorReporter;
bool fEncounteredFatalError;
ProgramKind fKind;
- String fText;
+ std::unique_ptr<String> fText;
Lexer fLexer;
// current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
// stack on pathological inputs
diff --git a/src/sksl/SkSLErrorReporter.cpp b/src/sksl/SkSLErrorReporter.cpp
index 49a66a4..0ef8f66 100644
--- a/src/sksl/SkSLErrorReporter.cpp
+++ b/src/sksl/SkSLErrorReporter.cpp
@@ -7,16 +7,25 @@
#include "include/sksl/SkSLErrorReporter.h"
+#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/dsl/priv/DSLWriter.h"
namespace SkSL {
void ErrorReporter::error(const char* msg, PositionInfo position) {
+ if (strstr(msg, Compiler::POISON_TAG)) {
+ // don't report errors on poison values
+ return;
+ }
++fErrorCount;
this->handleError(msg, position);
}
void ErrorReporter::error(int offset, const char* msg) {
+ if (strstr(msg, Compiler::POISON_TAG)) {
+ // don't report errors on poison values
+ return;
+ }
if (offset == -1) {
++fErrorCount;
fPendingErrors.push_back(std::string(msg));
diff --git a/src/sksl/dsl/DSLCore.cpp b/src/sksl/dsl/DSLCore.cpp
index e6a5326..f5a6d5b 100644
--- a/src/sksl/dsl/DSLCore.cpp
+++ b/src/sksl/dsl/DSLCore.cpp
@@ -121,12 +121,12 @@
return ir.call(/*offset=*/-1, ir.convertIdentifier(-1, name), std::move(argArray));
}
- static DSLStatement Break() {
- return SkSL::BreakStatement::Make(/*offset=*/-1);
+ static DSLStatement Break(PositionInfo pos) {
+ return SkSL::BreakStatement::Make(pos.offset());
}
- static DSLStatement Continue() {
- return SkSL::ContinueStatement::Make(/*offset=*/-1);
+ static DSLStatement Continue(PositionInfo pos) {
+ return SkSL::ContinueStatement::Make(pos.offset());
}
static DSLStatement Declare(DSLVar& var, PositionInfo pos) {
@@ -323,12 +323,12 @@
return DSLCore::sk_Position();
}
-DSLStatement Break() {
- return DSLCore::Break();
+DSLStatement Break(PositionInfo pos) {
+ return DSLCore::Break(pos);
}
-DSLStatement Continue() {
- return DSLCore::Continue();
+DSLStatement Continue(PositionInfo pos) {
+ return DSLCore::Continue(pos);
}
// Logically, we'd want the variable's initial value to appear on here in Declare, since that
diff --git a/src/sksl/dsl/DSLExpression.cpp b/src/sksl/dsl/DSLExpression.cpp
index fde1ab3..134318b 100644
--- a/src/sksl/dsl/DSLExpression.cpp
+++ b/src/sksl/dsl/DSLExpression.cpp
@@ -39,9 +39,9 @@
DSLWriter::ReportErrors();
}
-DSLExpression::DSLExpression(float value)
+DSLExpression::DSLExpression(float value, PositionInfo pos)
: fExpression(SkSL::FloatLiteral::Make(DSLWriter::Context(),
- /*offset=*/-1,
+ pos.offset(),
value)) {
if (!isfinite(value)) {
if (isinf(value)) {
@@ -52,32 +52,32 @@
}
}
-DSLExpression::DSLExpression(int value)
+DSLExpression::DSLExpression(int value, PositionInfo pos)
: fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(),
- /*offset=*/-1,
+ pos.offset(),
value)) {}
-DSLExpression::DSLExpression(int64_t value)
+DSLExpression::DSLExpression(int64_t value, PositionInfo pos)
: fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(),
- /*offset=*/-1,
+ pos.offset(),
value)) {}
-DSLExpression::DSLExpression(unsigned int value)
+DSLExpression::DSLExpression(unsigned int value, PositionInfo pos)
: fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(),
- /*offset=*/-1,
+ pos.offset(),
value)) {}
-DSLExpression::DSLExpression(bool value)
+DSLExpression::DSLExpression(bool value, PositionInfo pos)
: fExpression(SkSL::BoolLiteral::Make(DSLWriter::Context(),
- /*offset=*/-1,
+ pos.offset(),
value)) {}
-DSLExpression::DSLExpression(DSLVarBase& var) {
- fExpression = std::make_unique<SkSL::VariableReference>(/*offset=*/-1, DSLWriter::Var(var),
+DSLExpression::DSLExpression(DSLVarBase& var, PositionInfo pos) {
+ fExpression = std::make_unique<SkSL::VariableReference>(pos.offset(), DSLWriter::Var(var),
SkSL::VariableReference::RefKind::kRead);
}
-DSLExpression::DSLExpression(DSLVarBase&& var)
+DSLExpression::DSLExpression(DSLVarBase&& var, PositionInfo pos)
: DSLExpression(var) {}
DSLExpression::DSLExpression(DSLPossibleExpression expr, PositionInfo pos) {
@@ -85,10 +85,14 @@
if (expr.valid()) {
fExpression = std::move(expr.fExpression);
} else {
- fExpression = SkSL::Poison::Make(DSLWriter::Context());
+ fExpression = SkSL::Poison::Make(pos.offset(), DSLWriter::Context());
}
}
+DSLExpression DSLExpression::Poison(PositionInfo pos) {
+ return DSLExpression(SkSL::Poison::Make(pos.offset(), DSLWriter::Context()));
+}
+
DSLExpression::~DSLExpression() {
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
if (fExpression && DSLWriter::InFragmentProcessor()) {
@@ -166,13 +170,14 @@
return DSLWriter::ConvertIndex(this->release(), right.release());
}
-DSLPossibleExpression DSLExpression::operator()(SkTArray<DSLWrapper<DSLExpression>> args) {
+DSLPossibleExpression DSLExpression::operator()(SkTArray<DSLWrapper<DSLExpression>> args,
+ PositionInfo pos) {
ExpressionArray converted;
converted.reserve_back(args.count());
for (DSLWrapper<DSLExpression>& arg : args) {
converted.push_back(arg->release());
}
- return DSLWriter::Call(this->release(), std::move(converted));
+ return DSLWriter::Call(this->release(), std::move(converted), pos);
}
#define OP(op, token) \
@@ -338,8 +343,9 @@
return DSLExpression(this->release())[std::move(index)];
}
-DSLPossibleExpression DSLPossibleExpression::operator()(SkTArray<DSLWrapper<DSLExpression>> args) {
- return DSLExpression(this->release())(std::move(args));
+DSLPossibleExpression DSLPossibleExpression::operator()(SkTArray<DSLWrapper<DSLExpression>> args,
+ PositionInfo pos) {
+ return DSLExpression(this->release())(std::move(args), pos);
}
DSLPossibleExpression DSLPossibleExpression::operator++() {
diff --git a/src/sksl/dsl/DSLFunction.cpp b/src/sksl/dsl/DSLFunction.cpp
index 78bafb0..1c9256c 100644
--- a/src/sksl/dsl/DSLFunction.cpp
+++ b/src/sksl/dsl/DSLFunction.cpp
@@ -20,7 +20,7 @@
namespace dsl {
void DSLFunction::init(DSLModifiers modifiers, const DSLType& returnType, skstd::string_view name,
- SkTArray<DSLParameter*> params) {
+ SkTArray<DSLParameter*> params, PositionInfo pos) {
// Conservatively assume all user-defined functions have side effects.
if (!DSLWriter::IsModule()) {
modifiers.fModifiers.fFlags |= Modifiers::kHasSideEffects_Flag;
@@ -51,7 +51,7 @@
SkASSERT(paramVars.size() == params.size());
fDecl = SkSL::FunctionDeclaration::Convert(DSLWriter::Context(),
*DSLWriter::SymbolTable(),
- /*offset=*/-1,
+ pos.offset(),
DSLWriter::Modifiers(modifiers.fModifiers),
name == "main" ? name : DSLWriter::Name(name),
std::move(paramVars), &returnType.skslType(),
@@ -66,7 +66,7 @@
// case the definition is delayed. If we end up defining the function immediately, we'll
// remove the prototype in define().
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::FunctionPrototype>(
- /*offset=*/-1, fDecl, DSLWriter::IsModule()));
+ pos.offset(), fDecl, DSLWriter::IsModule()));
}
}
diff --git a/src/sksl/dsl/DSLSymbols.cpp b/src/sksl/dsl/DSLSymbols.cpp
index 52356e7..b490de4 100644
--- a/src/sksl/dsl/DSLSymbols.cpp
+++ b/src/sksl/dsl/DSLSymbols.cpp
@@ -26,8 +26,8 @@
return DSLWriter::IRGenerator().symbolTable();
}
-DSLPossibleExpression Symbol(skstd::string_view name) {
- return DSLWriter::IRGenerator().convertIdentifier(/*offset=*/-1, name);
+DSLPossibleExpression Symbol(skstd::string_view name, PositionInfo pos) {
+ return DSLWriter::IRGenerator().convertIdentifier(pos.offset(), name);
}
bool IsType(skstd::string_view name) {
diff --git a/src/sksl/dsl/DSLType.cpp b/src/sksl/dsl/DSLType.cpp
index 75e16d8..f4efe9f 100644
--- a/src/sksl/dsl/DSLType.cpp
+++ b/src/sksl/dsl/DSLType.cpp
@@ -204,25 +204,25 @@
return DSLWriter::Construct(type.skslType(), std::move(argArray));
}
-DSLType Array(const DSLType& base, int count) {
+DSLType Array(const DSLType& base, int count, PositionInfo pos) {
if (count <= 0) {
- DSLWriter::ReportError("array size must be positive");
+ DSLWriter::ReportError("array size must be positive", pos);
return base;
}
if (base.isArray()) {
- DSLWriter::ReportError("multidimensional arrays are not permitted");
- return base;
+ DSLWriter::ReportError("multi-dimensional arrays are not supported", pos);
+ return kPoison_Type;
}
return DSLWriter::SymbolTable()->addArrayDimension(&base.skslType(), count);
}
-DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields) {
+DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos) {
std::vector<SkSL::Type::Field> skslFields;
skslFields.reserve(fields.size());
for (const DSLField& field : fields) {
skslFields.emplace_back(field.fModifiers.fModifiers, field.fName, &field.fType.skslType());
}
- const SkSL::Type* result = DSLWriter::SymbolTable()->add(Type::MakeStructType(/*offset=*/-1,
+ const SkSL::Type* result = DSLWriter::SymbolTable()->add(Type::MakeStructType(pos.offset(),
name,
skslFields));
DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::StructDefinition>(/*offset=*/-1,
diff --git a/src/sksl/dsl/DSLVar.cpp b/src/sksl/dsl/DSLVar.cpp
index 188c41a..9e89be4 100644
--- a/src/sksl/dsl/DSLVar.cpp
+++ b/src/sksl/dsl/DSLVar.cpp
@@ -21,23 +21,26 @@
namespace dsl {
-DSLVarBase::DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue)
- : DSLVarBase(DSLModifiers(), std::move(type), name, std::move(initialValue)) {}
+DSLVarBase::DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue,
+ PositionInfo pos)
+ : DSLVarBase(DSLModifiers(), std::move(type), name, std::move(initialValue), pos) {}
-DSLVarBase::DSLVarBase(DSLType type, DSLExpression initialValue)
- : DSLVarBase(type, "var", std::move(initialValue)) {}
+DSLVarBase::DSLVarBase(DSLType type, DSLExpression initialValue, PositionInfo pos)
+ : DSLVarBase(type, "var", std::move(initialValue), pos) {}
-DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue)
- : DSLVarBase(modifiers, type, "var", std::move(initialValue)) {}
+DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue,
+ PositionInfo pos)
+ : DSLVarBase(modifiers, type, "var", std::move(initialValue), pos) {}
DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::string_view name,
- DSLExpression initialValue)
+ DSLExpression initialValue, PositionInfo pos)
: fModifiers(std::move(modifiers))
, fType(std::move(type))
, fRawName(name)
, fName(fType.skslType().isOpaque() ? name : DSLWriter::Name(name))
, fInitialValue(std::move(initialValue))
- , fDeclared(DSLWriter::MarkVarsDeclared()) {
+ , fDeclared(DSLWriter::MarkVarsDeclared())
+ , fPosition(pos) {
if (fModifiers.fModifiers.fFlags & Modifiers::kUniform_Flag) {
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
if (DSLWriter::InFragmentProcessor()) {
@@ -91,6 +94,7 @@
std::swap(fInitialValue.fExpression, other.fInitialValue.fExpression);
std::swap(fDeclared, other.fDeclared);
std::swap(fInitialized, other.fInitialized);
+ std::swap(fPosition, other.fPosition);
}
void DSLVar::swap(DSLVar& other) {
@@ -102,7 +106,7 @@
}
DSLGlobalVar::DSLGlobalVar(const char* name)
- : INHERITED(kVoid_Type, name, DSLExpression()) {
+ : INHERITED(kVoid_Type, name, DSLExpression(), PositionInfo()) {
fName = name;
DSLWriter::MarkDeclared(*this);
#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
diff --git a/src/sksl/dsl/priv/DSLWriter.cpp b/src/sksl/dsl/priv/DSLWriter.cpp
index d37afcb..9ab3380 100644
--- a/src/sksl/dsl/priv/DSLWriter.cpp
+++ b/src/sksl/dsl/priv/DSLWriter.cpp
@@ -136,17 +136,19 @@
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
std::unique_ptr<SkSL::Expression> DSLWriter::Call(const FunctionDeclaration& function,
- ExpressionArray arguments) {
+ ExpressionArray arguments,
+ PositionInfo pos) {
// We can't call FunctionCall::Convert directly here, because intrinsic management is handled in
// IRGenerator::call.
- return IRGenerator().call(/*offset=*/-1, function, std::move(arguments));
+ return IRGenerator().call(pos.offset(), function, std::move(arguments));
}
std::unique_ptr<SkSL::Expression> DSLWriter::Call(std::unique_ptr<SkSL::Expression> expr,
- ExpressionArray arguments) {
+ ExpressionArray arguments,
+ PositionInfo pos) {
// We can't call FunctionCall::Convert directly here, because intrinsic management is handled in
// IRGenerator::call.
- return IRGenerator().call(/*offset=*/-1, std::move(expr), std::move(arguments));
+ return IRGenerator().call(pos.offset(), std::move(expr), std::move(arguments));
}
DSLPossibleExpression DSLWriter::Coerce(std::unique_ptr<Expression> expr, const SkSL::Type& type) {
@@ -239,13 +241,13 @@
SkASSERT(!var.fVar);
var.fInitialized = true;
if (var.storage() != SkSL::VariableStorage::kParameter) {
- DSLWriter::IRGenerator().checkVarDeclaration(/*offset=*/-1,
+ DSLWriter::IRGenerator().checkVarDeclaration(var.fPosition.offset(),
var.fModifiers.fModifiers,
&var.fType.skslType(),
var.storage());
}
std::unique_ptr<SkSL::Variable> skslvar = DSLWriter::IRGenerator().convertVar(
- /*offset=*/-1,
+ var.fPosition.offset(),
var.fModifiers.fModifiers,
&var.fType.skslType(),
var.fName,
@@ -278,7 +280,7 @@
// This should only be called on undeclared parameter variables, but we allow the creation to go
// ahead regardless so we don't have to worry about null pointers potentially sneaking in and
// breaking things. DSLFunction is responsible for reporting errors for invalid parameters.
- return DSLWriter::IRGenerator().convertVar(/*offset=*/-1, var.fModifiers.fModifiers,
+ return DSLWriter::IRGenerator().convertVar(var.fPosition.offset(), var.fModifiers.fModifiers,
&var.fType.skslType(), var.fName, /*isArray=*/false,
/*arraySize=*/nullptr, var.storage());
}
diff --git a/src/sksl/dsl/priv/DSLWriter.h b/src/sksl/dsl/priv/DSLWriter.h
index 129b6bc..883f0c0 100644
--- a/src/sksl/dsl/priv/DSLWriter.h
+++ b/src/sksl/dsl/priv/DSLWriter.h
@@ -191,13 +191,15 @@
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
static std::unique_ptr<SkSL::Expression> Call(const FunctionDeclaration& function,
- ExpressionArray arguments);
+ ExpressionArray arguments,
+ PositionInfo pos = PositionInfo::Capture());
/**
* Invokes expr(arguments), where expr is a function or type reference.
*/
static std::unique_ptr<SkSL::Expression> Call(std::unique_ptr<SkSL::Expression> expr,
- ExpressionArray arguments);
+ ExpressionArray arguments,
+ PositionInfo pos = PositionInfo::Capture());
static DSLPossibleExpression Coerce(std::unique_ptr<Expression> expr, const SkSL::Type& type);
diff --git a/src/sksl/ir/SkSLIndexExpression.cpp b/src/sksl/ir/SkSLIndexExpression.cpp
index 7f31226..9e337b5 100644
--- a/src/sksl/ir/SkSLIndexExpression.cpp
+++ b/src/sksl/ir/SkSLIndexExpression.cpp
@@ -43,7 +43,7 @@
if (!arraySize) {
return nullptr;
}
- return std::make_unique<TypeReference>(context, /*offset=*/-1,
+ return std::make_unique<TypeReference>(context, base->fOffset,
symbolTable.addArrayDimension(&baseType, arraySize));
}
// Convert an index expression with an expression inside of it: `arr[a * 3]`.
diff --git a/src/sksl/ir/SkSLPoison.h b/src/sksl/ir/SkSLPoison.h
index 43e3a1c..a6b58fc 100644
--- a/src/sksl/ir/SkSLPoison.h
+++ b/src/sksl/ir/SkSLPoison.h
@@ -14,19 +14,19 @@
public:
static constexpr Kind kExpressionKind = Kind::kPoison;
- static std::unique_ptr<Expression> Make(const Context& context) {
- return std::make_unique<Poison>(context.fTypes.fPoison.get());
+ static std::unique_ptr<Expression> Make(int offset, const Context& context) {
+ return std::make_unique<Poison>(offset, context.fTypes.fPoison.get());
}
- Poison(const Type* type)
- : INHERITED(/*offset=*/-1, kExpressionKind, type) {}
+ Poison(int offset, const Type* type)
+ : INHERITED(offset, kExpressionKind, type) {}
bool hasProperty(Property property) const override {
return false;
}
std::unique_ptr<Expression> clone() const override {
- return std::make_unique<Poison>(&this->type());
+ return std::make_unique<Poison>(fOffset, &this->type());
}
String description() const override {
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index 2349249..6bfad93 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -566,7 +566,7 @@
}
{
- ExpectError error(r, "multidimensional arrays are not permitted");
+ ExpectError error(r, "multi-dimensional arrays are not supported");
Array(Array(kFloat_Type, 2), 2);
}
}