Remove a bogus assertion from the AST reader, which assumed that

redeclarations of a particular entity would occur in source
order. Friend declarations that occur within class templates (or
member classes thereof) do not follow this, nor would modules. Big
thanks to Erik Verbruggen for reducing this problem from the Very
Large Qt preamble testcase he found.

llvm-svn: 138557
This commit is contained in:
Douglas Gregor 2011-08-25 15:28:26 +00:00
parent c10edd6dd0
commit aa7cbfd259
2 changed files with 67 additions and 12 deletions

View File

@ -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);
}

View File

@ -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