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

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Dec 21 08:56:35 PST 2011


Author: akirtzidis
Date: Wed Dec 21 10:56:35 2011
New Revision: 147057

URL: http://llvm.org/viewvc/llvm-project?rev=147057&view=rev
Log:
Fix bugs in SourceManager::computeMacroArgsCache() and add a unit test for it.

Modified:
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/unittests/Basic/SourceManagerTest.cpp

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=147057&r1=147056&r2=147057&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Wed Dec 21 10:56:35 2011
@@ -300,6 +300,11 @@
         SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid();
     }
 
+    bool isFunctionMacroExpansion() const {
+      return getExpansionLocStart().isValid() &&
+          getExpansionLocStart() != getExpansionLocEnd();
+    }
+
     /// create - Return a ExpansionInfo for an expansion. Start and End specify
     /// the expansion range (where the macro is expanded), and SpellingLoc
     /// specifies the spelling location (where the characters from the token

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=147057&r1=147056&r2=147057&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Wed Dec 21 10:56:35 2011
@@ -1585,14 +1585,31 @@
       continue;
     }
 
-    if (!Entry.getExpansion().isMacroArgExpansion())
+    const ExpansionInfo &ExpInfo = Entry.getExpansion();
+
+    if (ExpInfo.getExpansionLocStart().isFileID()) {
+      if (!isInFileID(ExpInfo.getExpansionLocStart(), FID))
+        return; // No more files/macros that may be "contained" in this file.
+    }
+
+    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;
- 
-    SourceLocation SpellLoc =
-        getSpellingLoc(Entry.getExpansion().getSpellingLoc());
+    
     unsigned BeginOffs;
     if (!isInFileID(SpellLoc, FID, &BeginOffs))
-      return; // No more files/macros that may be "contained" in this file.
+      continue;
+
     unsigned EndOffs = BeginOffs + getFileIDSize(FileID::get(ID));
 
     // Add a new chunk for this macro argument. A previous macro argument chunk

Modified: cfe/trunk/unittests/Basic/SourceManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/SourceManagerTest.cpp?rev=147057&r1=147056&r2=147057&view=diff
==============================================================================
--- cfe/trunk/unittests/Basic/SourceManagerTest.cpp (original)
+++ cfe/trunk/unittests/Basic/SourceManagerTest.cpp Wed Dec 21 10:56:35 2011
@@ -16,6 +16,7 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
+#include "llvm/Config/config.h"
 
 #include "gtest/gtest.h"
 
@@ -105,4 +106,75 @@
   EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, macroExpEndLoc));
 }
 
+#if defined(LLVM_ON_UNIX)
+
+TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
+  const char *header =
+    "#define FM(x,y) x\n";
+
+  const char *main =
+    "#include \"/test-header.h\"\n"
+    "#define VAL 0\n"
+    "FM(VAL,0)\n"
+    "FM(0,VAL)\n"
+    "FM(FM(0,VAL),0)\n"
+    "#define CONCAT(X, Y) X##Y\n"
+    "CONCAT(1,1)\n";
+
+  MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header);
+  MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
+  FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(mainBuf);
+
+  const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
+                                                 headerBuf->getBufferSize(), 0);
+  SourceMgr.overrideFileContents(headerFile, headerBuf);
+
+  VoidModuleLoader ModLoader;
+  HeaderSearch HeaderInfo(FileMgr, Diags);
+  Preprocessor PP(Diags, LangOpts,
+                  Target.getPtr(),
+                  SourceMgr, HeaderInfo, ModLoader,
+                  /*IILookup =*/ 0,
+                  /*OwnsHeaderSearch =*/false,
+                  /*DelayInitialization =*/ false);
+  PP.EnterMainSourceFile();
+
+  std::vector<Token> toks;
+  while (1) {
+    Token tok;
+    PP.Lex(tok);
+    if (tok.is(tok::eof))
+      break;
+    toks.push_back(tok);
+  }
+
+  // Make sure we got the tokens that we expected.
+  ASSERT_EQ(4U, toks.size());
+  ASSERT_EQ(tok::numeric_constant, toks[0].getKind());
+  ASSERT_EQ(tok::numeric_constant, toks[1].getKind());
+  ASSERT_EQ(tok::numeric_constant, toks[2].getKind());
+  ASSERT_EQ(tok::numeric_constant, toks[3].getKind());
+
+  SourceLocation defLoc = SourceMgr.translateLineCol(mainFileID, 2, 13);
+  SourceLocation loc1 = SourceMgr.translateLineCol(mainFileID, 3, 8);
+  SourceLocation loc2 = SourceMgr.translateLineCol(mainFileID, 4, 4);
+  SourceLocation loc3 = SourceMgr.translateLineCol(mainFileID, 5, 7);
+  SourceLocation defLoc2 = SourceMgr.translateLineCol(mainFileID, 6, 22);
+  defLoc = SourceMgr.getMacroArgExpandedLocation(defLoc);
+  loc1 = SourceMgr.getMacroArgExpandedLocation(loc1);
+  loc2 = SourceMgr.getMacroArgExpandedLocation(loc2);
+  loc3 = SourceMgr.getMacroArgExpandedLocation(loc3);
+  defLoc2 = SourceMgr.getMacroArgExpandedLocation(defLoc2);
+
+  EXPECT_TRUE(defLoc.isFileID());
+  EXPECT_TRUE(loc1.isFileID());
+  EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc2));
+  EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc3));
+  EXPECT_EQ(loc2, toks[1].getLocation());
+  EXPECT_EQ(loc3, toks[2].getLocation());
+  EXPECT_TRUE(defLoc2.isFileID());
+}
+
+#endif
+
 } // anonymous namespace





More information about the cfe-commits mailing list