mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 17:40:39 +00:00
Perform #line pre-processing earlier, so it's picked up when reflecting
* If we only do this preprocessing when generating a disassembly string, it's not done when the files in the shader reflection are fetched.
This commit is contained in:
@@ -463,212 +463,21 @@ void DXBCFile::MakeDisassemblyString()
|
||||
|
||||
size_t d = 0;
|
||||
|
||||
vector<vector<string> > fileLines;
|
||||
|
||||
if(m_DebugInfo)
|
||||
{
|
||||
vector<string> fileNames;
|
||||
|
||||
fileLines.resize(m_DebugInfo->Files.size());
|
||||
fileNames.resize(m_DebugInfo->Files.size());
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
fileNames[i] = m_DebugInfo->Files[i].first;
|
||||
|
||||
// we essentially do a copy-paste out of m_DebugInfo->Files into fileLines,
|
||||
// by doing a mini-preprocess to handle #line directives. This means that
|
||||
// any lines that our source file declares to be in another filename via a #line
|
||||
// get put in the right place for what the debug information hopefully matches.
|
||||
// We also concatenate duplicate lines and display them all, to handle edge
|
||||
// cases where #lines declare duplicates.
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
{
|
||||
vector<string> srclines;
|
||||
vector<string> *dstFile =
|
||||
&fileLines[i]; // start off writing to the corresponding output file.
|
||||
|
||||
size_t dstLine = 0;
|
||||
|
||||
split(m_DebugInfo->Files[i].second, srclines, '\n');
|
||||
srclines.push_back("");
|
||||
|
||||
// handle #line directives by inserting empty lines or erasing as necessary
|
||||
|
||||
for(size_t srcLine = 0; srcLine < srclines.size(); srcLine++)
|
||||
{
|
||||
if(srclines[srcLine].empty())
|
||||
{
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
char *c = &srclines[srcLine][0];
|
||||
char *end = c + srclines[srcLine].size();
|
||||
|
||||
while(*c == '\t' || *c == ' ' || *c == '\r')
|
||||
c++;
|
||||
|
||||
if(c == end)
|
||||
{
|
||||
// blank line, just advance line counter
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(c + 5 > end || strncmp(c, "#line", 5))
|
||||
{
|
||||
// resize up to account for the current line, if necessary
|
||||
dstFile->resize(RDCMAX(dstLine + 1, dstFile->size()));
|
||||
|
||||
// if non-empty, append this line (to allow multiple lines on the same line
|
||||
// number to be concatenated)
|
||||
if((*dstFile)[dstLine].empty())
|
||||
(*dstFile)[dstLine] = srclines[srcLine];
|
||||
else
|
||||
(*dstFile)[dstLine] += "\n" + srclines[srcLine];
|
||||
|
||||
// advance line counter
|
||||
dstLine++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// we have a #line directive
|
||||
c += 5;
|
||||
|
||||
if(c >= end)
|
||||
{
|
||||
// invalid #line, just advance line counter
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
while(*c == '\t' || *c == ' ')
|
||||
c++;
|
||||
|
||||
if(c >= end)
|
||||
{
|
||||
// invalid #line, just advance line counter
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid #line, no line number. Skip/ignore and just advance line counter
|
||||
if(*c < '0' || *c > '9')
|
||||
{
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t newLineNum = 0;
|
||||
while(*c >= '0' && *c <= '9')
|
||||
{
|
||||
newLineNum *= 10;
|
||||
newLineNum += int((*c) - '0');
|
||||
c++;
|
||||
}
|
||||
|
||||
// convert to 0-indexed line number
|
||||
if(newLineNum > 0)
|
||||
newLineNum--;
|
||||
|
||||
while(*c == '\t' || *c == ' ')
|
||||
c++;
|
||||
|
||||
// no filename
|
||||
if(*c == 0)
|
||||
{
|
||||
// set the next line number, and continue processing
|
||||
dstLine = newLineNum;
|
||||
continue;
|
||||
}
|
||||
else if(*c == '"')
|
||||
{
|
||||
c++;
|
||||
|
||||
char *filename = c;
|
||||
|
||||
// parse out filename
|
||||
while(*c != '"' && *c != 0)
|
||||
{
|
||||
if(*c == '\\')
|
||||
{
|
||||
// skip escaped characters
|
||||
c += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
// parsed filename successfully
|
||||
if(*c == '"')
|
||||
{
|
||||
*c = 0;
|
||||
|
||||
// find the new destination file
|
||||
bool found = false;
|
||||
size_t dstFileIdx = 0;
|
||||
|
||||
for(size_t f = 0; f < fileNames.size(); f++)
|
||||
{
|
||||
if(fileNames[f] == filename)
|
||||
{
|
||||
found = true;
|
||||
dstFileIdx = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
dstFile = &fileLines[dstFileIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Couldn't find filename '%s' in #line directive in debug info", filename);
|
||||
|
||||
// make a dummy file to write into that won't be used.
|
||||
fileNames.push_back(filename);
|
||||
fileLines.push_back(vector<string>());
|
||||
|
||||
dstFile = &fileLines.back();
|
||||
}
|
||||
|
||||
// set the next line number, and continue processing
|
||||
dstLine = newLineNum;
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid #line, ignore
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid #line, ignore
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
{
|
||||
if(m_DebugInfo->Files[i].second.empty())
|
||||
{
|
||||
merge(fileLines[i], m_DebugInfo->Files[i].second, '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LineColumnInfo prevLineInfo;
|
||||
|
||||
size_t debugInst = 0;
|
||||
|
||||
std::vector<std::vector<std::string>> fileLines;
|
||||
|
||||
// generate fileLines by splitting each file in the debug info
|
||||
if(m_DebugInfo)
|
||||
{
|
||||
fileLines.resize(m_DebugInfo->Files.size());
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
split(m_DebugInfo->Files[i].second, fileLines[i], '\n');
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < m_Instructions.size(); i++)
|
||||
{
|
||||
for(; d < m_Declarations.size(); d++)
|
||||
@@ -3209,4 +3018,4 @@ char *SystemValueToString(SVSemantic name)
|
||||
return "";
|
||||
}
|
||||
|
||||
}; // namespace DXBC
|
||||
}; // namespace DXBC
|
||||
@@ -1069,6 +1069,205 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
|
||||
else if(*fourcc == FOURCC_SPDB)
|
||||
{
|
||||
m_DebugInfo = new SPDBChunk(fourcc);
|
||||
// we do a mini-preprocess of the files from the debug info to handle #line directives.
|
||||
// This means that any lines that our source file declares to be in another filename via a #line
|
||||
// get put in the right place for what the debug information hopefully matches.
|
||||
// We also concatenate duplicate lines and display them all, to handle edge cases where #lines
|
||||
// declare duplicates.
|
||||
|
||||
if(m_DebugInfo)
|
||||
{
|
||||
std::vector<std::vector<std::string>> fileLines;
|
||||
|
||||
std::vector<std::string> fileNames;
|
||||
|
||||
fileLines.resize(m_DebugInfo->Files.size());
|
||||
fileNames.resize(m_DebugInfo->Files.size());
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
fileNames[i] = m_DebugInfo->Files[i].first;
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
{
|
||||
std::vector<std::string> srclines;
|
||||
std::vector<std::string> *dstFile =
|
||||
&fileLines[i]; // start off writing to the corresponding output file.
|
||||
|
||||
size_t dstLine = 0;
|
||||
|
||||
split(m_DebugInfo->Files[i].second, srclines, '\n');
|
||||
srclines.push_back("");
|
||||
|
||||
// handle #line directives by inserting empty lines or erasing as necessary
|
||||
|
||||
for(size_t srcLine = 0; srcLine < srclines.size(); srcLine++)
|
||||
{
|
||||
if(srclines[srcLine].empty())
|
||||
{
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
char *c = &srclines[srcLine][0];
|
||||
char *end = c + srclines[srcLine].size();
|
||||
|
||||
while(*c == '\t' || *c == ' ' || *c == '\r')
|
||||
c++;
|
||||
|
||||
if(c == end)
|
||||
{
|
||||
// blank line, just advance line counter
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(c + 5 > end || strncmp(c, "#line", 5))
|
||||
{
|
||||
// resize up to account for the current line, if necessary
|
||||
dstFile->resize(RDCMAX(dstLine + 1, dstFile->size()));
|
||||
|
||||
// if non-empty, append this line (to allow multiple lines on the same line
|
||||
// number to be concatenated). To avoid screwing up line numbers we have to append with a
|
||||
// comment and not a newline.
|
||||
if((*dstFile)[dstLine].empty())
|
||||
(*dstFile)[dstLine] = srclines[srcLine];
|
||||
else
|
||||
(*dstFile)[dstLine] += " /* multiple #lines overlapping */ " + srclines[srcLine];
|
||||
|
||||
// advance line counter
|
||||
dstLine++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// we have a #line directive
|
||||
c += 5;
|
||||
|
||||
if(c >= end)
|
||||
{
|
||||
// invalid #line, just advance line counter
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
while(*c == '\t' || *c == ' ')
|
||||
c++;
|
||||
|
||||
if(c >= end)
|
||||
{
|
||||
// invalid #line, just advance line counter
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid #line, no line number. Skip/ignore and just advance line counter
|
||||
if(*c < '0' || *c > '9')
|
||||
{
|
||||
dstLine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t newLineNum = 0;
|
||||
while(*c >= '0' && *c <= '9')
|
||||
{
|
||||
newLineNum *= 10;
|
||||
newLineNum += int((*c) - '0');
|
||||
c++;
|
||||
}
|
||||
|
||||
// convert to 0-indexed line number
|
||||
if(newLineNum > 0)
|
||||
newLineNum--;
|
||||
|
||||
while(*c == '\t' || *c == ' ')
|
||||
c++;
|
||||
|
||||
// no filename
|
||||
if(*c == 0)
|
||||
{
|
||||
// set the next line number, and continue processing
|
||||
dstLine = newLineNum;
|
||||
continue;
|
||||
}
|
||||
else if(*c == '"')
|
||||
{
|
||||
c++;
|
||||
|
||||
char *filename = c;
|
||||
|
||||
// parse out filename
|
||||
while(*c != '"' && *c != 0)
|
||||
{
|
||||
if(*c == '\\')
|
||||
{
|
||||
// skip escaped characters
|
||||
c += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
// parsed filename successfully
|
||||
if(*c == '"')
|
||||
{
|
||||
*c = 0;
|
||||
|
||||
// find the new destination file
|
||||
bool found = false;
|
||||
size_t dstFileIdx = 0;
|
||||
|
||||
for(size_t f = 0; f < fileNames.size(); f++)
|
||||
{
|
||||
if(fileNames[f] == filename)
|
||||
{
|
||||
found = true;
|
||||
dstFileIdx = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
dstFile = &fileLines[dstFileIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Couldn't find filename '%s' in #line directive in debug info", filename);
|
||||
|
||||
// make a dummy file to write into that won't be used.
|
||||
fileNames.push_back(filename);
|
||||
fileLines.push_back(vector<string>());
|
||||
|
||||
dstFile = &fileLines.back();
|
||||
}
|
||||
|
||||
// set the next line number, and continue processing
|
||||
dstLine = newLineNum;
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid #line, ignore
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid #line, ignore
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < m_DebugInfo->Files.size(); i++)
|
||||
{
|
||||
if(m_DebugInfo->Files[i].second.empty())
|
||||
{
|
||||
merge(fileLines[i], m_DebugInfo->Files[i].second, '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user