================ @@ -0,0 +1,995 @@ +//===--- SemaAPINotes.cpp - API Notes Handling ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the mapping from API notes to declaration attributes. +// +//===----------------------------------------------------------------------===// + +#include "clang/APINotes/APINotesReader.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" +#include "clang/Sema/SemaInternal.h" + +using namespace clang; + +namespace { +enum class IsActive_t : bool { Inactive, Active }; +enum class IsReplacement_t : bool { Original, Replacement }; + +struct VersionedInfoMetadata { + /// An empty version refers to unversioned metadata. + VersionTuple Version; + unsigned IsActive : 1; + unsigned IsReplacement : 1; + + VersionedInfoMetadata(VersionTuple Version, IsActive_t Active, + IsReplacement_t Replacement) + : Version(Version), IsActive(Active == IsActive_t::Active), + IsReplacement(Replacement == IsReplacement_t::Replacement) {} +}; +} // end anonymous namespace + +/// Determine whether this is a multi-level pointer type. +static bool isIndirectPointerType(QualType Type) { + QualType Pointee = Type->getPointeeType(); + if (Pointee.isNull()) + return false; + + return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() || + Pointee->isMemberPointerType(); +} + +/// Apply nullability to the given declaration. +static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability, + VersionedInfoMetadata Metadata) { + if (!Metadata.IsActive) + return; + + QualType Type; + + // Nullability for a function/method appertains to the retain type. + if (auto Function = dyn_cast<FunctionDecl>(D)) + Type = Function->getReturnType(); + else if (auto Method = dyn_cast<ObjCMethodDecl>(D)) + Type = Method->getReturnType(); + else if (auto Value = dyn_cast<ValueDecl>(D)) + Type = Value->getType(); + else if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) + Type = Property->getType(); + + if (Type.isNull()) + return; + + // Check the nullability specifier on this type. + QualType OrigType = Type; + S.CheckImplicitNullabilityTypeSpecifier(Type, Nullability, D->getLocation(), + isa<ParmVarDecl>(D), + /*overrideExisting=*/true); + if (Type.getTypePtr() == OrigType.getTypePtr()) + return; + + if (auto Function = dyn_cast<FunctionDecl>(D)) { + QualType FnType = Function->getType(); + Function->setType(FnType); + } else if (auto Method = dyn_cast<ObjCMethodDecl>(D)) { + Method->setReturnType(Type); + + // Make it a context-sensitive keyword if we can. + if (!isIndirectPointerType(Type)) + Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier( + Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability)); + + } else if (auto Value = dyn_cast<ValueDecl>(D)) { + Value->setType(Type); + + // Make it a context-sensitive keyword if we can. + if (auto Parm = dyn_cast<ParmVarDecl>(D)) { + if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type)) + Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier( + Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability)); + } + } else if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) { + Property->setType(Type, Property->getTypeSourceInfo()); + + // Make it a property attribute if we can. + if (!isIndirectPointerType(Type)) + Property->setPropertyAttributes( + ObjCPropertyAttribute::kind_null_resettable); + + } else + llvm_unreachable("cannot handle nullability here"); ---------------- compnerd wrote:
That should allow us to get rid of this as well. https://github.com/llvm/llvm-project/pull/78445 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits