Author: rsmith Date: Tue Aug 11 17:00:24 2015 New Revision: 244682 URL: http://llvm.org/viewvc/llvm-project?rev=244682&view=rev Log: [modules] When instantiating the contents of an imported CXXRecordDecl, we can emit lexical contents for a declaration for another module. Track which module those contents came from, and ensure that we only grab the lexical contents from a single such instantiation.
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/test/Modules/Inputs/templates-right.h cfe/trunk/test/Modules/Inputs/templates-top.h cfe/trunk/test/Modules/templates.mm Modified: cfe/trunk/include/clang/Serialization/ASTReader.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=244682&r1=244681&r2=244682&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) +++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Aug 11 17:00:24 2015 @@ -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; Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=244682&r1=244681&r2=244682&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Aug 11 17:00:24 2015 @@ -975,11 +975,18 @@ bool ASTReader::ReadLexicalDeclContextSt 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; Modified: cfe/trunk/test/Modules/Inputs/templates-right.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/templates-right.h?rev=244682&r1=244681&r2=244682&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/templates-right.h (original) +++ cfe/trunk/test/Modules/Inputs/templates-right.h Tue Aug 11 17:00:24 2015 @@ -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); Modified: cfe/trunk/test/Modules/Inputs/templates-top.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/templates-top.h?rev=244682&r1=244681&r2=244682&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/templates-top.h (original) +++ cfe/trunk/test/Modules/Inputs/templates-top.h Tue Aug 11 17:00:24 2015 @@ -10,6 +10,7 @@ public: }; extern List<double> *instantiateListDoubleDeclaration; +extern List<long> *instantiateListLongDeclaration; namespace A { class Y { Modified: cfe/trunk/test/Modules/templates.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/templates.mm?rev=244682&r1=244681&r2=244682&view=diff ============================================================================== --- cfe/trunk/test/Modules/templates.mm (original) +++ cfe/trunk/test/Modules/templates.mm Tue Aug 11 17:00:24 2015 @@ -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); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits