-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Revert "[clang] improve class type sugar preservation in pointers to members" #132215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert "[clang] improve class type sugar preservation in pointers to members" #132215
Conversation
…members …" This reverts commit 9b1f905.
@llvm/pr-subscribers-clang-static-analyzer-1 @llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) ChangesReverts llvm/llvm-project#130537 This missed updating lldb, which we didn't notice due to lack of pre-commit CI. Patch is 141.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132215.diff 69 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index a6b00be75abf8..108717e151b57 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -493,7 +493,8 @@ UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NullMacrosStr(Options.get("NullMacros", "NULL")),
IgnoredTypes(utils::options::parseStringList(Options.get(
- "IgnoredTypes", "_CmpUnspecifiedParam;^std::__cmp_cat::__unspec"))) {
+ "IgnoredTypes",
+ "std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec"))) {
StringRef(NullMacrosStr).split(NullMacros, ",");
}
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index bc49fa856bafc..b66cc8512fad6 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -178,9 +178,7 @@ bool isFunctionPointerConvertible(QualType From, QualType To) {
// Note: converting Derived::* to Base::* is a different kind of conversion,
// called Pointer-to-member conversion.
- return FromMember->getQualifier() == ToMember->getQualifier() &&
- FromMember->getMostRecentCXXRecordDecl() ==
- ToMember->getMostRecentCXXRecordDecl() &&
+ return FromMember->getClass() == ToMember->getClass() &&
FromMember->getPointeeType() == ToMember->getPointeeType();
}
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 602f61d9ecb41..fc54f89f4941e 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -1489,7 +1489,7 @@ TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
"4: targets = {a}\n"
"5: targets = {a::b}, qualifier = 'a::'\n"
"6: targets = {a::b::S}\n"
- "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
+ "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
"8: targets = {y}, decl\n"},
{R"cpp(
void foo() {
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 97f6ea90d4705..88862f7661191 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -267,7 +267,6 @@ Improvements to Clang's diagnostics
under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
- Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
``-Wno-error=parentheses``.
-- Clang now better preserves the sugared types of pointers to member.
- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
- Fixed diagnostics adding a trailing ``::`` when printing some source code
constructs, like base classes.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index af8c49e99a7ce..f9a12260a6590 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1558,9 +1558,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getRValueReferenceType(QualType T) const;
/// Return the uniqued reference to the type for a member pointer to
- /// the specified type in the specified nested name.
- QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls) const;
+ /// the specified type in the specified class.
+ ///
+ /// The class \p Cls is a \c Type because it could be a dependent name.
+ QualType getMemberPointerType(QualType T, const Type *Cls) const;
/// Return a non-unique reference to the type for a variable array of
/// the specified element type.
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index f557555e96e59..3bc0bdff2bdd1 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -393,9 +393,7 @@ class ASTNodeTraverser
Visit(T->getPointeeType());
}
void VisitMemberPointerType(const MemberPointerType *T) {
- // FIXME: Provide a NestedNameSpecifier visitor.
- Visit(T->getQualifier()->getAsType());
- Visit(T->getMostRecentCXXRecordDecl());
+ Visit(T->getClass());
Visit(T->getPointeeType());
}
void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
@@ -487,8 +485,7 @@ class ASTNodeTraverser
}
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
- // FIXME: Provide NestedNamespecifierLoc visitor.
- Visit(TL.getQualifierLoc().getTypeLoc());
+ Visit(TL.getClassTInfo()->getTypeLoc());
}
void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
Visit(TL.getSizeExpr());
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 35db68971e029..50d1ba1b8f63f 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -453,7 +453,7 @@ template<>
struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier *, getQualifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
getMostRecentCXXRecordDecl)
};
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index e93d1d8eab56f..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1004,8 +1004,7 @@ DEF_TRAVERSE_TYPE(RValueReferenceType,
{ TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseDecl(T->getMostRecentCXXRecordDecl()));
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
TRY_TO(TraverseType(T->getPointeeType()));
})
@@ -1270,10 +1269,10 @@ DEF_TRAVERSE_TYPELOC(RValueReferenceType,
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
- TRY_TO(TraverseNestedNameSpecifierLoc(QL));
+ if (auto *TSI = TL.getClassTInfo())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
else
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 65756203f2073..3c942f2ed7486 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3527,16 +3527,14 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
/// The class of which the pointee is a member. Must ultimately be a
- /// CXXRecordType, but could be a typedef or a template parameter too.
- NestedNameSpecifier *Qualifier;
+ /// RecordType, but could be a typedef or a template parameter too.
+ const Type *Class;
- MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier,
- QualType CanonicalPtr)
+ MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
: Type(MemberPointer, CanonicalPtr,
- (toTypeDependence(Qualifier->getDependence()) &
- ~TypeDependence::VariablyModified) |
+ (Cls->getDependence() & ~TypeDependence::VariablyModified) |
Pointee->getDependence()),
- PointeeType(Pointee), Qualifier(Qualifier) {}
+ PointeeType(Pointee), Class(Cls) {}
public:
QualType getPointeeType() const { return PointeeType; }
@@ -3553,21 +3551,21 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
return !PointeeType->isFunctionProtoType();
}
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ const Type *getClass() const { return Class; }
CXXRecordDecl *getMostRecentCXXRecordDecl() const;
- bool isSugared() const;
- QualType desugar() const {
- return isSugared() ? getCanonicalTypeInternal() : QualType(this, 0);
- }
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType(), getQualifier(), getMostRecentCXXRecordDecl());
+ Profile(ID, getPointeeType(), getClass());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls);
+ const Type *Class) {
+ ID.AddPointer(Pointee.getAsOpaquePtr());
+ ID.AddPointer(Class);
+ }
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 17ce09fa5da4f..a55a38335ef6a 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -139,7 +139,6 @@ class TypeLoc {
}
/// Get the pointer where source information is stored.
- // FIXME: This should provide a type-safe interface.
void *getOpaqueData() const {
return Data;
}
@@ -1356,7 +1355,7 @@ class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
- void *QualifierData = nullptr;
+ TypeSourceInfo *ClassTInfo;
};
/// Wrapper for source info for member pointers.
@@ -1372,32 +1371,28 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
setSigilLoc(Loc);
}
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
+ const Type *getClass() const {
+ return getTypePtr()->getClass();
}
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier() ==
- getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+ TypeSourceInfo *getClassTInfo() const {
+ return getLocalData()->ClassTInfo;
+ }
+
+ void setClassTInfo(TypeSourceInfo* TI) {
+ getLocalData()->ClassTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
- if (auto *Qualifier = getTypePtr()->getQualifier()) {
- NestedNameSpecifierLocBuilder Builder;
- Builder.MakeTrivial(Context, Qualifier, Loc);
- setQualifierLoc(Builder.getWithLocInContext(Context));
- } else
- getLocalData()->QualifierData = nullptr;
+ setClassTInfo(nullptr);
}
SourceRange getLocalSourceRange() const {
- if (NestedNameSpecifierLoc QL = getQualifierLoc())
- return SourceRange(QL.getBeginLoc(), getStarLoc());
- return SourceRange(getStarLoc());
+ if (TypeSourceInfo *TI = getClassTInfo())
+ return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
+ else
+ return SourceRange(getStarLoc());
}
};
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 27f71bf5cc62f..6f1a76bd18fb5 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -100,15 +100,12 @@ let Class = MemberPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
- def : Property<"Qualifier", NestedNameSpecifier> {
- let Read = [{ node->getQualifier() }];
- }
- def : Property<"Cls", DeclRef> {
- let Read = [{ node->getMostRecentCXXRecordDecl() }];
+ def : Property<"baseType", QualType> {
+ let Read = [{ QualType(node->getClass(), 0) }];
}
def : Creator<[{
- return ctx.getMemberPointerType(pointeeType, Qualifier, cast_or_null<CXXRecordDecl>(Cls));
+ return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
}]>;
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4cb8f3d759817..1536a3b8c920a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7065,8 +7065,10 @@ def err_illegal_decl_mempointer_to_reference : Error<
"'%0' declared as a member pointer to a reference of type %1">;
def err_illegal_decl_mempointer_to_void : Error<
"'%0' declared as a member pointer to void">;
-def err_illegal_decl_mempointer_in_nonclass
- : Error<"'%0' does not point into a class">;
+def err_illegal_decl_mempointer_in_nonclass : Error<
+ "'%0' does not point into a class">;
+def err_mempointer_in_nonclass_type : Error<
+ "member pointer refers into non-class type %0">;
def err_reference_to_void : Error<"cannot form a reference to 'void'">;
def err_nonfunction_block_type : Error<
"block pointer to non-function type is invalid">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e215f07e2bf0a..9724f0def743a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1348,12 +1348,6 @@ class Sema final : public SemaBase {
unsigned DiagID, bool ForceCheck = false,
bool ForceUnprivileged = false);
- AccessResult CheckBaseClassAccess(
- SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
- const CXXBasePath &Path, unsigned DiagID,
- llvm::function_ref<void(PartialDiagnostic &PD)> SetupPDiag,
- bool ForceCheck = false, bool ForceUnprivileged = false);
-
/// Checks access to all the declarations in the given result set.
void CheckLookupAccess(const LookupResult &R);
@@ -14885,9 +14879,8 @@ class Sema final : public SemaBase {
///
/// \returns a member pointer type, if successful, or a NULL type if there was
/// an error.
- QualType BuildMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
- CXXRecordDecl *Cls, SourceLocation Loc,
- DeclarationName Entity);
+ QualType BuildMemberPointerType(QualType T, QualType Class,
+ SourceLocation Loc, DeclarationName Entity);
/// Build a block pointer type.
///
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index de868ac821745..68a02f3bbe1ec 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3322,8 +3322,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
case Type::MemberPointer: {
OS << "M";
const auto *MPT = T->castAs<MemberPointerType>();
- encodeTypeForFunctionPointerAuth(
- Ctx, OS, QualType(MPT->getQualifier()->getAsType(), 0));
+ encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
return;
}
@@ -3512,8 +3511,7 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
if (PointeeType->castAs<FunctionProtoType>()->getExceptionSpecType() !=
EST_None) {
QualType FT = getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
- T = getMemberPointerType(FT, MPT->getQualifier(),
- MPT->getMostRecentCXXRecordDecl());
+ T = getMemberPointerType(FT, MPT->getClass());
}
}
std::unique_ptr<MangleContext> MC(createMangleContext());
@@ -4027,50 +4025,32 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
return QualType(New, 0);
}
-QualType ASTContext::getMemberPointerType(QualType T,
- NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls) const {
- if (!Qualifier) {
- assert(Cls && "At least one of Qualifier or Cls must be provided");
- Qualifier = NestedNameSpecifier::Create(*this, /*Prefix=*/nullptr,
- /*Template=*/false,
- getTypeDeclType(Cls).getTypePtr());
- } else if (!Cls) {
- Cls = Qualifier->getAsRecordDecl();
- }
+/// getMemberPointerType - Return the uniqued reference to the type for a
+/// member pointer to the specified type, in the specified class.
+QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
- MemberPointerType::Profile(ID, T, Qualifier, Cls);
+ MemberPointerType::Profile(ID, T, Cls);
void *InsertPos = nullptr;
if (MemberPointerType *PT =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
- NestedNameSpecifier *CanonicalQualifier = [&] {
- if (!Cls)
- return getCanonicalNestedNameSpecifier(Qualifier);
- NestedNameSpecifier *R = NestedNameSpecifier::Create(
- *this, /*Prefix=*/nullptr, /*Template=*/false,
- Cls->getCanonicalDecl()->getTypeForDecl());
- assert(R == getCanonicalNestedNameSpecifier(R));
- return R;
- }();
// If the pointee or class type isn't canonical, this won't be a canonical
// type either, so fill in the canonical type field.
QualType Canonical;
- if (!T.isCanonical() || Qualifier != CanonicalQualifier) {
- Canonical =
- getMemberPointerType(getCanonicalType(T), CanonicalQualifier, Cls);
- assert(!cast<MemberPointerType>(Canonical)->isSugared());
+ if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
+ Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
+
// Get the new insert position for the node we care about.
- [[maybe_unused]] MemberPointerType *NewIP =
- MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!NewIP && "Shouldn't be in the map!");
+ MemberPointerType *NewIP =
+ MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
auto *New = new (*this, alignof(MemberPointerType))
- MemberPointerType(T, Qualifier, Canonical);
+ MemberPointerType(T, Cls, Canonical);
Types.push_back(New);
MemberPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -6832,16 +6812,11 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,
return true;
}
- if (const auto *T1MPType = T1->getAs<MemberPointerType>(),
- *T2MPType = T2->getAs<MemberPointerType>();
- T1MPType && T2MPType) {
- if (auto *RD1 = T1MPType->getMostRecentCXXRecordDecl(),
- *RD2 = T2MPType->getMostRecentCXXRecordDecl();
- RD1 != RD2 && RD1->getCanonicalDecl() != RD2->getCanonicalDecl())
- return false;
- if (getCanonicalNestedNameSpecifier(T1MPType->getQualifier()) !=
- getCanonicalNestedNameSpecifier(T2MPType->getQualifier()))
- return false;
+ const auto *T1MPType = T1->getAs<MemberPointerType>();
+ const auto *T2MPType = T2->getAs<MemberPointerType>();
+ if (T1MPType && T2MPType &&
+ hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
+ QualType(T2MPType->getClass(), 0))) {
T1 = T1MPType->getPointeeType();
T2 = T2MPType->getPointeeType();
return true;
@@ -13882,12 +13857,11 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
case Type::MemberPointer: {
const auto *PX = cast<MemberPointerType>(X),
*PY = cast<MemberPointerType>(Y);
- assert(declaresSameEntity(PX->getMostRecentCXXRecordDecl(),
- PY->getMostRecentCXXRecordDecl()));
return Ctx.getMemberPointerType(
getCommonPointeeType(Ctx, PX, PY),
- getCommonQualifier(Ctx, PX, PY, /*IsSame=*/true),
- PX->getMostRecentCXXRecordDec...
[truncated]
|
@llvm/pr-subscribers-clang-tidy Author: Matheus Izvekov (mizvekov) ChangesReverts llvm/llvm-project#130537 This missed updating lldb, which we didn't notice due to lack of pre-commit CI. Patch is 141.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132215.diff 69 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index a6b00be75abf8..108717e151b57 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -493,7 +493,8 @@ UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NullMacrosStr(Options.get("NullMacros", "NULL")),
IgnoredTypes(utils::options::parseStringList(Options.get(
- "IgnoredTypes", "_CmpUnspecifiedParam;^std::__cmp_cat::__unspec"))) {
+ "IgnoredTypes",
+ "std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec"))) {
StringRef(NullMacrosStr).split(NullMacros, ",");
}
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index bc49fa856bafc..b66cc8512fad6 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -178,9 +178,7 @@ bool isFunctionPointerConvertible(QualType From, QualType To) {
// Note: converting Derived::* to Base::* is a different kind of conversion,
// called Pointer-to-member conversion.
- return FromMember->getQualifier() == ToMember->getQualifier() &&
- FromMember->getMostRecentCXXRecordDecl() ==
- ToMember->getMostRecentCXXRecordDecl() &&
+ return FromMember->getClass() == ToMember->getClass() &&
FromMember->getPointeeType() == ToMember->getPointeeType();
}
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 602f61d9ecb41..fc54f89f4941e 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -1489,7 +1489,7 @@ TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
"4: targets = {a}\n"
"5: targets = {a::b}, qualifier = 'a::'\n"
"6: targets = {a::b::S}\n"
- "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
+ "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
"8: targets = {y}, decl\n"},
{R"cpp(
void foo() {
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 97f6ea90d4705..88862f7661191 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -267,7 +267,6 @@ Improvements to Clang's diagnostics
under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
- Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
``-Wno-error=parentheses``.
-- Clang now better preserves the sugared types of pointers to member.
- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
- Fixed diagnostics adding a trailing ``::`` when printing some source code
constructs, like base classes.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index af8c49e99a7ce..f9a12260a6590 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1558,9 +1558,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getRValueReferenceType(QualType T) const;
/// Return the uniqued reference to the type for a member pointer to
- /// the specified type in the specified nested name.
- QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls) const;
+ /// the specified type in the specified class.
+ ///
+ /// The class \p Cls is a \c Type because it could be a dependent name.
+ QualType getMemberPointerType(QualType T, const Type *Cls) const;
/// Return a non-unique reference to the type for a variable array of
/// the specified element type.
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index f557555e96e59..3bc0bdff2bdd1 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -393,9 +393,7 @@ class ASTNodeTraverser
Visit(T->getPointeeType());
}
void VisitMemberPointerType(const MemberPointerType *T) {
- // FIXME: Provide a NestedNameSpecifier visitor.
- Visit(T->getQualifier()->getAsType());
- Visit(T->getMostRecentCXXRecordDecl());
+ Visit(T->getClass());
Visit(T->getPointeeType());
}
void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
@@ -487,8 +485,7 @@ class ASTNodeTraverser
}
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
- // FIXME: Provide NestedNamespecifierLoc visitor.
- Visit(TL.getQualifierLoc().getTypeLoc());
+ Visit(TL.getClassTInfo()->getTypeLoc());
}
void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
Visit(TL.getSizeExpr());
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 35db68971e029..50d1ba1b8f63f 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -453,7 +453,7 @@ template<>
struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier *, getQualifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
getMostRecentCXXRecordDecl)
};
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index e93d1d8eab56f..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1004,8 +1004,7 @@ DEF_TRAVERSE_TYPE(RValueReferenceType,
{ TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseDecl(T->getMostRecentCXXRecordDecl()));
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
TRY_TO(TraverseType(T->getPointeeType()));
})
@@ -1270,10 +1269,10 @@ DEF_TRAVERSE_TYPELOC(RValueReferenceType,
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
- TRY_TO(TraverseNestedNameSpecifierLoc(QL));
+ if (auto *TSI = TL.getClassTInfo())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
else
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 65756203f2073..3c942f2ed7486 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3527,16 +3527,14 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
/// The class of which the pointee is a member. Must ultimately be a
- /// CXXRecordType, but could be a typedef or a template parameter too.
- NestedNameSpecifier *Qualifier;
+ /// RecordType, but could be a typedef or a template parameter too.
+ const Type *Class;
- MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier,
- QualType CanonicalPtr)
+ MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
: Type(MemberPointer, CanonicalPtr,
- (toTypeDependence(Qualifier->getDependence()) &
- ~TypeDependence::VariablyModified) |
+ (Cls->getDependence() & ~TypeDependence::VariablyModified) |
Pointee->getDependence()),
- PointeeType(Pointee), Qualifier(Qualifier) {}
+ PointeeType(Pointee), Class(Cls) {}
public:
QualType getPointeeType() const { return PointeeType; }
@@ -3553,21 +3551,21 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
return !PointeeType->isFunctionProtoType();
}
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ const Type *getClass() const { return Class; }
CXXRecordDecl *getMostRecentCXXRecordDecl() const;
- bool isSugared() const;
- QualType desugar() const {
- return isSugared() ? getCanonicalTypeInternal() : QualType(this, 0);
- }
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType(), getQualifier(), getMostRecentCXXRecordDecl());
+ Profile(ID, getPointeeType(), getClass());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls);
+ const Type *Class) {
+ ID.AddPointer(Pointee.getAsOpaquePtr());
+ ID.AddPointer(Class);
+ }
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 17ce09fa5da4f..a55a38335ef6a 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -139,7 +139,6 @@ class TypeLoc {
}
/// Get the pointer where source information is stored.
- // FIXME: This should provide a type-safe interface.
void *getOpaqueData() const {
return Data;
}
@@ -1356,7 +1355,7 @@ class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
- void *QualifierData = nullptr;
+ TypeSourceInfo *ClassTInfo;
};
/// Wrapper for source info for member pointers.
@@ -1372,32 +1371,28 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
setSigilLoc(Loc);
}
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
+ const Type *getClass() const {
+ return getTypePtr()->getClass();
}
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier() ==
- getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+ TypeSourceInfo *getClassTInfo() const {
+ return getLocalData()->ClassTInfo;
+ }
+
+ void setClassTInfo(TypeSourceInfo* TI) {
+ getLocalData()->ClassTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
- if (auto *Qualifier = getTypePtr()->getQualifier()) {
- NestedNameSpecifierLocBuilder Builder;
- Builder.MakeTrivial(Context, Qualifier, Loc);
- setQualifierLoc(Builder.getWithLocInContext(Context));
- } else
- getLocalData()->QualifierData = nullptr;
+ setClassTInfo(nullptr);
}
SourceRange getLocalSourceRange() const {
- if (NestedNameSpecifierLoc QL = getQualifierLoc())
- return SourceRange(QL.getBeginLoc(), getStarLoc());
- return SourceRange(getStarLoc());
+ if (TypeSourceInfo *TI = getClassTInfo())
+ return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
+ else
+ return SourceRange(getStarLoc());
}
};
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 27f71bf5cc62f..6f1a76bd18fb5 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -100,15 +100,12 @@ let Class = MemberPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
- def : Property<"Qualifier", NestedNameSpecifier> {
- let Read = [{ node->getQualifier() }];
- }
- def : Property<"Cls", DeclRef> {
- let Read = [{ node->getMostRecentCXXRecordDecl() }];
+ def : Property<"baseType", QualType> {
+ let Read = [{ QualType(node->getClass(), 0) }];
}
def : Creator<[{
- return ctx.getMemberPointerType(pointeeType, Qualifier, cast_or_null<CXXRecordDecl>(Cls));
+ return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
}]>;
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4cb8f3d759817..1536a3b8c920a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7065,8 +7065,10 @@ def err_illegal_decl_mempointer_to_reference : Error<
"'%0' declared as a member pointer to a reference of type %1">;
def err_illegal_decl_mempointer_to_void : Error<
"'%0' declared as a member pointer to void">;
-def err_illegal_decl_mempointer_in_nonclass
- : Error<"'%0' does not point into a class">;
+def err_illegal_decl_mempointer_in_nonclass : Error<
+ "'%0' does not point into a class">;
+def err_mempointer_in_nonclass_type : Error<
+ "member pointer refers into non-class type %0">;
def err_reference_to_void : Error<"cannot form a reference to 'void'">;
def err_nonfunction_block_type : Error<
"block pointer to non-function type is invalid">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e215f07e2bf0a..9724f0def743a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1348,12 +1348,6 @@ class Sema final : public SemaBase {
unsigned DiagID, bool ForceCheck = false,
bool ForceUnprivileged = false);
- AccessResult CheckBaseClassAccess(
- SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
- const CXXBasePath &Path, unsigned DiagID,
- llvm::function_ref<void(PartialDiagnostic &PD)> SetupPDiag,
- bool ForceCheck = false, bool ForceUnprivileged = false);
-
/// Checks access to all the declarations in the given result set.
void CheckLookupAccess(const LookupResult &R);
@@ -14885,9 +14879,8 @@ class Sema final : public SemaBase {
///
/// \returns a member pointer type, if successful, or a NULL type if there was
/// an error.
- QualType BuildMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
- CXXRecordDecl *Cls, SourceLocation Loc,
- DeclarationName Entity);
+ QualType BuildMemberPointerType(QualType T, QualType Class,
+ SourceLocation Loc, DeclarationName Entity);
/// Build a block pointer type.
///
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index de868ac821745..68a02f3bbe1ec 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3322,8 +3322,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
case Type::MemberPointer: {
OS << "M";
const auto *MPT = T->castAs<MemberPointerType>();
- encodeTypeForFunctionPointerAuth(
- Ctx, OS, QualType(MPT->getQualifier()->getAsType(), 0));
+ encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
return;
}
@@ -3512,8 +3511,7 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
if (PointeeType->castAs<FunctionProtoType>()->getExceptionSpecType() !=
EST_None) {
QualType FT = getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
- T = getMemberPointerType(FT, MPT->getQualifier(),
- MPT->getMostRecentCXXRecordDecl());
+ T = getMemberPointerType(FT, MPT->getClass());
}
}
std::unique_ptr<MangleContext> MC(createMangleContext());
@@ -4027,50 +4025,32 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
return QualType(New, 0);
}
-QualType ASTContext::getMemberPointerType(QualType T,
- NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls) const {
- if (!Qualifier) {
- assert(Cls && "At least one of Qualifier or Cls must be provided");
- Qualifier = NestedNameSpecifier::Create(*this, /*Prefix=*/nullptr,
- /*Template=*/false,
- getTypeDeclType(Cls).getTypePtr());
- } else if (!Cls) {
- Cls = Qualifier->getAsRecordDecl();
- }
+/// getMemberPointerType - Return the uniqued reference to the type for a
+/// member pointer to the specified type, in the specified class.
+QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
- MemberPointerType::Profile(ID, T, Qualifier, Cls);
+ MemberPointerType::Profile(ID, T, Cls);
void *InsertPos = nullptr;
if (MemberPointerType *PT =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
- NestedNameSpecifier *CanonicalQualifier = [&] {
- if (!Cls)
- return getCanonicalNestedNameSpecifier(Qualifier);
- NestedNameSpecifier *R = NestedNameSpecifier::Create(
- *this, /*Prefix=*/nullptr, /*Template=*/false,
- Cls->getCanonicalDecl()->getTypeForDecl());
- assert(R == getCanonicalNestedNameSpecifier(R));
- return R;
- }();
// If the pointee or class type isn't canonical, this won't be a canonical
// type either, so fill in the canonical type field.
QualType Canonical;
- if (!T.isCanonical() || Qualifier != CanonicalQualifier) {
- Canonical =
- getMemberPointerType(getCanonicalType(T), CanonicalQualifier, Cls);
- assert(!cast<MemberPointerType>(Canonical)->isSugared());
+ if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
+ Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
+
// Get the new insert position for the node we care about.
- [[maybe_unused]] MemberPointerType *NewIP =
- MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!NewIP && "Shouldn't be in the map!");
+ MemberPointerType *NewIP =
+ MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
auto *New = new (*this, alignof(MemberPointerType))
- MemberPointerType(T, Qualifier, Canonical);
+ MemberPointerType(T, Cls, Canonical);
Types.push_back(New);
MemberPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -6832,16 +6812,11 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,
return true;
}
- if (const auto *T1MPType = T1->getAs<MemberPointerType>(),
- *T2MPType = T2->getAs<MemberPointerType>();
- T1MPType && T2MPType) {
- if (auto *RD1 = T1MPType->getMostRecentCXXRecordDecl(),
- *RD2 = T2MPType->getMostRecentCXXRecordDecl();
- RD1 != RD2 && RD1->getCanonicalDecl() != RD2->getCanonicalDecl())
- return false;
- if (getCanonicalNestedNameSpecifier(T1MPType->getQualifier()) !=
- getCanonicalNestedNameSpecifier(T2MPType->getQualifier()))
- return false;
+ const auto *T1MPType = T1->getAs<MemberPointerType>();
+ const auto *T2MPType = T2->getAs<MemberPointerType>();
+ if (T1MPType && T2MPType &&
+ hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
+ QualType(T2MPType->getClass(), 0))) {
T1 = T1MPType->getPointeeType();
T2 = T2MPType->getPointeeType();
return true;
@@ -13882,12 +13857,11 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
case Type::MemberPointer: {
const auto *PX = cast<MemberPointerType>(X),
*PY = cast<MemberPointerType>(Y);
- assert(declaresSameEntity(PX->getMostRecentCXXRecordDecl(),
- PY->getMostRecentCXXRecordDecl()));
return Ctx.getMemberPointerType(
getCommonPointeeType(Ctx, PX, PY),
- getCommonQualifier(Ctx, PX, PY, /*IsSame=*/true),
- PX->getMostRecentCXXRecordDec...
[truncated]
|
@llvm/pr-subscribers-clangd Author: Matheus Izvekov (mizvekov) ChangesReverts llvm/llvm-project#130537 This missed updating lldb, which we didn't notice due to lack of pre-commit CI. Patch is 141.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132215.diff 69 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index a6b00be75abf8..108717e151b57 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -493,7 +493,8 @@ UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NullMacrosStr(Options.get("NullMacros", "NULL")),
IgnoredTypes(utils::options::parseStringList(Options.get(
- "IgnoredTypes", "_CmpUnspecifiedParam;^std::__cmp_cat::__unspec"))) {
+ "IgnoredTypes",
+ "std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec"))) {
StringRef(NullMacrosStr).split(NullMacros, ",");
}
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index bc49fa856bafc..b66cc8512fad6 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -178,9 +178,7 @@ bool isFunctionPointerConvertible(QualType From, QualType To) {
// Note: converting Derived::* to Base::* is a different kind of conversion,
// called Pointer-to-member conversion.
- return FromMember->getQualifier() == ToMember->getQualifier() &&
- FromMember->getMostRecentCXXRecordDecl() ==
- ToMember->getMostRecentCXXRecordDecl() &&
+ return FromMember->getClass() == ToMember->getClass() &&
FromMember->getPointeeType() == ToMember->getPointeeType();
}
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 602f61d9ecb41..fc54f89f4941e 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -1489,7 +1489,7 @@ TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
"4: targets = {a}\n"
"5: targets = {a::b}, qualifier = 'a::'\n"
"6: targets = {a::b::S}\n"
- "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
+ "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
"8: targets = {y}, decl\n"},
{R"cpp(
void foo() {
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 97f6ea90d4705..88862f7661191 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -267,7 +267,6 @@ Improvements to Clang's diagnostics
under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
- Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
``-Wno-error=parentheses``.
-- Clang now better preserves the sugared types of pointers to member.
- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
- Fixed diagnostics adding a trailing ``::`` when printing some source code
constructs, like base classes.
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index af8c49e99a7ce..f9a12260a6590 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1558,9 +1558,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getRValueReferenceType(QualType T) const;
/// Return the uniqued reference to the type for a member pointer to
- /// the specified type in the specified nested name.
- QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls) const;
+ /// the specified type in the specified class.
+ ///
+ /// The class \p Cls is a \c Type because it could be a dependent name.
+ QualType getMemberPointerType(QualType T, const Type *Cls) const;
/// Return a non-unique reference to the type for a variable array of
/// the specified element type.
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index f557555e96e59..3bc0bdff2bdd1 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -393,9 +393,7 @@ class ASTNodeTraverser
Visit(T->getPointeeType());
}
void VisitMemberPointerType(const MemberPointerType *T) {
- // FIXME: Provide a NestedNameSpecifier visitor.
- Visit(T->getQualifier()->getAsType());
- Visit(T->getMostRecentCXXRecordDecl());
+ Visit(T->getClass());
Visit(T->getPointeeType());
}
void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
@@ -487,8 +485,7 @@ class ASTNodeTraverser
}
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
- // FIXME: Provide NestedNamespecifierLoc visitor.
- Visit(TL.getQualifierLoc().getTypeLoc());
+ Visit(TL.getClassTInfo()->getTypeLoc());
}
void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
Visit(TL.getSizeExpr());
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 35db68971e029..50d1ba1b8f63f 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -453,7 +453,7 @@ template<>
struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier *, getQualifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
getMostRecentCXXRecordDecl)
};
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index e93d1d8eab56f..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1004,8 +1004,7 @@ DEF_TRAVERSE_TYPE(RValueReferenceType,
{ TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseDecl(T->getMostRecentCXXRecordDecl()));
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
TRY_TO(TraverseType(T->getPointeeType()));
})
@@ -1270,10 +1269,10 @@ DEF_TRAVERSE_TYPELOC(RValueReferenceType,
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
- TRY_TO(TraverseNestedNameSpecifierLoc(QL));
+ if (auto *TSI = TL.getClassTInfo())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
else
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 65756203f2073..3c942f2ed7486 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3527,16 +3527,14 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
/// The class of which the pointee is a member. Must ultimately be a
- /// CXXRecordType, but could be a typedef or a template parameter too.
- NestedNameSpecifier *Qualifier;
+ /// RecordType, but could be a typedef or a template parameter too.
+ const Type *Class;
- MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier,
- QualType CanonicalPtr)
+ MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
: Type(MemberPointer, CanonicalPtr,
- (toTypeDependence(Qualifier->getDependence()) &
- ~TypeDependence::VariablyModified) |
+ (Cls->getDependence() & ~TypeDependence::VariablyModified) |
Pointee->getDependence()),
- PointeeType(Pointee), Qualifier(Qualifier) {}
+ PointeeType(Pointee), Class(Cls) {}
public:
QualType getPointeeType() const { return PointeeType; }
@@ -3553,21 +3551,21 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
return !PointeeType->isFunctionProtoType();
}
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ const Type *getClass() const { return Class; }
CXXRecordDecl *getMostRecentCXXRecordDecl() const;
- bool isSugared() const;
- QualType desugar() const {
- return isSugared() ? getCanonicalTypeInternal() : QualType(this, 0);
- }
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType(), getQualifier(), getMostRecentCXXRecordDecl());
+ Profile(ID, getPointeeType(), getClass());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls);
+ const Type *Class) {
+ ID.AddPointer(Pointee.getAsOpaquePtr());
+ ID.AddPointer(Class);
+ }
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 17ce09fa5da4f..a55a38335ef6a 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -139,7 +139,6 @@ class TypeLoc {
}
/// Get the pointer where source information is stored.
- // FIXME: This should provide a type-safe interface.
void *getOpaqueData() const {
return Data;
}
@@ -1356,7 +1355,7 @@ class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
- void *QualifierData = nullptr;
+ TypeSourceInfo *ClassTInfo;
};
/// Wrapper for source info for member pointers.
@@ -1372,32 +1371,28 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
setSigilLoc(Loc);
}
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
+ const Type *getClass() const {
+ return getTypePtr()->getClass();
}
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier() ==
- getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+ TypeSourceInfo *getClassTInfo() const {
+ return getLocalData()->ClassTInfo;
+ }
+
+ void setClassTInfo(TypeSourceInfo* TI) {
+ getLocalData()->ClassTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
- if (auto *Qualifier = getTypePtr()->getQualifier()) {
- NestedNameSpecifierLocBuilder Builder;
- Builder.MakeTrivial(Context, Qualifier, Loc);
- setQualifierLoc(Builder.getWithLocInContext(Context));
- } else
- getLocalData()->QualifierData = nullptr;
+ setClassTInfo(nullptr);
}
SourceRange getLocalSourceRange() const {
- if (NestedNameSpecifierLoc QL = getQualifierLoc())
- return SourceRange(QL.getBeginLoc(), getStarLoc());
- return SourceRange(getStarLoc());
+ if (TypeSourceInfo *TI = getClassTInfo())
+ return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
+ else
+ return SourceRange(getStarLoc());
}
};
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 27f71bf5cc62f..6f1a76bd18fb5 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -100,15 +100,12 @@ let Class = MemberPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
- def : Property<"Qualifier", NestedNameSpecifier> {
- let Read = [{ node->getQualifier() }];
- }
- def : Property<"Cls", DeclRef> {
- let Read = [{ node->getMostRecentCXXRecordDecl() }];
+ def : Property<"baseType", QualType> {
+ let Read = [{ QualType(node->getClass(), 0) }];
}
def : Creator<[{
- return ctx.getMemberPointerType(pointeeType, Qualifier, cast_or_null<CXXRecordDecl>(Cls));
+ return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
}]>;
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4cb8f3d759817..1536a3b8c920a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7065,8 +7065,10 @@ def err_illegal_decl_mempointer_to_reference : Error<
"'%0' declared as a member pointer to a reference of type %1">;
def err_illegal_decl_mempointer_to_void : Error<
"'%0' declared as a member pointer to void">;
-def err_illegal_decl_mempointer_in_nonclass
- : Error<"'%0' does not point into a class">;
+def err_illegal_decl_mempointer_in_nonclass : Error<
+ "'%0' does not point into a class">;
+def err_mempointer_in_nonclass_type : Error<
+ "member pointer refers into non-class type %0">;
def err_reference_to_void : Error<"cannot form a reference to 'void'">;
def err_nonfunction_block_type : Error<
"block pointer to non-function type is invalid">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e215f07e2bf0a..9724f0def743a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1348,12 +1348,6 @@ class Sema final : public SemaBase {
unsigned DiagID, bool ForceCheck = false,
bool ForceUnprivileged = false);
- AccessResult CheckBaseClassAccess(
- SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
- const CXXBasePath &Path, unsigned DiagID,
- llvm::function_ref<void(PartialDiagnostic &PD)> SetupPDiag,
- bool ForceCheck = false, bool ForceUnprivileged = false);
-
/// Checks access to all the declarations in the given result set.
void CheckLookupAccess(const LookupResult &R);
@@ -14885,9 +14879,8 @@ class Sema final : public SemaBase {
///
/// \returns a member pointer type, if successful, or a NULL type if there was
/// an error.
- QualType BuildMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
- CXXRecordDecl *Cls, SourceLocation Loc,
- DeclarationName Entity);
+ QualType BuildMemberPointerType(QualType T, QualType Class,
+ SourceLocation Loc, DeclarationName Entity);
/// Build a block pointer type.
///
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index de868ac821745..68a02f3bbe1ec 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3322,8 +3322,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
case Type::MemberPointer: {
OS << "M";
const auto *MPT = T->castAs<MemberPointerType>();
- encodeTypeForFunctionPointerAuth(
- Ctx, OS, QualType(MPT->getQualifier()->getAsType(), 0));
+ encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
return;
}
@@ -3512,8 +3511,7 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
if (PointeeType->castAs<FunctionProtoType>()->getExceptionSpecType() !=
EST_None) {
QualType FT = getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
- T = getMemberPointerType(FT, MPT->getQualifier(),
- MPT->getMostRecentCXXRecordDecl());
+ T = getMemberPointerType(FT, MPT->getClass());
}
}
std::unique_ptr<MangleContext> MC(createMangleContext());
@@ -4027,50 +4025,32 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
return QualType(New, 0);
}
-QualType ASTContext::getMemberPointerType(QualType T,
- NestedNameSpecifier *Qualifier,
- const CXXRecordDecl *Cls) const {
- if (!Qualifier) {
- assert(Cls && "At least one of Qualifier or Cls must be provided");
- Qualifier = NestedNameSpecifier::Create(*this, /*Prefix=*/nullptr,
- /*Template=*/false,
- getTypeDeclType(Cls).getTypePtr());
- } else if (!Cls) {
- Cls = Qualifier->getAsRecordDecl();
- }
+/// getMemberPointerType - Return the uniqued reference to the type for a
+/// member pointer to the specified type, in the specified class.
+QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
- MemberPointerType::Profile(ID, T, Qualifier, Cls);
+ MemberPointerType::Profile(ID, T, Cls);
void *InsertPos = nullptr;
if (MemberPointerType *PT =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
- NestedNameSpecifier *CanonicalQualifier = [&] {
- if (!Cls)
- return getCanonicalNestedNameSpecifier(Qualifier);
- NestedNameSpecifier *R = NestedNameSpecifier::Create(
- *this, /*Prefix=*/nullptr, /*Template=*/false,
- Cls->getCanonicalDecl()->getTypeForDecl());
- assert(R == getCanonicalNestedNameSpecifier(R));
- return R;
- }();
// If the pointee or class type isn't canonical, this won't be a canonical
// type either, so fill in the canonical type field.
QualType Canonical;
- if (!T.isCanonical() || Qualifier != CanonicalQualifier) {
- Canonical =
- getMemberPointerType(getCanonicalType(T), CanonicalQualifier, Cls);
- assert(!cast<MemberPointerType>(Canonical)->isSugared());
+ if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
+ Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
+
// Get the new insert position for the node we care about.
- [[maybe_unused]] MemberPointerType *NewIP =
- MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!NewIP && "Shouldn't be in the map!");
+ MemberPointerType *NewIP =
+ MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
auto *New = new (*this, alignof(MemberPointerType))
- MemberPointerType(T, Qualifier, Canonical);
+ MemberPointerType(T, Cls, Canonical);
Types.push_back(New);
MemberPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -6832,16 +6812,11 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,
return true;
}
- if (const auto *T1MPType = T1->getAs<MemberPointerType>(),
- *T2MPType = T2->getAs<MemberPointerType>();
- T1MPType && T2MPType) {
- if (auto *RD1 = T1MPType->getMostRecentCXXRecordDecl(),
- *RD2 = T2MPType->getMostRecentCXXRecordDecl();
- RD1 != RD2 && RD1->getCanonicalDecl() != RD2->getCanonicalDecl())
- return false;
- if (getCanonicalNestedNameSpecifier(T1MPType->getQualifier()) !=
- getCanonicalNestedNameSpecifier(T2MPType->getQualifier()))
- return false;
+ const auto *T1MPType = T1->getAs<MemberPointerType>();
+ const auto *T2MPType = T2->getAs<MemberPointerType>();
+ if (T1MPType && T2MPType &&
+ hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
+ QualType(T2MPType->getClass(), 0))) {
T1 = T1MPType->getPointeeType();
T2 = T2MPType->getPointeeType();
return true;
@@ -13882,12 +13857,11 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
case Type::MemberPointer: {
const auto *PX = cast<MemberPointerType>(X),
*PY = cast<MemberPointerType>(Y);
- assert(declaresSameEntity(PX->getMostRecentCXXRecordDecl(),
- PY->getMostRecentCXXRecordDecl()));
return Ctx.getMemberPointerType(
getCommonPointeeType(Ctx, PX, PY),
- getCommonQualifier(Ctx, PX, PY, /*IsSame=*/true),
- PX->getMostRecentCXXRecordDec...
[truncated]
|
This is unfortunate, because lack of lldb testing on clang changes was a temporary measure that has been in effect for 8 months at this point (#95537). |
Reverts #130537
This missed updating lldb, which we didn't notice due to lack of pre-commit CI.