summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2016-03-30 22:18:29 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2016-03-30 22:18:29 +0000
commitbab6f96fff363fbfdc15fd1f62452ff243da843c (patch)
treede254d8844eac530c84100e03dab88909baf8cdd /clang/lib
parentd8d94652b2345f596b3a62dbcd32cbb0a1a50856 (diff)
downloadbcm5719-llvm-bab6f96fff363fbfdc15fd1f62452ff243da843c.tar.gz
bcm5719-llvm-bab6f96fff363fbfdc15fd1f62452ff243da843c.zip
Canonicalize UnaryTransformType types when they don't have a known underlying type.
Fixes https://llvm.org/bugs/show_bug.cgi?id=26014 Reviewed by Richard Smith. llvm-svn: 264937
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp36
-rw-r--r--clang/lib/AST/Type.cpp29
2 files changed, 47 insertions, 18 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 77e5087b8c7..aa9277cdc1a 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4020,13 +4020,35 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,
QualType UnderlyingType,
UnaryTransformType::UTTKind Kind)
const {
- UnaryTransformType *Ty =
- new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType,
- Kind,
- UnderlyingType->isDependentType() ?
- QualType() : getCanonicalType(UnderlyingType));
- Types.push_back(Ty);
- return QualType(Ty, 0);
+ UnaryTransformType *ut = nullptr;
+
+ if (BaseType->isDependentType()) {
+ // Look in the folding set for an existing type.
+ llvm::FoldingSetNodeID ID;
+ DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind);
+
+ void *InsertPos = nullptr;
+ DependentUnaryTransformType *Canon
+ = DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!Canon) {
+ // Build a new, canonical __underlying_type(type) type.
+ Canon = new (*this, TypeAlignment)
+ DependentUnaryTransformType(*this, getCanonicalType(BaseType),
+ Kind);
+ DependentUnaryTransformTypes.InsertNode(Canon, InsertPos);
+ }
+ ut = new (*this, TypeAlignment) UnaryTransformType (BaseType,
+ QualType(), Kind,
+ QualType(Canon, 0));
+ } else {
+ QualType CanonType = getCanonicalType(UnderlyingType);
+ ut = new (*this, TypeAlignment) UnaryTransformType (BaseType,
+ UnderlyingType, Kind,
+ CanonType);
+ }
+ Types.push_back(ut);
+ return QualType(ut, 0);
}
/// getAutoType - Return the uniqued reference to the 'auto' type which has been
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 74aa323dbc8..d3c7259c38d 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2935,6 +2935,24 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
E->Profile(ID, Context, true);
}
+UnaryTransformType::UnaryTransformType(QualType BaseType,
+ QualType UnderlyingType,
+ UTTKind UKind,
+ QualType CanonicalType)
+ : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(),
+ BaseType->isInstantiationDependentType(),
+ BaseType->isVariablyModifiedType(),
+ BaseType->containsUnexpandedParameterPack())
+ , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind)
+{}
+
+DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C,
+ QualType BaseType,
+ UTTKind UKind)
+ : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType())
+{}
+
+
TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
: Type(TC, can, D->isDependentType(),
/*InstantiationDependent=*/D->isDependentType(),
@@ -2951,17 +2969,6 @@ static TagDecl *getInterestingTagDecl(TagDecl *decl) {
return decl;
}
-UnaryTransformType::UnaryTransformType(QualType BaseType,
- QualType UnderlyingType,
- UTTKind UKind,
- QualType CanonicalType)
- : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(),
- UnderlyingType->isInstantiationDependentType(),
- UnderlyingType->isVariablyModifiedType(),
- BaseType->containsUnexpandedParameterPack())
- , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind)
-{}
-
TagDecl *TagType::getDecl() const {
return getInterestingTagDecl(decl);
}
OpenPOWER on IntegriCloud