[cfe-commits] r166359 - in /cfe/trunk: include/clang/Basic/SourceManager.h lib/Basic/SourceManager.cpp test/Index/get-cursor-macro-args.h test/Index/get-cursor-macro-args.m

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Oct 19 17:51:33 PDT 2012


Author: akirtzidis
Date: Fri Oct 19 19:51:32 2012
New Revision: 166359

URL: http://llvm.org/viewvc/llvm-project?rev=166359&view=rev
Log:
When associating file ranges of macro arguments with their
macro expansion ranges, make sure to check all the FileID
entries that are contained in the spelling range of the
expansion for the macro argument.

Fixes rdar://12537982

Modified:
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/test/Index/get-cursor-macro-args.h
    cfe/trunk/test/Index/get-cursor-macro-args.m

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=166359&r1=166358&r2=166359&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Fri Oct 19 19:51:32 2012
@@ -1556,7 +1556,11 @@
   getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
                                    unsigned Offset) const;
   void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const;
-
+  void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
+                                         FileID FID,
+                                         SourceLocation SpellLoc,
+                                         SourceLocation ExpansionLoc,
+                                         unsigned ExpansionLength) const;
   friend class ASTReader;
   friend class ASTWriter;
 };

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=166359&r1=166358&r2=166359&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Fri Oct 19 19:51:32 2012
@@ -1705,46 +1705,91 @@
     if (!ExpInfo.isMacroArgExpansion())
       continue;
 
-    SourceLocation SpellLoc = ExpInfo.getSpellingLoc();
-    while (!SpellLoc.isFileID()) {
-      std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(SpellLoc);
-      const ExpansionInfo &Info = getSLocEntry(LocInfo.first).getExpansion();
-      if (!Info.isMacroArgExpansion())
-        break;
-      SpellLoc = Info.getSpellingLoc().getLocWithOffset(LocInfo.second);
-    }
-    if (!SpellLoc.isFileID())
-      continue;
-    
-    unsigned BeginOffs;
-    if (!isInFileID(SpellLoc, FID, &BeginOffs))
-      continue;
+    associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
+                                 ExpInfo.getSpellingLoc(),
+                                 SourceLocation::getMacroLoc(Entry.getOffset()),
+                                 getFileIDSize(FileID::get(ID)));
+  }
+}
+
+void SourceManager::associateFileChunkWithMacroArgExp(
+                                         MacroArgsMap &MacroArgsCache,
+                                         FileID FID,
+                                         SourceLocation SpellLoc,
+                                         SourceLocation ExpansionLoc,
+                                         unsigned ExpansionLength) const {
+  if (!SpellLoc.isFileID()) {
+    unsigned SpellBeginOffs = SpellLoc.getOffset();
+    unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
+
+    // The spelling range for this macro argument expansion can span multiple
+    // consecutive FileID entries. Go through each entry contained in the
+    // spelling range and if one is itself a macro argument expansion, recurse
+    // and associate the file chunk that it represents.
+
+    FileID SpellFID; // Current FileID in the spelling range.
+    unsigned SpellRelativeOffs;
+    llvm::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
+    while (1) {
+      const SLocEntry &Entry = getSLocEntry(SpellFID);
+      unsigned SpellFIDBeginOffs = Entry.getOffset();
+      unsigned SpellFIDSize = getFileIDSize(SpellFID);
+      unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
+      const ExpansionInfo &Info = Entry.getExpansion();
+      if (Info.isMacroArgExpansion()) {
+        unsigned CurrSpellLength;
+        if (SpellFIDEndOffs < SpellEndOffs)
+          CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
+        else
+          CurrSpellLength = ExpansionLength;
+        associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
+                      Info.getSpellingLoc().getLocWithOffset(SpellRelativeOffs),
+                      ExpansionLoc, CurrSpellLength);
+      }
 
-    unsigned EndOffs = BeginOffs + getFileIDSize(FileID::get(ID));
+      if (SpellFIDEndOffs >= SpellEndOffs)
+        return; // we covered all FileID entries in the spelling range.
+
+      // Move to the next FileID entry in the spelling range.
+      unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
+      ExpansionLoc = ExpansionLoc.getLocWithOffset(advance);
+      ExpansionLength -= advance;
+      ++SpellFID.ID;
+      SpellRelativeOffs = 0;
+    }
 
-    // Add a new chunk for this macro argument. A previous macro argument chunk
-    // may have been lexed again, so e.g. if the map is
-    //     0   -> SourceLocation()
-    //     100 -> Expanded loc #1
-    //     110 -> SourceLocation()
-    // and we found a new macro FileID that lexed from offet 105 with length 3,
-    // the new map will be:
-    //     0   -> SourceLocation()
-    //     100 -> Expanded loc #1
-    //     105 -> Expanded loc #2
-    //     108 -> Expanded loc #1
-    //     110 -> SourceLocation()
-    //
-    // Since re-lexed macro chunks will always be the same size or less of
-    // previous chunks, we only need to find where the ending of the new macro
-    // chunk is mapped to and update the map with new begin/end mappings.
-
-    MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
-    --I;
-    SourceLocation EndOffsMappedLoc = I->second;
-    MacroArgsCache[BeginOffs] = SourceLocation::getMacroLoc(Entry.getOffset());
-    MacroArgsCache[EndOffs] = EndOffsMappedLoc;
   }
+
+  assert(SpellLoc.isFileID());
+
+  unsigned BeginOffs;
+  if (!isInFileID(SpellLoc, FID, &BeginOffs))
+    return;
+
+  unsigned EndOffs = BeginOffs + ExpansionLength;
+
+  // Add a new chunk for this macro argument. A previous macro argument chunk
+  // may have been lexed again, so e.g. if the map is
+  //     0   -> SourceLocation()
+  //     100 -> Expanded loc #1
+  //     110 -> SourceLocation()
+  // and we found a new macro FileID that lexed from offet 105 with length 3,
+  // the new map will be:
+  //     0   -> SourceLocation()
+  //     100 -> Expanded loc #1
+  //     105 -> Expanded loc #2
+  //     108 -> Expanded loc #1
+  //     110 -> SourceLocation()
+  //
+  // Since re-lexed macro chunks will always be the same size or less of
+  // previous chunks, we only need to find where the ending of the new macro
+  // chunk is mapped to and update the map with new begin/end mappings.
+
+  MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
+  --I;
+  SourceLocation EndOffsMappedLoc = I->second;
+  MacroArgsCache[BeginOffs] = ExpansionLoc;
+  MacroArgsCache[EndOffs] = EndOffsMappedLoc;
 }
 
 /// \brief If \arg Loc points inside a function macro argument, the returned

Modified: cfe/trunk/test/Index/get-cursor-macro-args.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/get-cursor-macro-args.h?rev=166359&r1=166358&r2=166359&view=diff
==============================================================================
--- cfe/trunk/test/Index/get-cursor-macro-args.h (original)
+++ cfe/trunk/test/Index/get-cursor-macro-args.h Fri Oct 19 19:51:32 2012
@@ -2,8 +2,8 @@
 +(void)meth;
 @end
 
-#define MACRO2(x) x
-#define MACRO(x) MACRO2(x)
+#define MACRO2(x) (x)
+#define MACRO(x) MACRO2((x))
 
 void test() {
   MACRO([MyClass meth]);

Modified: cfe/trunk/test/Index/get-cursor-macro-args.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/get-cursor-macro-args.m?rev=166359&r1=166358&r2=166359&view=diff
==============================================================================
--- cfe/trunk/test/Index/get-cursor-macro-args.m (original)
+++ cfe/trunk/test/Index/get-cursor-macro-args.m Fri Oct 19 19:51:32 2012
@@ -1,6 +1,8 @@
 // Test without PCH
 // RUN: c-index-test -cursor-at=%S/get-cursor-macro-args.h:9:12 \
 // RUN:              -cursor-at=%S/get-cursor-macro-args.h:9:21 \
+// RUN:              -cursor-at=%S/get-cursor-macro-args.h:9:9 \
+// RUN:              -cursor-at=%S/get-cursor-macro-args.h:9:22 \
 // RUN:              -cursor-at=%S/get-cursor-macro-args.h:15:12 \
 // RUN:              -cursor-at=%S/get-cursor-macro-args.h:15:20 \
 // RUN:       %s -include %S/get-cursor-macro-args.h | FileCheck %s
@@ -9,6 +11,8 @@
 // RUN: c-index-test -write-pch %t.pch -x objective-c-header %S/get-cursor-macro-args.h
 // RUN: c-index-test -cursor-at=%S/get-cursor-macro-args.h:9:12 \
 // RUN:              -cursor-at=%S/get-cursor-macro-args.h:9:21 \
+// RUN:              -cursor-at=%S/get-cursor-macro-args.h:9:9 \
+// RUN:              -cursor-at=%S/get-cursor-macro-args.h:9:22 \
 // RUN:              -cursor-at=%S/get-cursor-macro-args.h:15:12 \
 // RUN:              -cursor-at=%S/get-cursor-macro-args.h:15:20 \
 // RUN:       %s -include-pch %t.pch | FileCheck %s
@@ -16,4 +20,6 @@
 // CHECK:      ObjCClassRef=MyClass:1:12
 // CHECK-NEXT: ObjCMessageExpr=meth:2:8
 // CHECK-NEXT: ObjCMessageExpr=meth:2:8
+// CHECK-NEXT: ObjCMessageExpr=meth:2:8
+// CHECK-NEXT: ObjCMessageExpr=meth:2:8
 // CHECK-NEXT: ObjCClassRef=MyClass:1:12





More information about the cfe-commits mailing list