[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