From f4ac79a364f2de7270a3238b176e17b40b036305 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 8 Sep 2020 20:06:07 +0000 Subject: [PATCH] Sema: extract a check for `isCFError` (NFC) Extract a simple check to check if a `RecordDecl` is a `CFError` Decl. This is a simple refactoring to prepare for an upcoming change. NFC. Patch is extracted from https://github.com/llvm/llvm-project-staging/commit/8afaf3aad2af43cfedca7a24cd817848c4e95c0c. --- clang/include/clang/Sema/Sema.h | 1 + clang/lib/Sema/SemaType.cpp | 52 +++++++++++++++++---------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 53d0285d3702..129ac0355c87 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12415,6 +12415,7 @@ public: /// The struct behind the CFErrorRef pointer. RecordDecl *CFError = nullptr; + bool isCFError(RecordDecl *D); /// Retrieve the identifier "NSError". IdentifierInfo *getNSErrorIdent(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 03442fb03b3a..d8ea9c037259 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -4043,32 +4043,9 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, if (auto recordType = type->getAs()) { RecordDecl *recordDecl = recordType->getDecl(); - bool isCFError = false; - if (S.CFError) { - // If we already know about CFError, test it directly. - isCFError = (S.CFError == recordDecl); - } else { - // Check whether this is CFError, which we identify based on its bridge - // to NSError. CFErrorRef used to be declared with "objc_bridge" but is - // now declared with "objc_bridge_mutable", so look for either one of - // the two attributes. - if (recordDecl->getTagKind() == TTK_Struct && numNormalPointers > 0) { - IdentifierInfo *bridgedType = nullptr; - if (auto bridgeAttr = recordDecl->getAttr()) - bridgedType = bridgeAttr->getBridgedType(); - else if (auto bridgeAttr = - recordDecl->getAttr()) - bridgedType = bridgeAttr->getBridgedType(); - - if (bridgedType == S.getNSErrorIdent()) { - S.CFError = recordDecl; - isCFError = true; - } - } - } - // If this is CFErrorRef*, report it as such. - if (isCFError && numNormalPointers == 2 && numTypeSpecifierPointers < 2) { + if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 && + S.isCFError(recordDecl)) { return PointerDeclaratorKind::CFErrorRefPointer; } break; @@ -4092,6 +4069,31 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, } } +bool Sema::isCFError(RecordDecl *RD) { + // If we already know about CFError, test it directly. + if (CFError) + return CFError == RD; + + // Check whether this is CFError, which we identify based on its bridge to + // NSError. CFErrorRef used to be declared with "objc_bridge" but is now + // declared with "objc_bridge_mutable", so look for either one of the two + // attributes. + if (RD->getTagKind() == TTK_Struct) { + IdentifierInfo *bridgedType = nullptr; + if (auto bridgeAttr = RD->getAttr()) + bridgedType = bridgeAttr->getBridgedType(); + else if (auto bridgeAttr = RD->getAttr()) + bridgedType = bridgeAttr->getBridgedType(); + + if (bridgedType == getNSErrorIdent()) { + CFError = RD; + return true; + } + } + + return false; +} + static FileID getNullabilityCompletenessCheckFileID(Sema &S, SourceLocation loc) { // If we're anywhere in a function, method, or closure context, don't perform