Skip to content

Commit 6cd62ad

Browse files
authored
Revert "[clang] improve class type sugar preservation in pointers to members" (llvm#132215)
Reverts llvm#130537 This missed updating lldb, which we didn't notice due to lack of pre-commit CI.
1 parent e6a87da commit 6cd62ad

File tree

69 files changed

+423
-1039
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+423
-1039
lines changed

clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,8 @@ UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
493493
: ClangTidyCheck(Name, Context),
494494
NullMacrosStr(Options.get("NullMacros", "NULL")),
495495
IgnoredTypes(utils::options::parseStringList(Options.get(
496-
"IgnoredTypes", "_CmpUnspecifiedParam;^std::__cmp_cat::__unspec"))) {
496+
"IgnoredTypes",
497+
"std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec"))) {
497498
StringRef(NullMacrosStr).split(NullMacros, ",");
498499
}
499500

clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,7 @@ bool isFunctionPointerConvertible(QualType From, QualType To) {
178178

179179
// Note: converting Derived::* to Base::* is a different kind of conversion,
180180
// called Pointer-to-member conversion.
181-
return FromMember->getQualifier() == ToMember->getQualifier() &&
182-
FromMember->getMostRecentCXXRecordDecl() ==
183-
ToMember->getMostRecentCXXRecordDecl() &&
181+
return FromMember->getClass() == ToMember->getClass() &&
184182
FromMember->getPointeeType() == ToMember->getPointeeType();
185183
}
186184

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1489,7 +1489,7 @@ TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
14891489
"4: targets = {a}\n"
14901490
"5: targets = {a::b}, qualifier = 'a::'\n"
14911491
"6: targets = {a::b::S}\n"
1492-
"7: targets = {a::b::S::type}, qualifier = 'S::'\n"
1492+
"7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
14931493
"8: targets = {y}, decl\n"},
14941494
{R"cpp(
14951495
void foo() {

clang/docs/ReleaseNotes.rst

-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ Improvements to Clang's diagnostics
267267
under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
268268
- Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
269269
``-Wno-error=parentheses``.
270-
- Clang now better preserves the sugared types of pointers to member.
271270
- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
272271
- Fixed diagnostics adding a trailing ``::`` when printing some source code
273272
constructs, like base classes.

clang/include/clang/AST/ASTContext.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -1558,9 +1558,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
15581558
QualType getRValueReferenceType(QualType T) const;
15591559

15601560
/// Return the uniqued reference to the type for a member pointer to
1561-
/// the specified type in the specified nested name.
1562-
QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
1563-
const CXXRecordDecl *Cls) const;
1561+
/// the specified type in the specified class.
1562+
///
1563+
/// The class \p Cls is a \c Type because it could be a dependent name.
1564+
QualType getMemberPointerType(QualType T, const Type *Cls) const;
15641565

15651566
/// Return a non-unique reference to the type for a variable array of
15661567
/// the specified element type.

clang/include/clang/AST/ASTNodeTraverser.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,7 @@ class ASTNodeTraverser
393393
Visit(T->getPointeeType());
394394
}
395395
void VisitMemberPointerType(const MemberPointerType *T) {
396-
// FIXME: Provide a NestedNameSpecifier visitor.
397-
Visit(T->getQualifier()->getAsType());
398-
Visit(T->getMostRecentCXXRecordDecl());
396+
Visit(T->getClass());
399397
Visit(T->getPointeeType());
400398
}
401399
void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
@@ -487,8 +485,7 @@ class ASTNodeTraverser
487485
}
488486
}
489487
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
490-
// FIXME: Provide NestedNamespecifierLoc visitor.
491-
Visit(TL.getQualifierLoc().getTypeLoc());
488+
Visit(TL.getClassTInfo()->getTypeLoc());
492489
}
493490
void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
494491
Visit(TL.getSizeExpr());

clang/include/clang/AST/CanonicalType.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ template<>
453453
struct CanProxyAdaptor<MemberPointerType>
454454
: public CanProxyBase<MemberPointerType> {
455455
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
456-
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier *, getQualifier)
456+
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
457457
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
458458
getMostRecentCXXRecordDecl)
459459
};

clang/include/clang/AST/RecursiveASTVisitor.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -1004,8 +1004,7 @@ DEF_TRAVERSE_TYPE(RValueReferenceType,
10041004
{ TRY_TO(TraverseType(T->getPointeeType())); })
10051005

10061006
DEF_TRAVERSE_TYPE(MemberPointerType, {
1007-
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1008-
TRY_TO(TraverseDecl(T->getMostRecentCXXRecordDecl()));
1007+
TRY_TO(TraverseType(QualType(T->getClass(), 0)));
10091008
TRY_TO(TraverseType(T->getPointeeType()));
10101009
})
10111010

@@ -1270,10 +1269,10 @@ DEF_TRAVERSE_TYPELOC(RValueReferenceType,
12701269
// We traverse this in the type case as well, but how is it not reached through
12711270
// the pointee type?
12721271
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1273-
if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
1274-
TRY_TO(TraverseNestedNameSpecifierLoc(QL));
1272+
if (auto *TSI = TL.getClassTInfo())
1273+
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
12751274
else
1276-
TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1275+
TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
12771276
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
12781277
})
12791278

clang/include/clang/AST/Type.h

+13-15
Original file line numberDiff line numberDiff line change
@@ -3527,16 +3527,14 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
35273527
QualType PointeeType;
35283528

35293529
/// The class of which the pointee is a member. Must ultimately be a
3530-
/// CXXRecordType, but could be a typedef or a template parameter too.
3531-
NestedNameSpecifier *Qualifier;
3530+
/// RecordType, but could be a typedef or a template parameter too.
3531+
const Type *Class;
35323532

3533-
MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier,
3534-
QualType CanonicalPtr)
3533+
MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
35353534
: Type(MemberPointer, CanonicalPtr,
3536-
(toTypeDependence(Qualifier->getDependence()) &
3537-
~TypeDependence::VariablyModified) |
3535+
(Cls->getDependence() & ~TypeDependence::VariablyModified) |
35383536
Pointee->getDependence()),
3539-
PointeeType(Pointee), Qualifier(Qualifier) {}
3537+
PointeeType(Pointee), Class(Cls) {}
35403538

35413539
public:
35423540
QualType getPointeeType() const { return PointeeType; }
@@ -3553,21 +3551,21 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
35533551
return !PointeeType->isFunctionProtoType();
35543552
}
35553553

3556-
NestedNameSpecifier *getQualifier() const { return Qualifier; }
3554+
const Type *getClass() const { return Class; }
35573555
CXXRecordDecl *getMostRecentCXXRecordDecl() const;
35583556

3559-
bool isSugared() const;
3560-
QualType desugar() const {
3561-
return isSugared() ? getCanonicalTypeInternal() : QualType(this, 0);
3562-
}
3557+
bool isSugared() const { return false; }
3558+
QualType desugar() const { return QualType(this, 0); }
35633559

35643560
void Profile(llvm::FoldingSetNodeID &ID) {
3565-
Profile(ID, getPointeeType(), getQualifier(), getMostRecentCXXRecordDecl());
3561+
Profile(ID, getPointeeType(), getClass());
35663562
}
35673563

35683564
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
3569-
const NestedNameSpecifier *Qualifier,
3570-
const CXXRecordDecl *Cls);
3565+
const Type *Class) {
3566+
ID.AddPointer(Pointee.getAsOpaquePtr());
3567+
ID.AddPointer(Class);
3568+
}
35713569

35723570
static bool classof(const Type *T) {
35733571
return T->getTypeClass() == MemberPointer;

clang/include/clang/AST/TypeLoc.h

+14-19
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ class TypeLoc {
139139
}
140140

141141
/// Get the pointer where source information is stored.
142-
// FIXME: This should provide a type-safe interface.
143142
void *getOpaqueData() const {
144143
return Data;
145144
}
@@ -1356,7 +1355,7 @@ class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
13561355
};
13571356

13581357
struct MemberPointerLocInfo : public PointerLikeLocInfo {
1359-
void *QualifierData = nullptr;
1358+
TypeSourceInfo *ClassTInfo;
13601359
};
13611360

13621361
/// Wrapper for source info for member pointers.
@@ -1372,32 +1371,28 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
13721371
setSigilLoc(Loc);
13731372
}
13741373

1375-
NestedNameSpecifierLoc getQualifierLoc() const {
1376-
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1377-
getLocalData()->QualifierData);
1374+
const Type *getClass() const {
1375+
return getTypePtr()->getClass();
13781376
}
13791377

1380-
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1381-
assert(QualifierLoc.getNestedNameSpecifier() ==
1382-
getTypePtr()->getQualifier() &&
1383-
"Inconsistent nested-name-specifier pointer");
1384-
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1378+
TypeSourceInfo *getClassTInfo() const {
1379+
return getLocalData()->ClassTInfo;
1380+
}
1381+
1382+
void setClassTInfo(TypeSourceInfo* TI) {
1383+
getLocalData()->ClassTInfo = TI;
13851384
}
13861385

13871386
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
13881387
setSigilLoc(Loc);
1389-
if (auto *Qualifier = getTypePtr()->getQualifier()) {
1390-
NestedNameSpecifierLocBuilder Builder;
1391-
Builder.MakeTrivial(Context, Qualifier, Loc);
1392-
setQualifierLoc(Builder.getWithLocInContext(Context));
1393-
} else
1394-
getLocalData()->QualifierData = nullptr;
1388+
setClassTInfo(nullptr);
13951389
}
13961390

13971391
SourceRange getLocalSourceRange() const {
1398-
if (NestedNameSpecifierLoc QL = getQualifierLoc())
1399-
return SourceRange(QL.getBeginLoc(), getStarLoc());
1400-
return SourceRange(getStarLoc());
1392+
if (TypeSourceInfo *TI = getClassTInfo())
1393+
return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1394+
else
1395+
return SourceRange(getStarLoc());
14011396
}
14021397
};
14031398

clang/include/clang/AST/TypeProperties.td

+3-6
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,12 @@ let Class = MemberPointerType in {
100100
def : Property<"pointeeType", QualType> {
101101
let Read = [{ node->getPointeeType() }];
102102
}
103-
def : Property<"Qualifier", NestedNameSpecifier> {
104-
let Read = [{ node->getQualifier() }];
105-
}
106-
def : Property<"Cls", DeclRef> {
107-
let Read = [{ node->getMostRecentCXXRecordDecl() }];
103+
def : Property<"baseType", QualType> {
104+
let Read = [{ QualType(node->getClass(), 0) }];
108105
}
109106

110107
def : Creator<[{
111-
return ctx.getMemberPointerType(pointeeType, Qualifier, cast_or_null<CXXRecordDecl>(Cls));
108+
return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
112109
}]>;
113110
}
114111

clang/include/clang/Basic/DiagnosticSemaKinds.td

+4-2
Original file line numberDiff line numberDiff line change
@@ -7065,8 +7065,10 @@ def err_illegal_decl_mempointer_to_reference : Error<
70657065
"'%0' declared as a member pointer to a reference of type %1">;
70667066
def err_illegal_decl_mempointer_to_void : Error<
70677067
"'%0' declared as a member pointer to void">;
7068-
def err_illegal_decl_mempointer_in_nonclass
7069-
: Error<"'%0' does not point into a class">;
7068+
def err_illegal_decl_mempointer_in_nonclass : Error<
7069+
"'%0' does not point into a class">;
7070+
def err_mempointer_in_nonclass_type : Error<
7071+
"member pointer refers into non-class type %0">;
70707072
def err_reference_to_void : Error<"cannot form a reference to 'void'">;
70717073
def err_nonfunction_block_type : Error<
70727074
"block pointer to non-function type is invalid">;

clang/include/clang/Sema/Sema.h

+2-9
Original file line numberDiff line numberDiff line change
@@ -1348,12 +1348,6 @@ class Sema final : public SemaBase {
13481348
unsigned DiagID, bool ForceCheck = false,
13491349
bool ForceUnprivileged = false);
13501350

1351-
AccessResult CheckBaseClassAccess(
1352-
SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
1353-
const CXXBasePath &Path, unsigned DiagID,
1354-
llvm::function_ref<void(PartialDiagnostic &PD)> SetupPDiag,
1355-
bool ForceCheck = false, bool ForceUnprivileged = false);
1356-
13571351
/// Checks access to all the declarations in the given result set.
13581352
void CheckLookupAccess(const LookupResult &R);
13591353

@@ -14885,9 +14879,8 @@ class Sema final : public SemaBase {
1488514879
///
1488614880
/// \returns a member pointer type, if successful, or a NULL type if there was
1488714881
/// an error.
14888-
QualType BuildMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
14889-
CXXRecordDecl *Cls, SourceLocation Loc,
14890-
DeclarationName Entity);
14882+
QualType BuildMemberPointerType(QualType T, QualType Class,
14883+
SourceLocation Loc, DeclarationName Entity);
1489114884

1489214885
/// Build a block pointer type.
1489314886
///

clang/lib/AST/ASTContext.cpp

+21-47
Original file line numberDiff line numberDiff line change
@@ -3322,8 +3322,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
33223322
case Type::MemberPointer: {
33233323
OS << "M";
33243324
const auto *MPT = T->castAs<MemberPointerType>();
3325-
encodeTypeForFunctionPointerAuth(
3326-
Ctx, OS, QualType(MPT->getQualifier()->getAsType(), 0));
3325+
encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
33273326
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
33283327
return;
33293328
}
@@ -3512,8 +3511,7 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
35123511
if (PointeeType->castAs<FunctionProtoType>()->getExceptionSpecType() !=
35133512
EST_None) {
35143513
QualType FT = getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
3515-
T = getMemberPointerType(FT, MPT->getQualifier(),
3516-
MPT->getMostRecentCXXRecordDecl());
3514+
T = getMemberPointerType(FT, MPT->getClass());
35173515
}
35183516
}
35193517
std::unique_ptr<MangleContext> MC(createMangleContext());
@@ -4027,50 +4025,32 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
40274025
return QualType(New, 0);
40284026
}
40294027

4030-
QualType ASTContext::getMemberPointerType(QualType T,
4031-
NestedNameSpecifier *Qualifier,
4032-
const CXXRecordDecl *Cls) const {
4033-
if (!Qualifier) {
4034-
assert(Cls && "At least one of Qualifier or Cls must be provided");
4035-
Qualifier = NestedNameSpecifier::Create(*this, /*Prefix=*/nullptr,
4036-
/*Template=*/false,
4037-
getTypeDeclType(Cls).getTypePtr());
4038-
} else if (!Cls) {
4039-
Cls = Qualifier->getAsRecordDecl();
4040-
}
4028+
/// getMemberPointerType - Return the uniqued reference to the type for a
4029+
/// member pointer to the specified type, in the specified class.
4030+
QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
40414031
// Unique pointers, to guarantee there is only one pointer of a particular
40424032
// structure.
40434033
llvm::FoldingSetNodeID ID;
4044-
MemberPointerType::Profile(ID, T, Qualifier, Cls);
4034+
MemberPointerType::Profile(ID, T, Cls);
40454035

40464036
void *InsertPos = nullptr;
40474037
if (MemberPointerType *PT =
40484038
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
40494039
return QualType(PT, 0);
40504040

4051-
NestedNameSpecifier *CanonicalQualifier = [&] {
4052-
if (!Cls)
4053-
return getCanonicalNestedNameSpecifier(Qualifier);
4054-
NestedNameSpecifier *R = NestedNameSpecifier::Create(
4055-
*this, /*Prefix=*/nullptr, /*Template=*/false,
4056-
Cls->getCanonicalDecl()->getTypeForDecl());
4057-
assert(R == getCanonicalNestedNameSpecifier(R));
4058-
return R;
4059-
}();
40604041
// If the pointee or class type isn't canonical, this won't be a canonical
40614042
// type either, so fill in the canonical type field.
40624043
QualType Canonical;
4063-
if (!T.isCanonical() || Qualifier != CanonicalQualifier) {
4064-
Canonical =
4065-
getMemberPointerType(getCanonicalType(T), CanonicalQualifier, Cls);
4066-
assert(!cast<MemberPointerType>(Canonical)->isSugared());
4044+
if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
4045+
Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
4046+
40674047
// Get the new insert position for the node we care about.
4068-
[[maybe_unused]] MemberPointerType *NewIP =
4069-
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
4070-
assert(!NewIP && "Shouldn't be in the map!");
4048+
MemberPointerType *NewIP =
4049+
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
4050+
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
40714051
}
40724052
auto *New = new (*this, alignof(MemberPointerType))
4073-
MemberPointerType(T, Qualifier, Canonical);
4053+
MemberPointerType(T, Cls, Canonical);
40744054
Types.push_back(New);
40754055
MemberPointerTypes.InsertNode(New, InsertPos);
40764056
return QualType(New, 0);
@@ -6832,16 +6812,11 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,
68326812
return true;
68336813
}
68346814

6835-
if (const auto *T1MPType = T1->getAs<MemberPointerType>(),
6836-
*T2MPType = T2->getAs<MemberPointerType>();
6837-
T1MPType && T2MPType) {
6838-
if (auto *RD1 = T1MPType->getMostRecentCXXRecordDecl(),
6839-
*RD2 = T2MPType->getMostRecentCXXRecordDecl();
6840-
RD1 != RD2 && RD1->getCanonicalDecl() != RD2->getCanonicalDecl())
6841-
return false;
6842-
if (getCanonicalNestedNameSpecifier(T1MPType->getQualifier()) !=
6843-
getCanonicalNestedNameSpecifier(T2MPType->getQualifier()))
6844-
return false;
6815+
const auto *T1MPType = T1->getAs<MemberPointerType>();
6816+
const auto *T2MPType = T2->getAs<MemberPointerType>();
6817+
if (T1MPType && T2MPType &&
6818+
hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
6819+
QualType(T2MPType->getClass(), 0))) {
68456820
T1 = T1MPType->getPointeeType();
68466821
T2 = T2MPType->getPointeeType();
68476822
return true;
@@ -13882,12 +13857,11 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
1388213857
case Type::MemberPointer: {
1388313858
const auto *PX = cast<MemberPointerType>(X),
1388413859
*PY = cast<MemberPointerType>(Y);
13885-
assert(declaresSameEntity(PX->getMostRecentCXXRecordDecl(),
13886-
PY->getMostRecentCXXRecordDecl()));
1388713860
return Ctx.getMemberPointerType(
1388813861
getCommonPointeeType(Ctx, PX, PY),
13889-
getCommonQualifier(Ctx, PX, PY, /*IsSame=*/true),
13890-
PX->getMostRecentCXXRecordDecl());
13862+
Ctx.getCommonSugaredType(QualType(PX->getClass(), 0),
13863+
QualType(PY->getClass(), 0))
13864+
.getTypePtr());
1389113865
}
1389213866
case Type::LValueReference: {
1389313867
const auto *PX = cast<LValueReferenceType>(X),

0 commit comments

Comments
 (0)