//===--- ClangAdapter.cpp - Interfaces with Clang entities ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file provides convenient and canonical interfaces with Clang entities,
// serving as both a useful place to put utility functions and a canonical
// interface that can abstract nitty gritty Clang internal details.
//
//===----------------------------------------------------------------------===//

#include "CFTypeInfo.h"
#include "ClangAdapter.h"
#include "ImportName.h"
#include "ImporterImpl.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Lex/Lexer.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"

using namespace swift;
using namespace importer;

/// Get a bit vector indicating which arguments are non-null for a
/// given function or method.
llvm::SmallBitVector
importer::getNonNullArgs(const clang::Decl *decl,
                         ArrayRef<const clang::ParmVarDecl *> params) {
  llvm::SmallBitVector result;
  if (!decl)
    return result;

  for (const auto *nonnull : decl->specific_attrs<clang::NonNullAttr>()) {
    if (!nonnull->args_size()) {
      // Easy case: all pointer arguments are non-null.
      if (result.empty())
        result.resize(params.size(), true);
      else
        result.set(0, params.size());

      return result;
    }

    // Mark each of the listed parameters as non-null.
    if (result.empty())
      result.resize(params.size(), false);

    for (unsigned idx : nonnull->args()) {
      if (idx < result.size())
        result.set(idx);
    }
  }

  return result;
}

Optional<const clang::Decl *>
importer::getDefinitionForClangTypeDecl(const clang::Decl *D) {
  if (auto OID = dyn_cast<clang::ObjCInterfaceDecl>(D))
    return OID->getDefinition();

  if (auto TD = dyn_cast<clang::TagDecl>(D))
    return TD->getDefinition();

  if (auto OPD = dyn_cast<clang::ObjCProtocolDecl>(D))
    return OPD->getDefinition();

  return None;
}

Optional<clang::Module *>
importer::getClangSubmoduleForDecl(const clang::Decl *D,
                                   bool allowForwardDeclaration) {
  const clang::Decl *actual = nullptr;

  // Put an Objective-C class into the module that contains the @interface
  // definition, not just some @class forward declaration.
  if (auto maybeDefinition = getDefinitionForClangTypeDecl(D)) {
    actual = maybeDefinition.getValue();
    if (!actual && !allowForwardDeclaration)
      return None;
  }

  if (!actual)
    actual = D->getCanonicalDecl();

  return actual->getImportedOwningModule();
}

/// Retrieve the instance type of the given Clang declaration context.
clang::QualType
importer::getClangDeclContextType(const clang::DeclContext *dc) {
  auto &ctx = dc->getParentASTContext();
  if (auto objcClass = dyn_cast<clang::ObjCInterfaceDecl>(dc))
    return ctx.getObjCObjectPointerType(ctx.getObjCInterfaceType(objcClass));

  if (auto objcCategory = dyn_cast<clang::ObjCCategoryDecl>(dc)) {
    if (objcCategory->isInvalidDecl())
      return clang::QualType();

    return ctx.getObjCObjectPointerType(
        ctx.getObjCInterfaceType(objcCategory->getClassInterface()));
  }

  if (auto constProto = dyn_cast<clang::ObjCProtocolDecl>(dc)) {
    auto proto = const_cast<clang::ObjCProtocolDecl *>(constProto);
    auto type = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, {}, {proto}, false);
    return ctx.getObjCObjectPointerType(type);
  }

  if (auto tag = dyn_cast<clang::TagDecl>(dc)) {
    return ctx.getTagDeclType(tag);
  }

  return clang::QualType();
}

/// Determine whether this is the name of a collection with a single
/// element type.
static bool isCollectionName(StringRef typeName) {
  auto lastWord = camel_case::getLastWord(typeName);
  return lastWord == "Array" || lastWord == "Set";
}

/// Retrieve the name of the given Clang type for use when omitting
/// needless words.
OmissionTypeName importer::getClangTypeNameForOmission(clang::ASTContext &ctx,
                                                       clang::QualType type) {
  if (type.isNull())
    return OmissionTypeName();

  // Dig through the type, looking for a typedef-name and stripping
  // references along the way.
  StringRef lastTypedefName;
  do {
    // The name of a typedef-name.
    auto typePtr = type.getTypePtr();
    if (auto typedefType = dyn_cast<clang::TypedefType>(typePtr)) {
      auto name = typedefType->getDecl()->getName();

      // Objective-C selector type.
      if (ctx.hasSameUnqualifiedType(type, ctx.getObjCSelType()) &&
          name == "SEL")
        return "Selector";

      // Objective-C "id" type.
      if (type->isObjCIdType() && name == "id")
        return "Object";

      // Objective-C "Class" type.
      if (type->isObjCClassType() && name == "Class")
        return "Class";

      // Objective-C "BOOL" type.
      if (name == "BOOL")
        return OmissionTypeName("Bool", OmissionTypeFlags::Boolean);

      // If this is an imported CF type, use that name.
      StringRef CFName = getCFTypeName(typedefType->getDecl());
      if (!CFName.empty())
        return CFName;

      // If we have NS(U)Integer or CGFloat, return it.
      if (name == "NSInteger" || name == "NSUInteger" || name == "CGFloat")
        return name;

      // If it's a collection name and of pointer type, call it an
      // array of the pointee type.
      if (isCollectionName(name)) {
        if (auto ptrType = type->getAs<clang::PointerType>()) {
          return OmissionTypeName(
              name, None,
              getClangTypeNameForOmission(ctx, ptrType->getPointeeType()).Name);
        }
      }

      // Otherwise, desugar one level...
      lastTypedefName = name;
      type = typedefType->getDecl()->getUnderlyingType();
      continue;
    }

    // For array types, convert the element type and treat this an as array.
    if (auto arrayType = dyn_cast<clang::ArrayType>(typePtr)) {
      return OmissionTypeName(
          "Array", None,
          getClangTypeNameForOmission(ctx, arrayType->getElementType()).Name);
    }

    // Look through reference types.
    if (auto refType = dyn_cast<clang::ReferenceType>(typePtr)) {
      type = refType->getPointeeTypeAsWritten();
      continue;
    }

    // Look through pointer types.
    if (auto ptrType = dyn_cast<clang::PointerType>(typePtr)) {
      type = ptrType->getPointeeType();
      continue;
    }

    // Try to desugar one level...
    clang::QualType desugared = type.getSingleStepDesugaredType(ctx);
    if (desugared.getTypePtr() == type.getTypePtr())
      break;

    type = desugared;
  } while (true);

  // Objective-C object pointers.
  if (auto objcObjectPtr = type->getAs<clang::ObjCObjectPointerType>()) {
    auto objcClass = objcObjectPtr->getInterfaceDecl();

    // For id<Proto> or NSObject<Proto>, retrieve the name of "Proto".
    if (objcObjectPtr->getNumProtocols() == 1 &&
        (!objcClass || objcClass->getName() == "NSObject"))
      return (*objcObjectPtr->qual_begin())->getName();

    // If there is a class, use it.
    if (objcClass) {
      // If this isn't the name of an Objective-C collection, we're done.
      auto className = objcClass->getName();
      if (!isCollectionName(className))
        return className;

      // If we don't have type parameters, use the prefix of the type
      // name as the collection element type.
      if (objcClass && !objcClass->getTypeParamList()) {
        unsigned lastWordSize = camel_case::getLastWord(className).size();
        StringRef elementName =
            className.substr(0, className.size() - lastWordSize);
        return OmissionTypeName(className, None, elementName);
      }

      // If we don't have type arguments, the collection element type
      // is "Object".
      auto typeArgs = objcObjectPtr->getTypeArgs();
      if (typeArgs.empty())
        return OmissionTypeName(className, None, "Object");

      return OmissionTypeName(
          className, None, getClangTypeNameForOmission(ctx, typeArgs[0]).Name);
    }

    // Objective-C "id" type.
    if (objcObjectPtr->isObjCIdType())
      return "Object";

    // Objective-C "Class" type.
    if (objcObjectPtr->isObjCClassType())
      return "Class";

    return StringRef();
  }

  // Handle builtin types by importing them and getting the Swift name.
  if (auto builtinTy = type->getAs<clang::BuiltinType>()) {
    // Names of integer types.
    static const char *intTypeNames[] = {"UInt8", "UInt16", "UInt32", "UInt64",
                                         "UInt128"};

    /// Retrieve the name for an integer type based on its size.
    auto getIntTypeName = [&](bool isSigned) -> StringRef {
      switch (ctx.getTypeSize(builtinTy)) {
      case 8:
        return StringRef(intTypeNames[0]).substr(isSigned ? 1 : 0);
      case 16:
        return StringRef(intTypeNames[1]).substr(isSigned ? 1 : 0);
      case 32:
        return StringRef(intTypeNames[2]).substr(isSigned ? 1 : 0);
      case 64:
        return StringRef(intTypeNames[3]).substr(isSigned ? 1 : 0);
      case 128:
        return StringRef(intTypeNames[4]).substr(isSigned ? 1 : 0);
      default:
        llvm_unreachable("bad integer type size");
      }
    };

    switch (builtinTy->getKind()) {
    case clang::BuiltinType::Void:
      return "Void";

    case clang::BuiltinType::Bool:
      return OmissionTypeName("Bool", OmissionTypeFlags::Boolean);

    case clang::BuiltinType::Float:
      return "Float";

    case clang::BuiltinType::Double:
      return "Double";

    case clang::BuiltinType::Char16:
      return "UInt16";

    case clang::BuiltinType::Char32:
      return "UnicodeScalar";

    case clang::BuiltinType::Char_U:
    case clang::BuiltinType::UChar:
    case clang::BuiltinType::UShort:
    case clang::BuiltinType::UInt:
    case clang::BuiltinType::ULong:
    case clang::BuiltinType::ULongLong:
    case clang::BuiltinType::UInt128:
    case clang::BuiltinType::WChar_U:
      return getIntTypeName(false);

    case clang::BuiltinType::Char_S:
    case clang::BuiltinType::SChar:
    case clang::BuiltinType::Short:
    case clang::BuiltinType::Int:
    case clang::BuiltinType::Long:
    case clang::BuiltinType::LongLong:
    case clang::BuiltinType::Int128:
    case clang::BuiltinType::WChar_S:
      return getIntTypeName(true);

    // Types that cannot be mapped into Swift, and probably won't ever be.
    case clang::BuiltinType::Dependent:
    case clang::BuiltinType::ARCUnbridgedCast:
    case clang::BuiltinType::BoundMember:
    case clang::BuiltinType::BuiltinFn:
    case clang::BuiltinType::Overload:
    case clang::BuiltinType::PseudoObject:
    case clang::BuiltinType::UnknownAny:
      return OmissionTypeName();

    // FIXME: Types that can be mapped, but aren't yet.
    case clang::BuiltinType::Half:
    case clang::BuiltinType::LongDouble:
    case clang::BuiltinType::Float128:
    case clang::BuiltinType::NullPtr:
      return OmissionTypeName();

    // Objective-C types that aren't mapped directly; rather, pointers to
    // these types will be mapped.
    case clang::BuiltinType::ObjCClass:
    case clang::BuiltinType::ObjCId:
    case clang::BuiltinType::ObjCSel:
      return OmissionTypeName();

    // OpenCL types that don't have Swift equivalents.
    case clang::BuiltinType::OCLImage1dRO:
    case clang::BuiltinType::OCLImage1dRW:
    case clang::BuiltinType::OCLImage1dWO:
    case clang::BuiltinType::OCLImage1dArrayRO:
    case clang::BuiltinType::OCLImage1dArrayRW:
    case clang::BuiltinType::OCLImage1dArrayWO:
    case clang::BuiltinType::OCLImage1dBufferRO:
    case clang::BuiltinType::OCLImage1dBufferRW:
    case clang::BuiltinType::OCLImage1dBufferWO:
    case clang::BuiltinType::OCLImage2dRO:
    case clang::BuiltinType::OCLImage2dRW:
    case clang::BuiltinType::OCLImage2dWO:
    case clang::BuiltinType::OCLImage2dArrayRO:
    case clang::BuiltinType::OCLImage2dArrayRW:
    case clang::BuiltinType::OCLImage2dArrayWO:
    case clang::BuiltinType::OCLImage2dDepthRO:
    case clang::BuiltinType::OCLImage2dDepthRW:
    case clang::BuiltinType::OCLImage2dDepthWO:
    case clang::BuiltinType::OCLImage2dArrayDepthRO:
    case clang::BuiltinType::OCLImage2dArrayDepthRW:
    case clang::BuiltinType::OCLImage2dArrayDepthWO:
    case clang::BuiltinType::OCLImage2dMSAARO:
    case clang::BuiltinType::OCLImage2dMSAARW:
    case clang::BuiltinType::OCLImage2dMSAAWO:
    case clang::BuiltinType::OCLImage2dArrayMSAARO:
    case clang::BuiltinType::OCLImage2dArrayMSAARW:
    case clang::BuiltinType::OCLImage2dArrayMSAAWO:
    case clang::BuiltinType::OCLImage2dMSAADepthRO:
    case clang::BuiltinType::OCLImage2dMSAADepthRW:
    case clang::BuiltinType::OCLImage2dMSAADepthWO:
    case clang::BuiltinType::OCLImage2dArrayMSAADepthRO:
    case clang::BuiltinType::OCLImage2dArrayMSAADepthRW:
    case clang::BuiltinType::OCLImage2dArrayMSAADepthWO:
    case clang::BuiltinType::OCLImage3dRO:
    case clang::BuiltinType::OCLImage3dRW:
    case clang::BuiltinType::OCLImage3dWO:
    case clang::BuiltinType::OCLSampler:
    case clang::BuiltinType::OCLEvent:
    case clang::BuiltinType::OCLClkEvent:
    case clang::BuiltinType::OCLQueue:
    case clang::BuiltinType::OCLReserveID:
      return OmissionTypeName();

    // OpenMP types that don't have Swift equivalents.
    case clang::BuiltinType::OMPArraySection:
      return OmissionTypeName();
    }
  }

  // Tag types.
  if (auto tagType = type->getAs<clang::TagType>()) {
    if (tagType->getDecl()->getName().empty())
      return lastTypedefName;

    return tagType->getDecl()->getName();
  }

  // Block pointers.
  if (type->getAs<clang::BlockPointerType>())
    return OmissionTypeName("Block", OmissionTypeFlags::Function);

  // Function pointers.
  if (type->isFunctionType())
    return OmissionTypeName("Function", OmissionTypeFlags::Function);

  return StringRef();
}

static clang::SwiftNewtypeAttr *
retrieveNewTypeAttr(const clang::TypedefNameDecl *decl) {
  // Retrieve the attribute.
  auto attr = decl->getAttr<clang::SwiftNewtypeAttr>();
  if (!attr)
    return nullptr;

  // FIXME: CFErrorDomain is marked as CF_EXTENSIBLE_STRING_ENUM, but it turned
  // out to be more disruptive than not to leave it that way.
  auto name = decl->getName();
  if (name == "CFErrorDomain")
    return nullptr;

  return attr;
}

clang::SwiftNewtypeAttr *
importer::getSwiftNewtypeAttr(const clang::TypedefNameDecl *decl,
                              ImportNameVersion version) {
  // Newtype was introduced in Swift 3
  if (version <= ImportNameVersion::swift2())
    return nullptr;
  return retrieveNewTypeAttr(decl);
}

// If this decl is associated with a swift_newtype typedef, return it, otherwise
// null
clang::TypedefNameDecl *importer::findSwiftNewtype(const clang::NamedDecl *decl,
                                                   clang::Sema &clangSema,
                                                   ImportNameVersion version) {
  // Newtype was introduced in Swift 3
  if (version <= ImportNameVersion::swift2())
    return nullptr;

  auto varDecl = dyn_cast<clang::VarDecl>(decl);
  if (!varDecl)
    return nullptr;

  if (auto typedefTy = varDecl->getType()->getAs<clang::TypedefType>())
    if (retrieveNewTypeAttr(typedefTy->getDecl()))
      return typedefTy->getDecl();

  // Special case: "extern NSString * fooNotification" adopts
  // NSNotificationName type, and is a member of NSNotificationName
  if (isNSNotificationGlobal(decl)) {
    clang::IdentifierInfo *notificationName =
        &clangSema.getASTContext().Idents.get("NSNotificationName");
    clang::LookupResult lookupResult(clangSema, notificationName,
                                     clang::SourceLocation(),
                                     clang::Sema::LookupOrdinaryName);
    if (!clangSema.LookupName(lookupResult, nullptr))
      return nullptr;
    auto nsDecl = lookupResult.getAsSingle<clang::TypedefNameDecl>();
    if (!nsDecl)
      return nullptr;

    // Make sure it also has a newtype decl on it
    if (retrieveNewTypeAttr(nsDecl))
      return nsDecl;

    return nullptr;
  }

  return nullptr;
}

bool importer::isNSString(const clang::Type *type) {
  if (auto ptrType = type->getAs<clang::ObjCObjectPointerType>())
    if (auto interfaceType = ptrType->getInterfaceType())
      if (interfaceType->getDecl()->getName() == "NSString")
        return true;
  return false;
}

bool importer::isNSString(clang::QualType qt) {
  return qt.getTypePtrOrNull() && isNSString(qt.getTypePtrOrNull());
}

bool importer::isNSNotificationGlobal(const clang::NamedDecl *decl) {
  // Looking for: extern NSString *fooNotification;

  // Must be extern global variable
  auto vDecl = dyn_cast<clang::VarDecl>(decl);
  if (!vDecl || !vDecl->hasExternalFormalLinkage())
    return false;

  // No explicit swift_name
  if (decl->getAttr<clang::SwiftNameAttr>())
    return false;

  // Must end in Notification
  if (!vDecl->getDeclName().isIdentifier())
    return false;
  if (stripNotification(vDecl->getName()).empty())
    return false;

  // Must be NSString *
  if (!isNSString(vDecl->getType()))
    return false;

  // We're a match!
  return true;
}

bool importer::hasNativeSwiftDecl(const clang::Decl *decl) {
  for (auto annotation : decl->specific_attrs<clang::AnnotateAttr>()) {
    if (annotation->getAnnotation() == SWIFT_NATIVE_ANNOTATION_STRING) {
      return true;
    }
  }

  if (auto *category = dyn_cast<clang::ObjCCategoryDecl>(decl)) {
    clang::SourceLocation categoryNameLoc = category->getCategoryNameLoc();
    if (categoryNameLoc.isMacroID()) {
      // Climb up to the top-most macro invocation.
      clang::ASTContext &clangCtx = category->getASTContext();
      clang::SourceManager &SM = clangCtx.getSourceManager();

      clang::SourceLocation macroCaller =
          SM.getImmediateMacroCallerLoc(categoryNameLoc);
      while (macroCaller.isMacroID()) {
        categoryNameLoc = macroCaller;
        macroCaller = SM.getImmediateMacroCallerLoc(categoryNameLoc);
      }

      StringRef macroName = clang::Lexer::getImmediateMacroName(
          categoryNameLoc, SM, clangCtx.getLangOpts());
      if (macroName == "SWIFT_EXTENSION")
        return true;
    }
  }

  return false;
}

/// Translate the "nullability" notion from API notes into an optional type
/// kind.
OptionalTypeKind importer::translateNullability(clang::NullabilityKind kind) {
  switch (kind) {
  case clang::NullabilityKind::NonNull:
    return OptionalTypeKind::OTK_None;

  case clang::NullabilityKind::Nullable:
    return OptionalTypeKind::OTK_Optional;

  case clang::NullabilityKind::Unspecified:
    return OptionalTypeKind::OTK_ImplicitlyUnwrappedOptional;
  }

  llvm_unreachable("Invalid NullabilityKind.");
}

bool importer::hasDesignatedInitializers(
    const clang::ObjCInterfaceDecl *classDecl) {
  if (classDecl->hasDesignatedInitializers())
    return true;

  return false;
}

bool importer::isDesignatedInitializer(
    const clang::ObjCInterfaceDecl *classDecl,
    const clang::ObjCMethodDecl *method) {
  // If the information is on the AST, use it.
  if (classDecl->hasDesignatedInitializers()) {
    auto *methodParent = method->getClassInterface();
    if (!methodParent ||
        methodParent->getCanonicalDecl() == classDecl->getCanonicalDecl()) {
      return method->hasAttr<clang::ObjCDesignatedInitializerAttr>();
    }
  }

  return false;
}

bool importer::isRequiredInitializer(const clang::ObjCMethodDecl *method) {
  // FIXME: No way to express this in Objective-C.
  return false;
}

/// Check if this method is declared in the context that conforms to
/// NSAccessibility.
static bool isAccessibilityConformingContext(const clang::DeclContext *ctx) {
  const clang::ObjCProtocolList *protocols = nullptr;

  if (auto protocol = dyn_cast<clang::ObjCProtocolDecl>(ctx)) {
    if (protocol->getName() == "NSAccessibility")
      return true;
    return false;
  } else if (auto interface = dyn_cast<clang::ObjCInterfaceDecl>(ctx))
    protocols = &interface->getReferencedProtocols();
  else if (auto category = dyn_cast<clang::ObjCCategoryDecl>(ctx))
    protocols = &category->getReferencedProtocols();
  else
    return false;

  for (auto pi : *protocols) {
    if (pi->getName() == "NSAccessibility")
      return true;
  }
  return false;
}

bool
importer::shouldImportPropertyAsAccessors(const clang::ObjCPropertyDecl *prop) {
  if (prop->hasAttr<clang::SwiftImportPropertyAsAccessorsAttr>())
    return true;

  // Check if the property is one of the specially handled accessibility APIs.
  //
  // These appear as both properties and methods in ObjC and should be
  // imported as methods into Swift, as a sort of least-common-denominator
  // compromise.
  if (!prop->getName().startswith("accessibility"))
    return false;
  if (isAccessibilityConformingContext(prop->getDeclContext()))
    return true;

  return false;
}

bool importer::isInitMethod(const clang::ObjCMethodDecl *method) {
  // init methods are always instance methods.
  if (!method->isInstanceMethod())
    return false;

  // init methods must be classified as such by Clang.
  if (method->getMethodFamily() != clang::OMF_init)
    return false;

  // Swift restriction: init methods must start with the word "init".
  auto selector = method->getSelector();
  return camel_case::getFirstWord(selector.getNameForSlot(0)) == "init";
}

bool importer::isObjCId(const clang::Decl *decl) {
  auto typedefDecl = dyn_cast<clang::TypedefNameDecl>(decl);
  if (!typedefDecl)
    return false;

  if (!typedefDecl->getDeclContext()->getRedeclContext()->isTranslationUnit())
    return false;

  return typedefDecl->getName() == "id";
}

bool importer::isUnavailableInSwift(
    const clang::Decl *decl, const PlatformAvailability &platformAvailability,
    bool enableObjCInterop) {
  // 'id' is always unavailable in Swift.
  if (enableObjCInterop && isObjCId(decl))
    return true;

  if (decl->isUnavailable())
    return true;

  for (auto *attr : decl->specific_attrs<clang::AvailabilityAttr>()) {
    if (attr->getPlatform()->getName() == "swift")
      return true;

    if (platformAvailability.filter &&
        !platformAvailability.filter(attr->getPlatform()->getName())) {
      continue;
    }

    if (platformAvailability.deprecatedAsUnavailableFilter) {
      clang::VersionTuple version = attr->getDeprecated();
      if (version.empty())
        continue;
      if (platformAvailability.deprecatedAsUnavailableFilter(
            version.getMajor(), version.getMinor())) {
        return true;
      }
    }
  }

  return false;
}

OptionalTypeKind importer::getParamOptionality(version::Version swiftVersion,
                                               const clang::ParmVarDecl *param,
                                               bool knownNonNull) {
  auto &clangCtx = param->getASTContext();

  // If nullability is available on the type, use it.
  clang::QualType paramTy = param->getType();
  if (auto nullability = paramTy->getNullability(clangCtx)) {
    return translateNullability(*nullability);
  }

  // If it's known non-null, use that.
  if (knownNonNull || param->hasAttr<clang::NonNullAttr>())
    return OTK_None;

  // Check for the 'static' annotation on C arrays.
  if (!swiftVersion.isVersion3())
    if (const auto *DT = dyn_cast<clang::DecayedType>(paramTy))
      if (const auto *AT = DT->getOriginalType()->getAsArrayTypeUnsafe())
        if (AT->getSizeModifier() == clang::ArrayType::Static)
          return OTK_None;

  // Default to implicitly unwrapped optionals.
  return OTK_ImplicitlyUnwrappedOptional;
}
