aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp3
-rw-r--r--clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp4
-rw-r--r--clang-tools-extra/clangd/unittests/FindTargetTests.cpp2
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/include/clang/AST/ASTContext.h7
-rw-r--r--clang/include/clang/AST/ASTNodeTraverser.h7
-rw-r--r--clang/include/clang/AST/CanonicalType.h2
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h9
-rw-r--r--clang/include/clang/AST/Type.h28
-rw-r--r--clang/include/clang/AST/TypeLoc.h33
-rw-r--r--clang/include/clang/AST/TypeProperties.td9
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td6
-rw-r--r--clang/include/clang/Sema/Sema.h11
-rw-r--r--clang/lib/AST/ASTContext.cpp68
-rw-r--r--clang/lib/AST/ASTImporter.cpp14
-rw-r--r--clang/lib/AST/ASTStructuralEquivalence.cpp8
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp11
-rw-r--r--clang/lib/AST/NestedNameSpecifier.cpp1
-rw-r--r--clang/lib/AST/ODRHash.cpp2
-rw-r--r--clang/lib/AST/QualTypeNames.cpp7
-rw-r--r--clang/lib/AST/Type.cpp34
-rw-r--r--clang/lib/AST/TypePrinter.cpp4
-rw-r--r--clang/lib/CodeGen/CGCXXABI.cpp2
-rw-r--r--clang/lib/CodeGen/CGPointerAuth.cpp4
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp10
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp7
-rw-r--r--clang/lib/Sema/SemaAccess.cpp26
-rw-r--r--clang/lib/Sema/SemaCast.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp10
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp4
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp5
-rw-r--r--clang/lib/Sema/SemaOverload.cpp87
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp21
-rw-r--r--clang/lib/Sema/SemaType.cpp122
-rw-r--r--clang/lib/Sema/TreeTransform.h59
-rw-r--r--clang/lib/Serialization/ASTReader.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp2
-rw-r--r--clang/lib/Serialization/TemplateArgumentHasher.cpp4
-rw-r--r--clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp4
-rw-r--r--clang/test/AST/ast-dump-templates.cpp238
-rw-r--r--clang/test/AST/ast-dump-types-json.cpp382
-rw-r--r--clang/test/AST/attr-print-emit.cpp2
-rw-r--r--clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp10
-rw-r--r--clang/test/CXX/class.access/p6.cpp4
-rw-r--r--clang/test/CXX/drs/cwg0xx.cpp12
-rw-r--r--clang/test/CXX/drs/cwg13xx.cpp4
-rw-r--r--clang/test/CXX/drs/cwg26xx.cpp6
-rw-r--r--clang/test/CXX/drs/cwg2xx.cpp4
-rw-r--r--clang/test/CXX/drs/cwg4xx.cpp2
-rw-r--r--clang/test/CXX/drs/cwg7xx.cpp3
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp2
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp6
-rw-r--r--clang/test/Index/print-type.cpp2
-rw-r--r--clang/test/SemaCXX/addr-of-overloaded-function.cpp26
-rw-r--r--clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp4
-rw-r--r--clang/test/SemaCXX/calling-conv-compat.cpp42
-rw-r--r--clang/test/SemaCXX/err_init_conversion_failed.cpp2
-rw-r--r--clang/test/SemaCXX/member-pointer.cpp17
-rw-r--r--clang/test/SemaOpenACC/combined-construct-if-ast.cpp4
-rw-r--r--clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp4
-rw-r--r--clang/test/SemaOpenACC/compute-construct-clause-ast.cpp4
-rw-r--r--clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp4
-rw-r--r--clang/test/SemaOpenACC/data-construct-if-ast.cpp4
-rw-r--r--clang/test/SemaTemplate/instantiate-member-pointers.cpp3
-rw-r--r--clang/tools/libclang/CXType.cpp4
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp8
69 files changed, 1039 insertions, 423 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index 108717e..a6b00be 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -493,8 +493,7 @@ UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NullMacrosStr(Options.get("NullMacros", "NULL")),
IgnoredTypes(utils::options::parseStringList(Options.get(
- "IgnoredTypes",
- "std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec"))) {
+ "IgnoredTypes", "_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 b66cc85..bc49fa8 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -178,7 +178,9 @@ bool isFunctionPointerConvertible(QualType From, QualType To) {
// Note: converting Derived::* to Base::* is a different kind of conversion,
// called Pointer-to-member conversion.
- return FromMember->getClass() == ToMember->getClass() &&
+ return FromMember->getQualifier() == ToMember->getQualifier() &&
+ FromMember->getMostRecentCXXRecordDecl() ==
+ ToMember->getMostRecentCXXRecordDecl() &&
FromMember->getPointeeType() == ToMember->getPointeeType();
}
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index fc54f89..602f61d 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 = 'struct S::'\n"
+ "7: targets = {a::b::S::type}, qualifier = 'S::'\n"
"8: targets = {y}, decl\n"},
{R"cpp(
void foo() {
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88862f76..97f6ea90 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -267,6 +267,7 @@ 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 f9a1226..af8c49e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1558,10 +1558,9 @@ public:
QualType getRValueReferenceType(QualType T) const;
/// Return the uniqued reference to the type for a member pointer to
- /// 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;
+ /// the specified type in the specified nested name.
+ QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
+ const CXXRecordDecl *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 3bc0bdf..f557555 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -393,7 +393,9 @@ public:
Visit(T->getPointeeType());
}
void VisitMemberPointerType(const MemberPointerType *T) {
- Visit(T->getClass());
+ // FIXME: Provide a NestedNameSpecifier visitor.
+ Visit(T->getQualifier()->getAsType());
+ Visit(T->getMostRecentCXXRecordDecl());
Visit(T->getPointeeType());
}
void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
@@ -485,7 +487,8 @@ public:
}
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
- Visit(TL.getClassTInfo()->getTypeLoc());
+ // FIXME: Provide NestedNamespecifierLoc visitor.
+ Visit(TL.getQualifierLoc().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 50d1ba1..35db689 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(const Type *, getClass)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier *, getQualifier)
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 87a6c22..e93d1d8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1004,7 +1004,8 @@ DEF_TRAVERSE_TYPE(RValueReferenceType,
{ TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseDecl(T->getMostRecentCXXRecordDecl()));
TRY_TO(TraverseType(T->getPointeeType()));
})
@@ -1269,10 +1270,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 (auto *TSI = TL.getClassTInfo())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+ if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
+ TRY_TO(TraverseNestedNameSpecifierLoc(QL));
else
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+ TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 3c942f2..6575620 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3527,14 +3527,16 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
/// The class of which the pointee is a member. Must ultimately be a
- /// RecordType, but could be a typedef or a template parameter too.
- const Type *Class;
+ /// CXXRecordType, but could be a typedef or a template parameter too.
+ NestedNameSpecifier *Qualifier;
- MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
+ MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier,
+ QualType CanonicalPtr)
: Type(MemberPointer, CanonicalPtr,
- (Cls->getDependence() & ~TypeDependence::VariablyModified) |
+ (toTypeDependence(Qualifier->getDependence()) &
+ ~TypeDependence::VariablyModified) |
Pointee->getDependence()),
- PointeeType(Pointee), Class(Cls) {}
+ PointeeType(Pointee), Qualifier(Qualifier) {}
public:
QualType getPointeeType() const { return PointeeType; }
@@ -3551,21 +3553,21 @@ public:
return !PointeeType->isFunctionProtoType();
}
- const Type *getClass() const { return Class; }
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
CXXRecordDecl *getMostRecentCXXRecordDecl() const;
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
+ bool isSugared() const;
+ QualType desugar() const {
+ return isSugared() ? getCanonicalTypeInternal() : QualType(this, 0);
+ }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType(), getClass());
+ Profile(ID, getPointeeType(), getQualifier(), getMostRecentCXXRecordDecl());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const Type *Class) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- ID.AddPointer(Class);
- }
+ const NestedNameSpecifier *Qualifier,
+ const CXXRecordDecl *Cls);
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 a55a3833..17ce09f 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -139,6 +139,7 @@ public:
}
/// Get the pointer where source information is stored.
+ // FIXME: This should provide a type-safe interface.
void *getOpaqueData() const {
return Data;
}
@@ -1355,7 +1356,7 @@ public:
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
- TypeSourceInfo *ClassTInfo;
+ void *QualifierData = nullptr;
};
/// Wrapper for source info for member pointers.
@@ -1371,28 +1372,32 @@ public:
setSigilLoc(Loc);
}
- const Type *getClass() const {
- return getTypePtr()->getClass();
- }
-
- TypeSourceInfo *getClassTInfo() const {
- return getLocalData()->ClassTInfo;
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData);
}
- void setClassTInfo(TypeSourceInfo* TI) {
- getLocalData()->ClassTInfo = TI;
+ void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ getTypePtr()->getQualifier() &&
+ "Inconsistent nested-name-specifier pointer");
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
- setClassTInfo(nullptr);
+ if (auto *Qualifier = getTypePtr()->getQualifier()) {
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(Context, Qualifier, Loc);
+ setQualifierLoc(Builder.getWithLocInContext(Context));
+ } else
+ getLocalData()->QualifierData = nullptr;
}
SourceRange getLocalSourceRange() const {
- if (TypeSourceInfo *TI = getClassTInfo())
- return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
- else
- return SourceRange(getStarLoc());
+ if (NestedNameSpecifierLoc QL = getQualifierLoc())
+ return SourceRange(QL.getBeginLoc(), getStarLoc());
+ return SourceRange(getStarLoc());
}
};
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 6f1a76b..27f71bf 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -100,12 +100,15 @@ let Class = MemberPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
- def : Property<"baseType", QualType> {
- let Read = [{ QualType(node->getClass(), 0) }];
+ def : Property<"Qualifier", NestedNameSpecifier> {
+ let Read = [{ node->getQualifier() }];
+ }
+ def : Property<"Cls", DeclRef> {
+ let Read = [{ node->getMostRecentCXXRecordDecl() }];
}
def : Creator<[{
- return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
+ return ctx.getMemberPointerType(pointeeType, Qualifier, cast_or_null<CXXRecordDecl>(Cls));
}]>;
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1536a3b..4cb8f3d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7065,10 +7065,8 @@ 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_mempointer_in_nonclass_type : Error<
- "member pointer refers into non-class type %0">;
+def err_illegal_decl_mempointer_in_nonclass
+ : Error<"'%0' does not point into a class">;
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 9724f0d..e215f07 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1348,6 +1348,12 @@ public:
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);
@@ -14879,8 +14885,9 @@ public:
///
/// \returns a member pointer type, if successful, or a NULL type if there was
/// an error.
- QualType BuildMemberPointerType(QualType T, QualType Class,
- SourceLocation Loc, DeclarationName Entity);
+ QualType BuildMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
+ CXXRecordDecl *Cls, SourceLocation Loc,
+ DeclarationName Entity);
/// Build a block pointer type.
///
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 68a02f3..de868ac 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3322,7 +3322,8 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
case Type::MemberPointer: {
OS << "M";
const auto *MPT = T->castAs<MemberPointerType>();
- encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
+ encodeTypeForFunctionPointerAuth(
+ Ctx, OS, QualType(MPT->getQualifier()->getAsType(), 0));
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
return;
}
@@ -3511,7 +3512,8 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
if (PointeeType->castAs<FunctionProtoType>()->getExceptionSpecType() !=
EST_None) {
QualType FT = getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
- T = getMemberPointerType(FT, MPT->getClass());
+ T = getMemberPointerType(FT, MPT->getQualifier(),
+ MPT->getMostRecentCXXRecordDecl());
}
}
std::unique_ptr<MangleContext> MC(createMangleContext());
@@ -4025,32 +4027,50 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
return QualType(New, 0);
}
-/// 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 {
+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();
+ }
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
- MemberPointerType::Profile(ID, T, Cls);
+ MemberPointerType::Profile(ID, T, Qualifier, 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() || !Cls->isCanonicalUnqualified()) {
- Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
-
+ if (!T.isCanonical() || Qualifier != CanonicalQualifier) {
+ Canonical =
+ getMemberPointerType(getCanonicalType(T), CanonicalQualifier, Cls);
+ assert(!cast<MemberPointerType>(Canonical)->isSugared());
// Get the new insert position for the node we care about.
- MemberPointerType *NewIP =
- MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
+ [[maybe_unused]] MemberPointerType *NewIP =
+ MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!NewIP && "Shouldn't be in the map!");
}
auto *New = new (*this, alignof(MemberPointerType))
- MemberPointerType(T, Cls, Canonical);
+ MemberPointerType(T, Qualifier, Canonical);
Types.push_back(New);
MemberPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -6812,11 +6832,16 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,
return true;
}
- const auto *T1MPType = T1->getAs<MemberPointerType>();
- const auto *T2MPType = T2->getAs<MemberPointerType>();
- if (T1MPType && T2MPType &&
- hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
- QualType(T2MPType->getClass(), 0))) {
+ 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;
T1 = T1MPType->getPointeeType();
T2 = T2MPType->getPointeeType();
return true;
@@ -13857,11 +13882,12 @@ 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),
- Ctx.getCommonSugaredType(QualType(PX->getClass(), 0),
- QualType(PY->getClass(), 0))
- .getTypePtr());
+ getCommonQualifier(Ctx, PX, PY, /*IsSame=*/true),
+ PX->getMostRecentCXXRecordDecl());
}
case Type::LValueReference: {
const auto *PX = cast<LValueReferenceType>(X),
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 514887a..1db30b3 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1244,12 +1244,16 @@ ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
if (!ToPointeeTypeOrErr)
return ToPointeeTypeOrErr.takeError();
- ExpectedTypePtr ClassTypeOrErr = import(T->getClass());
- if (!ClassTypeOrErr)
- return ClassTypeOrErr.takeError();
+ auto QualifierOrErr = import(T->getQualifier());
+ if (!QualifierOrErr)
+ return QualifierOrErr.takeError();
- return Importer.getToContext().getMemberPointerType(*ToPointeeTypeOrErr,
- *ClassTypeOrErr);
+ auto ClsOrErr = import(T->getMostRecentCXXRecordDecl());
+ if (!ClsOrErr)
+ return ClsOrErr.takeError();
+
+ return Importer.getToContext().getMemberPointerType(
+ *ToPointeeTypeOrErr, *QualifierOrErr, *ClsOrErr);
}
ExpectedType
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index b74f67f..2c2c8fd 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -894,8 +894,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, MemPtr1->getPointeeType(),
MemPtr2->getPointeeType()))
return false;
- if (!IsStructurallyEquivalent(Context, QualType(MemPtr1->getClass(), 0),
- QualType(MemPtr2->getClass(), 0)))
+ if (!IsStructurallyEquivalent(Context, MemPtr1->getQualifier(),
+ MemPtr2->getQualifier()))
+ return false;
+ if (!IsStructurallyEquivalent(Context,
+ MemPtr1->getMostRecentCXXRecordDecl(),
+ MemPtr2->getMostRecentCXXRecordDecl()))
return false;
break;
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index c79f3e2..9174025 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3828,7 +3828,16 @@ void CXXNameMangler::mangleType(const IncompleteArrayType *T) {
// <pointer-to-member-type> ::= M <class type> <member type>
void CXXNameMangler::mangleType(const MemberPointerType *T) {
Out << 'M';
- mangleType(QualType(T->getClass(), 0));
+ if (auto *RD = T->getMostRecentCXXRecordDecl()) {
+ mangleCXXRecordDecl(RD);
+ } else {
+ NestedNameSpecifier *NNS = T->getQualifier();
+ if (auto *II = NNS->getAsIdentifier())
+ mangleType(getASTContext().getDependentNameType(
+ ElaboratedTypeKeyword::None, NNS->getPrefix(), II));
+ else
+ manglePrefix(NNS);
+ }
QualType PointeeType = T->getPointeeType();
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
mangleType(FPT);
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index 593f2fc..a256a87 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -297,6 +297,7 @@ void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
PrintingPolicy InnerPolicy(Policy);
InnerPolicy.SuppressScope = true;
+ InnerPolicy.SuppressTagKeyword = true;
// Nested-name-specifiers are intended to contain minimally-qualified
// types. An actual ElaboratedType will not occur, since we'll store
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 7c5c287..4c428cc 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -1076,7 +1076,7 @@ public:
void VisitMemberPointerType(const MemberPointerType *T) {
AddQualType(T->getPointeeType());
- AddType(T->getClass());
+ AddNestedNameSpecifier(T->getQualifier());
VisitType(T);
}
diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp
index e4d2a69..3c814b7 100644
--- a/clang/lib/AST/QualTypeNames.cpp
+++ b/clang/lib/AST/QualTypeNames.cpp
@@ -391,9 +391,10 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
Qualifiers Quals = QT.getQualifiers();
// Fully qualify the pointee and class types.
QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
- QualType Class = getFullyQualifiedType(QualType(MPT->getClass(), 0), Ctx,
- WithGlobalNsPrefix);
- QT = Ctx.getMemberPointerType(QT, Class.getTypePtr());
+ NestedNameSpecifier *Qualifier = getFullyQualifiedNestedNameSpecifier(
+ Ctx, MPT->getQualifier(), WithGlobalNsPrefix);
+ QT = Ctx.getMemberPointerType(QT, Qualifier,
+ MPT->getMostRecentCXXRecordDecl());
// Add back the qualifiers.
QT = Ctx.getQualifiedType(QT, Quals);
return QT;
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 33e7008..dee1cb8 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1068,7 +1068,8 @@ public:
if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
return QualType(T, 0);
- return Ctx.getMemberPointerType(pointeeType, T->getClass());
+ return Ctx.getMemberPointerType(pointeeType, T->getQualifier(),
+ T->getMostRecentCXXRecordDecl());
}
QualType VisitConstantArrayType(const ConstantArrayType *T) {
@@ -4621,8 +4622,15 @@ static CachedProperties computeCachedProperties(const Type *T) {
return Cache::get(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
const auto *MPT = cast<MemberPointerType>(T);
- return merge(Cache::get(MPT->getClass()),
- Cache::get(MPT->getPointeeType()));
+ CachedProperties Cls = [&] {
+ if (auto *RD = MPT->getMostRecentCXXRecordDecl())
+ return Cache::get(QualType(RD->getTypeForDecl(), 0));
+ if (const Type *T = MPT->getQualifier()->getAsType())
+ return Cache::get(T);
+ // Treat as a dependent type.
+ return CachedProperties(Linkage::External, false);
+ }();
+ return merge(Cls, Cache::get(MPT->getPointeeType()));
}
case Type::ConstantArray:
case Type::IncompleteArray:
@@ -5177,8 +5185,26 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
return DK_none;
}
+bool MemberPointerType::isSugared() const {
+ CXXRecordDecl *D1 = getMostRecentCXXRecordDecl(),
+ *D2 = getQualifier()->getAsRecordDecl();
+ assert(!D1 == !D2);
+ return D1 != D2 && D1->getCanonicalDecl() != D2->getCanonicalDecl();
+}
+
+void MemberPointerType::Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
+ const NestedNameSpecifier *Qualifier,
+ const CXXRecordDecl *Cls) {
+ ID.AddPointer(Pointee.getAsOpaquePtr());
+ ID.AddPointer(Qualifier);
+ if (Cls)
+ ID.AddPointer(Cls->getCanonicalDecl());
+}
+
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
- auto *RD = getClass()->getAsCXXRecordDecl();
+ auto *RD = dyn_cast<MemberPointerType>(getCanonicalTypeInternal())
+ ->getQualifier()
+ ->getAsRecordDecl();
if (!RD)
return nullptr;
return RD->getMostRecentNonInjectedDecl();
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index dfd1959..3982ca3 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -505,9 +505,9 @@ void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
PrintingPolicy InnerPolicy(Policy);
InnerPolicy.IncludeTagDefinition = false;
- TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
+ T->getQualifier()->print(OS, InnerPolicy);
- OS << "::*";
+ OS << "*";
}
void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 2777c78d..fd35f2a 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -107,7 +107,7 @@ CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
return GetBogusMemberPointer(CGM.getContext().getMemberPointerType(
- MD->getType(), MD->getParent()->getTypeForDecl()));
+ MD->getType(), /*Qualifier=*/nullptr, MD->getParent()));
}
llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index 0c63b9d..4b03230 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -394,8 +394,8 @@ llvm::Constant *CodeGenModule::getMemberFunctionPointer(llvm::Constant *Pointer,
llvm::Constant *CodeGenModule::getMemberFunctionPointer(const FunctionDecl *FD,
llvm::Type *Ty) {
QualType FT = FD->getType();
- FT = getContext().getMemberPointerType(
- FT, cast<CXXMethodDecl>(FD)->getParent()->getTypeForDecl());
+ FT = getContext().getMemberPointerType(FT, /*Qualifier=*/nullptr,
+ cast<CXXMethodDecl>(FD)->getParent());
return getMemberFunctionPointer(getRawFunctionPointer(FD, Ty), FT);
}
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index c910893..c7b3695 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -1400,9 +1400,8 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer)
continue;
llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
- Context.getMemberPointerType(
- Comps[I].getFunctionDecl()->getType(),
- Context.getRecordType(AP.Base).getTypePtr()));
+ Context.getMemberPointerType(Comps[I].getFunctionDecl()->getType(),
+ /*Qualifier=*/nullptr, AP.Base));
VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index f88d620..e26c6c3 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2667,7 +2667,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
for (const CXXRecordDecl *Base : getMostBaseClasses(MD->getParent())) {
llvm::Metadata *Id =
CreateMetadataIdentifierForType(Context.getMemberPointerType(
- MD->getType(), Context.getRecordType(Base).getTypePtr()));
+ MD->getType(), /*Qualifier=*/nullptr, Base));
F->addTypeMetadata(0, Id);
}
}
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index a5633f6..77e995b 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -810,9 +810,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
llvm::Value *Bit = Builder.getFalse();
for (const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
- getContext().getMemberPointerType(
- MPT->getPointeeType(),
- getContext().getRecordType(Base).getTypePtr()));
+ getContext().getMemberPointerType(MPT->getPointeeType(),
+ /*Qualifier=*/nullptr,
+ Base->getCanonicalDecl()));
llvm::Value *TypeId =
llvm::MetadataAsValue::get(CGF.getLLVMContext(), MD);
@@ -1220,7 +1220,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
QualType SrcType = getContext().getMemberPointerType(
- MD->getType(), MD->getParent()->getTypeForDecl());
+ MD->getType(), /*Qualifier=*/nullptr, MD->getParent());
return pointerAuthResignMemberFunctionPointer(Src, MPType, SrcType, CGM);
}
@@ -5135,7 +5135,7 @@ ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD) {
.getDecl());
llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
QualType funcType = CGM.getContext().getMemberPointerType(
- MD->getType(), MD->getParent()->getTypeForDecl());
+ MD->getType(), /*Qualifier=*/nullptr, MD->getParent());
return CGM.getMemberFunctionPointer(thunk, funcType);
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 5cb742a..40371d9 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -2928,9 +2928,9 @@ llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
if (!MemberPointerPath.empty()) {
const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
- const Type *SrcRecTy = Ctx.getTypeDeclType(SrcRD).getTypePtr();
const MemberPointerType *SrcTy =
- Ctx.getMemberPointerType(DstTy->getPointeeType(), SrcRecTy)
+ Ctx.getMemberPointerType(DstTy->getPointeeType(), /*Qualifier=*/nullptr,
+ SrcRD)
->castAs<MemberPointerType>();
bool DerivedMember = MP.isMemberPointerToDerivedMember();
@@ -3945,7 +3945,8 @@ static QualType decomposeTypeForEH(ASTContext &Context, QualType T,
// for "int A::*" and separately storing the const qualifier.
if (const auto *MPTy = T->getAs<MemberPointerType>())
T = Context.getMemberPointerType(PointeeType.getUnqualifiedType(),
- MPTy->getClass());
+ MPTy->getQualifier(),
+ MPTy->getMostRecentCXXRecordDecl());
// Pointer types like "const int * const *" are represented by having RTTI
// for "const int **" and separately storing the const qualifier.
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 4ba46a9..b77cbdb 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -1873,21 +1873,20 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
return CheckAccess(*this, Ovl->getNameLoc(), Entity);
}
-Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
- QualType Base, QualType Derived,
- const CXXBasePath &Path,
- unsigned DiagID, bool ForceCheck,
- bool ForceUnprivileged) {
+Sema::AccessResult Sema::CheckBaseClassAccess(
+ SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
+ const CXXBasePath &Path, unsigned DiagID,
+ llvm::function_ref<void(PartialDiagnostic &)> SetupPDiag, bool ForceCheck,
+ bool ForceUnprivileged) {
if (!ForceCheck && !getLangOpts().AccessControl)
return AR_accessible;
if (Path.Access == AS_public)
return AR_accessible;
- AccessTarget Entity(Context, AccessTarget::Base, Base->getAsCXXRecordDecl(),
- Derived->getAsCXXRecordDecl(), Path.Access);
+ AccessTarget Entity(Context, AccessTarget::Base, Base, Derived, Path.Access);
if (DiagID)
- Entity.setDiag(DiagID) << Derived << Base;
+ SetupPDiag(Entity.setDiag(DiagID));
if (ForceUnprivileged) {
switch (
@@ -1904,6 +1903,17 @@ Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
return CheckAccess(*this, AccessLoc, Entity);
}
+Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
+ QualType Base, QualType Derived,
+ const CXXBasePath &Path,
+ unsigned DiagID, bool ForceCheck,
+ bool ForceUnprivileged) {
+ return CheckBaseClassAccess(
+ AccessLoc, Base->getAsCXXRecordDecl(), Derived->getAsCXXRecordDecl(),
+ Path, DiagID, [&](PartialDiagnostic &PD) { PD << Derived << Base; },
+ ForceCheck, ForceUnprivileged);
+}
+
void Sema::CheckLookupAccess(const LookupResult &R) {
assert(getLangOpts().AccessControl
&& "performing access check without access control");
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 718f6be..a5dbc16 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -1788,8 +1788,8 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
= Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,
FoundOverload)) {
CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
- SrcType = Self.Context.getMemberPointerType(Fn->getType(),
- Self.Context.getTypeDeclType(M->getParent()).getTypePtr());
+ SrcType = Self.Context.getMemberPointerType(
+ Fn->getType(), /*Qualifier=*/nullptr, M->getParent());
WasOverloadedFunction = true;
}
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 42f0acb..16f0b6d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14314,9 +14314,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
CheckUseOfCXXMethodAsAddressOfOperand(OpLoc, OrigOp.get(), MD);
-
QualType MPTy = Context.getMemberPointerType(
- op->getType(), Context.getTypeDeclType(MD->getParent()).getTypePtr());
+ op->getType(), DRE->getQualifier(), MD->getParent());
if (getLangOpts().PointerAuthCalls && MD->isVirtual() &&
!isUnevaluatedContext() && !MPTy->isDependentType()) {
@@ -14404,8 +14403,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
// of some class C [...] and if E is a qualified-id, E is
// not the un-parenthesized operand of the unary & operator [...]
// the id-expression is transformed into a class member access expression.
- if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() &&
- !isa<ParenExpr>(OrigOp.get())) {
+ if (auto *DRE = dyn_cast<DeclRefExpr>(op);
+ DRE && DRE->getQualifier() && !isa<ParenExpr>(OrigOp.get())) {
DeclContext *Ctx = dcl->getDeclContext();
if (Ctx && Ctx->isRecord()) {
if (dcl->getType()->isReferenceType()) {
@@ -14419,8 +14418,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
Ctx = Ctx->getParent();
QualType MPTy = Context.getMemberPointerType(
- op->getType(),
- Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
+ op->getType(), DRE->getQualifier(), cast<CXXRecordDecl>(Ctx));
// Under the MS ABI, lock down the inheritance model now.
if (Context.getTargetInfo().getCXXABI().isMicrosoft())
(void)isCompleteType(OpLoc, MPTy);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index f085fac..90a4a5a 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7368,6 +7368,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
Qualifiers Quals;
/// The class for a pointer-to-member; a constant array type with a bound
/// (if any) for an array.
+ /// FIXME: Store Qualifier for pointer-to-member.
const Type *ClassOrBound;
Step(Kind K, const Type *ClassOrBound = nullptr)
@@ -7378,7 +7379,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
case Pointer:
return Ctx.getPointerType(T);
case MemberPointer:
- return Ctx.getMemberPointerType(T, ClassOrBound);
+ return Ctx.getMemberPointerType(T, /*Qualifier=*/nullptr,
+ ClassOrBound->getAsCXXRecordDecl());
case ObjCPointer:
return Ctx.getObjCObjectPointerType(T);
case Array:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 890de83..1c771b0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -7366,9 +7366,8 @@ SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG,
QualType FnPtrType;
auto *Method = dyn_cast<CXXMethodDecl>(FD);
if (Method && !Method->isStatic()) {
- const Type *ClassType =
- Context.getTypeDeclType(Method->getParent()).getTypePtr();
- FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
+ FnPtrType = Context.getMemberPointerType(
+ AdjustedFnType, /*Qualifier=*/nullptr, Method->getParent());
ExprResult ER;
{
// Build addr_of unary op to correctly handle type checks for member
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 161c0da..670c27f 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2243,9 +2243,8 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
assert(cast<UnaryOperator>(From->IgnoreParens())->getOpcode()
== UO_AddrOf &&
"Non-address-of operator on non-static member address");
- const Type *ClassType
- = S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
- FromType = S.Context.getMemberPointerType(FromType, ClassType);
+ FromType = S.Context.getMemberPointerType(
+ FromType, /*Qualifier=*/nullptr, Method->getParent());
} else if (isa<UnaryOperator>(From->IgnoreParens())) {
assert(cast<UnaryOperator>(From->IgnoreParens())->getOpcode() ==
UO_AddrOf &&
@@ -3293,8 +3292,17 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
*ToMember = ToType->castAs<MemberPointerType>();
if (!declaresSameEntity(FromMember->getMostRecentCXXRecordDecl(),
ToMember->getMostRecentCXXRecordDecl())) {
- PDiag << ft_different_class << QualType(ToMember->getClass(), 0)
- << QualType(FromMember->getClass(), 0);
+ PDiag << ft_different_class;
+ if (ToMember->isSugared())
+ PDiag << Context.getTypeDeclType(
+ ToMember->getMostRecentCXXRecordDecl());
+ else
+ PDiag << ToMember->getQualifier();
+ if (FromMember->isSugared())
+ PDiag << Context.getTypeDeclType(
+ FromMember->getMostRecentCXXRecordDecl());
+ else
+ PDiag << FromMember->getQualifier();
return;
}
FromType = FromMember->getPointeeType();
@@ -3535,13 +3543,13 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
// A pointer to member of B can be converted to a pointer to member of D,
// where D is derived from B (C++ 4.11p2).
- QualType FromClass(FromTypePtr->getClass(), 0);
- QualType ToClass(ToTypePtr->getClass(), 0);
+ CXXRecordDecl *FromClass = FromTypePtr->getMostRecentCXXRecordDecl();
+ CXXRecordDecl *ToClass = ToTypePtr->getMostRecentCXXRecordDecl();
- if (!Context.hasSameUnqualifiedType(FromClass, ToClass) &&
+ if (!declaresSameEntity(FromClass, ToClass) &&
IsDerivedFrom(From->getBeginLoc(), ToClass, FromClass)) {
- ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(),
- ToClass.getTypePtr());
+ ConvertedType = Context.getMemberPointerType(
+ FromTypePtr->getPointeeType(), FromTypePtr->getQualifier(), ToClass);
return true;
}
@@ -3572,10 +3580,23 @@ Sema::MemberPointerConversionResult Sema::CheckMemberPointerConversion(
ToPtrType->getPointeeType()))
return MemberPointerConversionResult::DifferentPointee;
- QualType FromClass = QualType(FromPtrType->getClass(), 0),
- ToClass = QualType(ToPtrType->getClass(), 0);
+ CXXRecordDecl *FromClass = FromPtrType->getMostRecentCXXRecordDecl(),
+ *ToClass = ToPtrType->getMostRecentCXXRecordDecl();
+
+ auto DiagCls = [](PartialDiagnostic &PD, NestedNameSpecifier *Qual,
+ const CXXRecordDecl *Cls) {
+ if (declaresSameEntity(Qual->getAsRecordDecl(), Cls))
+ PD << Qual;
+ else
+ PD << QualType(Cls->getTypeForDecl(), 0);
+ };
+ auto DiagFromTo = [&](PartialDiagnostic &PD) -> PartialDiagnostic & {
+ DiagCls(PD, FromPtrType->getQualifier(), FromClass);
+ DiagCls(PD, ToPtrType->getQualifier(), ToClass);
+ return PD;
+ };
- QualType Base = FromClass, Derived = ToClass;
+ CXXRecordDecl *Base = FromClass, *Derived = ToClass;
if (Direction == MemberPointerConversionDirection::Upcast)
std::swap(Base, Derived);
@@ -3584,16 +3605,19 @@ Sema::MemberPointerConversionResult Sema::CheckMemberPointerConversion(
if (!IsDerivedFrom(OpRange.getBegin(), Derived, Base, Paths))
return MemberPointerConversionResult::NotDerived;
- if (Paths.isAmbiguous(Base->getCanonicalTypeUnqualified())) {
- Diag(CheckLoc, diag::err_ambiguous_memptr_conv)
- << int(Direction) << FromClass << ToClass
- << getAmbiguousPathsDisplayString(Paths) << OpRange;
+ if (Paths.isAmbiguous(
+ Base->getTypeForDecl()->getCanonicalTypeUnqualified())) {
+ PartialDiagnostic PD = PDiag(diag::err_ambiguous_memptr_conv);
+ PD << int(Direction);
+ DiagFromTo(PD) << getAmbiguousPathsDisplayString(Paths) << OpRange;
+ Diag(CheckLoc, PD);
return MemberPointerConversionResult::Ambiguous;
}
if (const RecordType *VBase = Paths.getDetectedVirtual()) {
- Diag(CheckLoc, diag::err_memptr_conv_via_virtual)
- << FromClass << ToClass << QualType(VBase, 0) << OpRange;
+ PartialDiagnostic PD = PDiag(diag::err_memptr_conv_via_virtual);
+ DiagFromTo(PD) << QualType(VBase, 0) << OpRange;
+ Diag(CheckLoc, PD);
return MemberPointerConversionResult::Virtual;
}
@@ -3608,7 +3632,15 @@ Sema::MemberPointerConversionResult Sema::CheckMemberPointerConversion(
CheckLoc, Base, Derived, Paths.front(),
Direction == MemberPointerConversionDirection::Upcast
? diag::err_upcast_to_inaccessible_base
- : diag::err_downcast_from_inaccessible_base)) {
+ : diag::err_downcast_from_inaccessible_base,
+ [&](PartialDiagnostic &PD) {
+ NestedNameSpecifier *BaseQual = FromPtrType->getQualifier(),
+ *DerivedQual = ToPtrType->getQualifier();
+ if (Direction == MemberPointerConversionDirection::Upcast)
+ std::swap(BaseQual, DerivedQual);
+ DiagCls(PD, DerivedQual, Derived);
+ DiagCls(PD, BaseQual, Base);
+ })) {
case Sema::AR_accessible:
case Sema::AR_delayed:
case Sema::AR_dependent:
@@ -8727,7 +8759,7 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
// and those shouldn't have qualifier variants anyway.
if (PointeeTy->isArrayType())
return true;
- const Type *ClassTy = PointerTy->getClass();
+ CXXRecordDecl *Cls = PointerTy->getMostRecentCXXRecordDecl();
// Iterate through all strict supersets of the pointee type's CVR
// qualifiers.
@@ -8737,7 +8769,7 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
MemberPointerTypes.insert(
- Context.getMemberPointerType(QPointeeTy, ClassTy));
+ Context.getMemberPointerType(QPointeeTy, /*Qualifier=*/nullptr, Cls));
}
return true;
@@ -16431,16 +16463,17 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
assert(isa<DeclRefExpr>(SubExpr.get()) &&
"fixed to something other than a decl ref");
- assert(cast<DeclRefExpr>(SubExpr.get())->getQualifier() &&
+ NestedNameSpecifier *Qualifier =
+ cast<DeclRefExpr>(SubExpr.get())->getQualifier();
+ assert(Qualifier &&
"fixed to a member ref with no nested name qualifier");
// We have taken the address of a pointer to member
// function. Perform the computation here so that we get the
// appropriate pointer to member type.
- QualType ClassType
- = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
- QualType MemPtrType
- = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
+ QualType MemPtrType = Context.getMemberPointerType(
+ Fn->getType(), Qualifier,
+ cast<CXXRecordDecl>(Method->getDeclContext()));
// Under the MS ABI, lock down the inheritance model now.
if (Context.getTargetInfo().getCXXABI().isMicrosoft())
(void)isCompleteType(UnOp->getOperatorLoc(), MemPtrType);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c3c993d..45fb9d0 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5923,8 +5923,12 @@ bool UnnamedLocalNoLinkageFinder::VisitRValueReferenceType(
}
bool UnnamedLocalNoLinkageFinder::VisitMemberPointerType(
- const MemberPointerType* T) {
- return Visit(T->getPointeeType()) || Visit(QualType(T->getClass(), 0));
+ const MemberPointerType *T) {
+ if (Visit(T->getPointeeType()))
+ return true;
+ if (auto *RD = T->getMostRecentCXXRecordDecl())
+ return VisitTagDecl(RD);
+ return VisitNestedNameSpecifier(T->getQualifier());
}
bool UnnamedLocalNoLinkageFinder::VisitConstantArrayType(
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index e6ec4a7..c3bec6b 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2127,9 +2127,19 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
/*DeducedFromArrayBound=*/false, HasDeducedAnyParam);
Result != TemplateDeductionResult::Success)
return Result;
+ const Type *QP = MPP->getQualifier()->getAsType(),
+ *QA = MPA->getQualifier()->getAsType();
+ CXXRecordDecl *ClsP = MPP->getMostRecentCXXRecordDecl(),
+ *ClsA = MPA->getMostRecentCXXRecordDecl();
+ // FIXME: Don't drop the rest of the prefixes here.
+ QualType P = !ClsP || declaresSameEntity(QP->getAsCXXRecordDecl(), ClsP)
+ ? QualType(QP, 0)
+ : S.Context.getTypeDeclType(ClsP);
+ QualType A = !ClsA || declaresSameEntity(QA->getAsCXXRecordDecl(), ClsA)
+ ? QualType(QA, 0)
+ : S.Context.getTypeDeclType(ClsA);
return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, QualType(MPP->getClass(), 0),
- QualType(MPA->getClass(), 0), Info, Deduced, SubTDF,
+ S, TemplateParams, P, A, Info, Deduced, SubTDF,
degradeCallPartialOrderingKind(POK),
/*DeducedFromArrayBound=*/false, HasDeducedAnyParam);
}
@@ -4211,8 +4221,8 @@ static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,
if (!R.HasFormOfMemberPointer)
return {};
- return S.Context.getMemberPointerType(Fn->getType(),
- S.Context.getTypeDeclType(Method->getParent()).getTypePtr());
+ return S.Context.getMemberPointerType(
+ Fn->getType(), /*Qualifier=*/nullptr, Method->getParent());
}
if (!R.IsAddressOfOperand) return Fn->getType();
@@ -6833,7 +6843,8 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
const MemberPointerType *MemPtr = cast<MemberPointerType>(T.getTypePtr());
MarkUsedTemplateParameters(Ctx, MemPtr->getPointeeType(), OnlyDeduced,
Depth, Used);
- MarkUsedTemplateParameters(Ctx, QualType(MemPtr->getClass(), 0),
+ MarkUsedTemplateParameters(Ctx,
+ QualType(MemPtr->getQualifier()->getAsType(), 0),
OnlyDeduced, Depth, Used);
break;
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 11943c0..3971738 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2086,7 +2086,7 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM,
// an inheritance model, even if it's inside an unused typedef.
if (Context.getTargetInfo().getCXXABI().isMicrosoft())
if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
- if (!MPTy->getClass()->isDependentType())
+ if (!MPTy->getQualifier()->isDependent())
(void)isCompleteType(Loc, T);
} else {
@@ -2685,8 +2685,9 @@ QualType Sema::BuildFunctionType(QualType T,
return Context.getFunctionType(T, ParamTypes, EPI);
}
-QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
- SourceLocation Loc,
+QualType Sema::BuildMemberPointerType(QualType T,
+ NestedNameSpecifier *Qualifier,
+ CXXRecordDecl *Cls, SourceLocation Loc,
DeclarationName Entity) {
// Verify that we're not building a pointer to pointer to function with
// exception specification.
@@ -2709,11 +2710,6 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
return QualType();
}
- if (!Class->isDependentType() && !Class->isRecordType()) {
- Diag(Loc, diag::err_mempointer_in_nonclass_type) << Class;
- return QualType();
- }
-
if (T->isFunctionType() && getLangOpts().OpenCL &&
!getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers",
getLangOpts())) {
@@ -2734,7 +2730,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
if (T->isFunctionType())
adjustMemberFunctionCC(T, /*HasThisPointer=*/true, IsCtorOrDtor, Loc);
- return Context.getMemberPointerType(T, Class.getTypePtr());
+ return Context.getMemberPointerType(T, Qualifier, Cls);
}
QualType Sema::BuildBlockPointerType(QualType T,
@@ -5338,7 +5334,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
case DeclaratorChunk::MemberPointer: {
// The scope spec must refer to a class, or be dependent.
CXXScopeSpec &SS = DeclType.Mem.Scope();
- QualType ClsType;
// Handle pointer nullability.
inferPointerNullability(SimplePointerKind::MemberPointer, DeclType.Loc,
@@ -5348,56 +5343,22 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (SS.isInvalid()) {
// Avoid emitting extra errors if we already errored on the scope.
D.setInvalidType(true);
- } else if (S.isDependentScopeSpecifier(SS) ||
- isa_and_nonnull<CXXRecordDecl>(S.computeDeclContext(SS))) {
- NestedNameSpecifier *NNS = SS.getScopeRep();
- NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- ClsType = Context.getDependentNameType(
- ElaboratedTypeKeyword::None, NNSPrefix, NNS->getAsIdentifier());
- break;
-
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- llvm_unreachable("Nested-name-specifier must name a type");
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- const Type *NNSType = NNS->getAsType();
- ClsType = QualType(NNSType, 0);
- // Note: if the NNS has a prefix and ClsType is a nondependent
- // TemplateSpecializationType or a RecordType, then the NNS prefix is
- // NOT included in ClsType; hence we wrap ClsType into an
- // ElaboratedType. NOTE: in particular, no wrap occurs if ClsType
- // already is an Elaborated, DependentName, or
- // DependentTemplateSpecialization.
- if (isa<DependentTemplateSpecializationType>(NNSType)) {
- // FIXME: Rebuild DependentTemplateSpecializationType, adding the
- // Prefix.
- } else if (isa<TemplateSpecializationType, RecordType>(NNSType)) {
- // Either the dependent case (TemplateSpecializationType), or the
- // non-dependent one (RecordType).
- ClsType = Context.getElaboratedType(ElaboratedTypeKeyword::None,
- NNSPrefix, ClsType);
- }
- break;
- }
+ AreDeclaratorChunksValid = false;
+ } else if (auto *RD =
+ dyn_cast_or_null<CXXRecordDecl>(S.computeDeclContext(SS));
+ RD || S.isDependentScopeSpecifier(SS)) {
+ T = S.BuildMemberPointerType(T, SS.getScopeRep(), RD, DeclType.Loc,
+ D.getIdentifier());
} else {
S.Diag(DeclType.Mem.Scope().getBeginLoc(),
diag::err_illegal_decl_mempointer_in_nonclass)
<< (D.getIdentifier() ? D.getIdentifier()->getName() : "type name")
<< DeclType.Mem.Scope().getRange();
D.setInvalidType(true);
- }
-
- if (!ClsType.isNull())
- T = S.BuildMemberPointerType(T, ClsType, DeclType.Loc,
- D.getIdentifier());
- else
AreDeclaratorChunksValid = false;
+ // FIXME: Maybe we could model these as as a MemberPointerType with a
+ // non-dependent, non-class qualifier anyway.
+ }
if (T.isNull()) {
T = Context.IntTy;
@@ -6184,48 +6145,8 @@ namespace {
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
assert(Chunk.Kind == DeclaratorChunk::MemberPointer);
- const CXXScopeSpec& SS = Chunk.Mem.Scope();
- NestedNameSpecifierLoc NNSLoc = SS.getWithLocInContext(Context);
-
- const Type* ClsTy = TL.getClass();
- QualType ClsQT = QualType(ClsTy, 0);
- TypeSourceInfo *ClsTInfo = Context.CreateTypeSourceInfo(ClsQT, 0);
- // Now copy source location info into the type loc component.
- TypeLoc ClsTL = ClsTInfo->getTypeLoc();
- switch (NNSLoc.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- assert(isa<DependentNameType>(ClsTy) && "Unexpected TypeLoc");
- {
- DependentNameTypeLoc DNTLoc = ClsTL.castAs<DependentNameTypeLoc>();
- DNTLoc.setElaboratedKeywordLoc(SourceLocation());
- DNTLoc.setQualifierLoc(NNSLoc.getPrefix());
- DNTLoc.setNameLoc(NNSLoc.getLocalBeginLoc());
- }
- break;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- if (isa<ElaboratedType>(ClsTy)) {
- ElaboratedTypeLoc ETLoc = ClsTL.castAs<ElaboratedTypeLoc>();
- ETLoc.setElaboratedKeywordLoc(SourceLocation());
- ETLoc.setQualifierLoc(NNSLoc.getPrefix());
- TypeLoc NamedTL = ETLoc.getNamedTypeLoc();
- NamedTL.initializeFullCopy(NNSLoc.getTypeLoc());
- } else {
- ClsTL.initializeFullCopy(NNSLoc.getTypeLoc());
- }
- break;
-
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- llvm_unreachable("Nested-name-specifier must name a type");
- }
-
- // Finally fill in MemberPointerLocInfo fields.
TL.setStarLoc(Chunk.Mem.StarLoc);
- TL.setClassTInfo(ClsTInfo);
+ TL.setQualifierLoc(Chunk.Mem.Scope().getWithLocInContext(Context));
}
void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
assert(Chunk.Kind == DeclaratorChunk::Reference);
@@ -7054,7 +6975,8 @@ namespace {
case MemberPointer: {
const MemberPointerType *OldMPT = cast<MemberPointerType>(Old);
QualType New = wrap(C, OldMPT->getPointeeType(), I);
- return C.getMemberPointerType(New, OldMPT->getClass());
+ return C.getMemberPointerType(New, OldMPT->getQualifier(),
+ OldMPT->getMostRecentCXXRecordDecl());
}
case Reference: {
@@ -9333,17 +9255,17 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
// "Can't ask whether a dependent type is complete");
if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
- if (!MPTy->getClass()->isDependentType()) {
+ if (!MPTy->getQualifier()->isDependent()) {
+ QualType T = Context.getTypeDeclType(MPTy->getMostRecentCXXRecordDecl());
if (getLangOpts().CompleteMemberPointers &&
- !MPTy->getClass()->getAsCXXRecordDecl()->isBeingDefined() &&
- RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), Kind,
- diag::err_memptr_incomplete))
+ !MPTy->getMostRecentCXXRecordDecl()->isBeingDefined() &&
+ RequireCompleteType(Loc, T, Kind, diag::err_memptr_incomplete))
return true;
// We lock in the inheritance model once somebody has asked us to ensure
// that a pointer-to-member type is complete.
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
- (void)isCompleteType(Loc, QualType(MPTy->getClass(), 0));
+ (void)isCompleteType(Loc, T);
assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());
}
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index b5de98e..5686b9d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -859,12 +859,13 @@ public:
SourceLocation Sigil);
/// Build a new member pointer type given the pointee type and the
- /// class type it refers into.
+ /// qualifier it refers into.
///
/// By default, performs semantic analysis when building the member pointer
/// type. Subclasses may override this routine to provide different behavior.
- QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
- SourceLocation Sigil);
+ QualType RebuildMemberPointerType(QualType PointeeType,
+ NestedNameSpecifier *Qualifier,
+ CXXRecordDecl *Cls, SourceLocation Sigil);
QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
SourceLocation ProtocolLAngleLoc,
@@ -5607,31 +5608,30 @@ TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
if (PointeeType.isNull())
return QualType();
- TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
- TypeSourceInfo *NewClsTInfo = nullptr;
- if (OldClsTInfo) {
- NewClsTInfo = getDerived().TransformType(OldClsTInfo);
- if (!NewClsTInfo)
- return QualType();
- }
-
const MemberPointerType *T = TL.getTypePtr();
- QualType OldClsType = QualType(T->getClass(), 0);
- QualType NewClsType;
- if (NewClsTInfo)
- NewClsType = NewClsTInfo->getType();
- else {
- NewClsType = getDerived().TransformType(OldClsType);
- if (NewClsType.isNull())
+
+ NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
+ NestedNameSpecifierLoc NewQualifierLoc =
+ getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
+ if (!NewQualifierLoc)
+ return QualType();
+
+ CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
+ if (OldCls) {
+ NewCls = cast_or_null<CXXRecordDecl>(
+ getDerived().TransformDecl(TL.getStarLoc(), OldCls));
+ if (!NewCls)
return QualType();
}
QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() ||
- PointeeType != T->getPointeeType() ||
- NewClsType != OldClsType) {
- Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
- TL.getStarLoc());
+ if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
+ NewQualifierLoc.getNestedNameSpecifier() !=
+ OldQualifierLoc.getNestedNameSpecifier() ||
+ NewCls != OldCls) {
+ Result = getDerived().RebuildMemberPointerType(
+ PointeeType, NewQualifierLoc.getNestedNameSpecifier(), NewCls,
+ TL.getStarLoc());
if (Result.isNull())
return QualType();
}
@@ -5646,7 +5646,7 @@ TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
NewTL.setSigilLoc(TL.getSigilLoc());
- NewTL.setClassTInfo(NewClsTInfo);
+ NewTL.setQualifierLoc(NewQualifierLoc);
return Result;
}
@@ -17040,12 +17040,11 @@ TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
Sigil, getDerived().getBaseEntity());
}
-template<typename Derived>
-QualType
-TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
- QualType ClassType,
- SourceLocation Sigil) {
- return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
+template <typename Derived>
+QualType TreeTransform<Derived>::RebuildMemberPointerType(
+ QualType PointeeType, NestedNameSpecifier *Qualifier, CXXRecordDecl *Cls,
+ SourceLocation Sigil) {
+ return SemaRef.BuildMemberPointerType(PointeeType, Qualifier, Cls, Sigil,
getDerived().getBaseEntity());
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 2b03446..e53a30c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7103,7 +7103,7 @@ void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
TL.setStarLoc(readSourceLocation());
- TL.setClassTInfo(GetTypeSourceInfo());
+ TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
}
void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 9e6da4d..1ffa17d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -409,7 +409,7 @@ void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
addSourceLocation(TL.getStarLoc());
- Record.AddTypeSourceInfo(TL.getClassTInfo());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
}
void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp
index 598f098..3c7177b 100644
--- a/clang/lib/Serialization/TemplateArgumentHasher.cpp
+++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp
@@ -317,7 +317,9 @@ public:
void VisitMemberPointerType(const MemberPointerType *T) {
AddQualType(T->getPointeeType());
- AddType(T->getClass());
+ AddType(T->getQualifier()->getAsType());
+ if (auto *RD = T->getMostRecentCXXRecordDecl())
+ AddDecl(RD->getCanonicalDecl());
}
void VisitPackExpansionType(const PackExpansionType *T) {
diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
index 5ac55d2..9f0d3ef 100644
--- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
+++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
@@ -2452,6 +2452,9 @@ int main()
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x0"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "TemplateTypeParmType",
// CHECK-NEXT: "type": {
@@ -3225,4 +3228,3 @@ int main()
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
-
diff --git a/clang/test/AST/ast-dump-templates.cpp b/clang/test/AST/ast-dump-templates.cpp
index 2728dc1..0e0fa73 100644
--- a/clang/test/AST/ast-dump-templates.cpp
+++ b/clang/test/AST/ast-dump-templates.cpp
@@ -146,6 +146,18 @@ struct pr126341<{1, 2}>;
// DUMP: `-TemplateArgument structural value '1+2i'
} // namespace test8
+namespace TestMemberPointerPartialSpec {
+ template <class> struct A;
+ template <class T1, class T2> struct A<T1 T2::*>;
+// DUMP-LABEL: NamespaceDecl {{.+}} TestMemberPointerPartialSpec{{$}}
+// DUMP: ClassTemplatePartialSpecializationDecl {{.*}} struct A
+// DUMP-NEXT: |-TemplateArgument type 'type-parameter-0-0 type-parameter-0-1::*'
+// DUMP-NEXT: | `-MemberPointerType {{.+}} 'type-parameter-0-0 type-parameter-0-1::*' dependent
+// DUMP-NEXT: | |-TemplateTypeParmType {{.+}} 'type-parameter-0-1' dependent depth 0 index 1
+// DUMP-NEXT: | |-<<<NULL>>>
+// DUMP-NEXT: | `-TemplateTypeParmType {{.+}} 'type-parameter-0-0' dependent depth 0 index 0
+} // namespace TestMemberPointerPartialSpec
+
// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
@@ -6316,6 +6328,232 @@ struct pr126341<{1, 2}>;
// JSON-NEXT: ]
// JSON-NEXT: }
// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "NamespaceDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4680,
+// JSON-NEXT: "line": 149,
+// JSON-NEXT: "col": 11,
+// JSON-NEXT: "tokLen": 28
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4670,
+// JSON-NEXT: "col": 1,
+// JSON-NEXT: "tokLen": 9
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 5335,
+// JSON-NEXT: "line": 159,
+// JSON-NEXT: "col": 1,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "name": "TestMemberPointerPartialSpec",
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "ClassTemplateDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4737,
+// JSON-NEXT: "line": 150,
+// JSON-NEXT: "col": 27,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4713,
+// JSON-NEXT: "col": 3,
+// JSON-NEXT: "tokLen": 8
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 4737,
+// JSON-NEXT: "col": 27,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "name": "A",
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TemplateTypeParmDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4728,
+// JSON-NEXT: "col": 18,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4723,
+// JSON-NEXT: "col": 13,
+// JSON-NEXT: "tokLen": 5
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 4723,
+// JSON-NEXT: "col": 13,
+// JSON-NEXT: "tokLen": 5
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "tagUsed": "class",
+// JSON-NEXT: "depth": 0,
+// JSON-NEXT: "index": 0
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "CXXRecordDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4737,
+// JSON-NEXT: "col": 27,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4730,
+// JSON-NEXT: "col": 20,
+// JSON-NEXT: "tokLen": 6
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 4737,
+// JSON-NEXT: "col": 27,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "name": "A",
+// JSON-NEXT: "tagUsed": "struct"
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "ClassTemplatePartialSpecializationDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4779,
+// JSON-NEXT: "line": 151,
+// JSON-NEXT: "col": 40,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4742,
+// JSON-NEXT: "col": 3,
+// JSON-NEXT: "tokLen": 8
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 4789,
+// JSON-NEXT: "col": 50,
+// JSON-NEXT: "tokLen": 1
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "name": "A",
+// JSON-NEXT: "tagUsed": "struct",
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "kind": "TemplateArgument",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "type-parameter-0-0 type-parameter-0-1::*"
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "MemberPointerType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "type-parameter-0-0 type-parameter-0-1::*"
+// JSON-NEXT: },
+// JSON-NEXT: "isDependent": true,
+// JSON-NEXT: "isInstantiationDependent": true,
+// JSON-NEXT: "isData": true,
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TemplateTypeParmType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "type-parameter-0-1"
+// JSON-NEXT: },
+// JSON-NEXT: "isDependent": true,
+// JSON-NEXT: "isInstantiationDependent": true,
+// JSON-NEXT: "depth": 0,
+// JSON-NEXT: "index": 1,
+// JSON-NEXT: "decl": {
+// JSON-NEXT: "id": "0x0"
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x0"
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TemplateTypeParmType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "type-parameter-0-0"
+// JSON-NEXT: },
+// JSON-NEXT: "isDependent": true,
+// JSON-NEXT: "isInstantiationDependent": true,
+// JSON-NEXT: "depth": 0,
+// JSON-NEXT: "index": 0,
+// JSON-NEXT: "decl": {
+// JSON-NEXT: "id": "0x0"
+// JSON-NEXT: }
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TemplateTypeParmDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4758,
+// JSON-NEXT: "col": 19,
+// JSON-NEXT: "tokLen": 2
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4752,
+// JSON-NEXT: "col": 13,
+// JSON-NEXT: "tokLen": 5
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 4758,
+// JSON-NEXT: "col": 19,
+// JSON-NEXT: "tokLen": 2
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "isReferenced": true,
+// JSON-NEXT: "name": "T1",
+// JSON-NEXT: "tagUsed": "class",
+// JSON-NEXT: "depth": 0,
+// JSON-NEXT: "index": 0
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TemplateTypeParmDecl",
+// JSON-NEXT: "loc": {
+// JSON-NEXT: "offset": 4768,
+// JSON-NEXT: "col": 29,
+// JSON-NEXT: "tokLen": 2
+// JSON-NEXT: },
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {
+// JSON-NEXT: "offset": 4762,
+// JSON-NEXT: "col": 23,
+// JSON-NEXT: "tokLen": 5
+// JSON-NEXT: },
+// JSON-NEXT: "end": {
+// JSON-NEXT: "offset": 4768,
+// JSON-NEXT: "col": 29,
+// JSON-NEXT: "tokLen": 2
+// JSON-NEXT: }
+// JSON-NEXT: },
+// JSON-NEXT: "name": "T2",
+// JSON-NEXT: "tagUsed": "class",
+// JSON-NEXT: "depth": 0,
+// JSON-NEXT: "index": 1
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: }
+// JSON-NEXT: ]
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: }
diff --git a/clang/test/AST/ast-dump-types-json.cpp b/clang/test/AST/ast-dump-types-json.cpp
index fa1fb53..67379ac3 100644
--- a/clang/test/AST/ast-dump-types-json.cpp
+++ b/clang/test/AST/ast-dump-types-json.cpp
@@ -27,10 +27,11 @@ using ::TestUsingShadowDeclType;
// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 204,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 12,
// CHECK-NEXT: "col": 18,
@@ -38,12 +39,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 187,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 204,
// CHECK-NEXT: "col": 18,
// CHECK-NEXT: "tokLen": 19
// CHECK-NEXT: }
@@ -78,10 +79,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 239,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 13,
// CHECK-NEXT: "col": 15,
@@ -89,12 +91,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 225,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 239,
// CHECK-NEXT: "col": 15,
// CHECK-NEXT: "tokLen": 19
// CHECK-NEXT: }
@@ -129,10 +131,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 319,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 16,
// CHECK-NEXT: "col": 22,
@@ -140,12 +143,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 298,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 319,
// CHECK-NEXT: "col": 22,
// CHECK-NEXT: "tokLen": 22
// CHECK-NEXT: }
@@ -212,10 +215,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 366,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 18,
// CHECK-NEXT: "col": 20,
@@ -223,12 +227,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 347,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 397,
// CHECK-NEXT: "col": 51,
// CHECK-NEXT: "tokLen": 1
// CHECK-NEXT: }
@@ -248,21 +252,164 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ElaboratedType",
+// CHECK-NEXT: "kind": "RecordType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "T"
// CHECK-NEXT: },
+// CHECK-NEXT: "decl": {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "name": "T"
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 158,
+// CHECK-NEXT: "line": 7,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 151,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 6
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 183,
+// CHECK-NEXT: "line": 10,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "T",
+// CHECK-NEXT: "tagUsed": "struct",
+// CHECK-NEXT: "completeDefinition": true,
+// CHECK-NEXT: "definitionData": {
+// CHECK-NEXT: "canPassInRegisters": true,
+// CHECK-NEXT: "copyAssign": {
+// CHECK-NEXT: "hasConstParam": true,
+// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "copyCtor": {
+// CHECK-NEXT: "hasConstParam": true,
+// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "defaultCtor": {
+// CHECK-NEXT: "exists": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "dtor": {
+// CHECK-NEXT: "irrelevant": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "isAggregate": true,
+// CHECK-NEXT: "isLiteral": true,
+// CHECK-NEXT: "isPOD": true,
+// CHECK-NEXT: "isStandardLayout": true,
+// CHECK-NEXT: "isTrivial": true,
+// CHECK-NEXT: "isTriviallyCopyable": true,
+// CHECK-NEXT: "moveAssign": {
+// CHECK-NEXT: "exists": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "moveCtor": {
+// CHECK-NEXT: "exists": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: }
+// CHECK-NEXT: },
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "RecordType",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 158,
+// CHECK-NEXT: "line": 7,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 151,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 6
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 158,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "isImplicit": true,
+// CHECK-NEXT: "name": "T",
+// CHECK-NEXT: "tagUsed": "struct"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "FieldDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 168,
+// CHECK-NEXT: "line": 8,
+// CHECK-NEXT: "col": 7,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 164,
+// CHECK-NEXT: "col": 3,
+// CHECK-NEXT: "tokLen": 3
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 168,
+// CHECK-NEXT: "col": 7,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "I",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "T"
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXMethodDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 178,
+// CHECK-NEXT: "line": 9,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
// CHECK-NEXT: },
-// CHECK-NEXT: "decl": {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXRecordDecl",
-// CHECK-NEXT: "name": "T"
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 173,
+// CHECK-NEXT: "col": 3,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 180,
+// CHECK-NEXT: "col": 10,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "F",
+// CHECK-NEXT: "mangledName": "_ZN1T1FEv",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "void ()"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
@@ -298,10 +445,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 416,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 19,
// CHECK-NEXT: "col": 17,
@@ -309,12 +457,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 400,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 416,
// CHECK-NEXT: "col": 17,
// CHECK-NEXT: "tokLen": 25
// CHECK-NEXT: }
@@ -334,21 +482,164 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ElaboratedType",
+// CHECK-NEXT: "kind": "RecordType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "T"
// CHECK-NEXT: },
+// CHECK-NEXT: "decl": {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "name": "T"
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 158,
+// CHECK-NEXT: "line": 7,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 151,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 6
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 183,
+// CHECK-NEXT: "line": 10,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "T",
+// CHECK-NEXT: "tagUsed": "struct",
+// CHECK-NEXT: "completeDefinition": true,
+// CHECK-NEXT: "definitionData": {
+// CHECK-NEXT: "canPassInRegisters": true,
+// CHECK-NEXT: "copyAssign": {
+// CHECK-NEXT: "hasConstParam": true,
+// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "copyCtor": {
+// CHECK-NEXT: "hasConstParam": true,
+// CHECK-NEXT: "implicitHasConstParam": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "defaultCtor": {
+// CHECK-NEXT: "exists": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "dtor": {
+// CHECK-NEXT: "irrelevant": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "isAggregate": true,
+// CHECK-NEXT: "isLiteral": true,
+// CHECK-NEXT: "isPOD": true,
+// CHECK-NEXT: "isStandardLayout": true,
+// CHECK-NEXT: "isTrivial": true,
+// CHECK-NEXT: "isTriviallyCopyable": true,
+// CHECK-NEXT: "moveAssign": {
+// CHECK-NEXT: "exists": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: },
+// CHECK-NEXT: "moveCtor": {
+// CHECK-NEXT: "exists": true,
+// CHECK-NEXT: "needsImplicit": true,
+// CHECK-NEXT: "simple": true,
+// CHECK-NEXT: "trivial": true
+// CHECK-NEXT: }
+// CHECK-NEXT: },
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "RecordType",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 158,
+// CHECK-NEXT: "line": 7,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 151,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 6
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 158,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "isImplicit": true,
+// CHECK-NEXT: "name": "T",
+// CHECK-NEXT: "tagUsed": "struct"
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "FieldDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 168,
+// CHECK-NEXT: "line": 8,
+// CHECK-NEXT: "col": 7,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 164,
+// CHECK-NEXT: "col": 3,
+// CHECK-NEXT: "tokLen": 3
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 168,
+// CHECK-NEXT: "col": 7,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "I",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "T"
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXMethodDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 178,
+// CHECK-NEXT: "line": 9,
+// CHECK-NEXT: "col": 8,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 173,
+// CHECK-NEXT: "col": 3,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 180,
+// CHECK-NEXT: "col": 10,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
// CHECK-NEXT: },
-// CHECK-NEXT: "decl": {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXRecordDecl",
-// CHECK-NEXT: "name": "T"
+// CHECK-NEXT: "name": "F",
+// CHECK-NEXT: "mangledName": "_ZN1T1FEv",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "void ()"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
@@ -365,10 +656,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 456,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 21,
// CHECK-NEXT: "col": 13,
@@ -376,12 +668,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 444,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 490,
// CHECK-NEXT: "col": 47,
// CHECK-NEXT: "tokLen": 1
// CHECK-NEXT: }
@@ -437,10 +729,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "TypedefDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 506,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 23,
// CHECK-NEXT: "col": 13,
@@ -448,12 +741,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 494,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 7
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 506,
// CHECK-NEXT: "col": 13,
// CHECK-NEXT: "tokLen": 23
// CHECK-NEXT: }
@@ -473,10 +766,11 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "NamespaceDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 541,
// CHECK-NEXT: "file": "{{.*}}",
// CHECK-NEXT: "line": 24,
// CHECK-NEXT: "col": 11,
@@ -484,12 +778,12 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 531,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 9
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 609,
// CHECK-NEXT: "line": 26,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 1
@@ -501,19 +795,19 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "UsingDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 584,
// CHECK-NEXT: "line": 25,
// CHECK-NEXT: "col": 9,
// CHECK-NEXT: "tokLen": 23
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 576,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 5
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 584,
// CHECK-NEXT: "col": 9,
// CHECK-NEXT: "tokLen": 23
// CHECK-NEXT: }
@@ -524,18 +818,18 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "UsingShadowDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 584,
// CHECK-NEXT: "col": 9,
// CHECK-NEXT: "tokLen": 23
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 584,
// CHECK-NEXT: "col": 9,
// CHECK-NEXT: "tokLen": 23
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": {{[0-9]+}},
+// CHECK-NEXT: "offset": 584,
// CHECK-NEXT: "col": 9,
// CHECK-NEXT: "tokLen": 23
// CHECK-NEXT: }
diff --git a/clang/test/AST/attr-print-emit.cpp b/clang/test/AST/attr-print-emit.cpp
index 77826f8..66dbc50 100644
--- a/clang/test/AST/attr-print-emit.cpp
+++ b/clang/test/AST/attr-print-emit.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang -emit-ast -o %t.ast %s
+// RUN: %clang_cc1 -emit-pch -o %t.ast %s
// RUN: %clang_cc1 %t.ast -ast-print | FileCheck %s
// CHECK: void *aa() __attribute__((assume_aligned(64)));
diff --git a/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp b/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
index f46a2c9..d0eb9e80d 100644
--- a/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
+++ b/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
@@ -430,8 +430,8 @@ void fIntDynTypedVoidPointerTest1() {
struct RecordDynTypedVoidPointerTest {
struct RecordType {
- int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
- int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
+ int x; // expected-note{{uninitialized field 'static_cast<RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
+ int y; // expected-note{{uninitialized field 'static_cast<RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
};
void *vptr;
@@ -447,9 +447,9 @@ void fRecordDynTypedVoidPointerTest() {
struct NestedNonVoidDynTypedVoidPointerTest {
struct RecordType {
- int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
- int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
- void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}}
+ int x; // expected-note{{uninitialized field 'static_cast<NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}}
+ int y; // expected-note{{uninitialized field 'static_cast<NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}}
+ void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}}
};
void *vptr;
diff --git a/clang/test/CXX/class.access/p6.cpp b/clang/test/CXX/class.access/p6.cpp
index 510aaa2..6f26672 100644
--- a/clang/test/CXX/class.access/p6.cpp
+++ b/clang/test/CXX/class.access/p6.cpp
@@ -113,7 +113,7 @@ namespace test4 {
};
template <class U> void foo(U &, typename U::type) {}
-
+
void test() {
A<int> a;
foo(a, 0);
@@ -176,7 +176,7 @@ namespace test8 {
};
void test(A &a) {
- if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
+ if (a) return; // expected-error-re {{'operator void *(A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
}
}
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 282e71b..4d4e2f6 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -859,7 +859,7 @@ namespace cwg54 { // cwg54: 2.8
// expected-error@-1 {{cannot cast 'struct B' to its private base class 'A'}}
// expected-note@#cwg54-B {{declared private here}}
int A::*smab = static_cast<int A::*>(&B::b);
- // expected-error@-1 {{cannot cast 'cwg54::B' to its private base class 'A'}}
+ // expected-error@-1 {{cannot cast 'B' to its private base class 'A'}}
// expected-note@#cwg54-B {{declared private here}}
B &sba = static_cast<B&>(a);
// expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'cwg54::B'}}
@@ -868,19 +868,19 @@ namespace cwg54 { // cwg54: 2.8
// expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'cwg54::B'}}
// expected-note@#cwg54-B {{declared private here}}
int B::*smba = static_cast<int B::*>(&A::a);
- // expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'B'}}
+ // expected-error@-1 {{cannot cast private base class 'A' to 'B'}}
// expected-note@#cwg54-B {{declared private here}}
V &svb = static_cast<V&>(b);
V *spvb = static_cast<V*>(&b);
int V::*smvb = static_cast<int V::*>(&B::b);
- // expected-error@-1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
+ // expected-error@-1 {{conversion from pointer to member of class 'B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
B &sbv = static_cast<B&>(v);
// expected-error@-1 {{cannot cast 'struct V' to 'B &' via virtual base 'cwg54::V'}}
B *spbv = static_cast<B*>(&v);
// expected-error@-1 {{cannot cast 'cwg54::V *' to 'B *' via virtual base 'cwg54::V'}}
int B::*smbv = static_cast<int B::*>(&V::v);
- // expected-error@-1 {{conversion from pointer to member of class 'cwg54::V' to pointer to member of class 'B' via virtual base 'cwg54::V' is not allowed}}
+ // expected-error@-1 {{conversion from pointer to member of class 'V' to pointer to member of class 'B' via virtual base 'cwg54::V' is not allowed}}
A &cab = (A&)(b);
A *cpab = (A*)(&b);
@@ -892,13 +892,13 @@ namespace cwg54 { // cwg54: 2.8
V &cvb = (V&)(b);
V *cpvb = (V*)(&b);
int V::*cmvb = (int V::*)(&B::b);
- // expected-error@-1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
+ // expected-error@-1 {{conversion from pointer to member of class 'B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
B &cbv = (B&)(v);
// expected-error@-1 {{cannot cast 'struct V' to 'B &' via virtual base 'cwg54::V'}}
B *cpbv = (B*)(&v);
// expected-error@-1 {{cannot cast 'cwg54::V *' to 'B *' via virtual base 'cwg54::V'}}
int B::*cmbv = (int B::*)(&V::v);
- // expected-error@-1 {{conversion from pointer to member of class 'cwg54::V' to pointer to member of class 'B' via virtual base 'cwg54::V' is not allowed}}
+ // expected-error@-1 {{conversion from pointer to member of class 'V' to pointer to member of class 'B' via virtual base 'cwg54::V' is not allowed}}
} // namespace cwg54
namespace cwg55 { // cwg55: 2.7
diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp
index 9c72fef..92b9f3a 100644
--- a/clang/test/CXX/drs/cwg13xx.cpp
+++ b/clang/test/CXX/drs/cwg13xx.cpp
@@ -204,7 +204,7 @@ namespace cwg1330 { // cwg1330: 4 c++11
// since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
void (A::*af2)() throw() = &A::f;
// cxx98-14-error@-1 {{target exception specification is not superset of source}}
- // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (A::*)() throw()' with an rvalue of type 'void (cwg1330::A::*)() throw(T)': different exception specifications}}
+ // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (A::*)() throw()' with an rvalue of type 'void (A::*)() throw(T)': different exception specifications}}
#if __cplusplus >= 201103L
static_assert(noexcept(A().g()), "");
@@ -252,7 +252,7 @@ namespace cwg1330 { // cwg1330: 4 c++11
void (B<P>::*bpf3)() = &B<P>::f;
void (B<P>::*bpf4)() throw() = &B<P>::f;
// cxx98-14-error@-1 {{target exception specification is not superset of source}}
- // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (B<P>::*)() throw()' with an rvalue of type 'void (cwg1330::B<cwg1330::P>::*)() throw(T, typename P::type)': different exception specifications}}
+ // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (B<P>::*)() throw()' with an rvalue of type 'void (B<P>::*)() throw(T, typename P::type)': different exception specifications}}
#if __cplusplus >= 201103L
static_assert(noexcept(B<P>().g()), "");
diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp
index a817a1b..3eb7058 100644
--- a/clang/test/CXX/drs/cwg26xx.cpp
+++ b/clang/test/CXX/drs/cwg26xx.cpp
@@ -142,8 +142,8 @@ struct foo {
void f() {
foo fooable; // #cwg2628-fooable
- // since-cxx20-error@#cwg2628-fooable {{call to deleted}}
- // since-cxx20-note@#cwg2628-ctor {{marked deleted here}}
+ // since-cxx20-error@#cwg2628-fooable {{call to deleted}}
+ // since-cxx20-note@#cwg2628-ctor {{marked deleted here}}
}
#endif
} // namespace cwg2628
@@ -336,7 +336,7 @@ struct S{
void test() {
(&S::f)(1);
- // since-cxx23-error@-1 {{called object type 'void (cwg2687::S::*)(int)' is not a function or function pointer}}
+ // since-cxx23-error@-1 {{called object type 'void (S::*)(int)' is not a function or function pointer}}
(&S::g)(1);
(&S::h)(S(), 1);
}
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 4f383aa..b621318 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -98,8 +98,8 @@ public:
void foo() { Templ<Derived> x(&Derived::func); }
// expected-error@-1 {{no matching constructor for initialization of 'Templ<Derived>'}}
-// expected-note@#cwg203-ex3-Templ {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int (cwg203::ex3::Base::*)() const' to 'const Templ<Derived>' for 1st argument}}
-// since-cxx11-note@#cwg203-ex3-Templ {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int (cwg203::ex3::Base::*)() const' to 'Templ<Derived>' for 1st argument}}
+// expected-note@#cwg203-ex3-Templ {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int (Derived::*)() const' (aka 'int (Base::*)() const') to 'const Templ<Derived>' for 1st argument}}
+// since-cxx11-note@#cwg203-ex3-Templ {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int (Derived::*)() const' (aka 'int (Base::*)() const') to 'Templ<Derived>' for 1st argument}}
// expected-note@#cwg203-ex3-Templ-ctor {{candidate template ignored: could not match 'cwg203::ex3::Derived' against 'cwg203::ex3::Base'}}
} // namespace ex3
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index adbf63f..e8e2600 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -1176,7 +1176,7 @@ namespace cwg480 { // cwg480: 2.7
extern int D::*c;
int A::*d = static_cast<int A::*>(c);
- // expected-error@-1 {{conversion from pointer to member of class 'cwg480::D' to pointer to member of class 'A' via virtual base 'cwg480::B' is not allowed}}
+ // expected-error@-1 {{conversion from pointer to member of class 'D' to pointer to member of class 'A' via virtual base 'cwg480::B' is not allowed}}
D *e;
A *f = e;
diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp
index a8ab2e2..9ff01f3 100644
--- a/clang/test/CXX/drs/cwg7xx.cpp
+++ b/clang/test/CXX/drs/cwg7xx.cpp
@@ -348,6 +348,5 @@ struct X {
};
struct Y : X {};
B Y::*pm = &X::d;
-// expected-error@-1 {{cannot initialize a variable of type 'B Y::*' with an rvalue of type 'D cwg794::X::*': different classes ('Y' vs 'cwg794::X')}}
-// FIXME: why diagnostic says just `Y` and not `cwg794::Y`, like `cwg794::X`?
+// expected-error@-1 {{cannot initialize a variable of type 'B Y::*' with an rvalue of type 'D X::*': different classes ('Y' vs 'X')}}
} // namespace cwg794
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
index 629000d..73c7c75 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -169,7 +169,7 @@ namespace addr_of_obj_or_func {
struct Local { static int f() {} }; // precxx17-note {{here}}
X1<&Local::f> x1_no_linkage; // precxx17-error {{non-type template argument refers to function 'f' that does not have linkage}} cxx17-error {{value of type 'int (*)()' is not implicitly convertible to 'int (*)(int)'}}
- X0<&S::NonStaticMember> x0_non_static; // precxx17-error {{non-static data member}} cxx17-error {{value of type 'int addr_of_obj_or_func::S::*' is not implicitly convertible to 'int *'}}
+ X0<&S::NonStaticMember> x0_non_static; // precxx17-error {{non-static data member}} cxx17-error {{value of type 'int S::*' is not implicitly convertible to 'int *'}}
}
}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
index 034ad49..bf8f1af 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -223,7 +223,7 @@ namespace pointer_to_member_function {
template<int (Y::*)(int)> struct X0 {}; // expected-note 0-1{{template parameter is declared here}}
X0<&Y::f> x0a;
X0<&Y::g> x0b;
- X0<&Y::h> x0c; // expected-error-re{{type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' {{.*}} convert{{.*}} 'int (Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
+ X0<&Y::h> x0c; // expected-error-re{{type 'float (Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' {{.*}} convert{{.*}} 'int (Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
}
// -- For a non-type template-parameter of type pointer to data member,
@@ -238,9 +238,9 @@ namespace pointer_to_member_data {
X0<&Y::y> x0a;
X0<&Y::x> x0b;
#if __cplusplus <= 201402L
- // expected-error@-2 {{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int Y::*'}}
+ // expected-error@-2 {{non-type template argument of type 'int Y::*' (aka 'int X::*') cannot be converted to a value of type 'int Y::*'}}
#else
- // expected-error@-4 {{conversion from 'int pointer_to_member_data::X::*' to 'int Y::*' is not allowed in a converted constant expression}}
+ // expected-error@-4 {{conversion from 'int Y::*' (aka 'int X::*') to 'int Y::*' is not allowed in a converted constant expression}}
#endif
// Test qualification conversions
diff --git a/clang/test/Index/print-type.cpp b/clang/test/Index/print-type.cpp
index 35bf511..141895d 100644
--- a/clang/test/Index/print-type.cpp
+++ b/clang/test/Index/print-type.cpp
@@ -163,7 +163,7 @@ inline namespace InlineNS {}
// CHECK: DeclRefExpr=i:44:14 [type=int] [typekind=Int] [isPOD=1]
// CHECK: StructDecl=Blob:46:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
// CHECK: FieldDecl=i:47:7 (Definition) [type=int] [typekind=Int] [isPOD=1]
-// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [canonicaltype=int Blob::*] [canonicaltypekind=MemberPointer] [isPOD=1]
+// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1] [pointeetype=int] [pointeekind=Int] [isAnonRecDecl=0]
// CHECK: FunctionDecl=elaboratedNamespaceType:52:42 [type=NS::Type (const NS::Type)] [typekind=FunctionProto] [canonicaltype=NS::Type (NS::Type)] [canonicaltypekind=FunctionProto] [resulttype=NS::Type] [resulttypekind=Elaborated] [args= [const NS::Type] [Elaborated]] [isPOD=0]
// CHECK: NamespaceRef=NS:52:11 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TypeRef=struct NS::Type:52:23 [type=NS::Type] [typekind=Record] [isPOD=1]
diff --git a/clang/test/SemaCXX/addr-of-overloaded-function.cpp b/clang/test/SemaCXX/addr-of-overloaded-function.cpp
index 99f5ba6..5568bec 100644
--- a/clang/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/clang/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
int f(double); // expected-note{{candidate function}}
int f(int); // expected-note{{candidate function}}
@@ -139,7 +139,7 @@ namespace PR8196 {
template <typename T> struct mcdata {
typedef int result_type;
};
- template <class T>
+ template <class T>
typename mcdata<T>::result_type wrap_mean(mcdata<T> const&);
void add_property(double(*)(mcdata<double> const &)); // expected-note{{candidate function not viable: no overload of 'wrap_mean' matching}}
void f() {
@@ -204,7 +204,7 @@ namespace test1 {
double foo(int x, float y) {return 0;} // expected-note {{candidate function has different number of parameters (expected 1 but has 2)}}
double foo(float x) {return 0;} // expected-note {{candidate function has type mismatch at 1st parameter (expected 'int' but has 'float')}}
double foo(int x) {return 0;} // expected-note {{candidate function has different return type ('int' expected but has 'double')}}
-
+
int (*ptr)(int) = &foo; // expected-error {{address of overloaded function 'foo' does not match required type 'int (int)'}}
struct Qualifiers {
@@ -221,20 +221,20 @@ namespace test1 {
void QualifierTest() {
void (Qualifiers::*X)();
- X = &Qualifiers::C; // expected-error-re {{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (unqualified vs 'const')}}
- X = &Qualifiers::V; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (unqualified vs 'volatile')}}
- X = &Qualifiers::R; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (unqualified vs '__restrict')}}
- X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (unqualified vs 'const volatile')}}
- X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (unqualified vs 'const __restrict')}}
- X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (unqualified vs 'volatile __restrict')}}
- X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (unqualified vs 'const volatile __restrict')}}
+ X = &Qualifiers::C; // expected-error-re {{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (unqualified vs 'const')}}
+ X = &Qualifiers::V; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (unqualified vs 'volatile')}}
+ X = &Qualifiers::R; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (unqualified vs '__restrict')}}
+ X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (unqualified vs 'const volatile')}}
+ X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (unqualified vs 'const __restrict')}}
+ X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (unqualified vs 'volatile __restrict')}}
+ X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (unqualified vs 'const volatile __restrict')}}
}
struct Dummy {
void N() {};
};
- void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (test1::Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('Qualifiers' vs 'test1::Dummy')}}
+ void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('Qualifiers' vs 'Dummy')}}
}
template <typename T> class PR16561 {
diff --git a/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
index 4330c0c..e84c651 100644
--- a/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
+++ b/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
@@ -18,7 +18,7 @@ struct C : B {
void foo(C c, int A::* pmf) {
int i = c->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \
- // expected-note {{built-in candidate operator->*(const struct A *, int struct A::*)}} \
- // expected-note {{built-in candidate operator->*(struct A *, int struct A::*)}}
+ // expected-note {{built-in candidate operator->*(const struct A *, int A::*)}} \
+ // expected-note {{built-in candidate operator->*(struct A *, int A::*)}}
}
diff --git a/clang/test/SemaCXX/calling-conv-compat.cpp b/clang/test/SemaCXX/calling-conv-compat.cpp
index 5a51e34..9bb448f 100644
--- a/clang/test/SemaCXX/calling-conv-compat.cpp
+++ b/clang/test/SemaCXX/calling-conv-compat.cpp
@@ -183,31 +183,31 @@ typedef void ( C::*memb_c_default)();
typedef void (__cdecl C::*memb_c_cdecl)();
typedef void (__thiscall C::*memb_c_thiscall)();
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (A::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (A::*)() __attribute__((thiscall))') for 1st argument}}
void cb_memb_a_default(memb_a_default ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (A::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (A::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (A::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (A::*)() __attribute__((cdecl))') for 1st argument}}
void cb_memb_a_cdecl(memb_a_cdecl ptr);
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (A::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (A::*)() __attribute__((thiscall))') for 1st argument}}
void cb_memb_a_thiscall(memb_a_thiscall ptr);
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (B::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (B::*)() __attribute__((thiscall))') for 1st argument}}
void cb_memb_b_default(memb_b_default ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (B::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (B::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (B::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (B::*)() __attribute__((cdecl))') for 1st argument}}
void cb_memb_b_cdecl(memb_b_cdecl ptr);
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (B::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (B::*)() __attribute__((thiscall))') for 1st argument}}
void cb_memb_b_thiscall(memb_b_thiscall ptr);
-// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
void cb_memb_c_default(memb_c_default ptr);
-// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}}
void cb_memb_c_cdecl(memb_c_cdecl ptr);
-// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+3 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}}
void cb_memb_c_thiscall(memb_c_thiscall ptr);
void call_member() {
@@ -279,11 +279,11 @@ void cb_memb_a_default(memb_a_default ptr);
void cb_memb_a_cdecl(memb_a_cdecl ptr);
void cb_memb_b_default(memb_b_default ptr);
void cb_memb_b_cdecl(memb_b_cdecl ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_default' (aka 'void (C::*)(int, ...)') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (C::*)(int, ...)') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)(int, ...)' to 'memb_c_default' (aka 'void (C::*)(int, ...)') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (C::*)(int, ...)') for 1st argument}}
void cb_memb_c_default(memb_c_default ptr);
-// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
-// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'void (A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
+// expected-note@+1 {{candidate function not viable: no known conversion from 'void (A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (C::*)(int, ...) __attribute__((cdecl))') for 1st argument}}
void cb_memb_c_cdecl(memb_c_cdecl ptr);
void call_member() {
diff --git a/clang/test/SemaCXX/err_init_conversion_failed.cpp b/clang/test/SemaCXX/err_init_conversion_failed.cpp
index e31f215..f1949c0 100644
--- a/clang/test/SemaCXX/err_init_conversion_failed.cpp
+++ b/clang/test/SemaCXX/err_init_conversion_failed.cpp
@@ -56,6 +56,6 @@ template <class P> struct S2 {
void test_15() {
S2<S> X = {&S::foo};
- // expected-error-re@-1{{cannot initialize a member subobject of type 'void (template_test::S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (template_test::S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
+ // expected-error-re@-1{{cannot initialize a member subobject of type 'void (S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
}
}
diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp
index ec27d7a..81a3a3f 100644
--- a/clang/test/SemaCXX/member-pointer.cpp
+++ b/clang/test/SemaCXX/member-pointer.cpp
@@ -48,7 +48,7 @@ void f() {
// Conversion to member of base.
pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
-
+
// Comparisons
int (A::*pf2)(int, int);
int (D::*pf3)(int, int) = 0;
@@ -107,7 +107,7 @@ void h() {
int i = phm->*pi;
(void)&(hm.*pi);
(void)&(phm->*pi);
- (void)&((&hm)->*pi);
+ (void)&((&hm)->*pi);
void (HasMembers::*pf)() = &HasMembers::f;
(hm.*pf)();
@@ -205,7 +205,7 @@ namespace rdar8358512 {
static void stat();
static void stat(int);
-
+
template <typename T> struct Test0 {
void test() {
bind(&nonstat); // expected-error {{no matching function for call}}
@@ -296,7 +296,7 @@ namespace PR9973 {
{ call(u); } // expected-note{{in instantiation of}}
};
- template<class R, class T>
+ template<class R, class T>
dm<R, T> mem_fn(R T::*) ;
struct test
@@ -324,3 +324,12 @@ namespace test8 {
.**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
}
}
+
+namespace test9 {
+ struct FOO BAR;
+ // expected-error@-1 {{variable has incomplete type 'struct FOO'}}
+ // expected-note@-2 {{forward declaration of 'test9::FOO'}}
+ // expected-note@-3 {{'BAR' declared here}}
+ struct C { int BAR::*mp; };
+ // expected-error@-1 {{'BAR' is not a class, namespace, or enumeration}}
+} // namespace test9
diff --git a/clang/test/SemaOpenACC/combined-construct-if-ast.cpp b/clang/test/SemaOpenACC/combined-construct-if-ast.cpp
index f079640..96c465d 100644
--- a/clang/test/SemaOpenACC/combined-construct-if-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-if-ast.cpp
@@ -88,7 +88,7 @@ void TemplFunc() {
// CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float'
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <IntegralToFloating>
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename InstTy::IntTy <NoOp>
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
@@ -96,7 +96,7 @@ void TemplFunc() {
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}}serial loop
// CHECK-NEXT: if clause
// CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' <IntegralToBoolean>
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename InstTy::IntTy <NoOp>
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
diff --git a/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp b/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp
index 8aa361c..a04fcdd 100644
--- a/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp
@@ -204,14 +204,14 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop
// CHECK-NEXT: num_workers clause
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::IntTy':'int' functional cast to typename struct HasInt::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::IntTy':'int' functional cast to typename HasInt::IntTy <NoOp>
// CHECK-NEXT: InitListExpr{{.*}}'typename HasInt::IntTy':'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: num_workers clause
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::ShortTy':'short' functional cast to typename struct HasInt::ShortTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::ShortTy':'short' functional cast to typename HasInt::ShortTy <NoOp>
// CHECK-NEXT: InitListExpr{{.*}}'typename HasInt::ShortTy':'short'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
diff --git a/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp b/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp
index 58c12b8..babff53 100644
--- a/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp
@@ -356,7 +356,7 @@ void TemplFunc() {
// CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float'
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <IntegralToFloating>
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename InstTy::IntTy <NoOp>
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
@@ -365,7 +365,7 @@ void TemplFunc() {
// CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial
// CHECK-NEXT: if clause
// CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' <IntegralToBoolean>
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename InstTy::IntTy <NoOp>
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
diff --git a/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp b/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
index 2c48fc3..baf7aa6 100644
--- a/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
@@ -506,7 +506,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCComputeConstruct{{.*}}kernels
// CHECK-NEXT: num_workers clause
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::IntTy':'int' functional cast to typename struct HasInt::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::IntTy':'int' functional cast to typename HasInt::IntTy <NoOp>
// CHECK-NEXT: InitListExpr{{.*}}'typename HasInt::IntTy':'int'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
@@ -514,7 +514,7 @@ void TemplUses(T t, U u) {
// CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel
// CHECK-NEXT: num_workers clause
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::ShortTy':'short' functional cast to typename struct HasInt::ShortTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'typename HasInt::ShortTy':'short' functional cast to typename HasInt::ShortTy <NoOp>
// CHECK-NEXT: InitListExpr{{.*}}'typename HasInt::ShortTy':'short'
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
diff --git a/clang/test/SemaOpenACC/data-construct-if-ast.cpp b/clang/test/SemaOpenACC/data-construct-if-ast.cpp
index 9ceee4e..533a97d 100644
--- a/clang/test/SemaOpenACC/data-construct-if-ast.cpp
+++ b/clang/test/SemaOpenACC/data-construct-if-ast.cpp
@@ -94,7 +94,7 @@ void TemplFunc() {
// CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float'
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' <IntegralToFloating>
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename InstTy::IntTy <NoOp>
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
// CHECK-NEXT: NullStmt
@@ -103,7 +103,7 @@ void TemplFunc() {
// CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int'
// CHECK-NEXT: if clause
// CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' <IntegralToBoolean>
- // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy <NoOp>
+ // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename InstTy::IntTy <NoOp>
// CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int'
// CHECK-NEXT: NullStmt
diff --git a/clang/test/SemaTemplate/instantiate-member-pointers.cpp b/clang/test/SemaTemplate/instantiate-member-pointers.cpp
index 4757870..8b6c2ef 100644
--- a/clang/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/clang/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -5,7 +5,8 @@ struct Y {
template<typename T>
struct X1 {
- int f(T* ptr, int T::*pm) { // expected-error{{member pointer}}
+ int f(T* ptr, int T::*pm) {
+ // expected-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}}
return ptr->*pm;
}
};
diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp
index f4227fd..2c9ef28 100644
--- a/clang/tools/libclang/CXType.cpp
+++ b/clang/tools/libclang/CXType.cpp
@@ -966,12 +966,14 @@ long long clang_Type_getAlignOf(CXType T) {
}
CXType clang_Type_getClassType(CXType CT) {
+ ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext();
QualType ET = QualType();
QualType T = GetQualType(CT);
const Type *TP = T.getTypePtrOrNull();
if (TP && TP->getTypeClass() == Type::MemberPointer) {
- ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
+ ET = Ctx.getTypeDeclType(
+ cast<MemberPointerType>(TP)->getMostRecentCXXRecordDecl());
}
return MakeCXType(ET, GetTU(CT));
}
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 068cf66..7484416 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -5760,10 +5760,10 @@ TEST(ElaboratedTypeNarrowing, namesType) {
TEST(NNS, BindsNestedNameSpecifiers) {
EXPECT_TRUE(matchAndVerifyResultTrue(
- "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
- nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
- std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>(
- "nns", "ns::struct E::")));
+ "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
+ nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
+ std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("nns",
+ "ns::E::")));
}
TEST(NNS, BindsNestedNameSpecifierLocs) {