<commit_before>//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements semantic analysis for Objective C @property and
//  @synthesize declarations.
//
//===----------------------------------------------------------------------===//

#include "Sema.h"

using namespace clang;

//===----------------------------------------------------------------------===//
// Grammar actions.
//===----------------------------------------------------------------------===//

Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
                                    FieldDeclarator &FD,
                                    ObjCDeclSpec &ODS,
                                    Selector GetterSel,
                                    Selector SetterSel,
                                    DeclPtrTy ClassCategory,
                                    bool *isOverridingProperty,
                                    tok::ObjCKeywordKind MethodImplKind) {
  unsigned Attributes = ODS.getPropertyAttributes();
  bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
                      // default is readwrite!
                      !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
  // property is defaulted to 'assign' if it is readwrite and is
  // not retain or copy
  bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
                   (isReadWrite &&
                    !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
                    !(Attributes & ObjCDeclSpec::DQ_PR_copy)));

  QualType T = GetTypeForDeclarator(FD.D, S);
  if (T->isReferenceType()) {
    Diag(AtLoc, diag::error_reference_property);
    return DeclPtrTy();
  }
  // Validate the attributes on the @property.
  CheckObjCPropertyAttributes(T, AtLoc, Attributes);

  // Proceed with constructing the ObjCPropertDecls.
  ObjCContainerDecl *ClassDecl =
    cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());

  if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
    if (CDecl->IsClassExtension())
      return HandlePropertyInClassExtension(S, CDecl, AtLoc,
                                            FD, GetterSel, SetterSel,
                                            isAssign, isReadWrite,
                                            Attributes,
                                            isOverridingProperty, T,
                                            MethodImplKind);

  return DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
                                            GetterSel, SetterSel,
                                            isAssign, isReadWrite,
                                            Attributes, T, MethodImplKind));
}

Sema::DeclPtrTy
Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
                                     SourceLocation AtLoc, FieldDeclarator &FD,
                                     Selector GetterSel, Selector SetterSel,
                                     const bool isAssign,
                                     const bool isReadWrite,
                                     const unsigned Attributes,
                                     bool *isOverridingProperty,
                                     QualType T,
                                     tok::ObjCKeywordKind MethodImplKind) {

  // Diagnose if this property is already in continuation class.
  DeclContext *DC = cast<DeclContext>(CDecl);
  IdentifierInfo *PropertyId = FD.D.getIdentifier();

  if (ObjCPropertyDecl *prevDecl =
        ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
    Diag(AtLoc, diag::err_duplicate_property);
    Diag(prevDecl->getLocation(), diag::note_property_declare);
    return DeclPtrTy();
  }

  // Create a new ObjCPropertyDecl with the DeclContext being
  // the class extension.
  ObjCPropertyDecl *PDecl =
    ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(),
                             PropertyId, AtLoc, T);
  DC->addDecl(PDecl);

  // We need to look in the @interface to see if the @property was
  // already declared.
  ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
  if (!CCPrimary) {
    Diag(CDecl->getLocation(), diag::err_continuation_class);
    *isOverridingProperty = true;
    return DeclPtrTy();
  }

  // Find the property in continuation class's primary class only.
  ObjCPropertyDecl *PIDecl =
    CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId);

  if (!PIDecl) {
    // No matching property found in the primary class. Just fall thru
    // and add property to continuation class's primary class.
    ObjCPropertyDecl *PDecl =
      CreatePropertyDecl(S, CCPrimary, AtLoc,
                         FD, GetterSel, SetterSel, isAssign, isReadWrite,
                         Attributes, T, MethodImplKind);

    // A case of continuation class adding a new property in the class. This
    // is not what it was meant for. However, gcc supports it and so should we.
    // Make sure setter/getters are declared here.
    ProcessPropertyDecl(PDecl, CCPrimary);
    return DeclPtrTy::make(PDecl);

  }

  // The property 'PIDecl's readonly attribute will be over-ridden
  // with continuation class's readwrite property attribute!
  unsigned PIkind = PIDecl->getPropertyAttributes();
  if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
    unsigned retainCopyNonatomic =
    (ObjCPropertyDecl::OBJC_PR_retain |
     ObjCPropertyDecl::OBJC_PR_copy |
     ObjCPropertyDecl::OBJC_PR_nonatomic);
    if ((Attributes & retainCopyNonatomic) !=
        (PIkind & retainCopyNonatomic)) {
      Diag(AtLoc, diag::warn_property_attr_mismatch);
      Diag(PIDecl->getLocation(), diag::note_property_declare);
    }
    DeclContext *DC = dyn_cast<DeclContext>(CCPrimary);
    assert(DC && "ClassDecl is not a DeclContext");
    DeclContext::lookup_result Found =
    DC->lookup(PIDecl->getDeclName());
    bool PropertyInPrimaryClass = false;
    for (; Found.first != Found.second; ++Found.first)
      if (isa<ObjCPropertyDecl>(*Found.first)) {
        PropertyInPrimaryClass = true;
        break;
      }
    if (!PropertyInPrimaryClass) {
      // Protocol is not in the primary class. Must build one for it.
      ObjCDeclSpec ProtocolPropertyODS;
      // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind
      // and ObjCPropertyDecl::PropertyAttributeKind have identical
      // values.  Should consolidate both into one enum type.
      ProtocolPropertyODS.
      setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
                            PIkind);

      DeclPtrTy ProtocolPtrTy =
        ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
                      PIDecl->getGetterName(),
                      PIDecl->getSetterName(),
                      DeclPtrTy::make(CCPrimary), isOverridingProperty,
                      MethodImplKind);
      PIDecl = ProtocolPtrTy.getAs<ObjCPropertyDecl>();
    }
    PIDecl->makeitReadWriteAttribute();
    if (Attributes & ObjCDeclSpec::DQ_PR_retain)
      PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
    if (Attributes & ObjCDeclSpec::DQ_PR_copy)
      PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
    PIDecl->setSetterName(SetterSel);
  } else {
    Diag(AtLoc, diag::err_use_continuation_class)
      << CCPrimary->getDeclName();<commit_msg>Simplify code (and remove 'dyn_cast') by using ObjCProperyDecl::findPropertyDecl().<commit_after>//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements semantic analysis for Objective C @property and
//  @synthesize declarations.
//
//===----------------------------------------------------------------------===//

#include "Sema.h"

using namespace clang;

//===----------------------------------------------------------------------===//
// Grammar actions.
//===----------------------------------------------------------------------===//

Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
                                    FieldDeclarator &FD,
                                    ObjCDeclSpec &ODS,
                                    Selector GetterSel,
                                    Selector SetterSel,
                                    DeclPtrTy ClassCategory,
                                    bool *isOverridingProperty,
                                    tok::ObjCKeywordKind MethodImplKind) {
  unsigned Attributes = ODS.getPropertyAttributes();
  bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
                      // default is readwrite!
                      !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
  // property is defaulted to 'assign' if it is readwrite and is
  // not retain or copy
  bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
                   (isReadWrite &&
                    !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
                    !(Attributes & ObjCDeclSpec::DQ_PR_copy)));

  QualType T = GetTypeForDeclarator(FD.D, S);
  if (T->isReferenceType()) {
    Diag(AtLoc, diag::error_reference_property);
    return DeclPtrTy();
  }
  // Validate the attributes on the @property.
  CheckObjCPropertyAttributes(T, AtLoc, Attributes);

  // Proceed with constructing the ObjCPropertDecls.
  ObjCContainerDecl *ClassDecl =
    cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());

  if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
    if (CDecl->IsClassExtension())
      return HandlePropertyInClassExtension(S, CDecl, AtLoc,
                                            FD, GetterSel, SetterSel,
                                            isAssign, isReadWrite,
                                            Attributes,
                                            isOverridingProperty, T,
                                            MethodImplKind);

  return DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
                                            GetterSel, SetterSel,
                                            isAssign, isReadWrite,
                                            Attributes, T, MethodImplKind));
}

Sema::DeclPtrTy
Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
                                     SourceLocation AtLoc, FieldDeclarator &FD,
                                     Selector GetterSel, Selector SetterSel,
                                     const bool isAssign,
                                     const bool isReadWrite,
                                     const unsigned Attributes,
                                     bool *isOverridingProperty,
                                     QualType T,
                                     tok::ObjCKeywordKind MethodImplKind) {

  // Diagnose if this property is already in continuation class.
  DeclContext *DC = cast<DeclContext>(CDecl);
  IdentifierInfo *PropertyId = FD.D.getIdentifier();

  if (ObjCPropertyDecl *prevDecl =
        ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
    Diag(AtLoc, diag::err_duplicate_property);
    Diag(prevDecl->getLocation(), diag::note_property_declare);
    return DeclPtrTy();
  }

  // Create a new ObjCPropertyDecl with the DeclContext being
  // the class extension.
  ObjCPropertyDecl *PDecl =
    ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(),
                             PropertyId, AtLoc, T);
  DC->addDecl(PDecl);

  // We need to look in the @interface to see if the @property was
  // already declared.
  ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
  if (!CCPrimary) {
    Diag(CDecl->getLocation(), diag::err_continuation_class);
    *isOverridingProperty = true;
    return DeclPtrTy();
  }

  // Find the property in continuation class's primary class only.
  ObjCPropertyDecl *PIDecl =
    CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId);

  if (!PIDecl) {
    // No matching property found in the primary class. Just fall thru
    // and add property to continuation class's primary class.
    ObjCPropertyDecl *PDecl =
      CreatePropertyDecl(S, CCPrimary, AtLoc,
                         FD, GetterSel, SetterSel, isAssign, isReadWrite,
                         Attributes, T, MethodImplKind);

    // A case of continuation class adding a new property in the class. This
    // is not what it was meant for. However, gcc supports it and so should we.
    // Make sure setter/getters are declared here.
    ProcessPropertyDecl(PDecl, CCPrimary);
    return DeclPtrTy::make(PDecl);

  }

  // The property 'PIDecl's readonly attribute will be over-ridden
  // with continuation class's readwrite property attribute!
  unsigned PIkind = PIDecl->getPropertyAttributes();
  if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
    unsigned retainCopyNonatomic =
    (ObjCPropertyDecl::OBJC_PR_retain |
     ObjCPropertyDecl::OBJC_PR_copy |
     ObjCPropertyDecl::OBJC_PR_nonatomic);
    if ((Attributes & retainCopyNonatomic) !=
        (PIkind & retainCopyNonatomic)) {
      Diag(AtLoc, diag::warn_property_attr_mismatch);
      Diag(PIDecl->getLocation(), diag::note_property_declare);
    }
    DeclContext *DC = cast<DeclContext>(CCPrimary);
    if (!ObjCPropertyDecl::findPropertyDecl(DC,
                                 PIDecl->getDeclName().getAsIdentifierInfo())) {
      // Protocol is not in the primary class. Must build one for it.
      ObjCDeclSpec ProtocolPropertyODS;
      // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind
      // and ObjCPropertyDecl::PropertyAttributeKind have identical
      // values.  Should consolidate both into one enum type.
      ProtocolPropertyODS.
      setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
                            PIkind);

      DeclPtrTy ProtocolPtrTy =
        ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
                      PIDecl->getGetterName(),
                      PIDecl->getSetterName(),
                      DeclPtrTy::make(CCPrimary), isOverridingProperty,
                      MethodImplKind);
      PIDecl = ProtocolPtrTy.getAs<ObjCPropertyDecl>();
    }
    PIDecl->makeitReadWriteAttribute();
    if (Attributes & ObjCDeclSpec::DQ_PR_retain)
      PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
    if (Attributes & ObjCDeclSpec::DQ_PR_copy)
      PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
    PIDecl->setSetterName(SetterSel);
  } else {
    Diag(AtLoc, diag::err_use_continuation_class)
      << CCPrimary->getDeclName();
{'fraction_non_alphanumeric': 0.12684346273394617, 'fraction_numerical': 0.0, 'mean_word_length': 1.908076923076923, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 67, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6485634', 'n_tokens_mistral': 4054, 'n_tokens_neox': 3794, 'n_words': 914}