We build up a vector that is length of the DebugSource lines and get how long they are to make sure anyone using a DebugSource provides valid Line/Columns inside
| 1142 | // they are to make sure anyone using a DebugSource provides valid Line/Columns |
| 1143 | // inside |
| 1144 | void BuildDebugSourceLineLength(ValidationState_t& _, const Instruction* inst, |
| 1145 | uint32_t ext_inst_index) { |
| 1146 | if (ext_inst_index == NonSemanticShaderDebugInfoDebugSource && |
| 1147 | inst->words().size() < 7) { |
| 1148 | return; // The optional text was not provided |
| 1149 | } |
| 1150 | |
| 1151 | std::string debug_source_text = GetDebugSourceText(_, inst, ext_inst_index); |
| 1152 | |
| 1153 | // walk back to get DebugSource to update it's line length list |
| 1154 | uint32_t debug_source_id = inst->id(); |
| 1155 | uint32_t continue_count = 0; |
| 1156 | |
| 1157 | // There might be |
| 1158 | // %a = OpString "line starts here" |
| 1159 | // %b = OpString " and still the same line" |
| 1160 | // |
| 1161 | // %c = OpExtInst %void %1 DebugSource %_ %a |
| 1162 | // %d = OpExtInst %void %1 DebugSourceContinued %b |
| 1163 | // So we want to find the previous line for checking if we need to append on |
| 1164 | // to the length of the previous line |
| 1165 | bool start_new_line = true; |
| 1166 | if (ext_inst_index == NonSemanticShaderDebugInfoDebugSourceContinued) { |
| 1167 | auto prev_index = inst - &_.ordered_instructions()[0] - 1; |
| 1168 | auto prev_inst = &_.ordered_instructions()[prev_index]; |
| 1169 | |
| 1170 | std::string previous_line_text = |
| 1171 | GetDebugSourceText(_, prev_inst, prev_inst->GetOperandAs<uint32_t>(3)); |
| 1172 | if (!previous_line_text.empty() && previous_line_text.back() != '\n') { |
| 1173 | start_new_line = false; |
| 1174 | } |
| 1175 | } |
| 1176 | |
| 1177 | while (ext_inst_index == NonSemanticShaderDebugInfoDebugSourceContinued) { |
| 1178 | continue_count++; // might have multiple Continues in a row |
| 1179 | auto prev_index = inst - &_.ordered_instructions()[0] - continue_count; |
| 1180 | auto prev_inst = &_.ordered_instructions()[prev_index]; |
| 1181 | debug_source_id = prev_inst->id(); |
| 1182 | ext_inst_index = prev_inst->GetOperandAs<uint32_t>(3); |
| 1183 | } |
| 1184 | |
| 1185 | std::vector<uint32_t>& line_lengths = |
| 1186 | _.GetDebugSourceLineLength(debug_source_id); |
| 1187 | uint32_t line_start = 0; |
| 1188 | // If we have a line like "abc", it really column 1-to-4. |
| 1189 | // Even an empty line should have a column of 1 |
| 1190 | // Add 1 to length to emulate this later |
| 1191 | uint32_t length = 1; |
| 1192 | |
| 1193 | // Continue from the previous line length |
| 1194 | if (!start_new_line) { |
| 1195 | length = line_lengths.back(); |
| 1196 | line_lengths.pop_back(); |
| 1197 | } |
| 1198 | |
| 1199 | for (uint32_t i = 0; i < debug_source_text.size(); ++i) { |
| 1200 | if (debug_source_text[i] == '\n') { |
| 1201 | // Unix-style new line |
no test coverage detected