Index: clang/lib/Basic/SourceManager.cpp =================================================================== --- clang/lib/Basic/SourceManager.cpp +++ clang/lib/Basic/SourceManager.cpp @@ -1791,7 +1791,12 @@ if (Invalid) return; if (Entry.isFile()) { - SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc(); + auto File = Entry.getFile(); + if (File.getFileCharacteristic() == C_User_ModuleMap || + File.getFileCharacteristic() == C_System_ModuleMap) + continue; + + SourceLocation IncludeLoc = File.getIncludeLoc(); bool IncludedInFID = (IncludeLoc.isValid() && isInFileID(IncludeLoc, FID)) || // Predefined header doesn't have a valid include location in main Index: clang/unittests/Basic/SourceManagerTest.cpp =================================================================== --- clang/unittests/Basic/SourceManagerTest.cpp +++ clang/unittests/Basic/SourceManagerTest.cpp @@ -343,6 +343,83 @@ EXPECT_TRUE(defLoc2.isFileID()); } +TEST_F(SourceManagerTest, getMacroArgExpandedLocationRegression) { + const char *main_c_content = + "#include \"/modulefoo/foo.h\"\n" + "#define FOO234878786(a) (a + a)\n" + "const int a = 1;\n" + "const int b = FOO234878786(a);\n"; + std::unique_ptr main_c_buffer = + llvm::MemoryBuffer::getMemBuffer(main_c_content); + const FileEntry *main_c_file = FileMgr.getVirtualFile("/main.c", main_c_buffer->getBufferSize(), 0); + SourceMgr.overrideFileContents(main_c_file, std::move(main_c_buffer)); + FileID main_c_ID = SourceMgr.getOrCreateFileID(main_c_file, clang::SrcMgr::C_User); + SourceMgr.setMainFileID(main_c_ID); + + const char *module_map_content = + "module foo [system] [extern_c] {\n" + " extern module submodule \"submodule.modulemap\"\n" + " module foo {\n" + " header \"foo.h\"\n" + " export *\n" + " }\n" + "}\n"; + std::unique_ptr module_map_buffer = llvm::MemoryBuffer::getMemBuffer(module_map_content); + const FileEntry *module_map_file = FileMgr.getVirtualFile("/modulefoo/module.map", module_map_buffer->getBufferSize(), 0); + SourceMgr.overrideFileContents(module_map_file, std::move(module_map_buffer)); + + const char *foo_h_content = "\n"; + std::unique_ptr foo_h_buffer = llvm::MemoryBuffer::getMemBuffer(foo_h_content); + const FileEntry *foo_h_file = FileMgr.getVirtualFile("/modulefoo/foo.h", foo_h_buffer->getBufferSize(), 0); + SourceMgr.overrideFileContents(foo_h_file, std::move(foo_h_buffer)); + + const char *submodule_h_content = "\n"; + std::unique_ptr submodule_h_buffer = llvm::MemoryBuffer::getMemBuffer(submodule_h_content); + const FileEntry *submodule_h_file = FileMgr.getVirtualFile("/modulefoo/submodule.h", submodule_h_buffer->getBufferSize(), 0); + SourceMgr.overrideFileContents(submodule_h_file, std::move(submodule_h_buffer)); + + const char *submodule_map_content = + "module foo.submodule [system] [extern_c] {\n" + " header \"submodule.h\"\n" + " export *\n" + "}\n"; + std::unique_ptr submodule_map_buffer = llvm::MemoryBuffer::getMemBuffer(submodule_map_content); + const FileEntry *submodule_map_file = FileMgr.getVirtualFile("/modulefoo/submodule.modulemap", submodule_map_buffer->getBufferSize(), 0); + SourceMgr.overrideFileContents(submodule_map_file, std::move(submodule_map_buffer)); + + TrivialModuleLoader ModLoader; + HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, + Diags, LangOpts, &*Target); + + Preprocessor PP(std::make_shared(), Diags, LangOpts, + SourceMgr, HeaderInfo, ModLoader, + /*IILookup =*/nullptr, + /*OwnsHeaderSearch =*/false); + + // Ensure we can get expanded locations in presence of implicit includes. + // These are different 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(); + + + std::vector toks; + while (1) { + Token tok; + PP.Lex(tok); + if (tok.is(tok::eof)) + break; + toks.push_back(tok); + } + + SourceLocation macroArgLoc = SourceMgr.translateLineCol(main_c_ID, 4, 28); + SourceLocation macroArgExpandedLoc = SourceMgr.getMacroArgExpandedLocation(macroArgLoc); + + EXPECT_EQ(macroArgExpandedLoc, toks[13].getLocation()); +} + namespace { struct MacroAction {