[cfe-commits] r137794 - in /cfe/trunk: include/clang/Basic/SourceManager.h lib/Basic/SourceManager.cpp
Chandler Carruth
chandlerc at google.com
Tue Aug 16 17:53:00 PDT 2011
On Tue, Aug 16, 2011 at 5:31 PM, Argyrios Kyrtzidis <akyrtzi at gmail.com>wrote:
> Author: akirtzidis
> Date: Tue Aug 16 19:31:20 2011
> New Revision: 137794
>
> URL: http://llvm.org/viewvc/llvm-project?rev=137794&view=rev
> Log:
> Introduce SourceManager::getMacroArgExpandedLocation function.
>
Really cool!
+/// \brief If \arg Loc points inside a function macro argument, the
> returned
> +/// location will be the macro location in which the argument was
> expanded.
> +/// If a macro argument is used multiple times, the expanded location will
> +/// be at the first expansion of the argument.
> +/// e.g.
> +/// MY_MACRO(foo);
> +/// ^
> +/// Passing a file location pointing at 'foo', will yield a macro location
> +/// where 'foo' was expanded into.
> +SourceLocation SourceManager::getMacroArgExpandedLocation(SourceLocation
> Loc) {
> + if (Loc.isInvalid())
> + return Loc;
> +
> + FileID FID = getFileID(Loc);
> + if (FID.isInvalid())
> + return Loc;
> +
> + int ID = FID.ID;
>
Personally, I'd find it very helpful to have a description of the algorithm
here. This seems like fairly tricky code.
> + while (1) {
> + ++ID;
> + // Stop if there are no more FileIDs to check.
> + if (ID > 0) {
> + if (unsigned(ID) >= local_sloc_entry_size())
> + return Loc;
> + } else if (ID == -1) {
> + return Loc;
> + }
> +
> + const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID);
> + if (Entry.isFile()) {
> + if (Entry.getFile().getIncludeLoc().isValid() &&
> + !isBeforeInTranslationUnit(Entry.getFile().getIncludeLoc(),
> Loc))
> + return Loc;
> + continue;
> + }
> +
> + if (isBeforeInTranslationUnit(Loc,
> +
> Entry.getExpansion().getExpansionLocStart()))
> + return Loc;
> + if (!Entry.getExpansion().isMacroArgExpansion())
> + continue;
> +
> + // This is a macro argument expansion. See if Loc points in the
> argument
> + // that was lexed.
> +
> + SourceLocation SpellLoc = Entry.getExpansion().getSpellingLoc();
> + unsigned NextOffset;
> + if (ID > 0) {
> + if (unsigned(ID+1) == local_sloc_entry_size())
> + NextOffset = getNextLocalOffset();
> + else
> + NextOffset = getLocalSLocEntry(ID+1).getOffset();
> + } else {
> + if (ID+1 == -1)
> + NextOffset = MaxLoadedOffset;
> + else
> + NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset();
> + }
>
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. =]
> + unsigned EntrySize = NextOffset - Entry.getOffset() - 1;
> + unsigned BeginOffs = SpellLoc.getOffset();
> + unsigned EndOffs = BeginOffs + EntrySize;
> + if (BeginOffs <= Loc.getOffset() && Loc.getOffset() < EndOffs) {
> + SourceLocation ExpandLoc =
> SourceLocation::getMacroLoc(Entry.getOffset());
> + // Replace current Loc with the expanded location and continue.
> + // The expanded argument may end up being passed to another function
> macro
> + // and relexed again.
> + Loc = ExpandLoc.getFileLocWithOffset(Loc.getOffset()-BeginOffs);
> + }
> + }
> +}
> +
> /// Given a decomposed source location, move it up the include/expansion
> stack
> /// to the parent source location. If this is possible, return the
> decomposed
> /// version of the parent in Loc and return false. If Loc is the
> top-level
> @@ -1557,7 +1626,7 @@
> << NextLocalOffset << "B of Sloc address space used.\n";
> llvm::errs() << LoadedSLocEntryTable.size()
> << " loaded SLocEntries allocated, "
> - << (1U << 31U) - CurrentLoadedOffset
> + << MaxLoadedOffset - CurrentLoadedOffset
> << "B of Sloc address space used.\n";
>
> unsigned NumLineNumsComputed = 0;
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110816/d8c796ad/attachment.html>
More information about the cfe-commits
mailing list