[cfe-commits] r137794 - in /cfe/trunk: include/clang/Basic/SourceManager.h lib/Basic/SourceManager.cpp

Argyrios Kyrtzidis kyrtzidis at apple.com
Tue Aug 16 18:23:35 PDT 2011


On Aug 16, 2011, at 5:53 PM, Chandler Carruth wrote:

> 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.

This is an inefficient linear search of the SLocEntries, ideally I'd like it to skip as much irrelevant SLocEntries as possible,
maybe by keeping extra info of what SLocEntries a file "contains" and at which positions; needs more investigation..

BTW, providing a way to distinguish macro arg expansions is really useful! :-)

>  
> +  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. =]

Right, my thoughts exactly..

>  
> +    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/a912da84/attachment.html>


More information about the cfe-commits mailing list