Disallow identifier names that overlap existing types.

It's not legal to use identifiers like "int" or "sampler" to name your
variables (or enums, or structs, etc.). SkSL will now report this as an
error instead of relying on the driver to catch this.

(Note that in some contexts, it might be legal by the spec to reuse a
name that you introduced yourself, depending on the scope. In practice,
this confuses Apple GLSL, so we shouldn't support it anyway.)

This caught several existing places in our code where we used the name
"sampler." These were never exposed to the driver (they were intrinsics
that we would replace during compilation) so they were harmless before.

Change-Id: Ia6dcfca8c500d02e1eb5f9427bed8727e114dfc2
Bug: skia:11036
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340758
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index bf51d15..878bc8f 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -122,6 +122,13 @@
   "$_tests/sksl/errors/OverflowIntLiteral.sksl",
   "$_tests/sksl/errors/OverflowUintLiteral.sksl",
   "$_tests/sksl/errors/PrivateTypes.sksl",
+  "$_tests/sksl/errors/RedeclareBasicType.sksl",
+  "$_tests/sksl/errors/RedeclareEnum.sksl",
+  "$_tests/sksl/errors/RedeclareSamplerType.sksl",
+  "$_tests/sksl/errors/RedeclareStruct.sksl",
+  "$_tests/sksl/errors/RedeclareStructTypeWithName.sksl",
+  "$_tests/sksl/errors/RedeclareUserType.sksl",
+  "$_tests/sksl/errors/RedeclareVariable.sksl",
   "$_tests/sksl/errors/ReturnDifferentType.sksl",
   "$_tests/sksl/errors/ReturnFromVoid.sksl",
   "$_tests/sksl/errors/ReturnMissingValue.sksl",
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 5b5acfe..8bfe7bf 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -255,6 +255,18 @@
     }
 }
 
+bool Parser::expectIdentifier(Token* result) {
+    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", result)) {
+        return false;
+    }
+    if (this->isType(this->text(*result))) {
+        this->error(*result, "expected an identifier, but found type '" +
+                             this->text(*result) + "'");
+        return false;
+    }
+    return true;
+}
+
 StringFragment Parser::text(Token token) {
     return StringFragment(fText + token.fOffset, token.fLength);
 }
@@ -269,7 +281,7 @@
 
 bool Parser::isType(StringFragment name) {
     const Symbol* s = fSymbols[name];
-    return s && s->kind() == Symbol::Kind::kType;
+    return s && s->is<Type>();
 }
 
 /* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
@@ -282,7 +294,7 @@
     StringFragment text = this->text(start);
     if (text == "#extension") {
         Token name;
-        if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+        if (!this->expectIdentifier(&name)) {
             return ASTNode::ID::Invalid();
         }
         if (!this->expect(Token::Kind::TK_COLON, "':'")) {
@@ -310,7 +322,7 @@
     if (this->peek().fKind == Token::Kind::TK_LPAREN) {
         this->nextToken();
         Token argToken;
-        if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &argToken)) {
+        if (!this->expectIdentifier(&argToken)) {
             return ASTNode::ID::Invalid();
         }
         argument = this->text(argToken);
@@ -365,7 +377,7 @@
         return ASTNode::ID::Invalid();
     }
     Token name;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+    if (!this->expectIdentifier(&name)) {
         return ASTNode::ID::Invalid();
     }
     if (!this->expect(Token::Kind::TK_LBRACE, "'{'")) {
@@ -375,7 +387,7 @@
     ASTNode::ID result = this->createNode(name.fOffset, ASTNode::Kind::kEnum, this->text(name));
     if (!this->checkNext(Token::Kind::TK_RBRACE)) {
         Token id;
-        if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &id)) {
+        if (!this->expectIdentifier(&id)) {
             return ASTNode::ID::Invalid();
         }
         if (this->checkNext(Token::Kind::TK_EQ)) {
@@ -394,7 +406,7 @@
             if (!this->expect(Token::Kind::TK_COMMA, "','")) {
                 return ASTNode::ID::Invalid();
             }
-            if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &id)) {
+            if (!this->expectIdentifier(&id)) {
                 return ASTNode::ID::Invalid();
             }
             if (this->checkNext(Token::Kind::TK_EQ)) {
@@ -452,7 +464,7 @@
         return ASTNode::ID::Invalid();
     }
     Token name;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+    if (!this->expectIdentifier(&name)) {
         return ASTNode::ID::Invalid();
     }
     if (this->checkNext(Token::Kind::TK_LPAREN)) {
@@ -498,7 +510,7 @@
         return ASTNode::ID::Invalid();
     }
     Token name;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+    if (!this->expectIdentifier(&name)) {
         return ASTNode::ID::Invalid();
     }
     return this->varDeclarationEnd(modifiers, type, this->text(name));
@@ -510,7 +522,7 @@
         return ASTNode::ID::Invalid();
     }
     Token name;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+    if (!this->expectIdentifier(&name)) {
         return ASTNode::ID::Invalid();
     }
     if (!this->expect(Token::Kind::TK_LBRACE, "'{'")) {
@@ -649,7 +661,7 @@
 
     while (this->checkNext(Token::Kind::TK_COMMA)) {
         Token identifierName;
-        if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &identifierName)) {
+        if (!this->expectIdentifier(&identifierName)) {
             return ASTNode::ID::Invalid();
         }
 
@@ -680,7 +692,7 @@
         return ASTNode::ID::Invalid();
     }
     Token name;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+    if (!this->expectIdentifier(&name)) {
         return ASTNode::ID::Invalid();
     }
     ASTNode::ID result = this->createNode(name.fOffset, ASTNode::Kind::kParameter);
@@ -724,7 +736,7 @@
         return StringFragment();
     }
     Token resultToken;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &resultToken)) {
+    if (!this->expectIdentifier(&resultToken)) {
         return StringFragment();
     }
     return this->text(resultToken);
@@ -1185,7 +1197,7 @@
    RBRACE (IDENTIFIER (LBRACKET expression? RBRACKET)*)? SEMICOLON */
 ASTNode::ID Parser::interfaceBlock(Modifiers mods) {
     Token name;
-    if (!this->expect(Token::Kind::TK_IDENTIFIER, "an identifier", &name)) {
+    if (!this->expectIdentifier(&name)) {
         return ASTNode::ID::Invalid();
     }
     if (peek().fKind != Token::Kind::TK_LBRACE) {
diff --git a/src/sksl/SkSLParser.h b/src/sksl/SkSLParser.h
index faad24e..6d5c927 100644
--- a/src/sksl/SkSLParser.h
+++ b/src/sksl/SkSLParser.h
@@ -140,6 +140,14 @@
     bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
     bool expect(Token::Kind kind, String expected, Token* result = nullptr);
 
+    /**
+     * Behaves like expect(TK_IDENTIFIER), but also verifies that identifier is not a type.
+     * If the token was actually a type, generates an error message of the form:
+     *
+     * "expected an identifier, but found type 'float2'"
+     */
+    bool expectIdentifier(Token* result);
+
     void error(Token token, String msg);
     void error(int offset, String msg);
     /**
diff --git a/src/sksl/generated/sksl_gpu.dehydrated.sksl b/src/sksl/generated/sksl_gpu.dehydrated.sksl
index c352ebb..48ad1c4 100644
--- a/src/sksl/generated/sksl_gpu.dehydrated.sksl
+++ b/src/sksl/generated/sksl_gpu.dehydrated.sksl
@@ -150,6 +150,7 @@
 7,102,105,110,100,77,83,66,
 7,116,101,120,116,117,114,101,
 9,116,101,120,116,117,114,101,50,68,
+1,115,
 7,115,97,109,112,108,101,114,
 13,109,97,107,101,83,97,109,112,108,101,114,50,68,
 9,115,97,109,112,108,101,114,50,68,
@@ -196,7 +197,6 @@
 10,98,108,101,110,100,95,112,108,117,115,
 14,98,108,101,110,100,95,109,111,100,117,108,97,116,101,
 12,98,108,101,110,100,95,115,99,114,101,101,110,
-1,115,
 1,100,
 24,95,98,108,101,110,100,95,111,118,101,114,108,97,121,95,99,111,109,112,111,110,101,110,116,
 13,98,108,101,110,100,95,111,118,101,114,108,97,121,
@@ -2992,75 +2992,75 @@
 45,35,3,72,4,3,
 48,36,3,
 9,82,4,
-45,37,3,82,4,3,
+45,37,3,84,4,3,
 23,38,3,
-9,90,4,2,34,3,36,3,
-45,39,3,104,4,
+9,92,4,2,34,3,36,3,
+45,39,3,106,4,
 48,40,3,
 9,82,4,
-45,41,3,114,4,3,
+45,41,3,116,4,3,
 23,42,3,
-9,130,4,1,40,3,
-45,43,3,142,4,
+9,132,4,1,40,3,
+45,43,3,144,4,
 48,44,3,
 9,82,4,
-45,45,3,147,4,3,
+45,45,3,149,4,3,
 48,46,3,
-9,159,4,
+9,161,4,
 42,160,0,3,
 23,47,3,
-9,161,4,2,44,3,46,3,
+9,163,4,2,44,3,46,3,
 42,248,1,
 48,48,3,
 9,82,4,
 42,45,3,3,
 48,49,3,
-9,159,4,
+9,161,4,
 42,160,0,3,
 48,50,3,
-9,168,4,
+9,170,4,
 42,160,0,3,
 47,51,3,2,
 42,47,3,
 23,52,3,
-9,161,4,3,48,3,49,3,50,3,
+9,163,4,3,48,3,49,3,50,3,
 42,248,1,
 42,52,3,
 48,53,3,
 9,82,4,
-45,54,3,173,4,3,
+45,54,3,175,4,3,
 48,55,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 47,56,3,3,
 42,47,3,
 42,52,3,
 23,57,3,
-9,161,4,2,53,3,55,3,
+9,163,4,2,53,3,55,3,
 42,248,1,
 42,57,3,
 48,58,3,
 9,82,4,
-45,59,3,185,4,3,
+45,59,3,187,4,3,
 48,60,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 47,61,3,4,
 42,47,3,
 42,52,3,
 42,57,3,
 23,62,3,
-9,161,4,2,58,3,60,3,
-45,63,3,196,4,
+9,163,4,2,58,3,60,3,
+45,63,3,198,4,
 42,62,3,
 48,64,3,
 9,82,4,
-45,65,3,201,4,3,
+45,65,3,203,4,3,
 48,66,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 48,67,3,
-9,168,4,
+9,170,4,
 42,160,0,3,
 47,68,3,5,
 42,47,3,
@@ -3068,14 +3068,14 @@
 42,57,3,
 42,62,3,
 23,69,3,
-9,161,4,3,64,3,66,3,67,3,
+9,163,4,3,64,3,66,3,67,3,
 42,248,1,
 42,69,3,
 48,70,3,
 9,82,4,
 42,65,3,3,
 48,71,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 47,72,3,6,
 42,47,3,
@@ -3084,14 +3084,14 @@
 42,62,3,
 42,69,3,
 23,73,3,
-9,161,4,2,70,3,71,3,
+9,163,4,2,70,3,71,3,
 42,248,1,
 42,73,3,
 48,74,3,
 9,82,4,
 42,41,3,3,
 48,75,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 47,76,3,7,
 42,47,3,
@@ -3101,14 +3101,14 @@
 42,69,3,
 42,73,3,
 23,77,3,
-9,161,4,2,74,3,75,3,
+9,163,4,2,74,3,75,3,
 42,248,1,
 42,77,3,
 48,78,3,
 9,82,4,
 42,41,3,3,
 48,79,3,
-9,159,4,
+9,161,4,
 42,150,1,3,
 47,80,3,8,
 42,47,3,
@@ -3119,32 +3119,32 @@
 42,73,3,
 42,77,3,
 23,81,3,
-9,161,4,2,78,3,79,3,
+9,163,4,2,78,3,79,3,
 42,248,1,
 42,81,3,
 48,82,3,
-9,220,4,
-45,83,3,228,4,3,
+9,222,4,
+45,83,3,230,4,3,
 23,84,3,
-9,241,4,1,82,3,
+9,243,4,1,82,3,
 42,248,1,
 48,85,3,
-9,220,4,
-45,86,3,253,4,3,
+9,222,4,
+45,86,3,255,4,3,
 48,87,3,
-9,161,4,
+9,163,4,
 42,203,0,3,
 47,88,3,2,
 42,84,3,
 23,89,3,
-9,241,4,2,85,3,87,3,
+9,243,4,2,85,3,87,3,
 42,248,1,
 42,89,3,
 48,90,3,
 9,82,4,
 42,45,3,3,
 48,91,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 47,92,3,9,
 42,47,3,
@@ -3156,17 +3156,17 @@
 42,77,3,
 42,81,3,
 23,93,3,
-9,161,4,2,90,3,91,3,
+9,163,4,2,90,3,91,3,
 42,248,1,
 42,93,3,
 48,94,3,
 9,82,4,
 42,45,3,3,
 48,95,3,
-9,159,4,
+9,161,4,
 42,108,1,3,
 48,96,3,
-9,168,4,
+9,170,4,
 42,160,0,3,
 47,97,3,10,
 42,47,3,
@@ -3179,14 +3179,14 @@
 42,81,3,
 42,93,3,
 23,98,3,
-9,161,4,3,94,3,95,3,96,3,
+9,163,4,3,94,3,95,3,96,3,
 42,248,1,
 42,98,3,
 48,99,3,
 9,82,4,
 42,54,3,3,
 48,100,3,
-9,159,4,
+9,161,4,
 42,150,1,3,
 47,101,3,11,
 42,47,3,
@@ -3200,17 +3200,17 @@
 42,93,3,
 42,98,3,
 23,102,3,
-9,161,4,2,99,3,100,3,
+9,163,4,2,99,3,100,3,
 42,248,1,
 42,102,3,
 48,103,3,
 9,82,4,
 42,54,3,3,
 48,104,3,
-9,159,4,
+9,161,4,
 42,150,1,3,
 48,105,3,
-9,168,4,
+9,170,4,
 42,160,0,3,
 47,106,3,12,
 42,47,3,
@@ -3225,41 +3225,41 @@
 42,98,3,
 42,102,3,
 23,107,3,
-9,161,4,3,103,3,104,3,105,3,
+9,163,4,3,103,3,104,3,105,3,
 42,248,1,
 42,107,3,
 48,108,3,
-9,12,5,
-45,109,3,18,5,3,
+9,14,5,
+45,109,3,20,5,3,
 48,110,3,
-9,159,4,
+9,161,4,
 42,43,3,3,
 23,111,3,
-9,26,5,2,108,3,110,3,
+9,28,5,2,108,3,110,3,
 42,114,1,
 48,112,3,
-9,12,5,
-45,113,3,36,5,3,
+9,14,5,
+45,113,3,38,5,3,
 48,114,3,
-9,159,4,
+9,161,4,
 42,43,3,3,
 47,115,3,2,
 42,111,3,
 23,116,3,
-9,26,5,2,112,3,114,3,
+9,28,5,2,112,3,114,3,
 42,63,3,
 42,116,3,
 48,117,3,
 9,250,1,
 42,3,0,3,
 23,118,3,
-9,45,5,1,117,3,
+9,47,5,1,117,3,
 42,3,0,
 48,119,3,
 9,250,1,
 42,3,0,3,
 23,120,3,
-9,50,5,1,119,3,
+9,52,5,1,119,3,
 42,3,0,
 48,121,3,
 9,250,1,
@@ -3267,7 +3267,7 @@
 47,122,3,2,
 42,118,3,
 23,123,3,
-9,45,5,1,121,3,
+9,47,5,1,121,3,
 42,47,0,
 42,123,3,
 48,124,3,
@@ -3276,14 +3276,14 @@
 47,125,3,2,
 42,120,3,
 23,126,3,
-9,50,5,1,124,3,
+9,52,5,1,124,3,
 42,47,0,
 42,126,3,
 48,127,3,
 9,250,1,
 42,3,0,3,
 23,128,3,
-9,55,5,1,127,3,
+9,57,5,1,127,3,
 42,3,0,
 48,129,3,
 9,250,1,
@@ -3291,242 +3291,242 @@
 47,130,3,2,
 42,128,3,
 23,131,3,
-9,55,5,1,129,3,
+9,57,5,1,129,3,
 42,47,0,
 42,131,3,
 48,132,3,
-9,62,5,
+9,64,5,
 42,160,0,3,
 48,133,3,
-9,161,4,
+9,163,4,
 42,203,0,3,
 23,134,3,
-9,74,5,2,132,3,133,3,
+9,76,5,2,132,3,133,3,
 42,160,0,
 48,135,3,
-9,62,5,
+9,64,5,
 42,108,1,3,
 48,136,3,
-9,161,4,
+9,163,4,
 42,203,0,3,
 47,137,3,2,
 42,134,3,
 23,138,3,
-9,74,5,2,135,3,136,3,
+9,76,5,2,135,3,136,3,
 42,108,1,
 42,138,3,
 48,139,3,
-9,62,5,
+9,64,5,
 42,150,1,3,
 48,140,3,
-9,161,4,
+9,163,4,
 42,203,0,3,
 47,141,3,3,
 42,134,3,
 42,138,3,
 23,142,3,
-9,74,5,2,139,3,140,3,
+9,76,5,2,139,3,140,3,
 42,150,1,
 42,142,3,
 48,143,3,
-9,62,5,
+9,64,5,
 42,114,1,3,
 48,144,3,
-9,161,4,
+9,163,4,
 42,203,0,3,
 47,145,3,4,
 42,134,3,
 42,138,3,
 42,142,3,
 23,146,3,
-9,74,5,2,143,3,144,3,
+9,76,5,2,143,3,144,3,
 42,114,1,
 42,146,3,
 48,147,3,
-9,62,5,
+9,64,5,
 42,160,0,3,
 48,148,3,
-9,94,5,
+9,96,5,
 42,108,1,3,
 23,149,3,
-9,101,5,2,147,3,148,3,
+9,103,5,2,147,3,148,3,
 42,160,0,
 48,150,3,
-9,62,5,
+9,64,5,
 42,108,1,3,
 48,151,3,
-9,94,5,
+9,96,5,
 42,108,1,3,
 47,152,3,2,
 42,149,3,
 23,153,3,
-9,101,5,2,150,3,151,3,
+9,103,5,2,150,3,151,3,
 42,108,1,
 42,153,3,
 48,154,3,
-9,62,5,
+9,64,5,
 42,150,1,3,
 48,155,3,
-9,94,5,
+9,96,5,
 42,108,1,3,
 47,156,3,3,
 42,149,3,
 42,153,3,
 23,157,3,
-9,101,5,2,154,3,155,3,
+9,103,5,2,154,3,155,3,
 42,150,1,
 42,157,3,
 48,158,3,
-9,62,5,
+9,64,5,
 42,114,1,3,
 48,159,3,
-9,94,5,
+9,96,5,
 42,108,1,3,
 47,160,3,4,
 42,149,3,
 42,153,3,
 42,157,3,
 23,161,3,
-9,101,5,2,158,3,159,3,
+9,103,5,2,158,3,159,3,
 42,114,1,
 42,161,3,
 48,162,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,163,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,164,3,
-9,129,5,2,162,3,163,3,
+9,131,5,2,162,3,163,3,
 42,248,1,
 48,165,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,166,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,167,3,
-9,141,5,2,165,3,166,3,
+9,143,5,2,165,3,166,3,
 42,248,1,
 48,168,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,169,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,170,3,
-9,151,5,2,168,3,169,3,
+9,153,5,2,168,3,169,3,
 42,248,1,
 48,171,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,172,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,173,3,
-9,161,5,2,171,3,172,3,
+9,163,5,2,171,3,172,3,
 42,248,1,
 48,174,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,175,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,176,3,
-9,176,5,2,174,3,175,3,
+9,178,5,2,174,3,175,3,
 42,248,1,
 48,177,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,178,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,179,3,
-9,191,5,2,177,3,178,3,
+9,193,5,2,177,3,178,3,
 42,248,1,
 48,180,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,181,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,182,3,
-9,204,5,2,180,3,181,3,
+9,206,5,2,180,3,181,3,
 42,248,1,
 48,183,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,184,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,185,3,
-9,217,5,2,183,3,184,3,
+9,219,5,2,183,3,184,3,
 42,248,1,
 48,186,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,187,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,188,3,
-9,231,5,2,186,3,187,3,
+9,233,5,2,186,3,187,3,
 42,248,1,
 48,189,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,190,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,191,3,
-9,245,5,2,189,3,190,3,
+9,247,5,2,189,3,190,3,
 42,248,1,
 48,192,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,193,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,194,3,
-9,4,6,2,192,3,193,3,
+9,6,6,2,192,3,193,3,
 42,248,1,
 48,195,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,196,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,197,3,
-9,19,6,2,195,3,196,3,
+9,21,6,2,195,3,196,3,
 42,248,1,
 48,198,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,199,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,200,3,
-9,29,6,2,198,3,199,3,
+9,31,6,2,198,3,199,3,
 42,248,1,
 48,201,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,202,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,203,3,
-9,40,6,2,201,3,202,3,
+9,42,6,2,201,3,202,3,
 42,248,1,
 48,204,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,205,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,206,3,
-9,55,6,2,204,3,205,3,
+9,57,6,2,204,3,205,3,
 42,248,1,
 48,207,3,
-9,68,6,
+9,82,4,
 42,237,1,3,
 48,208,3,
 9,70,6,
@@ -3535,28 +3535,28 @@
 9,72,6,2,207,3,208,3,
 42,168,0,
 48,210,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,211,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,212,3,
 9,97,6,2,210,3,211,3,
 42,248,1,
 48,213,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,214,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,215,3,
 9,111,6,2,213,3,214,3,
 42,248,1,
 48,216,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,217,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,218,3,
 9,124,6,2,216,3,217,3,
@@ -3571,7 +3571,7 @@
 9,140,6,2,219,3,220,3,
 42,168,0,
 48,222,3,
-9,68,6,
+9,82,4,
 42,237,1,3,
 48,223,3,
 9,70,6,
@@ -3580,16 +3580,16 @@
 9,156,6,2,222,3,223,3,
 42,168,0,
 48,225,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,226,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,227,3,
 9,179,6,2,225,3,226,3,
 42,248,1,
 48,228,3,
-9,68,6,
+9,82,4,
 42,237,1,3,
 48,229,3,
 9,70,6,
@@ -3598,25 +3598,25 @@
 9,197,6,2,228,3,229,3,
 42,168,0,
 48,231,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,232,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,233,3,
 9,219,6,2,231,3,232,3,
 42,248,1,
 48,234,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,235,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,236,3,
 9,236,6,2,234,3,235,3,
 42,248,1,
 48,237,3,
-9,68,6,
+9,82,4,
 42,237,1,3,
 48,238,3,
 9,70,6,
@@ -3625,37 +3625,37 @@
 9,253,6,2,237,3,238,3,
 42,168,0,
 48,240,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,241,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,242,3,
 9,19,7,2,240,3,241,3,
 42,248,1,
 48,243,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,244,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,245,3,
 9,36,7,2,243,3,244,3,
 42,248,1,
 48,246,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,247,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,248,3,
 9,53,7,2,246,3,247,3,
 42,248,1,
 48,249,3,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,250,3,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,251,3,
 9,69,7,2,249,3,250,3,
@@ -3703,37 +3703,37 @@
 9,5,8,2,7,4,8,4,
 42,154,1,
 48,10,4,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,11,4,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,12,4,
 9,33,8,2,10,4,11,4,
 42,248,1,
 48,13,4,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,14,4,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,15,4,
 9,43,8,2,13,4,14,4,
 42,248,1,
 48,16,4,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,17,4,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,18,4,
 9,60,8,2,16,4,17,4,
 42,248,1,
 48,19,4,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,20,4,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,21,4,
 9,72,8,2,19,4,20,4,
@@ -3742,10 +3742,10 @@
 9,89,8,
 42,1,0,3,
 48,23,4,
-9,121,5,
+9,123,5,
 42,248,1,3,
 48,24,4,
-9,125,5,
+9,127,5,
 42,248,1,3,
 23,25,4,
 9,94,8,3,22,4,23,4,24,4,
diff --git a/src/sksl/ir/SkSLSymbolTable.h b/src/sksl/ir/SkSLSymbolTable.h
index 3ea5ba1..abd0154 100644
--- a/src/sksl/ir/SkSLSymbolTable.h
+++ b/src/sksl/ir/SkSLSymbolTable.h
@@ -46,6 +46,11 @@
         return std::make_shared<SymbolTable>(std::move(symbolTable), /*builtin=*/false);
     }
 
+    /**
+     * Looks up the requested symbol and returns it. If a function has overloads, an
+     * UnresolvedFunction symbol (pointing to all of the candidates) will be added to the symbol
+     * table and returned.
+     */
     const Symbol* operator[](StringFragment name);
 
     void addAlias(StringFragment name, const Symbol* symbol);
@@ -91,6 +96,7 @@
         return fSymbols.count();
     }
 
+    /** Returns true if this is a built-in SymbolTable. */
     bool isBuiltin() const {
         return fBuiltin;
     }
diff --git a/src/sksl/sksl_gpu.sksl b/src/sksl/sksl_gpu.sksl
index f08a590..98ee976 100644
--- a/src/sksl/sksl_gpu.sksl
+++ b/src/sksl/sksl_gpu.sksl
@@ -235,30 +235,30 @@
 $genIType findMSB($genIType value);
 $genIType findMSB($genUType value);
 
-sampler2D makeSampler2D(texture2D texture, sampler sampler);
-int2 textureSize($gsampler2DRect sampler);
+sampler2D makeSampler2D(texture2D texture, sampler s);
+int2 textureSize($gsampler2DRect s);
 
-half4 sample($gsampler1D sampler, float P);
-half4 sample($gsampler1D sampler, float P, float bias);
-half4 sample($gsampler2D sampler, float2 P);
+half4 sample($gsampler1D s, float P);
+half4 sample($gsampler1D s, float P, float bias);
+half4 sample($gsampler2D s, float2 P);
 // The above currently only expand to handle the float/fixed case. So we also declare this integer
 // version of sample().
-int4 sample(isampler2D sampler, float2 P);
-half4 sample(samplerExternalOES sampler, float2 P, float bias);
-half4 sample(samplerExternalOES sampler, float2 P);
+int4 sample(isampler2D s, float2 P);
+half4 sample(samplerExternalOES s, float2 P, float bias);
+half4 sample(samplerExternalOES s, float2 P);
 
-half4 sample($gsampler2DRect sampler, float2 P);
-half4 sample($gsampler2DRect sampler, float3 P);
+half4 sample($gsampler2DRect s, float2 P);
+half4 sample($gsampler2DRect s, float3 P);
 
 // Currently we do not support the generic types of loading subpassInput so we have some explicit
 // versions that we currently use
 half4 subpassLoad(subpassInput subpass);
 half4 subpassLoad(subpassInputMS subpass, int sample);
 
-half4 sample($gsampler1D sampler, float2 P);
-half4 sample($gsampler1D sampler, float2 P, float bias);
-half4 sample($gsampler2D sampler, float3 P);
-half4 sample($gsampler2D sampler, float3 P, float bias);
+half4 sample($gsampler1D s, float2 P);
+half4 sample($gsampler1D s, float2 P, float bias);
+half4 sample($gsampler2D s, float3 P);
+half4 sample($gsampler2D s, float3 P, float bias);
 
 float4 imageLoad(image2D image, int2 P);
 int4 imageLoad(iimage2D image, int2 P);
diff --git a/tests/sksl/errors/RedeclareBasicType.sksl b/tests/sksl/errors/RedeclareBasicType.sksl
new file mode 100644
index 0000000..4079d8c
--- /dev/null
+++ b/tests/sksl/errors/RedeclareBasicType.sksl
@@ -0,0 +1 @@
+float int;
diff --git a/tests/sksl/errors/RedeclareEnum.sksl b/tests/sksl/errors/RedeclareEnum.sksl
new file mode 100644
index 0000000..a82d83a
--- /dev/null
+++ b/tests/sksl/errors/RedeclareEnum.sksl
@@ -0,0 +1,5 @@
+enum class E {
+    hello,
+    world,
+    fragmentProcessor
+};
diff --git a/tests/sksl/errors/RedeclareSamplerType.sksl b/tests/sksl/errors/RedeclareSamplerType.sksl
new file mode 100644
index 0000000..6c3a204
--- /dev/null
+++ b/tests/sksl/errors/RedeclareSamplerType.sksl
@@ -0,0 +1 @@
+sampler sampler;
diff --git a/tests/sksl/errors/RedeclareStruct.sksl b/tests/sksl/errors/RedeclareStruct.sksl
new file mode 100644
index 0000000..de433a5
--- /dev/null
+++ b/tests/sksl/errors/RedeclareStruct.sksl
@@ -0,0 +1,3 @@
+struct void {
+    int x;
+};
diff --git a/tests/sksl/errors/RedeclareStructTypeWithName.sksl b/tests/sksl/errors/RedeclareStructTypeWithName.sksl
new file mode 100644
index 0000000..a19e868
--- /dev/null
+++ b/tests/sksl/errors/RedeclareStructTypeWithName.sksl
@@ -0,0 +1,3 @@
+struct foo {
+    int x;
+} foo;
diff --git a/tests/sksl/errors/RedeclareUserType.sksl b/tests/sksl/errors/RedeclareUserType.sksl
new file mode 100644
index 0000000..4db23d1
--- /dev/null
+++ b/tests/sksl/errors/RedeclareUserType.sksl
@@ -0,0 +1,2 @@
+struct S { int x; };
+float S;
diff --git a/tests/sksl/errors/RedeclareVariable.sksl b/tests/sksl/errors/RedeclareVariable.sksl
new file mode 100644
index 0000000..67ba3a8
--- /dev/null
+++ b/tests/sksl/errors/RedeclareVariable.sksl
@@ -0,0 +1,15 @@
+struct S { int i; };
+
+int x;
+int x;
+float4x4 x;
+bool2 x[2];
+S x;
+
+void main() {
+    float2 y;
+    float2 y;
+    int y;
+    float y[4];
+    S y;
+}
diff --git a/tests/sksl/errors/golden/RedeclareBasicType.glsl b/tests/sksl/errors/golden/RedeclareBasicType.glsl
new file mode 100644
index 0000000..cfb3041
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareBasicType.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: expected an identifier, but found type 'int'
+1 error
diff --git a/tests/sksl/errors/golden/RedeclareEnum.glsl b/tests/sksl/errors/golden/RedeclareEnum.glsl
new file mode 100644
index 0000000..ee80ec1
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareEnum.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 4: expected an identifier, but found type 'fragmentProcessor'
+1 error
diff --git a/tests/sksl/errors/golden/RedeclareSamplerType.glsl b/tests/sksl/errors/golden/RedeclareSamplerType.glsl
new file mode 100644
index 0000000..4bce878
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareSamplerType.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: expected an identifier, but found type 'sampler'
+1 error
diff --git a/tests/sksl/errors/golden/RedeclareStruct.glsl b/tests/sksl/errors/golden/RedeclareStruct.glsl
new file mode 100644
index 0000000..7ab0228
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareStruct.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: expected an identifier, but found type 'void'
+1 error
diff --git a/tests/sksl/errors/golden/RedeclareStructTypeWithName.glsl b/tests/sksl/errors/golden/RedeclareStructTypeWithName.glsl
new file mode 100644
index 0000000..f1117a0
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareStructTypeWithName.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 3: symbol 'foo' was already defined
+1 error
diff --git a/tests/sksl/errors/golden/RedeclareUserType.glsl b/tests/sksl/errors/golden/RedeclareUserType.glsl
new file mode 100644
index 0000000..b5b4ddc
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareUserType.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 2: expected an identifier, but found type 'S'
+1 error
diff --git a/tests/sksl/errors/golden/RedeclareVariable.glsl b/tests/sksl/errors/golden/RedeclareVariable.glsl
new file mode 100644
index 0000000..6c3b4aa
--- /dev/null
+++ b/tests/sksl/errors/golden/RedeclareVariable.glsl
@@ -0,0 +1,11 @@
+### Compilation failed:
+
+error: 4: symbol 'x' was already defined
+error: 5: symbol 'x' was already defined
+error: 6: symbol 'x' was already defined
+error: 7: symbol 'x' was already defined
+error: 11: symbol 'y' was already defined
+error: 12: symbol 'y' was already defined
+error: 13: symbol 'y' was already defined
+error: 14: symbol 'y' was already defined
+8 errors
diff --git a/tests/sksl/shared/ComplexDelete.sksl b/tests/sksl/shared/ComplexDelete.sksl
index 3af2de8..5e5d686 100644
--- a/tests/sksl/shared/ComplexDelete.sksl
+++ b/tests/sksl/shared/ComplexDelete.sksl
@@ -1,11 +1,11 @@
 layout(set=0) uniform float4x4 colorXform;
-layout(binding=0) uniform sampler2D sampler;
+layout(binding=0) uniform sampler2D s;
 
 void main() {
     float4 tmpColor;
     sk_FragColor =
             half4(1.0) *
-            (tmpColor = sample(sampler, float2(1)),
+            (tmpColor = sample(s, float2(1)),
              half4(colorXform != float4x4(1.0)
                            ? float4(clamp((float4x4(colorXform) * float4(tmpColor.xyz, 1.0)).xyz,
                                           0.0, tmpColor.w),
diff --git a/tests/sksl/shared/golden/ComplexDelete.asm.frag b/tests/sksl/shared/golden/ComplexDelete.asm.frag
index 49fc8c0..801bcf7 100644
--- a/tests/sksl/shared/golden/ComplexDelete.asm.frag
+++ b/tests/sksl/shared/golden/ComplexDelete.asm.frag
@@ -13,7 +13,7 @@
 OpName %sk_FragColor "sk_FragColor"
 OpName %sk_Clockwise "sk_Clockwise"
 OpName %colorXform "colorXform"
-OpName %sampler "sampler"
+OpName %s "s"
 OpName %main "main"
 OpName %tmpColor "tmpColor"
 OpDecorate %sk_FragColor RelaxedPrecision
@@ -22,8 +22,8 @@
 OpDecorate %sk_Clockwise RelaxedPrecision
 OpDecorate %sk_Clockwise BuiltIn FrontFacing
 OpDecorate %colorXform DescriptorSet 0
-OpDecorate %sampler RelaxedPrecision
-OpDecorate %sampler Binding 0
+OpDecorate %s RelaxedPrecision
+OpDecorate %s Binding 0
 OpDecorate %23 RelaxedPrecision
 %float = OpTypeFloat 32
 %v4float = OpTypeVector %float 4
@@ -38,7 +38,7 @@
 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown
 %15 = OpTypeSampledImage %16
 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
-%sampler = OpVariable %_ptr_UniformConstant_15 UniformConstant
+%s = OpVariable %_ptr_UniformConstant_15 UniformConstant
 %void = OpTypeVoid
 %18 = OpTypeFunction %void
 %_ptr_Function_v4float = OpTypePointer Function %v4float
@@ -52,7 +52,7 @@
 %19 = OpLabel
 %tmpColor = OpVariable %_ptr_Function_v4float Function
 %54 = OpVariable %_ptr_Function_v4float Function
-%23 = OpLoad %15 %sampler
+%23 = OpLoad %15 %s
 %22 = OpImageSampleImplicitLod %v4float %23 %24
 OpStore %tmpColor %22
 %27 = OpLoad %mat4v4float %colorXform
diff --git a/tests/sksl/shared/golden/ComplexDelete.glsl b/tests/sksl/shared/golden/ComplexDelete.glsl
index 0fcf225..e54be88 100644
--- a/tests/sksl/shared/golden/ComplexDelete.glsl
+++ b/tests/sksl/shared/golden/ComplexDelete.glsl
@@ -1,8 +1,8 @@
 
 out vec4 sk_FragColor;
 layout (set = 0) uniform mat4 colorXform;
-layout (binding = 0) uniform sampler2D sampler;
+layout (binding = 0) uniform sampler2D s;
 void main() {
     vec4 tmpColor;
-    sk_FragColor = (tmpColor = texture(sampler, vec2(1.0)) , colorXform != mat4(1.0) ? vec4(clamp((colorXform * vec4(tmpColor.xyz, 1.0)).xyz, 0.0, tmpColor.w), tmpColor.w) : tmpColor);
+    sk_FragColor = (tmpColor = texture(s, vec2(1.0)) , colorXform != mat4(1.0) ? vec4(clamp((colorXform * vec4(tmpColor.xyz, 1.0)).xyz, 0.0, tmpColor.w), tmpColor.w) : tmpColor);
 }
diff --git a/tests/sksl/shared/golden/ComplexDelete.metal b/tests/sksl/shared/golden/ComplexDelete.metal
index d775ba2..dd2c283 100644
--- a/tests/sksl/shared/golden/ComplexDelete.metal
+++ b/tests/sksl/shared/golden/ComplexDelete.metal
@@ -10,17 +10,17 @@
     float4 sk_FragColor [[color(0)]];
 };
 struct Globals {
-    texture2d<float> sampler;
-    sampler samplerSmplr;
+    texture2d<float> s;
+    sampler sSmplr;
 };
 
-fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], texture2d<float> sampler[[texture(0)]], sampler samplerSmplr[[sampler(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
-    Globals globalStruct{sampler, samplerSmplr};
+fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], texture2d<float> s[[texture(0)]], sampler sSmplr[[sampler(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
+    Globals globalStruct{s, sSmplr};
     thread Globals* _globals = &globalStruct;
     (void)_globals;
     Outputs _outputStruct;
     thread Outputs* _out = &_outputStruct;
     float4 tmpColor;
-    _out->sk_FragColor = (tmpColor = _globals->sampler.sample(_globals->samplerSmplr, float2(1.0)) , _uniforms.colorXform != float4x4(1.0) ? float4(clamp((_uniforms.colorXform * float4(tmpColor.xyz, 1.0)).xyz, 0.0, tmpColor.w), tmpColor.w) : tmpColor);
+    _out->sk_FragColor = (tmpColor = _globals->s.sample(_globals->sSmplr, float2(1.0)) , _uniforms.colorXform != float4x4(1.0) ? float4(clamp((_uniforms.colorXform * float4(tmpColor.xyz, 1.0)).xyz, 0.0, tmpColor.w), tmpColor.w) : tmpColor);
     return *_out;
 }