summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Serialization/ASTReader.h3
-rw-r--r--clang/lib/Serialization/ASTReader.cpp19
-rw-r--r--clang/test/Modules/Inputs/templates-right.h4
-rw-r--r--clang/test/Modules/Inputs/templates-top.h1
-rw-r--r--clang/test/Modules/templates.mm2
5 files changed, 22 insertions, 7 deletions
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 63bad2663e0..cc53b8ceb0c 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -499,7 +499,8 @@ private:
typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents;
/// \brief Map from a DeclContext to its lexical contents.
- llvm::DenseMap<const DeclContext*, LexicalContents> LexicalDecls;
+ llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
+ LexicalDecls;
/// \brief Map from the TU to its lexical contents from each module file.
std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index ad528b0213a..91dc4bdbc90 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -975,11 +975,18 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
assert(!isa<TranslationUnitDecl>(DC) &&
"expected a TU_UPDATE_LEXICAL record for TU");
- // FIXME: Once we remove RewriteDecl, assert that we didn't already have
- // lexical decls for this context.
- LexicalDecls[DC] = llvm::makeArrayRef(
- reinterpret_cast<const llvm::support::unaligned_uint32_t *>(Blob.data()),
- Blob.size() / 4);
+ // If we are handling a C++ class template instantiation, we can see multiple
+ // lexical updates for the same record. It's important that we select only one
+ // of them, so that field numbering works properly. Just pick the first one we
+ // see.
+ auto &Lex = LexicalDecls[DC];
+ if (!Lex.first) {
+ Lex = std::make_pair(
+ &M, llvm::makeArrayRef(
+ reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
+ Blob.data()),
+ Blob.size() / 4));
+ }
DC->setHasExternalLexicalStorage(true);
return false;
}
@@ -6253,7 +6260,7 @@ void ASTReader::FindExternalLexicalDecls(
} else {
auto I = LexicalDecls.find(DC);
if (I != LexicalDecls.end())
- Visit(getOwningModuleFile(cast<Decl>(DC)), I->second);
+ Visit(I->second.first, I->second.second);
}
++NumLexicalDeclContextsRead;
diff --git a/clang/test/Modules/Inputs/templates-right.h b/clang/test/Modules/Inputs/templates-right.h
index daea97b86b8..32487c60c26 100644
--- a/clang/test/Modules/Inputs/templates-right.h
+++ b/clang/test/Modules/Inputs/templates-right.h
@@ -38,6 +38,10 @@ int defineListDoubleRight() {
return ld.size;
}
+inline void defineListLongRight() {
+ List<long> ll;
+}
+
template<typename T> struct MergePatternDecl;
void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
diff --git a/clang/test/Modules/Inputs/templates-top.h b/clang/test/Modules/Inputs/templates-top.h
index 31f5e419928..a0826835239 100644
--- a/clang/test/Modules/Inputs/templates-top.h
+++ b/clang/test/Modules/Inputs/templates-top.h
@@ -10,6 +10,7 @@ public:
};
extern List<double> *instantiateListDoubleDeclaration;
+extern List<long> *instantiateListLongDeclaration;
namespace A {
class Y {
diff --git a/clang/test/Modules/templates.mm b/clang/test/Modules/templates.mm
index 4c6e4723a3b..190084ad2b7 100644
--- a/clang/test/Modules/templates.mm
+++ b/clang/test/Modules/templates.mm
@@ -28,6 +28,8 @@ void testTemplateClasses() {
N::Set<char> set_char;
set_char.insert('A');
+ static_assert(sizeof(List<long>) == sizeof(List<short>), "");
+
List<double> list_double;
list_double.push_back(0.0);
}
OpenPOWER on IntegriCloud