forked from OSchip/llvm-project
Fix bugs in SourceManager::computeMacroArgsCache() and add a unit test for it.
llvm-svn: 147057
This commit is contained in:
parent
2403797eec
commit
e841c901de
|
@ -300,6 +300,11 @@ namespace SrcMgr {
|
|||
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
|
||||
|
|
|
@ -1585,14 +1585,31 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
|
|||
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
|
||||
|
|
|
@ -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 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue