ABI/API checker: populate several lazily computed attributes to nodes

ABI/API checker should check semantic differences of two modules.
Adhering too strictly to the actual ASTs could yield false positives. This
patch populates ObjC, Dynamic and Final to the attribute list if AST
APIs say so.

rdar://50217247
This commit is contained in:
Xi Ge
2019-08-29 15:07:06 -07:00
parent 016acf3ac9
commit 1e173d8931
9 changed files with 107 additions and 39 deletions

View File

@@ -1278,6 +1278,24 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty, TypeInitInfo Info) :
}
}
static std::vector<DeclAttrKind> collectDeclAttributes(Decl *D) {
std::vector<DeclAttrKind> Results;
for (auto *Attr: D->getAttrs())
Results.push_back(Attr->getKind());
if (auto *VD = dyn_cast<ValueDecl>(D)) {
#define HANDLE(COND, KIND_NAME) \
if (VD->COND && !llvm::is_contained(Results, DeclAttrKind::KIND_NAME)) \
Results.emplace_back(DeclAttrKind::KIND_NAME);
// These attributes may be semantically applicable to the current decl but absent from
// the actual AST. Populting them to the nodes ensure we don't have false positives.
HANDLE(isObjC(), DAK_ObjC)
HANDLE(isFinal(), DAK_Final)
HANDLE(isDynamic(), DAK_Dynamic)
#undef HANDLE
}
return Results;
}
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Decl *D):
Ctx(Ctx), DKind(D->getKind()),
Location(calculateLocation(Ctx, D)),
@@ -1294,22 +1312,8 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Decl *D):
ObjCName(Ctx.getObjcName(D)),
IsImplicit(D->isImplicit()),
IsDeprecated(D->getAttrs().getDeprecated(D->getASTContext())),
IsABIPlaceholder(isABIPlaceholderRecursive(D)) {
// Force some attributes that are lazily computed.
// FIXME: we should use these AST predicates directly instead of looking at
// the attributes rdar://50217247.
if (auto *VD = dyn_cast<ValueDecl>(D)) {
(void) VD->isObjC();
(void) VD->isFinal();
(void) VD->isDynamic();
}
// Capture all attributes.
auto AllAttrs = D->getAttrs();
std::transform(AllAttrs.begin(), AllAttrs.end(), std::back_inserter(DeclAttrs),
[](DeclAttribute *attr) { return attr->getKind(); });
}
IsABIPlaceholder(isABIPlaceholderRecursive(D)),
DeclAttrs(collectDeclAttributes(D)) {}
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, OperatorDecl *OD):
SDKNodeInitInfo(Ctx, cast<Decl>(OD)) {