<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Aug 16, 2011, at 5:53 PM, Chandler Carruth wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div class="gmail_quote">On Tue, Aug 16, 2011 at 5:31 PM, Argyrios Kyrtzidis <span dir="ltr"><<a href="mailto:akyrtzi@gmail.com">akyrtzi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">
Author: akirtzidis<br>
Date: Tue Aug 16 19:31:20 2011<br>
New Revision: 137794<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=137794&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=137794&view=rev</a><br>
Log:<br>
Introduce SourceManager::getMacroArgExpandedLocation function.<br></blockquote><div><br></div><div>Really cool!</div><div><br></div><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">

+/// \brief If \arg Loc points inside a function macro argument, the returned<br>
+/// location will be the macro location in which the argument was expanded.<br>
+/// If a macro argument is used multiple times, the expanded location will<br>
+/// be at the first expansion of the argument.<br>
+/// e.g.<br>
+///   MY_MACRO(foo);<br>
+///             ^<br>
+/// Passing a file location pointing at 'foo', will yield a macro location<br>
+/// where 'foo' was expanded into.<br>
+SourceLocation SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) {<br>
+  if (Loc.isInvalid())<br>
+    return Loc;<br>
+<br>
+  FileID FID = getFileID(Loc);<br>
+  if (FID.isInvalid())<br>
+    return Loc;<br>
+<br>
+  int ID = <a href="http://FID.ID/" target="_blank">FID.ID</a>;<br></blockquote><div><br></div><div>Personally, I'd find it very helpful to have a description of the algorithm here. This seems like fairly tricky code.</div></div></blockquote><div><br></div><div>This is an inefficient linear search of the SLocEntries, ideally I'd like it to skip as much irrelevant SLocEntries as possible,</div><div>maybe by keeping extra info of what SLocEntries a file "contains" and at which positions; needs more investigation..</div><div><br></div><div>BTW, providing a way to distinguish macro arg expansions is really useful! :-)</div><br><blockquote type="cite"><div class="gmail_quote">
<div> </div><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">
+  while (1) {<br>
+    ++ID;<br>
+    // Stop if there are no more FileIDs to check.<br>
+    if (ID > 0) {<br>
+      if (unsigned(ID) >= local_sloc_entry_size())<br>
+        return Loc;<br>
+    } else if (ID == -1) {<br>
+      return Loc;<br>
+    }<br>
+<br>
+    const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID);<br>
+    if (Entry.isFile()) {<br>
+      if (Entry.getFile().getIncludeLoc().isValid() &&<br>
+          !isBeforeInTranslationUnit(Entry.getFile().getIncludeLoc(), Loc))<br>
+        return Loc;<br>
+      continue;<br>
+    }<br>
+<br>
+    if (isBeforeInTranslationUnit(Loc,<br>
+                                  Entry.getExpansion().getExpansionLocStart()))<br>
+      return Loc;<br>
+    if (!Entry.getExpansion().isMacroArgExpansion())<br>
+      continue;<br>
+<br>
+    // This is a macro argument expansion. See if Loc points in the argument<br>
+    // that was lexed.<br>
+<br>
+    SourceLocation SpellLoc = Entry.getExpansion().getSpellingLoc();<br>
+    unsigned NextOffset;<br>
+    if (ID > 0) {<br>
+      if (unsigned(ID+1) == local_sloc_entry_size())<br>
+        NextOffset = getNextLocalOffset();<br>
+      else<br>
+        NextOffset = getLocalSLocEntry(ID+1).getOffset();<br>
+    } else {<br>
+      if (ID+1 == -1)<br>
+        NextOffset = MaxLoadedOffset;<br>
+      else<br>
+        NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset();<br>
+    }<br></blockquote><div><br></div><div>And all of this makes me wish we had unit tests for the SourceManager that could exercise this algorithm in a contained fashion... oh well. =]</div></div></blockquote><div><br></div><div>Right, my thoughts exactly..</div><br><blockquote type="cite"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">

+    unsigned EntrySize = NextOffset - Entry.getOffset() - 1;<br>
+    unsigned BeginOffs = SpellLoc.getOffset();<br>
+    unsigned EndOffs = BeginOffs + EntrySize;<br>
+    if (BeginOffs <= Loc.getOffset() && Loc.getOffset() < EndOffs) {<br>
+      SourceLocation ExpandLoc = SourceLocation::getMacroLoc(Entry.getOffset());<br>
+      // Replace current Loc with the expanded location and continue.<br>
+      // The expanded argument may end up being passed to another function macro<br>
+      // and relexed again.<br>
+      Loc = ExpandLoc.getFileLocWithOffset(Loc.getOffset()-BeginOffs);<br>
+    }<br>
+  }<br>
+}<br>
+<br>
 /// Given a decomposed source location, move it up the include/expansion stack<br>
 /// to the parent source location.  If this is possible, return the decomposed<br>
 /// version of the parent in Loc and return false.  If Loc is the top-level<br>
@@ -1557,7 +1626,7 @@<br>
                << NextLocalOffset << "B of Sloc address space used.\n";<br>
   llvm::errs() << LoadedSLocEntryTable.size()<br>
                << " loaded SLocEntries allocated, "<br>
-               << (1U << 31U) - CurrentLoadedOffset<br>
+               << MaxLoadedOffset - CurrentLoadedOffset<br>
                << "B of Sloc address space used.\n";<br>
<br>
   unsigned NumLineNumsComputed = 0;<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>
</blockquote></div><br></body></html>