diff options
| -rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 3 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 19 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-right.h | 4 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-top.h | 1 | ||||
| -rw-r--r-- | clang/test/Modules/templates.mm | 2 |
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); } |

