[clang] 411a254 - [clang] Make sure argument expansion locations are correct in presence of predefined buffer
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 22 12:02:01 PDT 2020
Author: Kadir Cetinkaya
Date: 2020-04-22T21:01:52+02:00
New Revision: 411a254af3ff5dd05e6c522cc7bccdf043967070
URL: https://github.com/llvm/llvm-project/commit/411a254af3ff5dd05e6c522cc7bccdf043967070
DIFF: https://github.com/llvm/llvm-project/commit/411a254af3ff5dd05e6c522cc7bccdf043967070.diff
LOG: [clang] Make sure argument expansion locations are correct in presence of predefined buffer
Summary:
Macro argument expansion logic relies on skipping file IDs that created
as a result of an include. Unfortunately it fails to do that for
predefined buffer since it doesn't have a valid insertion location.
As a result of that any file ID created for an include inside the
predefined buffers breaks the traversal logic in
SourceManager::computeMacroArgsCache.
To fix this issue we first record number of created FIDs for predefined
buffer, and then skip them explicitly in source manager.
Another solution would be to just give predefined buffers a valid source
location, but it is unclear where that should be..
Reviewers: sammccall
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78649
Added:
Modified:
clang/lib/Basic/SourceManager.cpp
clang/lib/Lex/PPLexerChange.cpp
clang/unittests/Basic/SourceManagerTest.cpp
clang/unittests/Lex/LexerTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 8ba581598109..e42c3f4ca73f 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -1800,15 +1800,23 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
return;
if (Entry.isFile()) {
SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc();
- if (IncludeLoc.isInvalid())
+ bool IncludedInFID =
+ (IncludeLoc.isValid() && isInFileID(IncludeLoc, FID)) ||
+ // Predefined header doesn't have a valid include location in main
+ // file, but any files created by it should still be skipped when
+ // computing macro args expanded in the main file.
+ (FID == MainFileID && Entry.getFile().Filename == "<built-in>");
+ if (IncludedInFID) {
+ // Skip the files/macros of the #include'd file, we only care about
+ // macros that lexed macro arguments from our file.
+ if (Entry.getFile().NumCreatedFIDs)
+ ID += Entry.getFile().NumCreatedFIDs - 1 /*because of next ++ID*/;
continue;
- if (!isInFileID(IncludeLoc, FID))
- return; // No more files/macros that may be "contained" in this file.
-
- // Skip the files/macros of the #include'd file, we only care about macros
- // that lexed macro arguments from our file.
- if (Entry.getFile().NumCreatedFIDs)
- ID += Entry.getFile().NumCreatedFIDs - 1/*because of next ++ID*/;
+ } else if (IncludeLoc.isValid()) {
+ // If file was included but not from FID, there is no more files/macros
+ // that may be "contained" in this file.
+ return;
+ }
continue;
}
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index dd22cc207860..b7c7e2693ef1 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -415,7 +415,10 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
}
if (!isEndOfMacro && CurPPLexer &&
- SourceMgr.getIncludeLoc(CurPPLexer->getFileID()).isValid()) {
+ (SourceMgr.getIncludeLoc(CurPPLexer->getFileID()).isValid() ||
+ // Predefines file doesn't have a valid include location.
+ (PredefinesFileID.isValid() &&
+ CurPPLexer->getFileID() == PredefinesFileID))) {
// Notify SourceManager to record the number of FileIDs that were created
// during lexing of the #include'd file.
unsigned NumFIDs =
diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp
index f4bdd9c0aefc..850a08b74ace 100644
--- a/clang/unittests/Basic/SourceManagerTest.cpp
+++ b/clang/unittests/Basic/SourceManagerTest.cpp
@@ -294,10 +294,16 @@ TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
TrivialModuleLoader ModLoader;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, &*Target);
+
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
+ // Ensure we can get expanded locations in presence of implicit includes.
+ // These are
diff erent than normal includes since predefines buffer doesn't
+ // have a valid insertion location.
+ PP.setPredefines("#include \"/implicit-header.h\"");
+ FileMgr.getVirtualFile("/implicit-header.h", 0, 0);
PP.Initialize(*Target);
PP.EnterMainSourceFile();
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp
index c68eed9c864f..4cdabe042cc8 100644
--- a/clang/unittests/Lex/LexerTest.cpp
+++ b/clang/unittests/Lex/LexerTest.cpp
@@ -556,4 +556,17 @@ TEST_F(LexerTest, FindNextToken) {
EXPECT_THAT(GeneratedByNextToken, ElementsAre("abcd", "=", "0", ";", "int",
"xyz", "=", "abcd", ";"));
}
+
+TEST_F(LexerTest, CreatedFIDCountForPredefinedBuffer) {
+ TrivialModuleLoader ModLoader;
+ auto PP = CreatePP("", ModLoader);
+ while (1) {
+ Token tok;
+ PP->Lex(tok);
+ if (tok.is(tok::eof))
+ break;
+ }
+ EXPECT_EQ(SourceMgr.getNumCreatedFIDsForFileID(PP->getPredefinesFileID()),
+ 1U);
+}
} // anonymous namespace
More information about the cfe-commits
mailing list