Repository: apple/swift
File: lib/ClangImporter/ClangImporter.cpp (C++)

Code before:
}

// For certain types when the special member functions just forward to the
// members' special member functions we can derive escapability from the
// constituents.
static bool canDeriveEscapabilityFromMembers(const clang::CXXRecordDecl *decl) {
  // Do not do any inference for polymoprhic types as we might not know the
  // semantics of the derived types that can be used through base pointers.
  if (decl->isPolymorphic())
    return false;

  for (auto *ctor : decl->ctors()) {
    if ((ctor->isCopyConstructor() || ctor->isMoveConstructor()) &&
        ctor->isUserProvided())
      return false;
  }

  if (auto *dtor = decl->getDestructor()) {
    if (dtor->isUserProvided())
      return false;
  }

  return true;
}

static bool hasSwiftAttribute(const clang::Decl *decl, StringRef attr);

CxxEscapability
ClangTypeEscapability::evaluate(Evaluator &evaluator,
                                EscapabilityLookupDescriptor desc) const {

  // Escapability inference rules:
  // - array and vector types have the same escapability as their element type
  // - pointer and reference types are currently imported as unknown
  // (importing them as non-escapable broke backward compatibility)
  // - a record type is escapable or non-escapable if it is explicitly annotated
  // as such
  // - a record type is escapable if it is annotated with SWIFT_ESCAPABLE_IF()
  // and none of the annotation arguments are non-escapable
  // - a non-cxx record, or a CxxRecordDecl where the special member functions
  // are forwarding to the fields' special member functions, is escapable if
  // none of their fields or bases are non-escapable (as long as they have a
  // definition)
  //   * for more complex CxxRecordDecls, we rely solely on escapability
  //   annotations
  // - in all other cases, the record has unknown escapability (e.g. no
  // escapability annotations, malformed escapability annotations)

  bool hasUnknown = false;
  llvm::SmallVector<const clang::Type *, 4> stack;
  // Keep track of Types we've seen to avoid cycles

Review comment (refactor):
Should we just move this to a header? I think it would be useful in other parts of ClangImporter also

Code after:
}

// For certain types when the special member functions just forward to the
// members' special member functions we can derive escapability from the
// constituents.
static bool canDeriveEscapabilityFromMembers(const clang::CXXRecordDecl *decl) {
  // Do not do any inference for polymoprhic types as we might not know the
  // semantics of the derived types that can be used through base pointers.
  if (decl->isPolymorphic())
    return false;

  for (auto *ctor : decl->ctors()) {
    if ((ctor->isCopyConstructor() || ctor->isMoveConstructor()) &&
        ctor->isUserProvided())
      return false;
  }

  if (auto *dtor = decl->getDestructor()) {
    if (dtor->isUserProvided())
      return false;
  }

  for (auto *method : decl->methods()) {
    if ((method->isMoveAssignmentOperator() ||
         method->isCopyAssignmentOperator()) &&
        method->isUserProvided())
      return false;
  }

  return true;
}

CxxEscapability
ClangTypeEscapability::evaluate(Evaluator &evaluator,
                                EscapabilityLookupDescriptor desc) const {

  // Escapability inference rules:
  // - array and vector types have the same escapability as their element type
  // - pointer and reference types are currently imported as unknown
  // (importing them as non-escapable broke backward compatibility)
  // - a record type is escapable or non-escapable if it is explicitly annotated
  // as such
  // - a record type is escapable if it is annotated with SWIFT_ESCAPABLE_IF()
  // and none of the annotation arguments are non-escapable
  // - a non-cxx record, or a CxxRecordDecl where the special member functions
  // are forwarding to the fields' special member functions, is escapable if
  // none of their fields or bases are non-escapable (as long as they have a
  // definition)
  //   * for more complex CxxRecordDecls, we rely solely on escapability
  //   annotations
  // - in all other cases, the record has unknown escapability (e.g. no