diff options
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 18 | ||||
-rw-r--r-- | test/PCH/chain-friend-instantiation.cpp | 61 |
2 files changed, 67 insertions, 12 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index ab46e0a096..6e7cbbf9b0 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -123,8 +123,8 @@ namespace clang { ClassTemplateSpecializationDecl *D); void VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D); - void VisitClassScopeFunctionSpecializationDecl(
- ClassScopeFunctionSpecializationDecl *D);
+ void VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D); void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); void VisitValueDecl(ValueDecl *VD); void VisitEnumConstantDecl(EnumConstantDecl *ECD); @@ -1087,14 +1087,8 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { ASTReader::FirstLatestDeclIDMap::iterator I = Reader.FirstLatestDeclIDs.find(ThisDeclID); if (I != Reader.FirstLatestDeclIDs.end()) { - Decl *NewLatest = Reader.GetDecl(I->second); - assert((LatestDecl->getLocation().isInvalid() || - NewLatest->getLocation().isInvalid() || - !Reader.SourceMgr.isBeforeInTranslationUnit( - NewLatest->getLocation(), - LatestDecl->getLocation())) && - "The new latest is supposed to come after the previous latest"); - LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest); + if (Decl *NewLatest = Reader.GetDecl(I->second)) + LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest); } assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch"); @@ -1217,8 +1211,8 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( } } -void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
- ClassScopeFunctionSpecializationDecl *D) {
+void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D) { VisitDecl(D); D->Specialization = ReadDeclAs<CXXMethodDecl>(Record, Idx); } diff --git a/test/PCH/chain-friend-instantiation.cpp b/test/PCH/chain-friend-instantiation.cpp new file mode 100644 index 0000000000..294d979112 --- /dev/null +++ b/test/PCH/chain-friend-instantiation.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 %s -ast-print -o - -chain-include %s -chain-include %s + +#if !defined(PASS1) +#define PASS1 + +template <class T> class TClass; + +namespace NS { + template <class X, class Y> TClass<X> problematic(X * ptr, const TClass<Y> &src); + + template <class T> + class TBaseClass + { + protected: + template <class X, class Y> friend TClass<X> problematic(X * ptr, const TClass<Y> &src); + }; +} + +template <class T> +class TClass: public NS::TBaseClass<T> +{ +public: + inline TClass() { } +}; + + +namespace NS { + template <class X, class T> + TClass<X> problematic(X *ptr, const TClass<T> &src); +} + +template <class X, class T> +TClass<X> unconst(const TClass<T> &src); + +#elif !defined(PASS2) +#define PASS2 + +namespace std { +class s {}; +} + + +typedef TClass<std::s> TStr; + +struct crash { + TStr str; + + crash(const TClass<std::s> p) + { + unconst<TStr>(p); + } +}; + +#else + +void f() { + const TStr p; + crash c(p); +} + +#endif |