{"action":"created","comment":{"url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments/46072340","id":46072340,"diff_hunk":"@@ -261,6 +273,190 @@ spv_result_t spvValidateIDs(const spv_instruction_t* pInsts,\n   return SPV_SUCCESS;\n }\n \n+// TODO(umar): Validate header\n+// TODO(umar): The Id bound should be validated also. But you can only do that\n+// after you've seen all the instructions in the module.\n+// TODO(umar): The binary parser validates the magic word, and the length of the\n+// header, but nothing else.\n+spv_result_t setHeader(void* user_data, spv_endianness_t endian, uint32_t magic,\n+                       uint32_t version, uint32_t generator, uint32_t id_bound,\n+                       uint32_t reserved) {\n+  (void)user_data;\n+  (void)endian;\n+  (void)magic;\n+  (void)version;\n+  (void)generator;\n+  (void)id_bound;\n+  (void)reserved;\n+  return SPV_SUCCESS;\n+}\n+\n+// TODO(umar): Move this class to another file\n+class ValidationState_t {\n+ public:\n+  ValidationState_t(spv_diagnostic* diag)\n+      : diagnostic_(diag), instruction_counter_(0) {}\n+\n+  spv_result_t definedIds(uint32_t id) {\n+    if (defined_ids_.find(id) == std::end(defined_ids_)) {\n+      defined_ids_.insert(id);\n+    } else {\n+      return diag(SPV_ERROR_INVALID_ID)\n+             << \"ID cannot be assigned multiple times\";\n+    }\n+    return SPV_SUCCESS;\n+  }\n+\n+  spv_result_t forwardDeclareId(uint32_t id) {\n+    unresolved_forward_ids_.insert(id);\n+    return SPV_SUCCESS;\n+  }\n+\n+  spv_result_t removeIfForwardDeclared(uint32_t id) {\n+    unresolved_forward_ids_.erase(id);\n+    return SPV_SUCCESS;\n+  }\n+\n+  size_t unresolvedForwardIdCount() const {\n+    return unresolved_forward_ids_.size();\n+  }\n+\n+  //\n+  bool isDefinedId(uint32_t id) const {\n+    return defined_ids_.find(id) != std::end(defined_ids_);\n+  }\n+\n+  // Increments the instruction count. Used for diagnostic\n+  int incrementInstructionCount() { return instruction_counter_++; }\n+\n+  libspirv::DiagnosticStream diag(spv_result_t error_code) const {\n+    return libspirv::DiagnosticStream({0, 0, (uint64_t)(instruction_counter_)},\n+                                      diagnostic_, error_code);\n+  }\n+\n+ private:\n+  spv_diagnostic* diagnostic_;\n+  // Tracks the number of instructions evaluated by the validator\n+  int instruction_counter_;\n+\n+  // All IDs which have been defined\n+  unordered_set<uint32_t> defined_ids_;\n+\n+  // IDs which have been forward declared but have not been defined\n+  unordered_set<uint32_t> unresolved_forward_ids_;\n+};\n+\n+spv_result_t SSAPass(ValidationState_t& _,\n+                     function<bool(int)> can_have_forward_declared_ids,\n+                     const spv_parsed_instruction_t* inst) {\n+  for (int i = 0; i < inst->num_operands; i++) {\n+    const spv_parsed_operand_t& operand = inst->operands[i];\n+    const spv_operand_type_t& type = operand.type;\n+    const uint32_t* operand_ptr = inst->words + operand.offset;\n+\n+    auto ret = SPV_ERROR_INTERNAL;\n+    switch (type) {\n+      case SPV_OPERAND_TYPE_RESULT_ID: {\n+        _.removeIfForwardDeclared(*operand_ptr);\n+        ret = _.definedIds(*operand_ptr);\n+        break;\n+      }\n+      case SPV_OPERAND_TYPE_ID:\n+      case SPV_OPERAND_TYPE_TYPE_ID:\n+      case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:\n+      case SPV_OPERAND_TYPE_SCOPE_ID: {\n+        if (_.isDefinedId(*operand_ptr)) {\n+          ret = SPV_SUCCESS;\n+        } else if (can_have_forward_declared_ids(i)) {\n+          ret = _.forwardDeclareId(*operand_ptr);\n+        } else {\n+          ret = _.diag(SPV_ERROR_INVALID_ID) << \"ID \" << *operand_ptr\n+                                             << \" has not been defined\";\n+        }\n+        break;\n+      }\n+      default:\n+        ret = SPV_SUCCESS;\n+        break;\n+    }\n+    if (SPV_SUCCESS != ret) {\n+      return ret;\n+    }\n+  }\n+  return SPV_SUCCESS;\n+}\n+\n+template <SpvOp OP>\n+bool can_forward_declare(int index) {\n+  (void)index;\n+  return true;\n+}\n+\n+template <>\n+bool can_forward_declare<SpvOpPhi>(int index) {\n+  return (1 + index % 2);\n+}\n+\n+template <>\n+bool can_forward_declare<SpvOpBranchConditional>(int index) {\n+  return index != 0;\n+}\n+\n+template <>\n+bool can_forward_declare<SpvOpGroupDecorate>(int index) {\n+  return index != 0;\n+}\n+\n+function<bool(int)> getCanBeForwardDeclaredFunction(SpvOp opcode) {\n+  function<bool(int index)> out;\n+  switch (opcode) {\n+    case SpvOpExecutionMode:\n+    case SpvOpEntryPoint:\n+    case SpvOpFunctionCall:\n+    case SpvOpName:\n+    case SpvOpMemberName:\n+    case SpvOpSelectionMerge:\n+\n+    // Annotation Instructions\n+    case SpvOpDecorate:\n+    case SpvOpMemberDecorate:\n+    case SpvOpBranch:\n+      out = can_forward_declare<SpvOpNop>;\n+      break;\n+    case SpvOpGroupDecorate:\n+    case SpvOpGroupMemberDecorate:\n+      out = can_forward_declare<SpvOpGroupDecorate>;\n+      break;\n+\n+    case SpvOpBranchConditional:\n+      out = can_forward_declare<SpvOpBranchConditional>;\n+      break;\n+\n+    case SpvOpPhi:\n+      out = can_forward_declare<SpvOpPhi>;\n+      break;\n+\n+    default:\n+      out = [](int index) {","path":"source/validate.cpp","position":242,"original_position":242,"commit_id":"9691d3c68aab2dc875baf4fc4e8a7ac8b1fca190","original_commit_id":"9691d3c68aab2dc875baf4fc4e8a7ac8b1fca190","user":{"login":"dneto0","id":13054574,"avatar_url":"https://avatars.githubusercontent.com/u/13054574?v=3","gravatar_id":"","url":"https://api.github.com/users/dneto0","html_url":"https://github.com/dneto0","followers_url":"https://api.github.com/users/dneto0/followers","following_url":"https://api.github.com/users/dneto0/following{/other_user}","gists_url":"https://api.github.com/users/dneto0/gists{/gist_id}","starred_url":"https://api.github.com/users/dneto0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dneto0/subscriptions","organizations_url":"https://api.github.com/users/dneto0/orgs","repos_url":"https://api.github.com/users/dneto0/repos","events_url":"https://api.github.com/users/dneto0/events{/privacy}","received_events_url":"https://api.github.com/users/dneto0/received_events","type":"User","site_admin":false},"body":"Just don't name the argument and you don't have to write \" (void)index;'","created_at":"2015-11-27T22:49:03Z","updated_at":"2015-11-27T22:49:03Z","html_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/27#discussion_r46072340","pull_request_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27","_links":{"self":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments/46072340"},"html":{"href":"https://github.com/KhronosGroup/SPIRV-Tools/pull/27#discussion_r46072340"},"pull_request":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27"}}},"pull_request":{"url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27","id":51598321,"html_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/27","diff_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/27.diff","patch_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/27.patch","issue_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/27","number":27,"state":"open","locked":false,"title":"Basic SSA Validation","user":{"login":"umar456","id":457510,"avatar_url":"https://avatars.githubusercontent.com/u/457510?v=3","gravatar_id":"","url":"https://api.github.com/users/umar456","html_url":"https://github.com/umar456","followers_url":"https://api.github.com/users/umar456/followers","following_url":"https://api.github.com/users/umar456/following{/other_user}","gists_url":"https://api.github.com/users/umar456/gists{/gist_id}","starred_url":"https://api.github.com/users/umar456/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/umar456/subscriptions","organizations_url":"https://api.github.com/users/umar456/orgs","repos_url":"https://api.github.com/users/umar456/repos","events_url":"https://api.github.com/users/umar456/events{/privacy}","received_events_url":"https://api.github.com/users/umar456/received_events","type":"User","site_admin":false},"body":"* Updated validation tests to assignment form\r\n* Fixed function tests to handle multiple parameters\r\n* Basic SSA Validation","created_at":"2015-11-23T23:51:17Z","updated_at":"2015-11-27T22:49:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"55400d79f24e57ded42bd38316b0464ec63bd8b6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27/commits","review_comments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27/comments","review_comment_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/27/comments","statuses_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/statuses/9691d3c68aab2dc875baf4fc4e8a7ac8b1fca190","head":{"label":"umar456:master","ref":"master","sha":"9691d3c68aab2dc875baf4fc4e8a7ac8b1fca190","user":{"login":"umar456","id":457510,"avatar_url":"https://avatars.githubusercontent.com/u/457510?v=3","gravatar_id":"","url":"https://api.github.com/users/umar456","html_url":"https://github.com/umar456","followers_url":"https://api.github.com/users/umar456/followers","following_url":"https://api.github.com/users/umar456/following{/other_user}","gists_url":"https://api.github.com/users/umar456/gists{/gist_id}","starred_url":"https://api.github.com/users/umar456/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/umar456/subscriptions","organizations_url":"https://api.github.com/users/umar456/orgs","repos_url":"https://api.github.com/users/umar456/repos","events_url":"https://api.github.com/users/umar456/events{/privacy}","received_events_url":"https://api.github.com/users/umar456/received_events","type":"User","site_admin":false},"repo":{"id":46513608,"name":"SPIRV-Tools","full_name":"umar456/SPIRV-Tools","owner":{"login":"umar456","id":457510,"avatar_url":"https://avatars.githubusercontent.com/u/457510?v=3","gravatar_id":"","url":"https://api.github.com/users/umar456","html_url":"https://github.com/umar456","followers_url":"https://api.github.com/users/umar456/followers","following_url":"https://api.github.com/users/umar456/following{/other_user}","gists_url":"https://api.github.com/users/umar456/gists{/gist_id}","starred_url":"https://api.github.com/users/umar456/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/umar456/subscriptions","organizations_url":"https://api.github.com/users/umar456/orgs","repos_url":"https://api.github.com/users/umar456/repos","events_url":"https://api.github.com/users/umar456/events{/privacy}","received_events_url":"https://api.github.com/users/umar456/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/umar456/SPIRV-Tools","description":"","fork":true,"url":"https://api.github.com/repos/umar456/SPIRV-Tools","forks_url":"https://api.github.com/repos/umar456/SPIRV-Tools/forks","keys_url":"https://api.github.com/repos/umar456/SPIRV-Tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/umar456/SPIRV-Tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/umar456/SPIRV-Tools/teams","hooks_url":"https://api.github.com/repos/umar456/SPIRV-Tools/hooks","issue_events_url":"https://api.github.com/repos/umar456/SPIRV-Tools/issues/events{/number}","events_url":"https://api.github.com/repos/umar456/SPIRV-Tools/events","assignees_url":"https://api.github.com/repos/umar456/SPIRV-Tools/assignees{/user}","branches_url":"https://api.github.com/repos/umar456/SPIRV-Tools/branches{/branch}","tags_url":"https://api.github.com/repos/umar456/SPIRV-Tools/tags","blobs_url":"https://api.github.com/repos/umar456/SPIRV-Tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/umar456/SPIRV-Tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/umar456/SPIRV-Tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/umar456/SPIRV-Tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/umar456/SPIRV-Tools/statuses/{sha}","languages_url":"https://api.github.com/repos/umar456/SPIRV-Tools/languages","stargazers_url":"https://api.github.com/repos/umar456/SPIRV-Tools/stargazers","contributors_url":"https://api.github.com/repos/umar456/SPIRV-Tools/contributors","subscribers_url":"https://api.github.com/repos/umar456/SPIRV-Tools/subscribers","subscription_url":"https://api.github.com/repos/umar456/SPIRV-Tools/subscription","commits_url":"https://api.github.com/repos/umar456/SPIRV-Tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/umar456/SPIRV-Tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/umar456/SPIRV-Tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/umar456/SPIRV-Tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/umar456/SPIRV-Tools/contents/{+path}","compare_url":"https://api.github.com/repos/umar456/SPIRV-Tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/umar456/SPIRV-Tools/merges","archive_url":"https://api.github.com/repos/umar456/SPIRV-Tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/umar456/SPIRV-Tools/downloads","issues_url":"https://api.github.com/repos/umar456/SPIRV-Tools/issues{/number}","pulls_url":"https://api.github.com/repos/umar456/SPIRV-Tools/pulls{/number}","milestones_url":"https://api.github.com/repos/umar456/SPIRV-Tools/milestones{/number}","notifications_url":"https://api.github.com/repos/umar456/SPIRV-Tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/umar456/SPIRV-Tools/labels{/name}","releases_url":"https://api.github.com/repos/umar456/SPIRV-Tools/releases{/id}","created_at":"2015-11-19T18:58:25Z","updated_at":"2015-11-19T18:58:27Z","pushed_at":"2015-11-27T05:29:54Z","git_url":"git://github.com/umar456/SPIRV-Tools.git","ssh_url":"git@github.com:umar456/SPIRV-Tools.git","clone_url":"https://github.com/umar456/SPIRV-Tools.git","svn_url":"https://github.com/umar456/SPIRV-Tools","homepage":null,"size":891,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"KhronosGroup:master","ref":"master","sha":"c9e0845c7f4b55597349ed2d3de57646fa680aeb","user":{"login":"KhronosGroup","id":1608701,"avatar_url":"https://avatars.githubusercontent.com/u/1608701?v=3","gravatar_id":"","url":"https://api.github.com/users/KhronosGroup","html_url":"https://github.com/KhronosGroup","followers_url":"https://api.github.com/users/KhronosGroup/followers","following_url":"https://api.github.com/users/KhronosGroup/following{/other_user}","gists_url":"https://api.github.com/users/KhronosGroup/gists{/gist_id}","starred_url":"https://api.github.com/users/KhronosGroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KhronosGroup/subscriptions","organizations_url":"https://api.github.com/users/KhronosGroup/orgs","repos_url":"https://api.github.com/users/KhronosGroup/repos","events_url":"https://api.github.com/users/KhronosGroup/events{/privacy}","received_events_url":"https://api.github.com/users/KhronosGroup/received_events","type":"Organization","site_admin":false},"repo":{"id":45981801,"name":"SPIRV-Tools","full_name":"KhronosGroup/SPIRV-Tools","owner":{"login":"KhronosGroup","id":1608701,"avatar_url":"https://avatars.githubusercontent.com/u/1608701?v=3","gravatar_id":"","url":"https://api.github.com/users/KhronosGroup","html_url":"https://github.com/KhronosGroup","followers_url":"https://api.github.com/users/KhronosGroup/followers","following_url":"https://api.github.com/users/KhronosGroup/following{/other_user}","gists_url":"https://api.github.com/users/KhronosGroup/gists{/gist_id}","starred_url":"https://api.github.com/users/KhronosGroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KhronosGroup/subscriptions","organizations_url":"https://api.github.com/users/KhronosGroup/orgs","repos_url":"https://api.github.com/users/KhronosGroup/repos","events_url":"https://api.github.com/users/KhronosGroup/events{/privacy}","received_events_url":"https://api.github.com/users/KhronosGroup/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/KhronosGroup/SPIRV-Tools","description":"","fork":false,"url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools","forks_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/forks","keys_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/teams","hooks_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/hooks","issue_events_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/events{/number}","events_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/events","assignees_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/assignees{/user}","branches_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/branches{/branch}","tags_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/tags","blobs_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/statuses/{sha}","languages_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/languages","stargazers_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/stargazers","contributors_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/contributors","subscribers_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/subscribers","subscription_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/subscription","commits_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/contents/{+path}","compare_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/merges","archive_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/downloads","issues_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues{/number}","pulls_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls{/number}","milestones_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/milestones{/number}","notifications_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/labels{/name}","releases_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/releases{/id}","created_at":"2015-11-11T12:56:25Z","updated_at":"2015-11-25T22:42:12Z","pushed_at":"2015-11-27T16:42:59Z","git_url":"git://github.com/KhronosGroup/SPIRV-Tools.git","ssh_url":"git@github.com:KhronosGroup/SPIRV-Tools.git","clone_url":"https://github.com/KhronosGroup/SPIRV-Tools.git","svn_url":"https://github.com/KhronosGroup/SPIRV-Tools","homepage":null,"size":930,"stargazers_count":35,"watchers_count":35,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":7,"forks":7,"open_issues":7,"watchers":35,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27"},"html":{"href":"https://github.com/KhronosGroup/SPIRV-Tools/pull/27"},"issue":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/27"},"comments":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/27/comments"},"review_comments":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27/comments"},"review_comment":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/27/commits"},"statuses":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/statuses/9691d3c68aab2dc875baf4fc4e8a7ac8b1fca190"}}}}