<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
span.EmailStyle21
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=HU link=blue vlink=purple style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Oh, now I see why you were puzzled!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>`printf()` expects a null-terminated string (“%s”), but you pass an llvm::StringRef instead, which is not null terminated!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Thus, you will end up with undefined behavior, which ends up printing till the end of the file.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>I hope this is it!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Balazs<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US>From:</span></b><span lang=EN-US> benicsbalazs@gmail.com <benicsbalazs@gmail.com> <br><b>Sent:</b> 2021. augusztus 26., csütörtök 12:25<br><b>To:</b> 'chiasa.men' <chiasa.men@web.de><br><b>Cc:</b> llvm-dev@lists.llvm.org<br><b>Subject:</b> RE: [cfe-dev] Location (in Source Code) of String Literal in MacroExpansion<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Hi Chiasa,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>For the example you attached the MacroExpansionContext seems to work as I intended.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>It records what range gets replaced by what tokens at the end of the preprocessing, thus we get<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>`</span>CONCATMACRO("TEST")<span lang=EN-US style='mso-fareast-language:EN-US'>` -> `</span><span lang=EN-US> </span>L"TEST"<span lang=EN-US style='mso-fareast-language:EN-US'>`<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>About `</span>Lexer::getSourceText<span lang=EN-US style='mso-fareast-language:EN-US'>()` I’m not sure. I haven’t used that. The `at()` function was designed as a helper defining the unit tests. I might misused something when I created this code & tests, let me know!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Balazs<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US>From:</span></b><span lang=EN-US> cfe-dev <<a href="mailto:cfe-dev-bounces@lists.llvm.org">cfe-dev-bounces@lists.llvm.org</a>> <b>On Behalf Of </b>chiasa.men via cfe-dev<br><b>Sent:</b> 2021. augusztus 26., csütörtök 10:03<br><b>To:</b> cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>><br><b>Cc:</b> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br><b>Subject:</b> [cfe-dev] Location (in Source Code) of String Literal in MacroExpansion<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p style='margin:0cm'><span style='font-size:8.5pt'><a href="https://gist.github.com/T35R6braPwgDJKq/6439fda090e4ee8440d726f8dafa4dbb#file-mectest-cpp">https://gist.github.com/T35R6braPwgDJKq/6439fda090e4ee8440d726f8dafa4dbb#file-mectest-cpp</a></span><o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p style='margin:0cm'>Above I modified the MacroExpansionContext unittest.<o:p></o:p></p><p style='margin:0cm'>The relevant code:<o:p></o:p></p><p style='margin:0cm'>//--------------<o:p></o:p></p><p style='margin:0cm'>TEST_F(MacroExpansionContextTest, Custom) {<o:p></o:p></p><p style='margin:0cm'> // From the GCC website.<o:p></o:p></p><p style='margin:0cm'> const auto Ctx = getMacroExpansionContextFor(R"code(<o:p></o:p></p><p style='margin:0cm'>#define CONCATMACRO(parm) L##parm<o:p></o:p></p><p style='margin:0cm'>int f(wchar_t *b){}<o:p></o:p></p><p style='margin:0cm'>int main()<o:p></o:p></p><p style='margin:0cm'>{<o:p></o:p></p><p style='margin:0cm'> int a= f(CONCATMACRO("TEST"));<o:p></o:p></p><p style='margin:0cm'> int b= f(L"TEST");<o:p></o:p></p><p style='margin:0cm'> return 0;<o:p></o:p></p><p style='margin:0cm'>}<o:p></o:p></p><p style='margin:0cm'>)code");<o:p></o:p></p><p style='margin:0cm'> Ctx->dumpExpansionRanges();<o:p></o:p></p><p style='margin:0cm'> //> :6:14, :6:33<o:p></o:p></p><p style='margin:0cm'> Ctx->dumpExpandedTexts();<o:p></o:p></p><p style='margin:0cm'> //> :6:14 -> 'L"TEST"'<o:p></o:p></p><p style='margin:0cm'> printf("Exp: %s\n",Ctx->getExpandedText(at(6, 14)).getValue());<o:p></o:p></p><p style='margin:0cm'> //Exp: L"TEST"<o:p></o:p></p><p style='margin:0cm'> printf("Org: %s\n",Ctx->getOriginalText(at(6, 14)).getValue());<o:p></o:p></p><p style='margin:0cm'> //Org: CONCATMACRO("TEST"));<o:p></o:p></p><p style='margin:0cm'> // int b= f(L"TEST");<o:p></o:p></p><p style='margin:0cm'> // return 0;<o:p></o:p></p><p style='margin:0cm'> //}<o:p></o:p></p><p style='margin:0cm'> StringRef sourceText = clang::Lexer::getSourceText(CharSourceRange(SourceRange(at(6, 14),at(6, 33)),false),SourceMgr, LangOpts);<o:p></o:p></p><p style='margin:0cm'> printf("sourceText: %s\n",sourceText);<o:p></o:p></p><p style='margin:0cm'> // sourceText: CONCATMACRO("TEST"));<o:p></o:p></p><p style='margin:0cm'> // int b= f(L"TEST");<o:p></o:p></p><p style='margin:0cm'> // return 0;<o:p></o:p></p><p style='margin:0cm'> // }<o:p></o:p></p><p style='margin:0cm'>}<o:p></o:p></p><p style='margin:0cm'>//--------------<o:p></o:p></p><p style='margin:0cm'>I am interested in getting the range for "TEST" in the SourceText. Since the CONCATMACRO is preprocessed to L"TEST" I thought the MacroExpansionContext would be of help.<o:p></o:p></p><p style='margin:0cm'>It tells about the ExpansionRanges: 6:14, :6:33 which is CONCATMACRO("TEST")<o:p></o:p></p><p style='margin:0cm'>What I would need is: 6:26, 6:32<o:p></o:p></p><p style='margin:0cm'>Obviously I could just calculate a bit like:<o:p></o:p></p><p style='margin:0cm'>range.begin (14) + macronameLen (11) +1 (opening parenthesis) = 26<o:p></o:p></p><p style='margin:0cm'>to<o:p></o:p></p><p style='margin:0cm'>range.end (33) - 1 (closing parenthesis) = 32<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p style='margin:0cm'>But would that be reliable and is there no other way?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p style='margin:0cm'>Furthermore: Why do getSourceText/getOriginalText print the whole rest of the source code and not just from (6,14) to (6,33)?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>