Author: rsmith Date: Sat Aug 8 20:05:31 2015 New Revision: 244409 URL: http://llvm.org/viewvc/llvm-project?rev=244409&view=rev Log: [modules] When loading a template specialization, re-canonicalize its template arguments because the reloaded form might have become non-canonical across the serialization/deserialization step (this particularly happens when the canonical form of the type involves an expression).
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/test/Modules/Inputs/stress1/merge00.h cfe/trunk/test/Modules/Inputs/stress1/module.modulemap cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h cfe/trunk/test/Modules/stress1.cpp Modified: cfe/trunk/include/clang/Serialization/ASTReader.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) +++ cfe/trunk/include/clang/Serialization/ASTReader.h Sat Aug 8 20:05:31 2015 @@ -1927,8 +1927,9 @@ public: unsigned &Idx); /// \brief Read a template argument. - TemplateArgument ReadTemplateArgument(ModuleFile &F, - const RecordData &Record,unsigned &Idx); + TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record, + unsigned &Idx, + bool Canonicalize = false); /// \brief Read a template parameter list. TemplateParameterList *ReadTemplateParameterList(ModuleFile &F, @@ -1936,10 +1937,9 @@ public: unsigned &Idx); /// \brief Read a template argument array. - void - ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, - ModuleFile &F, const RecordData &Record, - unsigned &Idx); + void ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, + ModuleFile &F, const RecordData &Record, + unsigned &Idx, bool Canonicalize = false); /// \brief Read a UnresolvedSet structure. void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Aug 8 20:05:31 2015 @@ -7568,9 +7568,19 @@ ASTReader::ReadTemplateName(ModuleFile & llvm_unreachable("Unhandled template name kind!"); } -TemplateArgument -ASTReader::ReadTemplateArgument(ModuleFile &F, - const RecordData &Record, unsigned &Idx) { +TemplateArgument ASTReader::ReadTemplateArgument(ModuleFile &F, + const RecordData &Record, + unsigned &Idx, + bool Canonicalize) { + if (Canonicalize) { + // The caller wants a canonical template argument. Sometimes the AST only + // wants template arguments in canonical form (particularly as the template + // argument lists of template specializations) so ensure we preserve that + // canonical form across serialization. + TemplateArgument Arg = ReadTemplateArgument(F, Record, Idx, false); + return Context.getCanonicalTemplateArgument(Arg); + } + TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++]; switch (Kind) { case TemplateArgument::Null: @@ -7634,11 +7644,11 @@ void ASTReader:: ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, ModuleFile &F, const RecordData &Record, - unsigned &Idx) { + unsigned &Idx, bool Canonicalize) { unsigned NumTemplateArgs = Record[Idx++]; TemplArgs.reserve(NumTemplateArgs); while (NumTemplateArgs--) - TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx)); + TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx, Canonicalize)); } /// \brief Read a UnresolvedSet structure. Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sat Aug 8 20:05:31 2015 @@ -779,8 +779,9 @@ void ASTDeclReader::VisitFunctionDecl(Fu // Template arguments. SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); - + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx, + /*Canonicalize*/ true); + // Template args as written. SmallVector<TemplateArgumentLoc, 8> TemplArgLocs; SourceLocation LAngleLoc, RAngleLoc; @@ -1937,7 +1938,8 @@ ASTDeclReader::VisitClassTemplateSpecial } SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx, + /*Canonicalize*/ true); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); @@ -2064,7 +2066,8 @@ ASTDeclReader::VisitVarTemplateSpecializ } SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx, + /*Canonicalize*/ true); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); Modified: cfe/trunk/test/Modules/Inputs/stress1/merge00.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/stress1/merge00.h?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/stress1/merge00.h (original) +++ cfe/trunk/test/Modules/Inputs/stress1/merge00.h Sat Aug 8 20:05:31 2015 @@ -9,6 +9,10 @@ //#pragma weak pragma_weak01 // expected-warning {{weak identifier 'pragma_weak01' never declared}} //#pragma weak pragma_weak04 // expected-warning {{weak identifier 'pragma_waek04' never declared}} +#ifdef MERGE_NO_REEXPORT +#include "merge_no_reexport.h" +#endif + #include "common.h" #include "m00.h" #include "m01.h" Modified: cfe/trunk/test/Modules/Inputs/stress1/module.modulemap URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/stress1/module.modulemap?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/stress1/module.modulemap (original) +++ cfe/trunk/test/Modules/Inputs/stress1/module.modulemap Sat Aug 8 20:05:31 2015 @@ -3,4 +3,5 @@ module m01 { header "Inputs/stress1/m01. module m02 { header "Inputs/stress1/m02.h" export * } module m03 { header "Inputs/stress1/m03.h" export * } +module merge_no_reexport { header "Inputs/stress1/merge_no_reexport.h" } module merge00 { header "Inputs/stress1/merge00.h" export * } Modified: cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h (original) +++ cfe/trunk/test/Modules/Inputs/submodules-merge-defs/defs.h Sat Aug 8 20:05:31 2015 @@ -111,3 +111,16 @@ namespace Anon { }; }; } + +namespace ClassTemplatePartialSpec { + template<typename T> struct F; + template<template<int> class A, int B> struct F<A<B>> { + template<typename C> F(); + }; + template<template<int> class A, int B> template<typename C> F<A<B>>::F() {} + + template<typename A, int B> struct F<A[B]> { + template<typename C> F(); + }; + template<typename A, int B> template<typename C> F<A[B]>::F() {} +} Modified: cfe/trunk/test/Modules/stress1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/stress1.cpp?rev=244409&r1=244408&r2=244409&view=diff ============================================================================== --- cfe/trunk/test/Modules/stress1.cpp (original) +++ cfe/trunk/test/Modules/stress1.cpp Sat Aug 8 20:05:31 2015 @@ -107,6 +107,18 @@ // // RUN: diff -u %t/stress1.ll %t/stress1_check.ll // +// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \ +// RUN: -I Inputs/stress1 \ +// RUN: -fmodules-cache-path=%t \ +// RUN: -fmodule-map-file-home-is-cwd \ +// RUN: -fmodule-file=%t/m00.pcm \ +// RUN: -fmodule-file=%t/m01.pcm \ +// RUN: -fmodule-file=%t/m02.pcm \ +// RUN: -fmodule-file=%t/m03.pcm \ +// RUN: -emit-module -fmodule-name=merge00 -o /dev/null \ +// RUN: -DMERGE_NO_REEXPORT \ +// RUN: Inputs/stress1/module.modulemap +// // expected-no-diagnostics #include "m00.h" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits