diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 12 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 11 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/stress1/merge00.h | 4 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/stress1/module.modulemap | 1 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/submodules-merge-defs/defs.h | 13 | ||||
| -rw-r--r-- | clang/test/Modules/stress1.cpp | 12 | 
7 files changed, 58 insertions, 15 deletions
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index b01070edb4e..06ca46b2f6b 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -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, diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 2412d04666f..ff771fd00a3 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7568,9 +7568,19 @@ ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record,    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. diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b59b94f9bf9..972e2b829d1 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -779,8 +779,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {      // 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::VisitClassTemplateSpecializationDeclImpl(    }    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::VisitVarTemplateSpecializationDeclImpl(    }    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); diff --git a/clang/test/Modules/Inputs/stress1/merge00.h b/clang/test/Modules/Inputs/stress1/merge00.h index 46d5e413827..0aeb6ce0087 100644 --- a/clang/test/Modules/Inputs/stress1/merge00.h +++ b/clang/test/Modules/Inputs/stress1/merge00.h @@ -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" diff --git a/clang/test/Modules/Inputs/stress1/module.modulemap b/clang/test/Modules/Inputs/stress1/module.modulemap index 2b687b01521..33eb23e2a6e 100644 --- a/clang/test/Modules/Inputs/stress1/module.modulemap +++ b/clang/test/Modules/Inputs/stress1/module.modulemap @@ -3,4 +3,5 @@ module m01 { header "Inputs/stress1/m01.h" export * }  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 * } diff --git a/clang/test/Modules/Inputs/submodules-merge-defs/defs.h b/clang/test/Modules/Inputs/submodules-merge-defs/defs.h index 670c400ae3b..ba6956fb98d 100644 --- a/clang/test/Modules/Inputs/submodules-merge-defs/defs.h +++ b/clang/test/Modules/Inputs/submodules-merge-defs/defs.h @@ -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() {} +} diff --git a/clang/test/Modules/stress1.cpp b/clang/test/Modules/stress1.cpp index 0cefed27df8..4da1edd092e 100644 --- a/clang/test/Modules/stress1.cpp +++ b/clang/test/Modules/stress1.cpp @@ -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"  | 

