@@ -1828,6 +1828,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
18281828 }
18291829};
18301830
1831+ bool isFragileClangDecl (const clang::Decl *decl);
1832+
18311833bool isFragileClangType (clang::QualType type) {
18321834 if (type.isNull ())
18331835 return true ;
@@ -1842,20 +1844,21 @@ bool isFragileClangType(clang::QualType type) {
18421844 // Pointers to non-fragile types are non-fragile.
18431845 if (underlyingTypePtr->isPointerType ())
18441846 return isFragileClangType (underlyingTypePtr->getPointeeType ());
1847+ if (auto tagDecl = underlyingTypePtr->getAsTagDecl ())
1848+ return isFragileClangDecl (tagDecl);
18451849 return true ;
18461850}
18471851
1848- bool isFragileClangNode (const ClangNode &node) {
1849- auto *decl = node.getAsDecl ();
1850- if (!decl)
1851- return false ;
1852+ bool isFragileClangDecl (const clang::Decl *decl) {
18521853 // Namespaces by themselves don't impact ABI.
18531854 if (isa<clang::NamespaceDecl>(decl))
18541855 return false ;
18551856 // Objective-C type declarations are compatible with library evolution.
18561857 if (isa<clang::ObjCContainerDecl>(decl))
18571858 return false ;
18581859 if (auto *fd = dyn_cast<clang::FunctionDecl>(decl)) {
1860+ if (auto *ctorDecl = dyn_cast<clang::CXXConstructorDecl>(fd))
1861+ return isFragileClangDecl (ctorDecl->getParent ());
18591862 if (!isa<clang::CXXMethodDecl>(decl) &&
18601863 !isFragileClangType (fd->getDeclaredReturnType ())) {
18611864 for (const auto *param : fd->parameters ()) {
@@ -1885,13 +1888,27 @@ bool isFragileClangNode(const ClangNode &node) {
18851888 if (auto *typedefDecl = dyn_cast<clang::TypedefNameDecl>(decl))
18861889 return isFragileClangType (typedefDecl->getUnderlyingType ());
18871890 if (auto *rd = dyn_cast<clang::RecordDecl>(decl)) {
1888- if (!isa<clang::CXXRecordDecl>(rd))
1891+ auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(rd);
1892+ if (!cxxRecordDecl)
18891893 return false ;
1890- return !rd->getDeclContext ()->isExternCContext ();
1891- }
1894+ return !cxxRecordDecl->isCLike () &&
1895+ !cxxRecordDecl->getDeclContext ()->isExternCContext ();
1896+ }
1897+ if (auto *varDecl = dyn_cast<clang::VarDecl>(decl))
1898+ return isFragileClangType (varDecl->getType ());
1899+ if (auto *fieldDecl = dyn_cast<clang::FieldDecl>(decl))
1900+ return isFragileClangType (fieldDecl->getType ()) ||
1901+ isFragileClangDecl (fieldDecl->getParent ());
18921902 return true ;
18931903}
18941904
1905+ bool isFragileClangNode (const ClangNode &node) {
1906+ auto *decl = node.getAsDecl ();
1907+ if (!decl)
1908+ return false ;
1909+ return isFragileClangDecl (decl);
1910+ }
1911+
18951912} // end anonymous namespace
18961913
18971914// / Returns the kind of origin, implementation-only import or SPI declaration,
0 commit comments