@@ -1828,6 +1828,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
1828
1828
}
1829
1829
};
1830
1830
1831
+ bool isFragileClangDecl (const clang::Decl *decl);
1832
+
1831
1833
bool isFragileClangType (clang::QualType type) {
1832
1834
if (type.isNull ())
1833
1835
return true ;
@@ -1842,20 +1844,21 @@ bool isFragileClangType(clang::QualType type) {
1842
1844
// Pointers to non-fragile types are non-fragile.
1843
1845
if (underlyingTypePtr->isPointerType ())
1844
1846
return isFragileClangType (underlyingTypePtr->getPointeeType ());
1847
+ if (auto tagDecl = underlyingTypePtr->getAsTagDecl ())
1848
+ return isFragileClangDecl (tagDecl);
1845
1849
return true ;
1846
1850
}
1847
1851
1848
- bool isFragileClangNode (const ClangNode &node) {
1849
- auto *decl = node.getAsDecl ();
1850
- if (!decl)
1851
- return false ;
1852
+ bool isFragileClangDecl (const clang::Decl *decl) {
1852
1853
// Namespaces by themselves don't impact ABI.
1853
1854
if (isa<clang::NamespaceDecl>(decl))
1854
1855
return false ;
1855
1856
// Objective-C type declarations are compatible with library evolution.
1856
1857
if (isa<clang::ObjCContainerDecl>(decl))
1857
1858
return false ;
1858
1859
if (auto *fd = dyn_cast<clang::FunctionDecl>(decl)) {
1860
+ if (auto *ctorDecl = dyn_cast<clang::CXXConstructorDecl>(fd))
1861
+ return isFragileClangDecl (ctorDecl->getParent ());
1859
1862
if (!isa<clang::CXXMethodDecl>(decl) &&
1860
1863
!isFragileClangType (fd->getDeclaredReturnType ())) {
1861
1864
for (const auto *param : fd->parameters ()) {
@@ -1885,13 +1888,27 @@ bool isFragileClangNode(const ClangNode &node) {
1885
1888
if (auto *typedefDecl = dyn_cast<clang::TypedefNameDecl>(decl))
1886
1889
return isFragileClangType (typedefDecl->getUnderlyingType ());
1887
1890
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)
1889
1893
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 ());
1892
1902
return true ;
1893
1903
}
1894
1904
1905
+ bool isFragileClangNode (const ClangNode &node) {
1906
+ auto *decl = node.getAsDecl ();
1907
+ if (!decl)
1908
+ return false ;
1909
+ return isFragileClangDecl (decl);
1910
+ }
1911
+
1895
1912
} // end anonymous namespace
1896
1913
1897
1914
// / Returns the kind of origin, implementation-only import or SPI declaration,
0 commit comments