summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ASTContext.cpp45
-rw-r--r--clang/lib/Serialization/ASTReader.cpp4
-rw-r--r--clang/test/PCH/cxx-templates.cpp4
-rw-r--r--clang/test/PCH/cxx-templates.h14
4 files changed, 44 insertions, 23 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 10f875b1b76..d7ebedf72a0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1522,11 +1522,12 @@ QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
DependentSizedArrayType *Canon = 0;
llvm::FoldingSetNodeID ID;
+ QualType CanonicalEltTy = getCanonicalType(EltTy);
if (NumElts) {
// Dependently-sized array types that do not have a specified
// number of elements will have their sizes deduced from an
// initializer.
- DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM,
+ DependentSizedArrayType::Profile(ID, *this, CanonicalEltTy, ASM,
EltTypeQuals, NumElts);
Canon = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -1539,28 +1540,28 @@ QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
New = new (*this, TypeAlignment)
DependentSizedArrayType(*this, EltTy, QualType(Canon, 0),
NumElts, ASM, EltTypeQuals, Brackets);
- } else {
- QualType CanonEltTy = getCanonicalType(EltTy);
- if (CanonEltTy == EltTy) {
- New = new (*this, TypeAlignment)
- DependentSizedArrayType(*this, EltTy, QualType(),
- NumElts, ASM, EltTypeQuals, Brackets);
-
- if (NumElts) {
- DependentSizedArrayType *CanonCheck
- = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!CanonCheck && "Dependent-sized canonical array type broken");
- (void)CanonCheck;
- DependentSizedArrayTypes.InsertNode(New, InsertPos);
- }
- } else {
- QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts,
- ASM, EltTypeQuals,
- SourceRange());
- New = new (*this, TypeAlignment)
- DependentSizedArrayType(*this, EltTy, Canon,
- NumElts, ASM, EltTypeQuals, Brackets);
+ } else if (CanonicalEltTy == EltTy) {
+ // This is a canonical type. Record it.
+ New = new (*this, TypeAlignment)
+ DependentSizedArrayType(*this, EltTy, QualType(),
+ NumElts, ASM, EltTypeQuals, Brackets);
+
+ if (NumElts) {
+#ifndef NDEBUG
+ DependentSizedArrayType *CanonCheck
+ = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!CanonCheck && "Dependent-sized canonical array type broken");
+ (void)CanonCheck;
+#endif
+ DependentSizedArrayTypes.InsertNode(New, InsertPos);
}
+ } else {
+ QualType Canon = getDependentSizedArrayType(CanonicalEltTy, NumElts,
+ ASM, EltTypeQuals,
+ SourceRange());
+ New = new (*this, TypeAlignment)
+ DependentSizedArrayType(*this, EltTy, Canon,
+ NumElts, ASM, EltTypeQuals, Brackets);
}
Types.push_back(New);
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 38e786bff10..c0aff9afde3 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2764,6 +2764,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
}
TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
QualType Canonical = GetType(Record[1]);
+ if (!Canonical.isNull())
+ Canonical = Context->getCanonicalType(Canonical);
return Context->getTypedefType(Decl, Canonical);
}
@@ -2867,6 +2869,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
QualType Canon = GetType(Record[Idx++]);
+ if (!Canon.isNull())
+ Canon = Context->getCanonicalType(Canon);
return Context->getDependentNameType(Keyword, NNS, Name, Canon);
}
diff --git a/clang/test/PCH/cxx-templates.cpp b/clang/test/PCH/cxx-templates.cpp
index d36d5449c81..95477992e67 100644
--- a/clang/test/PCH/cxx-templates.cpp
+++ b/clang/test/PCH/cxx-templates.cpp
@@ -17,7 +17,7 @@ struct A {
static T my_templf(T x) { return x; }
};
-void test() {
+void test(const int (&a6)[17]) {
int x = templ_f<int, 5>(3);
S<char, float>::templ();
@@ -32,6 +32,8 @@ void test() {
s3.m();
TS5 ts(0);
+
+ S6<const int[17]>::t2 b6 = a6;
}
template struct S4<int>;
diff --git a/clang/test/PCH/cxx-templates.h b/clang/test/PCH/cxx-templates.h
index e1f285b19dc..5baa772b5d0 100644
--- a/clang/test/PCH/cxx-templates.h
+++ b/clang/test/PCH/cxx-templates.h
@@ -150,3 +150,17 @@ struct TS5 {
template<class T> void f_PR8134(T);
template<class T> void f_PR8134(T);
void g_PR8134() { f_PR8134(0); f_PR8134('x'); }
+
+// rdar8580149
+template <typename T>
+struct S6;
+
+template <typename T, unsigned N>
+struct S6<const T [N]>
+{
+private:
+ typedef const T t1[N];
+public:
+ typedef t1& t2;
+};
+
OpenPOWER on IntegriCloud