@@ -2364,12 +2364,12 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
2364
2364
return getTypeInfo(cast<UsingType>(T)->desugar().getTypePtr());
2365
2365
2366
2366
case Type::Typedef: {
2367
- const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl( );
2368
- TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType ().getTypePtr());
2367
+ const auto *TT = cast<TypedefType>(T);
2368
+ TypeInfo Info = getTypeInfo(TT->desugar ().getTypePtr());
2369
2369
// If the typedef has an aligned attribute on it, it overrides any computed
2370
2370
// alignment we have. This violates the GCC documentation (which says that
2371
2371
// attribute(aligned) can only round up) but matches its implementation.
2372
- if (unsigned AttrAlign = Typedef ->getMaxAlignment()) {
2372
+ if (unsigned AttrAlign = TT->getDecl() ->getMaxAlignment()) {
2373
2373
Align = AttrAlign;
2374
2374
AlignRequirement = AlignRequirementKind::RequiredByTypedef;
2375
2375
} else {
@@ -4638,34 +4638,60 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
4638
4638
/// specified typedef name decl.
4639
4639
QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl,
4640
4640
QualType Underlying) const {
4641
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
4641
+ if (!Decl->TypeForDecl) {
4642
+ if (Underlying.isNull())
4643
+ Underlying = Decl->getUnderlyingType();
4644
+ auto *NewType = new (*this, TypeAlignment) TypedefType(
4645
+ Type::Typedef, Decl, QualType(), getCanonicalType(Underlying));
4646
+ Decl->TypeForDecl = NewType;
4647
+ Types.push_back(NewType);
4648
+ return QualType(NewType, 0);
4649
+ }
4650
+ if (Underlying.isNull() || Decl->getUnderlyingType() == Underlying)
4651
+ return QualType(Decl->TypeForDecl, 0);
4652
+ assert(hasSameType(Decl->getUnderlyingType(), Underlying));
4642
4653
4643
- if (Underlying.isNull())
4644
- Underlying = Decl->getUnderlyingType();
4645
- QualType Canonical = getCanonicalType(Underlying);
4646
- auto *newType = new (*this, TypeAlignment)
4647
- TypedefType(Type::Typedef, Decl, Underlying, Canonical);
4648
- Decl->TypeForDecl = newType;
4649
- Types.push_back(newType);
4650
- return QualType(newType, 0);
4654
+ llvm::FoldingSetNodeID ID;
4655
+ TypedefType::Profile(ID, Decl, Underlying);
4656
+
4657
+ void *InsertPos = nullptr;
4658
+ if (TypedefType *T = TypedefTypes.FindNodeOrInsertPos(ID, InsertPos)) {
4659
+ assert(!T->typeMatchesDecl() &&
4660
+ "non-divergent case should be handled with TypeDecl");
4661
+ return QualType(T, 0);
4662
+ }
4663
+
4664
+ void *Mem =
4665
+ Allocate(TypedefType::totalSizeToAlloc<QualType>(true), TypeAlignment);
4666
+ auto *NewType = new (Mem) TypedefType(Type::Typedef, Decl, Underlying,
4667
+ getCanonicalType(Underlying));
4668
+ TypedefTypes.InsertNode(NewType, InsertPos);
4669
+ Types.push_back(NewType);
4670
+ return QualType(NewType, 0);
4651
4671
}
4652
4672
4653
4673
QualType ASTContext::getUsingType(const UsingShadowDecl *Found,
4654
4674
QualType Underlying) const {
4655
4675
llvm::FoldingSetNodeID ID;
4656
- UsingType::Profile(ID, Found);
4676
+ UsingType::Profile(ID, Found, Underlying );
4657
4677
4658
4678
void *InsertPos = nullptr;
4659
- UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos);
4660
- if (T)
4679
+ if (UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos))
4661
4680
return QualType(T, 0);
4662
4681
4663
- assert(!Underlying.hasLocalQualifiers());
4664
- assert(Underlying == getTypeDeclType(cast<TypeDecl>(Found->getTargetDecl())));
4665
- QualType Canon = Underlying.getCanonicalType();
4682
+ const Type *TypeForDecl =
4683
+ cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl();
4666
4684
4667
- UsingType *NewType =
4668
- new (*this, TypeAlignment) UsingType(Found, Underlying, Canon);
4685
+ assert(!Underlying.hasLocalQualifiers());
4686
+ QualType Canon = Underlying->getCanonicalTypeInternal();
4687
+ assert(TypeForDecl->getCanonicalTypeInternal() == Canon);
4688
+
4689
+ if (Underlying.getTypePtr() == TypeForDecl)
4690
+ Underlying = QualType();
4691
+ void *Mem =
4692
+ Allocate(UsingType::totalSizeToAlloc<QualType>(!Underlying.isNull()),
4693
+ TypeAlignment);
4694
+ UsingType *NewType = new (Mem) UsingType(Found, Underlying, Canon);
4669
4695
Types.push_back(NewType);
4670
4696
UsingTypes.InsertNode(NewType, InsertPos);
4671
4697
return QualType(NewType, 0);
0 commit comments