https://github.com/localspook updated https://github.com/llvm/llvm-project/pull/174524
>From 0f765712a6c5586478656998f15a3b581f09d704 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <[email protected]> Date: Mon, 5 Jan 2026 19:24:37 -0800 Subject: [PATCH 1/2] [LLVM][ADT] Add specialization of `DenseMapInfo` for `SourceRange` --- clang/include/clang/Basic/SourceLocation.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index 14543cc41a38e..85fe65901d207 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -521,6 +521,27 @@ namespace llvm { static void Profile(const clang::SourceLocation &X, FoldingSetNodeID &ID); }; + template <> struct DenseMapInfo<clang::SourceRange, void> { + static clang::SourceRange getEmptyKey() { + return {DenseMapInfo<clang::SourceLocation>::getEmptyKey(), + DenseMapInfo<clang::SourceLocation>::getEmptyKey()}; + } + + static clang::SourceRange getTombstoneKey() { + return {DenseMapInfo<clang::SourceLocation>::getTombstoneKey(), + DenseMapInfo<clang::SourceLocation>::getTombstoneKey()}; + } + + static unsigned getHashValue(clang::SourceRange Range) { + return detail::combineHashValue(Range.getBegin().getHashValue(), + Range.getEnd().getHashValue()); + } + + static bool isEqual(clang::SourceRange LHS, clang::SourceRange RHS) { + return LHS == RHS; + } + }; + } // namespace llvm #endif // LLVM_CLANG_BASIC_SOURCELOCATION_H >From 0f2b5b6e683c1c3f7848846777920cfb3d2bd637 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <[email protected]> Date: Tue, 6 Jan 2026 07:29:33 -0800 Subject: [PATCH 2/2] Add unit tests, slightly simplify implementation --- clang/include/clang/Basic/SourceLocation.h | 8 +- clang/unittests/Basic/SourceManagerTest.cpp | 113 +++++++++++--------- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index 85fe65901d207..bd0038d5ae1ae 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -521,15 +521,13 @@ namespace llvm { static void Profile(const clang::SourceLocation &X, FoldingSetNodeID &ID); }; - template <> struct DenseMapInfo<clang::SourceRange, void> { + template <> struct DenseMapInfo<clang::SourceRange> { static clang::SourceRange getEmptyKey() { - return {DenseMapInfo<clang::SourceLocation>::getEmptyKey(), - DenseMapInfo<clang::SourceLocation>::getEmptyKey()}; + return DenseMapInfo<clang::SourceLocation>::getEmptyKey(); } static clang::SourceRange getTombstoneKey() { - return {DenseMapInfo<clang::SourceLocation>::getTombstoneKey(), - DenseMapInfo<clang::SourceLocation>::getTombstoneKey()}; + return DenseMapInfo<clang::SourceLocation>::getTombstoneKey(); } static unsigned getHashValue(clang::SourceRange Range) { diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index 04b23dd13ba3e..87427241adbbb 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -11,6 +11,7 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Lex/HeaderSearch.h" @@ -18,6 +19,7 @@ #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/MemoryBuffer.h" @@ -125,9 +127,8 @@ TEST_F(SourceManagerTest, isInSystemHeader) { } TEST_F(SourceManagerTest, isBeforeInTranslationUnit) { - const char *source = - "#define M(x) [x]\n" - "M(foo)"; + const char *source = "#define M(x) [x]\n" + "M(foo)"; std::unique_ptr<llvm::MemoryBuffer> Buf = llvm::MemoryBuffer::getMemBuffer(source); FileID mainFileID = SourceMgr.createFileID(std::move(Buf)); @@ -150,12 +151,13 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnit) { ASSERT_EQ(tok::l_square, toks[0].getKind()); ASSERT_EQ(tok::identifier, toks[1].getKind()); ASSERT_EQ(tok::r_square, toks[2].getKind()); - + SourceLocation lsqrLoc = toks[0].getLocation(); SourceLocation idLoc = toks[1].getLocation(); SourceLocation rsqrLoc = toks[2].getLocation(); - - SourceLocation macroExpStartLoc = SourceMgr.translateLineCol(mainFileID, 2, 1); + + SourceLocation macroExpStartLoc = + SourceMgr.translateLineCol(mainFileID, 2, 1); SourceLocation macroExpEndLoc = SourceMgr.translateLineCol(mainFileID, 2, 6); ASSERT_TRUE(macroExpStartLoc.isFileID()); ASSERT_TRUE(macroExpEndLoc.isFileID()); @@ -241,9 +243,8 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithTokenSplit) { } TEST_F(SourceManagerTest, getColumnNumber) { - const char *Source = - "int x;\n" - "int y;"; + const char *Source = "int x;\n" + "int y;"; std::unique_ptr<llvm::MemoryBuffer> Buf = llvm::MemoryBuffer::getMemBuffer(Source); @@ -269,12 +270,12 @@ TEST_F(SourceManagerTest, getColumnNumber) { EXPECT_TRUE(!Invalid); Invalid = false; - EXPECT_EQ(7U, SourceMgr.getColumnNumber(MainFileID, strlen(Source), - &Invalid)); + EXPECT_EQ(7U, + SourceMgr.getColumnNumber(MainFileID, strlen(Source), &Invalid)); EXPECT_TRUE(!Invalid); Invalid = false; - SourceMgr.getColumnNumber(MainFileID, strlen(Source)+1, &Invalid); + SourceMgr.getColumnNumber(MainFileID, strlen(Source) + 1, &Invalid); EXPECT_TRUE(Invalid); // Test invalid files @@ -379,21 +380,18 @@ TEST_F(SourceManagerTest, getInvalidBOM) { "UTF-32 (LE)"); } -// Regression test - there was an out of bound access for buffers not terminated by zero. +// Regression test - there was an out of bound access for buffers not terminated +// by zero. TEST_F(SourceManagerTest, getLineNumber) { const unsigned pageSize = llvm::sys::Process::getPageSizeEstimate(); std::unique_ptr<char[]> source(new char[pageSize]); - for(unsigned i = 0; i < pageSize; ++i) { + for (unsigned i = 0; i < pageSize; ++i) { source[i] = 'a'; } - std::unique_ptr<llvm::MemoryBuffer> Buf = - llvm::MemoryBuffer::getMemBuffer( - llvm::MemoryBufferRef( - llvm::StringRef(source.get(), 3), "whatever" - ), - false - ); + std::unique_ptr<llvm::MemoryBuffer> Buf = llvm::MemoryBuffer::getMemBuffer( + llvm::MemoryBufferRef(llvm::StringRef(source.get(), 3), "whatever"), + false); FileID mainFileID = SourceMgr.createFileID(std::move(Buf)); SourceMgr.setMainFileID(mainFileID); @@ -401,6 +399,20 @@ TEST_F(SourceManagerTest, getLineNumber) { ASSERT_NO_FATAL_FAILURE(SourceMgr.getLineNumber(mainFileID, 1, nullptr)); } +TEST_F(SourceManagerTest, sourceRangeWorksWithDenseSet) { + llvm::DenseSet<SourceRange> Set; + SourceRange TestRange = {SourceLocation::getFromRawEncoding(10), + SourceLocation::getFromRawEncoding(11)}; + ASSERT_EQ(Set.size(), 0); + Set.insert(TestRange); + ASSERT_EQ(Set.size(), 1); + ASSERT_TRUE(Set.contains(TestRange)); + ASSERT_FALSE(Set.contains({SourceLocation::getFromRawEncoding(10), + SourceLocation::getFromRawEncoding(10)})); + Set.erase(TestRange); + ASSERT_EQ(Set.size(), 0); +} + struct FakeExternalSLocEntrySource : ExternalSLocEntrySource { bool ReadSLocEntry(int ID) override { return {}; } int getSLocEntryID(SourceLocation::UIntTy SLocOffset) override { return 0; } @@ -509,17 +521,15 @@ TEST_F(SourceManagerTest, ResetsIncludeLocMap) { } 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"; + 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"; std::unique_ptr<llvm::MemoryBuffer> HeaderBuf = llvm::MemoryBuffer::getMemBuffer(header); @@ -580,7 +590,7 @@ TEST_F(SourceManagerTest, getMacroArgExpandedLocation) { namespace { struct MacroAction { - enum Kind { kExpansion, kDefinition, kUnDefinition}; + enum Kind { kExpansion, kDefinition, kUnDefinition }; SourceLocation Loc; std::string Name; @@ -599,7 +609,7 @@ class MacroTracker : public PPCallbacks { std::vector<MacroAction> &Macros; public: - explicit MacroTracker(std::vector<MacroAction> &Macros) : Macros(Macros) { } + explicit MacroTracker(std::vector<MacroAction> &Macros) : Macros(Macros) {} void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override { @@ -607,9 +617,8 @@ class MacroTracker : public PPCallbacks { MacroNameTok.getIdentifierInfo()->getName(), MacroAction::kDefinition)); } - void MacroUndefined(const Token &MacroNameTok, - const MacroDefinition &MD, - const MacroDirective *UD) override { + void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, + const MacroDirective *UD) override { Macros.push_back( MacroAction(UD ? UD->getLocation() : SourceLocation(), MacroNameTok.getIdentifierInfo()->getName(), @@ -624,21 +633,19 @@ class MacroTracker : public PPCallbacks { } }; -} +} // namespace TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) { - const char *header = - "#define MACRO_IN_INCLUDE 0\n" - "#define MACRO_DEFINED\n" - "#undef MACRO_DEFINED\n" - "#undef MACRO_UNDEFINED\n"; - - const char *main = - "#define M(x) x\n" - "#define INC \"/test-header.h\"\n" - "#include M(INC)\n" - "#define INC2 </test-header.h>\n" - "#include M(INC2)\n"; + const char *header = "#define MACRO_IN_INCLUDE 0\n" + "#define MACRO_DEFINED\n" + "#undef MACRO_DEFINED\n" + "#undef MACRO_UNDEFINED\n"; + + const char *main = "#define M(x) x\n" + "#define INC \"/test-header.h\"\n" + "#include M(INC)\n" + "#define INC2 </test-header.h>\n" + "#include M(INC2)\n"; std::unique_ptr<llvm::MemoryBuffer> HeaderBuf = llvm::MemoryBuffer::getMemBuffer(header); @@ -712,11 +719,13 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) { // The INC expansion in #include M(INC) comes before the first // MACRO_IN_INCLUDE definition of the included file. - EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[3].Loc, Macros[4].Loc)); + EXPECT_TRUE( + SourceMgr.isBeforeInTranslationUnit(Macros[3].Loc, Macros[4].Loc)); // The INC2 expansion in #include M(INC2) comes before the second // MACRO_IN_INCLUDE definition of the included file. - EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[10].Loc, Macros[11].Loc)); + EXPECT_TRUE( + SourceMgr.isBeforeInTranslationUnit(Macros[10].Loc, Macros[11].Loc)); } TEST_F(SourceManagerTest, isMainFile) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
