From adafc2edc0dc4fa25ea6f0a136f599a6ac279081 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 19 Dec 2011 16:14:14 +0000 Subject: [PATCH] The submodule offset map can introduce "empty" remapping entries for imported modules that don't introduce any new entities of a particular kind. Allow these entries to be replaced with entries for another loaded module. In the included test case, selectors exhibit this behavior. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146870 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../clang/Serialization/ContinuousRangeMap.h | 10 ++++++++ lib/Serialization/ASTReader.cpp | 24 ++++++++++--------- test/Modules/Inputs/redecl-merge-left.h | 1 + test/Modules/redecl-merge.m | 5 ++++ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h index 7f78320410..f368a80a97 100644 --- a/include/clang/Serialization/ContinuousRangeMap.h +++ b/include/clang/Serialization/ContinuousRangeMap.h @@ -68,6 +68,16 @@ public: "Must insert keys in order."); Rep.push_back(Val); } + + void insertOrReplace(const value_type &Val) { + iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare()); + if (I != Rep.end() && I->first == Val.first) { + I->second = Val.second; + return; + } + + Rep.insert(I, Val); + } typedef typename Representation::iterator iterator; typedef typename Representation::const_iterator const_iterator; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index b782c184b9..fc49e88a50 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1817,8 +1817,9 @@ ASTReader::ReadASTBlock(ModuleFile &F) { GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F)); // Introduce the local -> global mapping for types within this module. - F.TypeRemap.insert(std::make_pair(LocalBaseTypeIndex, - F.BaseTypeIndex - LocalBaseTypeIndex)); + F.TypeRemap.insertOrReplace( + std::make_pair(LocalBaseTypeIndex, + F.BaseTypeIndex - LocalBaseTypeIndex)); TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes); } @@ -1843,8 +1844,8 @@ ASTReader::ReadASTBlock(ModuleFile &F) { // Introduce the local -> global mapping for declarations within this // module. - F.DeclRemap.insert(std::make_pair(LocalBaseDeclID, - F.BaseDeclID - LocalBaseDeclID)); + F.DeclRemap.insertOrReplace( + std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID)); // Introduce the global -> local mapping for declarations within this // module. @@ -1927,9 +1928,9 @@ ASTReader::ReadASTBlock(ModuleFile &F) { // Introduce the local -> global mapping for identifiers within this // module. - F.IdentifierRemap.insert( - std::make_pair(LocalBaseIdentifierID, - F.BaseIdentifierID - LocalBaseIdentifierID)); + F.IdentifierRemap.insertOrReplace( + std::make_pair(LocalBaseIdentifierID, + F.BaseIdentifierID - LocalBaseIdentifierID)); IdentifiersLoaded.resize(IdentifiersLoaded.size() + F.LocalNumIdentifiers); @@ -2004,8 +2005,9 @@ ASTReader::ReadASTBlock(ModuleFile &F) { // Introduce the local -> global mapping for selectors within this // module. - F.SelectorRemap.insert(std::make_pair(LocalBaseSelectorID, - F.BaseSelectorID - LocalBaseSelectorID)); + F.SelectorRemap.insertOrReplace( + std::make_pair(LocalBaseSelectorID, + F.BaseSelectorID - LocalBaseSelectorID)); SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors); } @@ -2275,7 +2277,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) { // Introduce the local -> global mapping for preprocessed entities in // this module. - F.PreprocessedEntityRemap.insert( + F.PreprocessedEntityRemap.insertOrReplace( std::make_pair(LocalBasePreprocessedEntityID, F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID)); } @@ -3184,7 +3186,7 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { // Introduce the local -> global mapping for submodules within this // module. - F.SubmoduleRemap.insert( + F.SubmoduleRemap.insertOrReplace( std::make_pair(LocalBaseSubmoduleID, F.BaseSubmoduleID - LocalBaseSubmoduleID)); diff --git a/test/Modules/Inputs/redecl-merge-left.h b/test/Modules/Inputs/redecl-merge-left.h index 048b3e6c2d..d97fb7b25c 100644 --- a/test/Modules/Inputs/redecl-merge-left.h +++ b/test/Modules/Inputs/redecl-merge-left.h @@ -5,6 +5,7 @@ __import_module__ redecl_merge_top; @class A; @interface B ++ (B*) create_a_B; @end @class A; diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index fe25044166..23524af3a5 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -14,11 +14,16 @@ void f(A *a) { @class A; +B *f1() { + return [B create_a_B]; +} + @class B; __import_module__ redecl_merge_bottom; @implementation B ++ (B*)create_a_B { return 0; } @end void g(A *a) { -- 2.40.0