text: //===--- SemaType.cpp - Semantic Analysis for Types -----------------------===//
  //
  // 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 type-related semantic analysis.
  //
  //===----------------------------------------------------------------------===//
  
  #include "TypeLocBuilder.h"
  #include "clang/AST/ASTConsumer.h"
  #include "clang/AST/ASTContext.h"
  #include "clang/AST/ASTMutationListener.h"
  #include "clang/AST/ASTStructuralEquivalence.h"
  #include "clang/AST/CXXInheritance.h"
  #include "clang/AST/DeclObjC.h"
  #include "clang/AST/DeclTemplate.h"
  #include "clang/AST/Expr.h"
  #include "clang/AST/TypeLoc.h"
  #include "clang/AST/TypeLocVisitor.h"
  #include "clang/Basic/PartialDiagnostic.h"
  #include "clang/Basic/TargetInfo.h"
  #include "clang/Lex/Preprocessor.h"
  #include "clang/Sema/DeclSpec.h"
  #include "clang/Sema/DelayedDiagnostic.h"
  #include "clang/Sema/Lookup.h"
  #include "clang/Sema/ParsedTemplate.h"
  #include "clang/Sema/ScopeInfo.h"
  #include "clang/Sema/SemaInternal.h"
  #include "clang/Sema/Template.h"
  #include "clang/Sema/TemplateInstCallback.h"
  #include "llvm/ADT/SmallPtrSet.h"
  #include "llvm/ADT/SmallString.h"
  #include "llvm/ADT/StringSwitch.h"
  #include "llvm/IR/DerivedTypes.h"
  #include "llvm/Support/ErrorHandling.h"
  #include <bitset>
  
  using namespace clang;
  
  enum TypeDiagSelector {
    TDS_Function,
    TDS_Pointer,
    TDS_ObjCObjOrBlock
  };
  
  /// isOmittedBlockReturnType - Return true if this declarator is missing a
  /// return type because this is a omitted return type on a block literal.
  static bool isOmittedBlockReturnType(const Declarator &D) {
    if (D.getContext() != DeclaratorContext::BlockLiteral ||
        D.getDeclSpec().hasTypeSpecifier())
      return false;
  
    if (D.getNumTypeObjects() == 0)
      return true;   // ^{ ... }
  
    if (D.getNumTypeObjects() == 1 &&
        D.getTypeObject(0).Kind == DeclaratorChunk::Function)
      return true;   // ^(int X, float Y) { ... }
  
    return false;
  }
  
  /// diagnoseBadTypeAttribute - Diagnoses a type attribute which
  /// doesn't apply to the given type.
  static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
                                       QualType type) {
    TypeDiagSelector WhichType;
    bool useExpansionLoc = true;
    switch (attr.getKind()) {
    case ParsedAttr::AT_ObjCGC:
      WhichType = TDS_Pointer;
      break;
    case ParsedAttr::AT_ObjCOwnership:
      WhichType = TDS_ObjCObjOrBlock;
      break;
    default:
      // Assume everything else was a function attribute.
      WhichType = TDS_Function;
      useExpansionLoc = false;
      break;
    }
  
    SourceLocation loc = attr.getLoc();
    StringRef name = attr.getAttrName()->getName();
  
    // The GC attributes are usually written with macros;  special-case them.
    IdentifierInfo *II = attr.isArgIdent(0) ? attr.getArgAsIdent(0)->Ident
                                            : nullptr;
    if (useExpansionLoc && loc.isMacroID() && II) {
      if (II->isStr("strong")) {
        if (S.findMacroSpelling(loc, "__strong")) name = "__strong";
      } else if (II->isStr("weak")) {
        if (S.findMacroSpelling(loc, "__weak")) name = "__weak";
      }
    }
  
    S.Diag(loc, diag::warn_type_attribute_wrong_type) << name << WhichType
      << type;
  }
  
  // objc_gc applies to Objective-C pointers or, otherwise, to the
  // smallest available pointer type (i.e. 'void*' in 'void**').
  #define OBJC_POINTER_TYPE_ATTRS_CASELIST                                       \
    case ParsedAttr::AT_ObjCGC:                                                  \
    case ParsedAttr::AT_ObjCOwnership
  
  // Calling convention attributes.
  #define CALLING_CONV_ATTRS_CASELIST                                            \
    case ParsedAttr::AT_CDecl:                                                   \
    case ParsedAttr::AT_FastCall:                                                \
    case ParsedAttr::AT_StdCall:                                                 \
    case ParsedAttr::AT_ThisCall:                                                \
    case ParsedAttr::AT_RegCall:                                                 \
    case ParsedAttr::AT_Pascal:                                                  \
    case ParsedAttr::AT_SwiftCall:                                               \
    case ParsedAttr::AT_VectorCall:                                              \
    case ParsedAttr::AT_AArch64VectorPcs:                                        \
    case ParsedAttr::AT_MSABI:                                                   \
    case ParsedAttr::AT_SysVABI:                                                 \
    case ParsedAttr::AT_Pcs:                                                     \
    case ParsedAttr::AT_IntelOclBicc:                                            \
    case ParsedAttr::AT_PreserveMost:                                            \
    case ParsedAttr::AT_PreserveAll
  
  // Function type attributes.
  #define FUNCTION_TYPE_ATTRS_CASELIST                                           \
    case ParsedAttr::AT_NSReturnsRetained:                                       \
    case ParsedAttr::AT_NoReturn:                                                \
    case ParsedAttr::AT_Regparm:                                                 \
    case ParsedAttr::AT_CmseNSCall:                                              \
    case ParsedAttr::AT_AnyX86NoCallerSavedRegisters:                            \
    case ParsedAttr::AT_AnyX86NoCfCheck:                                         \
      CALLING_CONV_ATTRS_CASELIST
  
  // Microsoft-specific type qualifiers.
  #define MS_TYPE_ATTRS_CASELIST                                                 \
    case ParsedAttr::AT_Ptr32:                                                   \
    case ParsedAttr::AT_Ptr64:                                                   \
    case ParsedAttr::AT_SPtr:                                                    \
    case ParsedAttr::AT_UPtr
  
  // Nullability qualifiers.
  #define NULLABILITY_TYPE_ATTRS_CASELIST                                        \
    case ParsedAttr::AT_TypeNonNull:                                             \
    case ParsedAttr::AT_TypeNullable:                                            \
    case ParsedAttr::AT_TypeNullableResult:                                      \
    case ParsedAttr::AT_TypeNullUnspecified
  
  namespace {
    /// An object which stores processing state for the entire
    /// GetTypeForDeclarator process.
    class TypeProcessingState {
      Sema &sema;
  
      /// The declarator being processed.
      Declarator &declarator;
  
      /// The index of the declarator chunk we're currently processing.
      /// May be the total number of valid chunks, indicating the
      /// DeclSpec.
      unsigned chunkIndex;
  
      /// Whether there are non-trivial modifications to the decl spec.
      bool trivial;
  
      /// Whether we saved the attributes in the decl spec.
      bool hasSavedAttrs;
  
      /// The original set of attributes on the DeclSpec.
      SmallVector<ParsedAttr *, 2> savedAttrs;
  
      /// A list of attributes to diagnose the uselessness of when the
      /// processing is complete.
      SmallVector<ParsedAttr *, 2> ignoredTypeAttrs;
  
      /// Attributes corresponding to AttributedTypeLocs that we have not yet
      /// populated.
      // FIXME: The two-phase mechanism by which we construct Types and fill
      // their TypeLocs makes it hard to correctly assign these. We keep the
      // attributes in creation order as an attempt to make them line up
      // properly.
      using TypeAttrPair = std::pair<const AttributedType*, const Attr*>;
      SmallVector<TypeAttrPair, 8> AttrsForTypes;
      bool AttrsForTypesSorted = true;
  
      /// MacroQualifiedTypes mapping to macro expansion locations that will be
      /// stored in a MacroQualifiedTypeLoc.
      llvm::DenseMap<const MacroQualifiedType *, SourceLocation> LocsForMacros;
  
      /// Flag to indicate we parsed a noderef attribute. This is used for
      /// validating that noderef was used on a pointer or array.
      bool parsedNoDeref;
  
    public:
      TypeProcessingState(Sema &sema, Declarator &declarator)
          : sema(sema), declarator(declarator),
            chunkIndex(declarator.getNumTypeObjects()), trivial(true),
            hasSavedAttrs(false), parsedNoDeref(false) {}
  
      Sema &getSema() const {
        return sema;
      }
  
      Declarator &getDeclarator() const {
        return declarator;
      }
  
      bool isProcessingDeclSpec() const {
        return chunkIndex == declarator.getNumTypeObjects();
      }
  
      bool isProcessingLambdaExpr() const {
        return declarator.isFunctionDeclarator() &&
               declarator.getContext() == DeclaratorContext::LambdaExpr;
      }
  
      unsigned getCurrentChunkIndex() const {
        return chunkIndex;
      }
  
      void setCurrentChunkIndex(unsigned idx) {
        assert(idx <= declarator.getNumTypeObjects());
        chunkIndex = idx;
      }
  
      ParsedAttributesView &getCurrentAttributes() const {
        if (isProcessingDeclSpec())
          return getMutableDeclSpec().getAttributes();
        return declarator.getTypeObject(chunkIndex).getAttrs();
      }
  
      /// Save the current set of attributes on the DeclSpec.
      void saveDeclSpecAttrs() {
        // Don't try to save them multiple times.
        if (hasSavedAttrs) return;
  
        DeclSpec &spec = getMutableDeclSpec();
        for (ParsedAttr &AL : spec.getAttributes())
          savedAttrs.push_back(&AL);
        trivial &= savedAttrs.empty();
        hasSavedAttrs = true;
      }
  
      /// Record that we had nowhere to put the given type attribute.
      /// We will diagnose such attributes later.
      void addIgnoredTypeAttr(ParsedAttr &attr) {
        ignoredTypeAttrs.push_back(&attr);
      }
  
      /// Diagnose all the ignored type attributes, given that the
      /// declarator worked out to the given type.
      void diagnoseIgnoredTypeAttrs(QualType type) const {
        for (auto *Attr : ignoredTypeAttrs)
          diagnoseBadTypeAttribute(getSema(), *Attr, type);
      }
  
      /// Get an attributed type for the given attribute, and remember the Attr
      /// object so that we can attach it to the AttributedTypeLoc.
      QualType getAttributedType(Attr *A, QualType ModifiedType,
                                 QualType EquivType) {
        QualType T =
            sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType);
        AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
        AttrsForTypesSorted = false;
        return T;
      }
  
      /// Completely replace the \c auto in \p TypeWithAuto by
      /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if
      /// necessary.
      QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement) {
        QualType T = sema.ReplaceAutoType(TypeWithAuto, Replacement);
        if (auto *AttrTy = TypeWithAuto->getAs<AttributedType>()) {
          // Attributed type still should be an attributed type after replacement.
          auto *NewAttrTy = cast<AttributedType>(T.getTypePtr());
          for (TypeAttrPair &A : AttrsForTypes) {
            if (A.first == AttrTy)
              A.first = NewAttrTy;
          }
          AttrsForTypesSorted = false;
        }
        return T;
      }
  
      /// Extract and remove the Attr* for a given attributed type.
      const Attr *takeAttrForAttributedType(const AttributedType *AT) {
        if (!AttrsForTypesSorted) {
          llvm::stable_sort(AttrsForTypes, llvm::less_first());
          AttrsForTypesSorted = true;
        }
  
        // FIXME: This is quadratic if we have lots of reuses of the same
        // attributed type.
        for (auto It = std::partition_point(
                 AttrsForTypes.begin(), AttrsForTypes.end(),
                 [=](const TypeAttrPair &A) { return A.first < AT; });
             It != AttrsForTypes.end() && It->first == AT; ++It) {
          if (It->second) {
            const Attr *Result = It->second;
            It->second = nullptr;
            return Result;
          }
        }
  
        llvm_unreachable("no Attr* for AttributedType*");
      }
  
      SourceLocation
      getExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT) const {
        auto FoundLoc = LocsForMacros.find(MQT);
        assert(FoundLoc != LocsForMacros.end() &&
               "Unable to find macro expansion location for MacroQualifedType");
        return FoundLoc->second;
      }
  
      void setExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT,
                                                SourceLocation Loc) {
        LocsForMacros[MQT] = Loc;
      }
  
      void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; }
  
      bool didParseNoDeref() const { return parsedNoDeref; }
  
      ~TypeProcessingState() {
        if (trivial) return;
  
        restoreDeclSpecAttrs();
      }
  
    private:
      DeclSpec &getMutableDeclSpec() const {
        return const_cast<DeclSpec&>(declarator.getDeclSpec());
      }
  
      void restoreDeclSpecAttrs() {
        assert(hasSavedAttrs);
  
        getMutableDeclSpec().getAttributes().clearListOnly();
        for (ParsedAttr *AL : savedAttrs)
          getMutableDeclSpec().getAttributes().addAtEnd(AL);
      }
    };
  } // end anonymous namespace
  
  static void moveAttrFromListToList(ParsedAttr &attr,
                                     ParsedAttributesView &fromList,
                                     ParsedAttributesView &toList) {
    fromList.remove(&attr);
    toList.addAtEnd(&attr);
  }
  
  /// The location of a type attribute.
  enum TypeAttrLocation {
    /// The attribute is in the decl-specifier-seq.
    TAL_DeclSpec,
    /// The attribute is part of a DeclaratorChunk.
    TAL_DeclChunk,
    /// The attribute is immediately after the declaration's name.
    TAL_DeclName
  };
  
  static void processTypeAttrs(TypeProcessingState &state, QualType &type,
                               TypeAttrLocation TAL, ParsedAttributesView &attrs);
  
  static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
                                     QualType &type);
  
  static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &state,
                                               ParsedAttr &attr, QualType &type);
  
  static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
                                   QualType &type);
  
  static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
                                          ParsedAttr &attr, QualType &type);
  
  static bool handleObjCPointerTypeAttr(TypeProcessingState &state,
                                        ParsedAttr &attr, QualType &type) {
    if (attr.getKind() == ParsedAttr::AT_ObjCGC)
      return handleObjCGCTypeAttr(state, attr, type);
    assert(attr.getKind() == ParsedAttr::AT_ObjCOwnership);
    return handleObjCOwnershipTypeAttr(state, attr, type);
  }
  
  /// Given the index of a declarator chunk, check whether that chunk
  /// directly specifies the return type of a function and, if so, find
  /// an appropriate place for it.
  ///
  /// \param i - a notional index which the search will start
  ///   immediately inside
  ///
  /// \param onlyBlockPointers Whether we should only look into block
  /// pointer types (vs. all pointer types).
  static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator,
                                                  unsigned i,
                                                  bool onlyBlockPointers) {
    assert(i <= declarator.getNumTypeObjects());
  
    DeclaratorChunk *result = nullptr;
  
    // First, look inwards past parens for a function declarator.
    for (; i != 0; --i) {
      DeclaratorChunk &fnChunk = declarator.getTypeObject(i-1);
      switch (fnChunk.Kind) {
      case DeclaratorChunk::Paren:
        continue;
  
      // If we find anything except a function, bail out.
      case DeclaratorChunk::Pointer:
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::Array:
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        return result;
  
      // If we do find a function declarator, scan inwards from that,
      // looking for a (block-)pointer declarator.
      case DeclaratorChunk::Function:
        for (--i; i != 0; --i) {
          DeclaratorChunk &ptrChunk = declarator.getTypeObject(i-1);
          switch (ptrChunk.Kind) {
          case DeclaratorChunk::Paren:
          case DeclaratorChunk::Array:
          case DeclaratorChunk::Function:
          case DeclaratorChunk::Reference:
          case DeclaratorChunk::Pipe:
            continue;
  
          case DeclaratorChunk::MemberPointer:
          case DeclaratorChunk::Pointer:
            if (onlyBlockPointers)
              continue;
  
            LLVM_FALLTHROUGH;
  
          case DeclaratorChunk::BlockPointer:
            result = &ptrChunk;
            goto continue_outer;
          }
          llvm_unreachable("bad declarator chunk kind");
        }
  
        // If we run out of declarators doing that, we're done.
        return result;
      }
      llvm_unreachable("bad declarator chunk kind");
  
      // Okay, reconsider from our new point.
    continue_outer: ;
    }
  
    // Ran out of chunks, bail out.
    return result;
  }
  
  /// Given that an objc_gc attribute was written somewhere on a
  /// declaration *other* than on the declarator itself (for which, use
  /// distributeObjCPointerTypeAttrFromDeclarator), and given that it
  /// didn't apply in whatever position it was written in, try to move
  /// it to a more appropriate position.
  static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
                                            ParsedAttr &attr, QualType type) {
    Declarator &declarator = state.getDeclarator();
  
    // Move it to the outermost normal or block pointer declarator.
    for (unsigned i = state.getCurrentChunkIndex(); i != 0; --i) {
      DeclaratorChunk &chunk = declarator.getTypeObject(i-1);
      switch (chunk.Kind) {
      case DeclaratorChunk::Pointer:
      case DeclaratorChunk::BlockPointer: {
        // But don't move an ARC ownership attribute to the return type
        // of a block.
        DeclaratorChunk *destChunk = nullptr;
        if (state.isProcessingDeclSpec() &&
            attr.getKind() == ParsedAttr::AT_ObjCOwnership)
          destChunk = maybeMovePastReturnType(declarator, i - 1,
                                              /*onlyBlockPointers=*/true);
        if (!destChunk) destChunk = &chunk;
  
        moveAttrFromListToList(attr, state.getCurrentAttributes(),
                               destChunk->getAttrs());
        return;
      }
  
      case DeclaratorChunk::Paren:
      case DeclaratorChunk::Array:
        continue;
  
      // We may be starting at the return type of a block.
      case DeclaratorChunk::Function:
        if (state.isProcessingDeclSpec() &&
            attr.getKind() == ParsedAttr::AT_ObjCOwnership) {
          if (DeclaratorChunk *dest = maybeMovePastReturnType(
                                        declarator, i,
                                        /*onlyBlockPointers=*/true)) {
            moveAttrFromListToList(attr, state.getCurrentAttributes(),
                                   dest->getAttrs());
            return;
          }
        }
        goto error;
  
      // Don't walk through these.
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        goto error;
      }
    }
   error:
  
    diagnoseBadTypeAttribute(state.getSema(), attr, type);
  }
  
  /// Distribute an objc_gc type attribute that was written on the
  /// declarator.
  static void distributeObjCPointerTypeAttrFromDeclarator(
      TypeProcessingState &state, ParsedAttr &attr, QualType &declSpecType) {
    Declarator &declarator = state.getDeclarator();
  
    // objc_gc goes on the innermost pointer to something that's not a
    // pointer.
    unsigned innermost = -1U;
    bool considerDeclSpec = true;
    for (unsigned i = 0, e = declarator.getNumTypeObjects(); i != e; ++i) {
      DeclaratorChunk &chunk = declarator.getTypeObject(i);
      switch (chunk.Kind) {
      case DeclaratorChunk::Pointer:
      case DeclaratorChunk::BlockPointer:
        innermost = i;
        continue;
  
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Paren:
      case DeclaratorChunk::Array:
      case DeclaratorChunk::Pipe:
        continue;
  
      case DeclaratorChunk::Function:
        considerDeclSpec = false;
        goto done;
      }
    }
   done:
  
    // That might actually be the decl spec if we weren't blocked by
    // anything in the declarator.
    if (considerDeclSpec) {
      if (handleObjCPointerTypeAttr(state, attr, declSpecType)) {
        // Splice the attribute into the decl spec.  Prevents the
        // attribute from being applied multiple times and gives
        // the source-location-filler something to work with.
        state.saveDeclSpecAttrs();
        declarator.getMutableDeclSpec().getAttributes().takeOneFrom(
            declarator.getAttributes(), &attr);
        return;
      }
    }
  
    // Otherwise, if we found an appropriate chunk, splice the attribute
    // into it.
    if (innermost != -1U) {
      moveAttrFromListToList(attr, declarator.getAttributes(),
                             declarator.getTypeObject(innermost).getAttrs());
      return;
    }
  
    // Otherwise, diagnose when we're done building the type.
    declarator.getAttributes().remove(&attr);
    state.addIgnoredTypeAttr(attr);
  }
  
  /// A function type attribute was written somewhere in a declaration
  /// *other* than on the declarator itself or in the decl spec.  Given
  /// that it didn't apply in whatever position it was written in, try
  /// to move it to a more appropriate position.
  static void distributeFunctionTypeAttr(TypeProcessingState &state,
                                         ParsedAttr &attr, QualType type) {
    Declarator &declarator = state.getDeclarator();
  
    // Try to push the attribute from the return type of a function to
    // the function itself.
    for (unsigned i = state.getCurrentChunkIndex(); i != 0; --i) {
      DeclaratorChunk &chunk = declarator.getTypeObject(i-1);
      switch (chunk.Kind) {
      case DeclaratorChunk::Function:
        moveAttrFromListToList(attr, state.getCurrentAttributes(),
                               chunk.getAttrs());
        return;
  
      case DeclaratorChunk::Paren:
      case DeclaratorChunk::Pointer:
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::Array:
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        continue;
      }
    }
  
    diagnoseBadTypeAttribute(state.getSema(), attr, type);
  }
  
  /// Try to distribute a function type attribute to the innermost
  /// function chunk or type.  Returns true if the attribute was
  /// distributed, false if no location was found.
  static bool distributeFunctionTypeAttrToInnermost(
      TypeProcessingState &state, ParsedAttr &attr,
      ParsedAttributesView &attrList, QualType &declSpecType) {
    Declarator &declarator = state.getDeclarator();
  
    // Put it on the innermost function chunk, if there is one.
    for (unsigned i = 0, e = declarator.getNumTypeObjects(); i != e; ++i) {
      DeclaratorChunk &chunk = declarator.getTypeObject(i);
      if (chunk.Kind != DeclaratorChunk::Function) continue;
  
      moveAttrFromListToList(attr, attrList, chunk.getAttrs());
      return true;
    }
  
    return handleFunctionTypeAttr(state, attr, declSpecType);
  }
  
  /// A function type attribute was written in the decl spec.  Try to
  /// apply it somewhere.
  static void distributeFunctionTypeAttrFromDeclSpec(TypeProcessingState &state,
                                                     ParsedAttr &attr,
                                                     QualType &declSpecType) {
    state.saveDeclSpecAttrs();
  
    // C++11 attributes before the decl specifiers actually appertain to
    // the declarators. Move them straight there. We don't support the
    // 'put them wherever you like' semantics we allow for GNU attributes.
    if (attr.isCXX11Attribute()) {
      moveAttrFromListToList(attr, state.getCurrentAttributes(),
                             state.getDeclarator().getAttributes());
      return;
    }
  
    // Try to distribute to the innermost.
    if (distributeFunctionTypeAttrToInnermost(
            state, attr, state.getCurrentAttributes(), declSpecType))
      return;
  
    // If that failed, diagnose the bad attribute when the declarator is
    // fully built.
    state.addIgnoredTypeAttr(attr);
  }
  
  /// A function type attribute was written on the declarator.  Try to
  /// apply it somewhere.
  static void distributeFunctionTypeAttrFromDeclarator(TypeProcessingState &state,
                                                       ParsedAttr &attr,
                                                       QualType &declSpecType) {
    Declarator &declarator = state.getDeclarator();
  
    // Try to distribute to the innermost.
    if (distributeFunctionTypeAttrToInnermost(
            state, attr, declarator.getAttributes(), declSpecType))
      return;
  
    // If that failed, diagnose the bad attribute when the declarator is
    // fully built.
    declarator.getAttributes().remove(&attr);
    state.addIgnoredTypeAttr(attr);
  }
  
  /// Given that there are attributes written on the declarator
  /// itself, try to distribute any type attributes to the appropriate
  /// declarator chunk.
  ///
  /// These are attributes like the following:
  ///   int f ATTR;
  ///   int (f ATTR)();
  /// but not necessarily this:
  ///   int f() ATTR;
  static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
                                                QualType &declSpecType) {
    // Collect all the type attributes from the declarator itself.
    assert(!state.getDeclarator().getAttributes().empty() &&
           "declarator has no attrs!");
    // The called functions in this loop actually remove things from the current
    // list, so iterating over the existing list isn't possible.  Instead, make a
    // non-owning copy and iterate over that.
    ParsedAttributesView AttrsCopy{state.getDeclarator().getAttributes()};
    for (ParsedAttr &attr : AttrsCopy) {
      // Do not distribute C++11 attributes. They have strict rules for what
      // they appertain to.
      if (attr.isCXX11Attribute())
        continue;
  
      switch (attr.getKind()) {
      OBJC_POINTER_TYPE_ATTRS_CASELIST:
        distributeObjCPointerTypeAttrFromDeclarator(state, attr, declSpecType);
        break;
  
      FUNCTION_TYPE_ATTRS_CASELIST:
        distributeFunctionTypeAttrFromDeclarator(state, attr, declSpecType);
        break;
  
      MS_TYPE_ATTRS_CASELIST:
        // Microsoft type attributes cannot go after the declarator-id.
        continue;
  
      NULLABILITY_TYPE_ATTRS_CASELIST:
        // Nullability specifiers cannot go after the declarator-id.
  
      // Objective-C __kindof does not get distributed.
      case ParsedAttr::AT_ObjCKindOf:
        continue;
  
      default:
        break;
      }
    }
  }
  
  /// Add a synthetic '()' to a block-literal declarator if it is
  /// required, given the return type.
  static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
                                            QualType declSpecType) {
    Declarator &declarator = state.getDeclarator();
  
    // First, check whether the declarator would produce a function,
    // i.e. whether the innermost semantic chunk is a function.
    if (declarator.isFunctionDeclarator()) {
      // If so, make that declarator a prototyped declarator.
      declarator.getFunctionTypeInfo().hasPrototype = true;
      return;
    }
  
    // If there are any type objects, the type as written won't name a
    // function, regardless of the decl spec type.  This is because a
    // block signature declarator is always an abstract-declarator, and
    // abstract-declarators can't just be parentheses chunks.  Therefore
    // we need to build a function chunk unless there are no type
    // objects and the decl spec type is a function.
    if (!declarator.getNumTypeObjects() && declSpecType->isFunctionType())
      return;
  
    // Note that there *are* cases with invalid declarators where
    // declarators consist solely of parentheses.  In general, these
    // occur only in failed efforts to make function declarators, so
    // faking up the function chunk is still the right thing to do.
  
    // Otherwise, we need to fake up a function declarator.
    SourceLocation loc = declarator.getBeginLoc();
  
    // ...and *prepend* it to the declarator.
    SourceLocation NoLoc;
    declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction(
        /*HasProto=*/true,
        /*IsAmbiguous=*/false,
        /*LParenLoc=*/NoLoc,
        /*ArgInfo=*/nullptr,
        /*NumParams=*/0,
        /*EllipsisLoc=*/NoLoc,
        /*RParenLoc=*/NoLoc,
        /*RefQualifierIsLvalueRef=*/true,
        /*RefQualifierLoc=*/NoLoc,
        /*MutableLoc=*/NoLoc, EST_None,
        /*ESpecRange=*/SourceRange(),
        /*Exceptions=*/nullptr,
        /*ExceptionRanges=*/nullptr,
        /*NumExceptions=*/0,
        /*NoexceptExpr=*/nullptr,
        /*ExceptionSpecTokens=*/nullptr,
        /*DeclsInPrototype=*/None, loc, loc, declarator));
  
    // For consistency, make sure the state still has us as processing
    // the decl spec.
    assert(state.getCurrentChunkIndex() == declarator.getNumTypeObjects() - 1);
    state.setCurrentChunkIndex(declarator.getNumTypeObjects());
  }
  
  static void diagnoseAndRemoveTypeQualifiers(Sema &S, const DeclSpec &DS,
                                              unsigned &TypeQuals,
                                              QualType TypeSoFar,
                                              unsigned RemoveTQs,
                                              unsigned DiagID) {
    // If this occurs outside a template instantiation, warn the user about
    // it; they probably didn't mean to specify a redundant qualifier.
    typedef std::pair<DeclSpec::TQ, SourceLocation> QualLoc;
    for (QualLoc Qual : {QualLoc(DeclSpec::TQ_const, DS.getConstSpecLoc()),
                         QualLoc(DeclSpec::TQ_restrict, DS.getRestrictSpecLoc()),
                         QualLoc(DeclSpec::TQ_volatile, DS.getVolatileSpecLoc()),
                         QualLoc(DeclSpec::TQ_atomic, DS.getAtomicSpecLoc())}) {
      if (!(RemoveTQs & Qual.first))
        continue;
  
      if (!S.inTemplateInstantiation()) {
        if (TypeQuals & Qual.first)
          S.Diag(Qual.second, DiagID)
            << DeclSpec::getSpecifierName(Qual.first) << TypeSoFar
            << FixItHint::CreateRemoval(Qual.second);
      }
  
      TypeQuals &= ~Qual.first;
    }
  }
  
  /// Return true if this is omitted block return type. Also check type
  /// attributes and type qualifiers when returning true.
  static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator,
                                          QualType Result) {
    if (!isOmittedBlockReturnType(declarator))
      return false;
  
    // Warn if we see type attributes for omitted return type on a block literal.
    SmallVector<ParsedAttr *, 2> ToBeRemoved;
    for (ParsedAttr &AL : declarator.getMutableDeclSpec().getAttributes()) {
      if (AL.isInvalid() || !AL.isTypeAttr())
        continue;
      S.Diag(AL.getLoc(),
             diag::warn_block_literal_attributes_on_omitted_return_type)
          << AL;
      ToBeRemoved.push_back(&AL);
    }
    // Remove bad attributes from the list.
    for (ParsedAttr *AL : ToBeRemoved)
      declarator.getMutableDeclSpec().getAttributes().remove(AL);
  
    // Warn if we see type qualifiers for omitted return type on a block literal.
    const DeclSpec &DS = declarator.getDeclSpec();
    unsigned TypeQuals = DS.getTypeQualifiers();
    diagnoseAndRemoveTypeQualifiers(S, DS, TypeQuals, Result, (unsigned)-1,
        diag::warn_block_literal_qualifiers_on_omitted_return_type);
    declarator.getMutableDeclSpec().ClearTypeQualifiers();
  
    return true;
  }
  
  /// Apply Objective-C type arguments to the given type.
  static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type,
                                    ArrayRef<TypeSourceInfo *> typeArgs,
                                    SourceRange typeArgsRange,
                                    bool failOnError = false) {
    // We can only apply type arguments to an Objective-C class type.
    const auto *objcObjectType = type->getAs<ObjCObjectType>();
    if (!objcObjectType || !objcObjectType->getInterface()) {
      S.Diag(loc, diag::err_objc_type_args_non_class)
        << type
        << typeArgsRange;
  
      if (failOnError)
        return QualType();
      return type;
    }
  
    // The class type must be parameterized.
    ObjCInterfaceDecl *objcClass = objcObjectType->getInterface();
    ObjCTypeParamList *typeParams = objcClass->getTypeParamList();
    if (!typeParams) {
      S.Diag(loc, diag::err_objc_type_args_non_parameterized_class)
        << objcClass->getDeclName()
        << FixItHint::CreateRemoval(typeArgsRange);
  
      if (failOnError)
        return QualType();
  
      return type;
    }
  
    // The type must not already be specialized.
    if (objcObjectType->isSpecialized()) {
      S.Diag(loc, diag::err_objc_type_args_specialized_class)
        << type
        << FixItHint::CreateRemoval(typeArgsRange);
  
      if (failOnError)
        return QualType();
  
      return type;
    }
  
    // Check the type arguments.
    SmallVector<QualType, 4> finalTypeArgs;
    unsigned numTypeParams = typeParams->size();
    bool anyPackExpansions = false;
    for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) {
      TypeSourceInfo *typeArgInfo = typeArgs[i];
      QualType typeArg = typeArgInfo->getType();
  
      // Type arguments cannot have explicit qualifiers or nullability.
      // We ignore indirect sources of these, e.g. behind typedefs or
      // template arguments.
      if (TypeLoc qual = typeArgInfo->getTypeLoc().findExplicitQualifierLoc()) {
        bool diagnosed = false;
        SourceRange rangeToRemove;
        if (auto attr = qual.getAs<AttributedTypeLoc>()) {
          rangeToRemove = attr.getLocalSourceRange();
          if (attr.getTypePtr()->getImmediateNullability()) {
            typeArg = attr.getTypePtr()->getModifiedType();
            S.Diag(attr.getBeginLoc(),
                   diag::err_objc_type_arg_explicit_nullability)
                << typeArg << FixItHint::CreateRemoval(rangeToRemove);
            diagnosed = true;
          }
        }
  
        if (!diagnosed) {
          S.Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified)
              << typeArg << typeArg.getQualifiers().getAsString()
              << FixItHint::CreateRemoval(rangeToRemove);
        }
      }
  
      // Remove qualifiers even if they're non-local.
      typeArg = typeArg.getUnqualifiedType();
  
      finalTypeArgs.push_back(typeArg);
  
      if (typeArg->getAs<PackExpansionType>())
        anyPackExpansions = true;
  
      // Find the corresponding type parameter, if there is one.
      ObjCTypeParamDecl *typeParam = nullptr;
      if (!anyPackExpansions) {
        if (i < numTypeParams) {
          typeParam = typeParams->begin()[i];
        } else {
          // Too many arguments.
          S.Diag(loc, diag::err_objc_type_args_wrong_arity)
            << false
            << objcClass->getDeclName()
            << (unsigned)typeArgs.size()
            << numTypeParams;
          S.Diag(objcClass->getLocation(), diag::note_previous_decl)
            << objcClass;
  
          if (failOnError)
            return QualType();
  
          return type;
        }
      }
  
      // Objective-C object pointer types must be substitutable for the bounds.
      if (const auto *typeArgObjC = typeArg->getAs<ObjCObjectPointerType>()) {
        // If we don't have a type parameter to match against, assume
        // everything is fine. There was a prior pack expansion that
        // means we won't be able to match anything.
        if (!typeParam) {
          assert(anyPackExpansions && "Too many arguments?");
          continue;
        }
  
        // Retrieve the bound.
        QualType bound = typeParam->getUnderlyingType();
        const auto *boundObjC = bound->getAs<ObjCObjectPointerType>();
  
        // Determine whether the type argument is substitutable for the bound.
        if (typeArgObjC->isObjCIdType()) {
          // When the type argument is 'id', the only acceptable type
          // parameter bound is 'id'.
          if (boundObjC->isObjCIdType())
            continue;
        } else if (S.Context.canAssignObjCInterfaces(boundObjC, typeArgObjC)) {
          // Otherwise, we follow the assignability rules.
          continue;
        }
  
        // Diagnose the mismatch.
        S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(),
               diag::err_objc_type_arg_does_not_match_bound)
            << typeArg << bound << typeParam->getDeclName();
        S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)
          << typeParam->getDeclName();
  
        if (failOnError)
          return QualType();
  
        return type;
      }
  
      // Block pointer types are permitted for unqualified 'id' bounds.
      if (typeArg->isBlockPointerType()) {
        // If we don't have a type parameter to match against, assume
        // everything is fine. There was a prior pack expansion that
        // means we won't be able to match anything.
        if (!typeParam) {
          assert(anyPackExpansions && "Too many arguments?");
          continue;
        }
  
        // Retrieve the bound.
        QualType bound = typeParam->getUnderlyingType();
        if (bound->isBlockCompatibleObjCPointerType(S.Context))
          continue;
  
        // Diagnose the mismatch.
        S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(),
               diag::err_objc_type_arg_does_not_match_bound)
            << typeArg << bound << typeParam->getDeclName();
        S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here)
          << typeParam->getDeclName();
  
        if (failOnError)
          return QualType();
  
        return type;
      }
  
      // Dependent types will be checked at instantiation time.
      if (typeArg->isDependentType()) {
        continue;
      }
  
      // Diagnose non-id-compatible type arguments.
      S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(),
             diag::err_objc_type_arg_not_id_compatible)
          << typeArg << typeArgInfo->getTypeLoc().getSourceRange();
  
      if (failOnError)
        return QualType();
  
      return type;
    }
  
    // Make sure we didn't have the wrong number of arguments.
    if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) {
      S.Diag(loc, diag::err_objc_type_args_wrong_arity)
        << (typeArgs.size() < typeParams->size())
        << objcClass->getDeclName()
        << (unsigned)finalTypeArgs.size()
        << (unsigned)numTypeParams;
      S.Diag(objcClass->getLocation(), diag::note_previous_decl)
        << objcClass;
  
      if (failOnError)
        return QualType();
  
      return type;
    }
  
    // Success. Form the specialized type.
    return S.Context.getObjCObjectType(type, finalTypeArgs, { }, false);
  }
  
  QualType Sema::BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
                                        SourceLocation ProtocolLAngleLoc,
                                        ArrayRef<ObjCProtocolDecl *> Protocols,
                                        ArrayRef<SourceLocation> ProtocolLocs,
                                        SourceLocation ProtocolRAngleLoc,
                                        bool FailOnError) {
    QualType Result = QualType(Decl->getTypeForDecl(), 0);
    if (!Protocols.empty()) {
      bool HasError;
      Result = Context.applyObjCProtocolQualifiers(Result, Protocols,
                                                   HasError);
      if (HasError) {
        Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers)
          << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
        if (FailOnError) Result = QualType();
      }
      if (FailOnError && Result.isNull())
        return QualType();
    }
  
    return Result;
  }
  
  QualType Sema::BuildObjCObjectType(QualType BaseType,
                                     SourceLocation Loc,
                                     SourceLocation TypeArgsLAngleLoc,
                                     ArrayRef<TypeSourceInfo *> TypeArgs,
                                     SourceLocation TypeArgsRAngleLoc,
                                     SourceLocation ProtocolLAngleLoc,
                                     ArrayRef<ObjCProtocolDecl *> Protocols,
                                     ArrayRef<SourceLocation> ProtocolLocs,
                                     SourceLocation ProtocolRAngleLoc,
                                     bool FailOnError) {
    QualType Result = BaseType;
    if (!TypeArgs.empty()) {
      Result = applyObjCTypeArgs(*this, Loc, Result, TypeArgs,
                                 SourceRange(TypeArgsLAngleLoc,
                                             TypeArgsRAngleLoc),
                                 FailOnError);
      if (FailOnError && Result.isNull())
        return QualType();
    }
  
    if (!Protocols.empty()) {
      bool HasError;
      Result = Context.applyObjCProtocolQualifiers(Result, Protocols,
                                                   HasError);
      if (HasError) {
        Diag(Loc, diag::err_invalid_protocol_qualifiers)
          << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
        if (FailOnError) Result = QualType();
      }
      if (FailOnError && Result.isNull())
        return QualType();
    }
  
    return Result;
  }
  
  TypeResult Sema::actOnObjCProtocolQualifierType(
               SourceLocation lAngleLoc,
               ArrayRef<Decl *> protocols,
               ArrayRef<SourceLocation> protocolLocs,
               SourceLocation rAngleLoc) {
    // Form id<protocol-list>.
    QualType Result = Context.getObjCObjectType(
                        Context.ObjCBuiltinIdTy, { },
                        llvm::makeArrayRef(
                          (ObjCProtocolDecl * const *)protocols.data(),
                          protocols.size()),
                        false);
    Result = Context.getObjCObjectPointerType(Result);
  
    TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result);
    TypeLoc ResultTL = ResultTInfo->getTypeLoc();
  
    auto ObjCObjectPointerTL = ResultTL.castAs<ObjCObjectPointerTypeLoc>();
    ObjCObjectPointerTL.setStarLoc(SourceLocation()); // implicit
  
    auto ObjCObjectTL = ObjCObjectPointerTL.getPointeeLoc()
                          .castAs<ObjCObjectTypeLoc>();
    ObjCObjectTL.setHasBaseTypeAsWritten(false);
    ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation());
  
    // No type arguments.
    ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation());
    ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation());
  
    // Fill in protocol qualifiers.
    ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc);
    ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc);
    for (unsigned i = 0, n = protocols.size(); i != n; ++i)
      ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]);
  
    // We're done. Return the completed type to the parser.
    return CreateParsedType(Result, ResultTInfo);
  }
  
  TypeResult Sema::actOnObjCTypeArgsAndProtocolQualifiers(
               Scope *S,
               SourceLocation Loc,
               ParsedType BaseType,
               SourceLocation TypeArgsLAngleLoc,
               ArrayRef<ParsedType> TypeArgs,
               SourceLocation TypeArgsRAngleLoc,
               SourceLocation ProtocolLAngleLoc,
               ArrayRef<Decl *> Protocols,
               ArrayRef<SourceLocation> ProtocolLocs,
               SourceLocation ProtocolRAngleLoc) {
    TypeSourceInfo *BaseTypeInfo = nullptr;
    QualType T = GetTypeFromParser(BaseType, &BaseTypeInfo);
    if (T.isNull())
      return true;
  
    // Handle missing type-source info.
    if (!BaseTypeInfo)
      BaseTypeInfo = Context.getTrivialTypeSourceInfo(T, Loc);
  
    // Extract type arguments.
    SmallVector<TypeSourceInfo *, 4> ActualTypeArgInfos;
    for (unsigned i = 0, n = TypeArgs.size(); i != n; ++i) {
      TypeSourceInfo *TypeArgInfo = nullptr;
      QualType TypeArg = GetTypeFromParser(TypeArgs[i], &TypeArgInfo);
      if (TypeArg.isNull()) {
        ActualTypeArgInfos.clear();
        break;
      }
  
      assert(TypeArgInfo && "No type source info?");
      ActualTypeArgInfos.push_back(TypeArgInfo);
    }
  
    // Build the object type.
    QualType Result = BuildObjCObjectType(
        T, BaseTypeInfo->getTypeLoc().getSourceRange().getBegin(),
        TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc,
        ProtocolLAngleLoc,
        llvm::makeArrayRef((ObjCProtocolDecl * const *)Protocols.data(),
                           Protocols.size()),
        ProtocolLocs, ProtocolRAngleLoc,
        /*FailOnError=*/false);
  
    if (Result == T)
      return BaseType;
  
    // Create source information for this type.
    TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result);
    TypeLoc ResultTL = ResultTInfo->getTypeLoc();
  
    // For id<Proto1, Proto2> or Class<Proto1, Proto2>, we'll have an
    // object pointer type. Fill in source information for it.
    if (auto ObjCObjectPointerTL = ResultTL.getAs<ObjCObjectPointerTypeLoc>()) {
      // The '*' is implicit.
      ObjCObjectPointerTL.setStarLoc(SourceLocation());
      ResultTL = ObjCObjectPointerTL.getPointeeLoc();
    }
  
    if (auto OTPTL = ResultTL.getAs<ObjCTypeParamTypeLoc>()) {
      // Protocol qualifier information.
      if (OTPTL.getNumProtocols() > 0) {
        assert(OTPTL.getNumProtocols() == Protocols.size());
        OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
        OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
        for (unsigned i = 0, n = Protocols.size(); i != n; ++i)
          OTPTL.setProtocolLoc(i, ProtocolLocs[i]);
      }
  
      // We're done. Return the completed type to the parser.
      return CreateParsedType(Result, ResultTInfo);
    }
  
    auto ObjCObjectTL = ResultTL.castAs<ObjCObjectTypeLoc>();
  
    // Type argument information.
    if (ObjCObjectTL.getNumTypeArgs() > 0) {
      assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size());
      ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc);
      ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc);
      for (unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i)
        ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]);
    } else {
      ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation());
      ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation());
    }
  
    // Protocol qualifier information.
    if (ObjCObjectTL.getNumProtocols() > 0) {
      assert(ObjCObjectTL.getNumProtocols() == Protocols.size());
      ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
      ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
      for (unsigned i = 0, n = Protocols.size(); i != n; ++i)
        ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]);
    } else {
      ObjCObjectTL.setProtocolLAngleLoc(SourceLocation());
      ObjCObjectTL.setProtocolRAngleLoc(SourceLocation());
    }
  
    // Base type.
    ObjCObjectTL.setHasBaseTypeAsWritten(true);
    if (ObjCObjectTL.getType() == T)
      ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->getTypeLoc());
    else
      ObjCObjectTL.getBaseLoc().initialize(Context, Loc);
  
    // We're done. Return the completed type to the parser.
    return CreateParsedType(Result, ResultTInfo);
  }
  
  static OpenCLAccessAttr::Spelling
  getImageAccess(const ParsedAttributesView &Attrs) {
    for (const ParsedAttr &AL : Attrs)
      if (AL.getKind() == ParsedAttr::AT_OpenCLAccess)
        return static_cast<OpenCLAccessAttr::Spelling>(AL.getSemanticSpelling());
    return OpenCLAccessAttr::Keyword_read_only;
  }
  
  /// Convert the specified declspec to the appropriate type
  /// object.
  /// \param state Specifies the declarator containing the declaration specifier
  /// to be converted, along with other associated processing state.
  /// \returns The type described by the declaration specifiers.  This function
  /// never returns null.
  static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
    // FIXME: Should move the logic from DeclSpec::Finish to here for validity
    // checking.
  
    Sema &S = state.getSema();
    Declarator &declarator = state.getDeclarator();
    DeclSpec &DS = declarator.getMutableDeclSpec();
    SourceLocation DeclLoc = declarator.getIdentifierLoc();
    if (DeclLoc.isInvalid())
      DeclLoc = DS.getBeginLoc();
  
    ASTContext &Context = S.Context;
  
    QualType Result;
    switch (DS.getTypeSpecType()) {
    case DeclSpec::TST_void:
      Result = Context.VoidTy;
      break;
    case DeclSpec::TST_char:
      if (DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified)
        Result = Context.CharTy;
      else if (DS.getTypeSpecSign() == TypeSpecifierSign::Signed)
        Result = Context.SignedCharTy;
      else {
        assert(DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned &&
               "Unknown TSS value");
        Result = Context.UnsignedCharTy;
      }
      break;
    case DeclSpec::TST_wchar:
      if (DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified)
        Result = Context.WCharTy;
      else if (DS.getTypeSpecSign() == TypeSpecifierSign::Signed) {
        S.Diag(DS.getTypeSpecSignLoc(), diag::ext_wchar_t_sign_spec)
          << DS.getSpecifierName(DS.getTypeSpecType(),
                                 Context.getPrintingPolicy());
        Result = Context.getSignedWCharType();
      } else {
        assert(DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned &&
               "Unknown TSS value");
        S.Diag(DS.getTypeSpecSignLoc(), diag::ext_wchar_t_sign_spec)
          << DS.getSpecifierName(DS.getTypeSpecType(),
                                 Context.getPrintingPolicy());
        Result = Context.getUnsignedWCharType();
      }
      break;
    case DeclSpec::TST_char8:
      assert(DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
             "Unknown TSS value");
      Result = Context.Char8Ty;
      break;
    case DeclSpec::TST_char16:
      assert(DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
             "Unknown TSS value");
      Result = Context.Char16Ty;
      break;
    case DeclSpec::TST_char32:
      assert(DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
             "Unknown TSS value");
      Result = Context.Char32Ty;
      break;
    case DeclSpec::TST_unspecified:
      // If this is a missing declspec in a block literal return context, then it
      // is inferred from the return statements inside the block.
      // The declspec is always missing in a lambda expr context; it is either
      // specified with a trailing return type or inferred.
      if (S.getLangOpts().CPlusPlus14 &&
          declarator.getContext() == DeclaratorContext::LambdaExpr) {
        // In C++1y, a lambda's implicit return type is 'auto'.
        Result = Context.getAutoDeductType();
        break;
      } else if (declarator.getContext() == DeclaratorContext::LambdaExpr ||
                 checkOmittedBlockReturnType(S, declarator,
                                             Context.DependentTy)) {
        Result = Context.DependentTy;
        break;
      }
  
      // Unspecified typespec defaults to int in C90.  However, the C90 grammar
      // [C90 6.5] only allows a decl-spec if there was *some* type-specifier,
      // type-qualifier, or storage-class-specifier.  If not, emit an extwarn.
      // Note that the one exception to this is function definitions, which are
      // allowed to be completely missing a declspec.  This is handled in the
      // parser already though by it pretending to have seen an 'int' in this
      // case.
      if (S.getLangOpts().ImplicitInt) {
        // In C89 mode, we only warn if there is a completely missing declspec
        // when one is not allowed.
        if (DS.isEmpty()) {
          S.Diag(DeclLoc, diag::ext_missing_declspec)
              << DS.getSourceRange()
              << FixItHint::CreateInsertion(DS.getBeginLoc(), "int");
        }
      } else if (!DS.hasTypeSpecifier()) {
        // C99 and C++ require a type specifier.  For example, C99 6.7.2p2 says:
        // "At least one type specifier shall be given in the declaration
        // specifiers in each declaration, and in the specifier-qualifier list in
        // each struct declaration and type name."
        if (S.getLangOpts().CPlusPlus && !DS.isTypeSpecPipe()) {
          S.Diag(DeclLoc, diag::err_missing_type_specifier)
            << DS.getSourceRange();
  
          // When this occurs in C++ code, often something is very broken with the
          // value being declared, poison it as invalid so we don't get chains of
          // errors.
          declarator.setInvalidType(true);
        } else if ((S.getLangOpts().OpenCLVersion >= 200 ||
                    S.getLangOpts().OpenCLCPlusPlus ||
                    S.getLangOpts().SYCLIsDevice) &&
                   DS.isTypeSpecPipe()) {
          S.Diag(DeclLoc, diag::err_missing_actual_pipe_type)
            << DS.getSourceRange();
          declarator.setInvalidType(true);
        } else {
          S.Diag(DeclLoc, diag::ext_missing_type_specifier)
            << DS.getSourceRange();
        }
      }
  
      LLVM_FALLTHROUGH;
    case DeclSpec::TST_int: {
      if (DS.getTypeSpecSign() != TypeSpecifierSign::Unsigned) {
        switch (DS.getTypeSpecWidth()) {
        case TypeSpecifierWidth::Unspecified:
          Result = Context.IntTy;
          break;
        case TypeSpecifierWidth::Short:
          Result = Context.ShortTy;
          break;
        case TypeSpecifierWidth::Long:
          Result = Context.LongTy;
          break;
        case TypeSpecifierWidth::LongLong:
          Result = Context.LongLongTy;
  
          // 'long long' is a C99 or C++11 feature.
          if (!S.getLangOpts().C99) {
            if (S.getLangOpts().CPlusPlus)
              S.Diag(DS.getTypeSpecWidthLoc(),
                     S.getLangOpts().CPlusPlus11 ?
                     diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
            else
              S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong);
          }
          break;
        }
      } else {
        switch (DS.getTypeSpecWidth()) {
        case TypeSpecifierWidth::Unspecified:
          Result = Context.UnsignedIntTy;
          break;
        case TypeSpecifierWidth::Short:
          Result = Context.UnsignedShortTy;
          break;
        case TypeSpecifierWidth::Long:
          Result = Context.UnsignedLongTy;
          break;
        case TypeSpecifierWidth::LongLong:
          Result = Context.UnsignedLongLongTy;
  
          // 'long long' is a C99 or C++11 feature.
          if (!S.getLangOpts().C99) {
            if (S.getLangOpts().CPlusPlus)
              S.Diag(DS.getTypeSpecWidthLoc(),
                     S.getLangOpts().CPlusPlus11 ?
                     diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
            else
              S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong);
          }
          break;
        }
      }
      break;
    }
    case DeclSpec::TST_extint: {
      if (!S.Context.getTargetInfo().hasExtIntType())
        S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
          << "_ExtInt";
      Result =
          S.BuildExtIntType(DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned,
                            DS.getRepAsExpr(), DS.getBeginLoc());
      if (Result.isNull()) {
        Result = Context.IntTy;
        declarator.setInvalidType(true);
      }
      break;
    }
    case DeclSpec::TST_accum: {
      switch (DS.getTypeSpecWidth()) {
      case TypeSpecifierWidth::Short:
        Result = Context.ShortAccumTy;
        break;
      case TypeSpecifierWidth::Unspecified:
        Result = Context.AccumTy;
        break;
      case TypeSpecifierWidth::Long:
        Result = Context.LongAccumTy;
        break;
      case TypeSpecifierWidth::LongLong:
        llvm_unreachable("Unable to specify long long as _Accum width");
      }
  
      if (DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned)
        Result = Context.getCorrespondingUnsignedType(Result);
  
      if (DS.isTypeSpecSat())
        Result = Context.getCorrespondingSaturatedType(Result);
  
      break;
    }
    case DeclSpec::TST_fract: {
      switch (DS.getTypeSpecWidth()) {
      case TypeSpecifierWidth::Short:
        Result = Context.ShortFractTy;
        break;
      case TypeSpecifierWidth::Unspecified:
        Result = Context.FractTy;
        break;
      case TypeSpecifierWidth::Long:
        Result = Context.LongFractTy;
        break;
      case TypeSpecifierWidth::LongLong:
        llvm_unreachable("Unable to specify long long as _Fract width");
      }
  
      if (DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned)
        Result = Context.getCorrespondingUnsignedType(Result);
  
      if (DS.isTypeSpecSat())
        Result = Context.getCorrespondingSaturatedType(Result);
  
      break;
    }
    case DeclSpec::TST_int128:
      if (!S.Context.getTargetInfo().hasInt128Type() &&
          !S.getLangOpts().SYCLIsDevice &&
          !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))
        S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
          << "__int128";
      if (DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned)
        Result = Context.UnsignedInt128Ty;
      else
        Result = Context.Int128Ty;
      break;
    case DeclSpec::TST_float16:
      {
        // CUDA host and device may have different _Float16 support, therefore
        // do not diagnose _Float16 usage to avoid false alarm.
        // ToDo: more precise diagnostics for CUDA.
        if (!S.Context.getTargetInfo().hasFloat16Type() &&
            !S.getLangOpts().CUDA &&
            !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))
          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
              << "_Float16";
      }
      Result = Context.Float16Ty;
      break;
    case DeclSpec::TST_half:    Result = Context.HalfTy; break;
    case DeclSpec::TST_BFloat16:
      if (!S.Context.getTargetInfo().hasBFloat16Type())
        S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
          << "__bf16";
      Result = Context.BFloat16Ty;
      break;
    case DeclSpec::TST_float:   Result = Context.FloatTy; break;
    case DeclSpec::TST_double:
      if (DS.getTypeSpecWidth() == TypeSpecifierWidth::Long)
        Result = Context.LongDoubleTy;
      else
        Result = Context.DoubleTy;
      break;
    case DeclSpec::TST_float128:
      if (!S.Context.getTargetInfo().hasFloat128Type() &&
          !S.getLangOpts().SYCLIsDevice &&
          !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))
        S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
            << "__float128";
      Result = Context.Float128Ty;
      break;
    case DeclSpec::TST_bool:
      Result = Context.BoolTy; // _Bool or bool
      break;
    case DeclSpec::TST_decimal32:    // _Decimal32
    case DeclSpec::TST_decimal64:    // _Decimal64
    case DeclSpec::TST_decimal128:   // _Decimal128
      S.Diag(DS.getTypeSpecTypeLoc(), diag::err_decimal_unsupported);
      Result = Context.IntTy;
      declarator.setInvalidType(true);
      break;
    case DeclSpec::TST_class:
    case DeclSpec::TST_enum:
    case DeclSpec::TST_union:
    case DeclSpec::TST_struct:
    case DeclSpec::TST_interface: {
      TagDecl *D = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl());
      if (!D) {
        // This can happen in C++ with ambiguous lookups.
        Result = Context.IntTy;
        declarator.setInvalidType(true);
        break;
      }
  
      // If the type is deprecated or unavailable, diagnose it.
      S.DiagnoseUseOfDecl(D, DS.getTypeSpecTypeNameLoc());
  
      assert(DS.getTypeSpecWidth() == TypeSpecifierWidth::Unspecified &&
             DS.getTypeSpecComplex() == 0 &&
             DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
             "No qualifiers on tag names!");
  
      // TypeQuals handled by caller.
      Result = Context.getTypeDeclType(D);
  
      // In both C and C++, make an ElaboratedType.
      ElaboratedTypeKeyword Keyword
        = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType());
      Result = S.getElaboratedType(Keyword, DS.getTypeSpecScope(), Result,
                                   DS.isTypeSpecOwned() ? D : nullptr);
      break;
    }
    case DeclSpec::TST_typename: {
      assert(DS.getTypeSpecWidth() == TypeSpecifierWidth::Unspecified &&
             DS.getTypeSpecComplex() == 0 &&
             DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
             "Can't handle qualifiers on typedef names yet!");
      Result = S.GetTypeFromParser(DS.getRepAsType());
      if (Result.isNull()) {
        declarator.setInvalidType(true);
      }
  
      // TypeQuals handled by caller.
      break;
    }
    case DeclSpec::TST_typeofType:
      // FIXME: Preserve type source info.
      Result = S.GetTypeFromParser(DS.getRepAsType());
      assert(!Result.isNull() && "Didn't get a type for typeof?");
      if (!Result->isDependentType())
        if (const TagType *TT = Result->getAs<TagType>())
          S.DiagnoseUseOfDecl(TT->getDecl(), DS.getTypeSpecTypeLoc());
      // TypeQuals handled by caller.
      Result = Context.getTypeOfType(Result);
      break;
    case DeclSpec::TST_typeofExpr: {
      Expr *E = DS.getRepAsExpr();
      assert(E && "Didn't get an expression for typeof?");
      // TypeQuals handled by caller.
      Result = S.BuildTypeofExprType(E, DS.getTypeSpecTypeLoc());
      if (Result.isNull()) {
        Result = Context.IntTy;
        declarator.setInvalidType(true);
      }
      break;
    }
    case DeclSpec::TST_decltype: {
      Expr *E = DS.getRepAsExpr();
      assert(E && "Didn't get an expression for decltype?");
      // TypeQuals handled by caller.
      Result = S.BuildDecltypeType(E, DS.getTypeSpecTypeLoc());
      if (Result.isNull()) {
        Result = Context.IntTy;
        declarator.setInvalidType(true);
      }
      break;
    }
    case DeclSpec::TST_underlyingType:
      Result = S.GetTypeFromParser(DS.getRepAsType());
      assert(!Result.isNull() && "Didn't get a type for __underlying_type?");
      Result = S.BuildUnaryTransformType(Result,
                                         UnaryTransformType::EnumUnderlyingType,
                                         DS.getTypeSpecTypeLoc());
      if (Result.isNull()) {
        Result = Context.IntTy;
        declarator.setInvalidType(true);
      }
      break;
  
    case DeclSpec::TST_auto:
    case DeclSpec::TST_decltype_auto: {
      auto AutoKW = DS.getTypeSpecType() == DeclSpec::TST_decltype_auto
                        ? AutoTypeKeyword::DecltypeAuto
                        : AutoTypeKeyword::Auto;
  
      ConceptDecl *TypeConstraintConcept = nullptr;
      llvm::SmallVector<TemplateArgument, 8> TemplateArgs;
      if (DS.isConstrainedAuto()) {
        if (TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId()) {
          TypeConstraintConcept =
              cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl());
          TemplateArgumentListInfo TemplateArgsInfo;
          TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc);
          TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc);
          ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
                                             TemplateId->NumArgs);
          S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
          for (const auto &ArgLoc : TemplateArgsInfo.arguments())
            TemplateArgs.push_back(ArgLoc.getArgument());
        } else {
          declarator.setInvalidType(true);
        }
      }
      Result = S.Context.getAutoType(QualType(), AutoKW,
                                     /*IsDependent*/ false, /*IsPack=*/false,
                                     TypeConstraintConcept, TemplateArgs);
      break;
    }
  
    case DeclSpec::TST_auto_type:
      Result = Context.getAutoType(QualType(), AutoTypeKeyword::GNUAutoType, false);
      break;
  
    case DeclSpec::TST_unknown_anytype:
      Result = Context.UnknownAnyTy;
      break;
  
    case DeclSpec::TST_atomic:
      Result = S.GetTypeFromParser(DS.getRepAsType());
      assert(!Result.isNull() && "Didn't get a type for _Atomic?");
      Result = S.BuildAtomicType(Result, DS.getTypeSpecTypeLoc());
      if (Result.isNull()) {
        Result = Context.IntTy;
        declarator.setInvalidType(true);
      }
      break;
  
  #define GENERIC_IMAGE_TYPE(ImgType, Id)                                        \
    case DeclSpec::TST_##ImgType##_t:                                            \
      switch (getImageAccess(DS.getAttributes())) {                              \
      case OpenCLAccessAttr::Keyword_write_only:                                 \
        Result = Context.Id##WOTy;                                               \
        break;                                                                   \
      case OpenCLAccessAttr::Keyword_read_write:                                 \
        Result = Context.Id##RWTy;                                               \
        break;                                                                   \
      case OpenCLAccessAttr::Keyword_read_only:                                  \
        Result = Context.Id##ROTy;                                               \
        break;                                                                   \
      case OpenCLAccessAttr::SpellingNotCalculated:                              \
        llvm_unreachable("Spelling not yet calculated");                         \
      }                                                                          \
      break;
  #include "clang/Basic/OpenCLImageTypes.def"
  
    case DeclSpec::TST_error:
      Result = Context.IntTy;
      declarator.setInvalidType(true);
      break;
    }
  
    // FIXME: we want resulting declarations to be marked invalid, but claiming
    // the type is invalid is too strong - e.g. it causes ActOnTypeName to return
    // a null type.
    if (Result->containsErrors())
      declarator.setInvalidType();
  
    if (S.getLangOpts().OpenCL &&
        S.checkOpenCLDisabledTypeDeclSpec(DS, Result))
      declarator.setInvalidType(true);
  
    bool IsFixedPointType = DS.getTypeSpecType() == DeclSpec::TST_accum ||
                            DS.getTypeSpecType() == DeclSpec::TST_fract;
  
    // Only fixed point types can be saturated
    if (DS.isTypeSpecSat() && !IsFixedPointType)
      S.Diag(DS.getTypeSpecSatLoc(), diag::err_invalid_saturation_spec)
          << DS.getSpecifierName(DS.getTypeSpecType(),
                                 Context.getPrintingPolicy());
  
    // Handle complex types.
    if (DS.getTypeSpecComplex() == DeclSpec::TSC_complex) {
      if (S.getLangOpts().Freestanding)
        S.Diag(DS.getTypeSpecComplexLoc(), diag::ext_freestanding_complex);
      Result = Context.getComplexType(Result);
    } else if (DS.isTypeAltiVecVector()) {
      unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result));
      assert(typeSize > 0 && "type size for vector must be greater than 0 bits");
      VectorType::VectorKind VecKind = VectorType::AltiVecVector;
      if (DS.isTypeAltiVecPixel())
        VecKind = VectorType::AltiVecPixel;
      else if (DS.isTypeAltiVecBool())
        VecKind = VectorType::AltiVecBool;
      Result = Context.getVectorType(Result, 128/typeSize, VecKind);
    }
  
    // FIXME: Imaginary.
    if (DS.getTypeSpecComplex() == DeclSpec::TSC_imaginary)
      S.Diag(DS.getTypeSpecComplexLoc(), diag::err_imaginary_not_supported);
  
    // Before we process any type attributes, synthesize a block literal
    // function declarator if necessary.
    if (declarator.getContext() == DeclaratorContext::BlockLiteral)
      maybeSynthesizeBlockSignature(state, Result);
  
    // Apply any type attributes from the decl spec.  This may cause the
    // list of type attributes to be temporarily saved while the type
    // attributes are pushed around.
    // pipe attributes will be handled later ( at GetFullTypeForDeclarator )
    if (!DS.isTypeSpecPipe())
      processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes());
  
    // Apply const/volatile/restrict qualifiers to T.
    if (unsigned TypeQuals = DS.getTypeQualifiers()) {
      // Warn about CV qualifiers on function types.
      // C99 6.7.3p8:
      //   If the specification of a function type includes any type qualifiers,
      //   the behavior is undefined.
      // C++11 [dcl.fct]p7:
      //   The effect of a cv-qualifier-seq in a function declarator is not the
      //   same as adding cv-qualification on top of the function type. In the
      //   latter case, the cv-qualifiers are ignored.
      if (Result->isFunctionType()) {
        diagnoseAndRemoveTypeQualifiers(
            S, DS, TypeQuals, Result, DeclSpec::TQ_const | DeclSpec::TQ_volatile,
            S.getLangOpts().CPlusPlus
                ? diag::warn_typecheck_function_qualifiers_ignored
                : diag::warn_typecheck_function_qualifiers_unspecified);
        // No diagnostic for 'restrict' or '_Atomic' applied to a
        // function type; we'll diagnose those later, in BuildQualifiedType.
      }
  
      // C++11 [dcl.ref]p1:
      //   Cv-qualified references are ill-formed except when the
      //   cv-qualifiers are introduced through the use of a typedef-name
      //   or decltype-specifier, in which case the cv-qualifiers are ignored.
      //
      // There don't appear to be any other contexts in which a cv-qualified
      // reference type could be formed, so the 'ill-formed' clause here appears
      // to never happen.
      if (TypeQuals && Result->isReferenceType()) {
        diagnoseAndRemoveTypeQualifiers(
            S, DS, TypeQuals, Result,
            DeclSpec::TQ_const | DeclSpec::TQ_volatile | DeclSpec::TQ_atomic,
            diag::warn_typecheck_reference_qualifiers);
      }
  
      // C90 6.5.3 constraints: "The same type qualifier shall not appear more
      // than once in the same specifier-list or qualifier-list, either directly
      // or via one or more typedefs."
      if (!S.getLangOpts().C99 && !S.getLangOpts().CPlusPlus
          && TypeQuals & Result.getCVRQualifiers()) {
        if (TypeQuals & DeclSpec::TQ_const && Result.isConstQualified()) {
          S.Diag(DS.getConstSpecLoc(), diag::ext_duplicate_declspec)
            << "const";
        }
  
        if (TypeQuals & DeclSpec::TQ_volatile && Result.isVolatileQualified()) {
          S.Diag(DS.getVolatileSpecLoc(), diag::ext_duplicate_declspec)
            << "volatile";
        }
  
        // C90 doesn't have restrict nor _Atomic, so it doesn't force us to
        // produce a warning in this case.
      }
  
      QualType Qualified = S.BuildQualifiedType(Result, DeclLoc, TypeQuals, &DS);
  
      // If adding qualifiers fails, just use the unqualified type.
      if (Qualified.isNull())
        declarator.setInvalidType(true);
      else
        Result = Qualified;
    }
  
    assert(!Result.isNull() && "This function should not return a null type");
    return Result;
  }
  
  static std::string getPrintableNameForEntity(DeclarationName Entity) {
    if (Entity)
      return Entity.getAsString();
  
    return "type name";
  }
  
  QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,
                                    Qualifiers Qs, const DeclSpec *DS) {
    if (T.isNull())
      return QualType();
  
    // Ignore any attempt to form a cv-qualified reference.
    if (T->isReferenceType()) {
      Qs.removeConst();
      Qs.removeVolatile();
    }
  
    // Enforce C99 6.7.3p2: "Types other than pointer types derived from
    // object or incomplete types shall not be restrict-qualified."
    if (Qs.hasRestrict()) {
      unsigned DiagID = 0;
      QualType ProblemTy;
  
      if (T->isAnyPointerType() || T->isReferenceType() ||
          T->isMemberPointerType()) {
        QualType EltTy;
        if (T->isObjCObjectPointerType())
          EltTy = T;
        else if (const MemberPointerType *PTy = T->getAs<MemberPointerType>())
          EltTy = PTy->getPointeeType();
        else
          EltTy = T->getPointeeType();
  
        // If we have a pointer or reference, the pointee must have an object
        // incomplete type.
        if (!EltTy->isIncompleteOrObjectType()) {
          DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee;
          ProblemTy = EltTy;
        }
      } else if (!T->isDependentType()) {
        DiagID = diag::err_typecheck_invalid_restrict_not_pointer;
        ProblemTy = T;
      }
  
      if (DiagID) {
        Diag(DS ? DS->getRestrictSpecLoc() : Loc, DiagID) << ProblemTy;
        Qs.removeRestrict();
      }
    }
  
    return Context.getQualifiedType(T, Qs);
  }
  
  QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,
                                    unsigned CVRAU, const DeclSpec *DS) {
    if (T.isNull())
      return QualType();
  
    // Ignore any attempt to form a cv-qualified reference.
    if (T->isReferenceType())
      CVRAU &=
          ~(DeclSpec::TQ_const | DeclSpec::TQ_volatile | DeclSpec::TQ_atomic);
  
    // Convert from DeclSpec::TQ to Qualifiers::TQ by just dropping TQ_atomic and
    // TQ_unaligned;
    unsigned CVR = CVRAU & ~(DeclSpec::TQ_atomic | DeclSpec::TQ_unaligned);
  
    // C11 6.7.3/5:
    //   If the same qualifier appears more than once in the same
    //   specifier-qualifier-list, either directly or via one or more typedefs,
    //   the behavior is the same as if it appeared only once.
    //
    // It's not specified what happens when the _Atomic qualifier is applied to
    // a type specified with the _Atomic specifier, but we assume that this
    // should be treated as if the _Atomic qualifier appeared multiple times.
    if (CVRAU & DeclSpec::TQ_atomic && !T->isAtomicType()) {
      // C11 6.7.3/5:
      //   If other qualifiers appear along with the _Atomic qualifier in a
      //   specifier-qualifier-list, the resulting type is the so-qualified
      //   atomic type.
      //
      // Don't need to worry about array types here, since _Atomic can't be
      // applied to such types.
      SplitQualType Split = T.getSplitUnqualifiedType();
      T = BuildAtomicType(QualType(Split.Ty, 0),
                          DS ? DS->getAtomicSpecLoc() : Loc);
      if (T.isNull())
        return T;
      Split.Quals.addCVRQualifiers(CVR);
      return BuildQualifiedType(T, Loc, Split.Quals);
    }
  
    Qualifiers Q = Qualifiers::fromCVRMask(CVR);
    Q.setUnaligned(CVRAU & DeclSpec::TQ_unaligned);
    return BuildQualifiedType(T, Loc, Q, DS);
  }
  
  /// Build a paren type including \p T.
  QualType Sema::BuildParenType(QualType T) {
    return Context.getParenType(T);
  }
  
  /// Given that we're building a pointer or reference to the given
  static QualType inferARCLifetimeForPointee(Sema &S, QualType type,
                                             SourceLocation loc,
                                             bool isReference) {
    // Bail out if retention is unrequired or already specified.
    if (!type->isObjCLifetimeType() ||
        type.getObjCLifetime() != Qualifiers::OCL_None)
      return type;
  
    Qualifiers::ObjCLifetime implicitLifetime = Qualifiers::OCL_None;
  
    // If the object type is const-qualified, we can safely use
    // __unsafe_unretained.  This is safe (because there are no read
    // barriers), and it'll be safe to coerce anything but __weak* to
    // the resulting type.
    if (type.isConstQualified()) {
      implicitLifetime = Qualifiers::OCL_ExplicitNone;
  
    // Otherwise, check whether the static type does not require
    // retaining.  This currently only triggers for Class (possibly
    // protocol-qualifed, and arrays thereof).
    } else if (type->isObjCARCImplicitlyUnretainedType()) {
      implicitLifetime = Qualifiers::OCL_ExplicitNone;
  
    // If we are in an unevaluated context, like sizeof, skip adding a
    // qualification.
    } else if (S.isUnevaluatedContext()) {
      return type;
  
    // If that failed, give an error and recover using __strong.  __strong
    // is the option most likely to prevent spurious second-order diagnostics,
    // like when binding a reference to a field.
    } else {
      // These types can show up in private ivars in system headers, so
      // we need this to not be an error in those cases.  Instead we
      // want to delay.
      if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
        S.DelayedDiagnostics.add(
            sema::DelayedDiagnostic::makeForbiddenType(loc,
                diag::err_arc_indirect_no_ownership, type, isReference));
      } else {
        S.Diag(loc, diag::err_arc_indirect_no_ownership) << type << isReference;
      }
      implicitLifetime = Qualifiers::OCL_Strong;
    }
    assert(implicitLifetime && "didn't infer any lifetime!");
  
    Qualifiers qs;
    qs.addObjCLifetime(implicitLifetime);
    return S.Context.getQualifiedType(type, qs);
  }
  
  static std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy){
    std::string Quals = FnTy->getMethodQuals().getAsString();
  
    switch (FnTy->getRefQualifier()) {
    case RQ_None:
      break;
  
    case RQ_LValue:
      if (!Quals.empty())
        Quals += ' ';
      Quals += '&';
      break;
  
    case RQ_RValue:
      if (!Quals.empty())
        Quals += ' ';
      Quals += "&&";
      break;
    }
  
    return Quals;
  }
  
  namespace {
  /// Kinds of declarator that cannot contain a qualified function type.
  ///
  /// C++98 [dcl.fct]p4 / C++11 [dcl.fct]p6:
  ///     a function type with a cv-qualifier or a ref-qualifier can only appear
  ///     at the topmost level of a type.
  ///
  /// Parens and member pointers are permitted. We don't diagnose array and
  /// function declarators, because they don't allow function types at all.
  ///
  /// The values of this enum are used in diagnostics.
  enum QualifiedFunctionKind { QFK_BlockPointer, QFK_Pointer, QFK_Reference };
  } // end anonymous namespace
  
  /// Check whether the type T is a qualified function type, and if it is,
  /// diagnose that it cannot be contained within the given kind of declarator.
  static bool checkQualifiedFunction(Sema &S, QualType T, SourceLocation Loc,
                                     QualifiedFunctionKind QFK) {
    // Does T refer to a function type with a cv-qualifier or a ref-qualifier?
    const FunctionProtoType *FPT = T->getAs<FunctionProtoType>();
    if (!FPT ||
        (FPT->getMethodQuals().empty() && FPT->getRefQualifier() == RQ_None))
      return false;
  
    S.Diag(Loc, diag::err_compound_qualified_function_type)
      << QFK << isa<FunctionType>(T.IgnoreParens()) << T
      << getFunctionQualifiersAsString(FPT);
    return true;
  }
  
  bool Sema::CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc) {
    const FunctionProtoType *FPT = T->getAs<FunctionProtoType>();
    if (!FPT ||
        (FPT->getMethodQuals().empty() && FPT->getRefQualifier() == RQ_None))
      return false;
  
    Diag(Loc, diag::err_qualified_function_typeid)
        << T << getFunctionQualifiersAsString(FPT);
    return true;
  }
  
  // Helper to deduce addr space of a pointee type in OpenCL mode.
  static QualType deduceOpenCLPointeeAddrSpace(Sema &S, QualType PointeeType) {
    if (!PointeeType->isUndeducedAutoType() && !PointeeType->isDependentType() &&
        !PointeeType->isSamplerT() &&
        !PointeeType.hasAddressSpace())
      PointeeType = S.getASTContext().getAddrSpaceQualType(
          PointeeType, S.getLangOpts().OpenCLGenericAddressSpace
                           ? LangAS::opencl_generic
                           : LangAS::opencl_private);
    return PointeeType;
  }
  
  /// Build a pointer type.
  ///
  /// \param T The type to which we'll be building a pointer.
  ///
  /// \param Loc The location of the entity whose type involves this
  /// pointer type or, if there is no such entity, the location of the
  /// type that will have pointer type.
  ///
  /// \param Entity The name of the entity that involves the pointer
  /// type, if known.
  ///
  /// \returns A suitable pointer type, if there are no
  /// errors. Otherwise, returns a NULL type.
  QualType Sema::BuildPointerType(QualType T,
                                  SourceLocation Loc, DeclarationName Entity) {
    if (T->isReferenceType()) {
      // C++ 8.3.2p4: There shall be no ... pointers to references ...
      Diag(Loc, diag::err_illegal_decl_pointer_to_reference)
        << getPrintableNameForEntity(Entity) << T;
      return QualType();
    }
  
    if (T->isFunctionType() && getLangOpts().OpenCL &&
        !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers",
                                              getLangOpts())) {
      Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0;
      return QualType();
    }
  
    if (checkQualifiedFunction(*this, T, Loc, QFK_Pointer))
      return QualType();
  
    assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");
  
    // In ARC, it is forbidden to build pointers to unqualified pointers.
    if (getLangOpts().ObjCAutoRefCount)
      T = inferARCLifetimeForPointee(*this, T, Loc, /*reference*/ false);
  
    if (getLangOpts().OpenCL)
      T = deduceOpenCLPointeeAddrSpace(*this, T);
  
    // Build the pointer type.
    return Context.getPointerType(T);
  }
  
  /// Build a reference type.
  ///
  /// \param T The type to which we'll be building a reference.
  ///
  /// \param Loc The location of the entity whose type involves this
  /// reference type or, if there is no such entity, the location of the
  /// type that will have reference type.
  ///
  /// \param Entity The name of the entity that involves the reference
  /// type, if known.
  ///
  /// \returns A suitable reference type, if there are no
  /// errors. Otherwise, returns a NULL type.
  QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
                                    SourceLocation Loc,
                                    DeclarationName Entity) {
    assert(Context.getCanonicalType(T) != Context.OverloadTy &&
           "Unresolved overloaded function type");
  
    // C++0x [dcl.ref]p6:
    //   If a typedef (7.1.3), a type template-parameter (14.3.1), or a
    //   decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a
    //   type T, an attempt to create the type "lvalue reference to cv TR" creates
    //   the type "lvalue reference to T", while an attempt to create the type
    //   "rvalue reference to cv TR" creates the type TR.
    bool LValueRef = SpelledAsLValue || T->getAs<LValueReferenceType>();
  
    // C++ [dcl.ref]p4: There shall be no references to references.
    //
    // According to C++ DR 106, references to references are only
    // diagnosed when they are written directly (e.g., "int & &"),
    // but not when they happen via a typedef:
    //
    //   typedef int& intref;
    //   typedef intref& intref2;
    //
    // Parser::ParseDeclaratorInternal diagnoses the case where
    // references are written directly; here, we handle the
    // collapsing of references-to-references as described in C++0x.
    // DR 106 and 540 introduce reference-collapsing into C++98/03.
  
    // C++ [dcl.ref]p1:
    //   A declarator that specifies the type "reference to cv void"
    //   is ill-formed.
    if (T->isVoidType()) {
      Diag(Loc, diag::err_reference_to_void);
      return QualType();
    }
  
    if (checkQualifiedFunction(*this, T, Loc, QFK_Reference))
      return QualType();
  
    if (T->isFunctionType() && getLangOpts().OpenCL &&
        !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers",
                                              getLangOpts())) {
      Diag(Loc, diag::err_opencl_function_pointer) << /*reference*/ 1;
      return QualType();
    }
  
    // In ARC, it is forbidden to build references to unqualified pointers.
    if (getLangOpts().ObjCAutoRefCount)
      T = inferARCLifetimeForPointee(*this, T, Loc, /*reference*/ true);
  
    if (getLangOpts().OpenCL)
      T = deduceOpenCLPointeeAddrSpace(*this, T);
  
    // Handle restrict on references.
    if (LValueRef)
      return Context.getLValueReferenceType(T, SpelledAsLValue);
    return Context.getRValueReferenceType(T);
  }
  
  /// Build a Read-only Pipe type.
  ///
  /// \param T The type to which we'll be building a Pipe.
  ///
  /// \param Loc We do not use it for now.
  ///
  /// \returns A suitable pipe type, if there are no errors. Otherwise, returns a
  /// NULL type.
  QualType Sema::BuildReadPipeType(QualType T, SourceLocation Loc) {
    return Context.getReadPipeType(T);
  }
  
  /// Build a Write-only Pipe type.
  ///
  /// \param T The type to which we'll be building a Pipe.
  ///
  /// \param Loc We do not use it for now.
  ///
  /// \returns A suitable pipe type, if there are no errors. Otherwise, returns a
  /// NULL type.
  QualType Sema::BuildWritePipeType(QualType T, SourceLocation Loc) {
    return Context.getWritePipeType(T);
  }
  
  /// Build a extended int type.
  ///
  /// \param IsUnsigned Boolean representing the signedness of the type.
  ///
  /// \param BitWidth Size of this int type in bits, or an expression representing
  /// that.
  ///
  /// \param Loc Location of the keyword.
  QualType Sema::BuildExtIntType(bool IsUnsigned, Expr *BitWidth,
                                 SourceLocation Loc) {
    if (BitWidth->isInstantiationDependent())
      return Context.getDependentExtIntType(IsUnsigned, BitWidth);
  
    llvm::APSInt Bits(32);
    ExprResult ICE =
        VerifyIntegerConstantExpression(BitWidth, &Bits, /*FIXME*/ AllowFold);
  
    if (ICE.isInvalid())
      return QualType();
  
    int64_t NumBits = Bits.getSExtValue();
    if (!IsUnsigned && NumBits < 2) {
      Diag(Loc, diag::err_ext_int_bad_size) << 0;
      return QualType();
    }
  
    if (IsUnsigned && NumBits < 1) {
      Diag(Loc, diag::err_ext_int_bad_size) << 1;
      return QualType();
    }
  
    if (NumBits > llvm::IntegerType::MAX_INT_BITS) {
      Diag(Loc, diag::err_ext_int_max_size) << IsUnsigned
                                            << llvm::IntegerType::MAX_INT_BITS;
      return QualType();
    }
  
    return Context.getExtIntType(IsUnsigned, NumBits);
  }
  
  /// Check whether the specified array bound can be evaluated using the relevant
  /// language rules. If so, returns the possibly-converted expression and sets
  /// SizeVal to the size. If not, but the expression might be a VLA bound,
  /// returns ExprResult(). Otherwise, produces a diagnostic and returns
  /// ExprError().
  static ExprResult checkArraySize(Sema &S, Expr *&ArraySize,
                                   llvm::APSInt &SizeVal, unsigned VLADiag,
                                   bool VLAIsError) {
    if (S.getLangOpts().CPlusPlus14 &&
        (VLAIsError ||
         !ArraySize->getType()->isIntegralOrUnscopedEnumerationType())) {
      // C++14 [dcl.array]p1:
      //   The constant-expression shall be a converted constant expression of
      //   type std::size_t.
      //
      // Don't apply this rule if we might be forming a VLA: in that case, we
      // allow non-constant expressions and constant-folding. We only need to use
      // the converted constant expression rules (to properly convert the source)
      // when the source expression is of class type.
      return S.CheckConvertedConstantExpression(
          ArraySize, S.Context.getSizeType(), SizeVal, Sema::CCEK_ArrayBound);
    }
  
    // If the size is an ICE, it certainly isn't a VLA. If we're in a GNU mode
    // (like gnu99, but not c99) accept any evaluatable value as an extension.
    class VLADiagnoser : public Sema::VerifyICEDiagnoser {
    public:
      unsigned VLADiag;
      bool VLAIsError;
      bool IsVLA = false;
  
      VLADiagnoser(unsigned VLADiag, bool VLAIsError)
          : VLADiag(VLADiag), VLAIsError(VLAIsError) {}
  
      Sema::SemaDiagnosticBuilder diagnoseNotICEType(Sema &S, SourceLocation Loc,
                                                     QualType T) override {
        return S.Diag(Loc, diag::err_array_size_non_int) << T;
      }
  
      Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
                                                 SourceLocation Loc) override {
        IsVLA = !VLAIsError;
        return S.Diag(Loc, VLADiag);
      }
  
      Sema::SemaDiagnosticBuilder diagnoseFold(Sema &S,
                                               SourceLocation Loc) override {
        return S.Diag(Loc, diag::ext_vla_folded_to_constant);
      }
    } Diagnoser(VLADiag, VLAIsError);
  
    ExprResult R =
        S.VerifyIntegerConstantExpression(ArraySize, &SizeVal, Diagnoser);
    if (Diagnoser.IsVLA)
      return ExprResult();
    return R;
  }
  
  /// Build an array type.
  ///
  /// \param T The type of each element in the array.
  ///
  /// \param ASM C99 array size modifier (e.g., '*', 'static').
  ///
  /// \param ArraySize Expression describing the size of the array.
  ///
  /// \param Brackets The range from the opening '[' to the closing ']'.
  ///
  /// \param Entity The name of the entity that involves the array
  /// type, if known.
  ///
  /// \returns A suitable array type, if there are no errors. Otherwise,
  /// returns a NULL type.
  QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
                                Expr *ArraySize, unsigned Quals,
                                SourceRange Brackets, DeclarationName Entity) {
  
    SourceLocation Loc = Brackets.getBegin();
    if (getLangOpts().CPlusPlus) {
      // C++ [dcl.array]p1:
      //   T is called the array element type; this type shall not be a reference
      //   type, the (possibly cv-qualified) type void, a function type or an
      //   abstract class type.
      //
      // C++ [dcl.array]p3:
      //   When several "array of" specifications are adjacent, [...] only the
      //   first of the constant expressions that specify the bounds of the arrays
      //   may be omitted.
      //
      // Note: function types are handled in the common path with C.
      if (T->isReferenceType()) {
        Diag(Loc, diag::err_illegal_decl_array_of_references)
        << getPrintableNameForEntity(Entity) << T;
        return QualType();
      }
  
      if (T->isVoidType() || T->isIncompleteArrayType()) {
        Diag(Loc, diag::err_array_incomplete_or_sizeless_type) << 0 << T;
        return QualType();
      }
  
      if (RequireNonAbstractType(Brackets.getBegin(), T,
                                 diag::err_array_of_abstract_type))
        return QualType();
  
      // Mentioning a member pointer type for an array type causes us to lock in
      // an inheritance model, even if it's inside an unused typedef.
      if (Context.getTargetInfo().getCXXABI().isMicrosoft())
        if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
          if (!MPTy->getClass()->isDependentType())
            (void)isCompleteType(Loc, T);
  
    } else {
      // C99 6.7.5.2p1: If the element type is an incomplete or function type,
      // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
      if (RequireCompleteSizedType(Loc, T,
                                   diag::err_array_incomplete_or_sizeless_type))
        return QualType();
    }
  
    if (T->isSizelessType()) {
      Diag(Loc, diag::err_array_incomplete_or_sizeless_type) << 1 << T;
      return QualType();
    }
  
    if (T->isFunctionType()) {
      Diag(Loc, diag::err_illegal_decl_array_of_functions)
        << getPrintableNameForEntity(Entity) << T;
      return QualType();
    }
  
    if (const RecordType *EltTy = T->getAs<RecordType>()) {
      // If the element type is a struct or union that contains a variadic
      // array, accept it as a GNU extension: C99 6.7.2.1p2.
      if (EltTy->getDecl()->hasFlexibleArrayMember())
        Diag(Loc, diag::ext_flexible_array_in_array) << T;
    } else if (T->isObjCObjectType()) {
      Diag(Loc, diag::err_objc_array_of_interfaces) << T;
      return QualType();
    }
  
    // Do placeholder conversions on the array size expression.
    if (ArraySize && ArraySize->hasPlaceholderType()) {
      ExprResult Result = CheckPlaceholderExpr(ArraySize);
      if (Result.isInvalid()) return QualType();
      ArraySize = Result.get();
    }
  
    // Do lvalue-to-rvalue conversions on the array size expression.
    if (ArraySize && !ArraySize->isRValue()) {
      ExprResult Result = DefaultLvalueConversion(ArraySize);
      if (Result.isInvalid())
        return QualType();
  
      ArraySize = Result.get();
    }
  
    // C99 6.7.5.2p1: The size expression shall have integer type.
    // C++11 allows contextual conversions to such types.
    if (!getLangOpts().CPlusPlus11 &&
        ArraySize && !ArraySize->isTypeDependent() &&
        !ArraySize->getType()->isIntegralOrUnscopedEnumerationType()) {
      Diag(ArraySize->getBeginLoc(), diag::err_array_size_non_int)
          << ArraySize->getType() << ArraySize->getSourceRange();
      return QualType();
    }
  
    // VLAs always produce at least a -Wvla diagnostic, sometimes an error.
    unsigned VLADiag;
    bool VLAIsError;
    if (getLangOpts().OpenCL) {
      // OpenCL v1.2 s6.9.d: variable length arrays are not supported.
      VLADiag = diag::err_opencl_vla;
      VLAIsError = true;
    } else if (getLangOpts().C99) {
      VLADiag = diag::warn_vla_used;
      VLAIsError = false;
    } else if (isSFINAEContext()) {
      VLADiag = diag::err_vla_in_sfinae;
      VLAIsError = true;
    } else {
      VLADiag = diag::ext_vla;
      VLAIsError = false;
    }
  
    llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
    if (!ArraySize) {
      if (ASM == ArrayType::Star) {
        Diag(Loc, VLADiag);
        if (VLAIsError)
          return QualType();
  
        T = Context.getVariableArrayType(T, nullptr, ASM, Quals, Brackets);
      } else {
        T = Context.getIncompleteArrayType(T, ASM, Quals);
      }
    } else if (ArraySize->isTypeDependent() || ArraySize->isValueDependent()) {
      T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals, Brackets);
    } else {
      ExprResult R =
          checkArraySize(*this, ArraySize, ConstVal, VLADiag, VLAIsError);
      if (R.isInvalid())
        return QualType();
  
      if (!R.isUsable()) {
        // C99: an array with a non-ICE size is a VLA. We accept any expression
        // that we can fold to a non-zero positive value as a non-VLA as an
        // extension.
        T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
      } else if (!T->isDependentType() && !T->isIncompleteType() &&
                 !T->isConstantSizeType()) {
        // C99: an array with an element type that has a non-constant-size is a
        // VLA.
        // FIXME: Add a note to explain why this isn't a VLA.
        Diag(Loc, VLADiag);
        if (VLAIsError)
          return QualType();
        T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
      } else {
        // C99 6.7.5.2p1: If the expression is a constant expression, it shall
        // have a value greater than zero.
        // In C++, this follows from narrowing conversions being disallowed.
        if (ConstVal.isSigned() && ConstVal.isNegative()) {
          if (Entity)
            Diag(ArraySize->getBeginLoc(), diag::err_decl_negative_array_size)
                << getPrintableNameForEntity(Entity)
                << ArraySize->getSourceRange();
          else
            Diag(ArraySize->getBeginLoc(),
                 diag::err_typecheck_negative_array_size)
                << ArraySize->getSourceRange();
          return QualType();
        }
        if (ConstVal == 0) {
          // GCC accepts zero sized static arrays. We allow them when
          // we're not in a SFINAE context.
          Diag(ArraySize->getBeginLoc(),
               isSFINAEContext() ? diag::err_typecheck_zero_array_size
                                 : diag::ext_typecheck_zero_array_size)
              << ArraySize->getSourceRange();
        }
  
        // Is the array too large?
        unsigned ActiveSizeBits =
            (!T->isDependentType() && !T->isVariablyModifiedType() &&
             !T->isIncompleteType() && !T->isUndeducedType())
                ? ConstantArrayType::getNumAddressingBits(Context, T, ConstVal)
                : ConstVal.getActiveBits();
        if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
          Diag(ArraySize->getBeginLoc(), diag::err_array_too_large)
              << ConstVal.toString(10) << ArraySize->getSourceRange();
          return QualType();
        }
  
        T = Context.getConstantArrayType(T, ConstVal, ArraySize, ASM, Quals);
      }
    }
  
    // Delay diagnostic to SemaSYCL so only Kernel functions are diagnosed.
    if (T->isVariableArrayType() && !Context.getTargetInfo().isVLASupported() &&
        !getLangOpts().SYCLIsDevice) {
      // CUDA device code and some other targets don't support VLAs.
      targetDiag(Loc, (getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
                          ? diag::err_cuda_vla
                          : diag::err_vla_unsupported)
          << ((getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
                  ? CurrentCUDATarget()
                  : CFT_InvalidTarget);
    }
  
    // If this is not C99, diagnose array size modifiers on non-VLAs.
    if (!getLangOpts().C99 && !T->isVariableArrayType() &&
        (ASM != ArrayType::Normal || Quals != 0)) {
      Diag(Loc, getLangOpts().CPlusPlus ? diag::err_c99_array_usage_cxx
                                        : diag::ext_c99_array_usage)
          << ASM;
    }
  
    // OpenCL v2.0 s6.12.5 - Arrays of blocks are not supported.
    // OpenCL v2.0 s6.16.13.1 - Arrays of pipe type are not supported.
    // OpenCL v2.0 s6.9.b - Arrays of image/sampler type are not supported.
    if (getLangOpts().OpenCL) {
      const QualType ArrType = Context.getBaseElementType(T);
      if (ArrType->isBlockPointerType() || ArrType->isPipeType() ||
          ArrType->isSamplerT() || ArrType->isImageType()) {
        Diag(Loc, diag::err_opencl_invalid_type_array) << ArrType;
        return QualType();
      }
    }
  
    return T;
  }
  
  QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr,
                                 SourceLocation AttrLoc) {
    // The base type must be integer (not Boolean or enumeration) or float, and
    // can't already be a vector.
    if ((!CurType->isDependentType() &&
         (!CurType->isBuiltinType() || CurType->isBooleanType() ||
          (!CurType->isIntegerType() && !CurType->isRealFloatingType()))) ||
        CurType->isArrayType()) {
      Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << CurType;
      return QualType();
    }
  
    if (SizeExpr->isTypeDependent() || SizeExpr->isValueDependent())
      return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc,
                                                 VectorType::GenericVector);
  
    Optional<llvm::APSInt> VecSize = SizeExpr->getIntegerConstantExpr(Context);
    if (!VecSize) {
      Diag(AttrLoc, diag::err_attribute_argument_type)
          << "vector_size" << AANT_ArgumentIntegerConstant
          << SizeExpr->getSourceRange();
      return QualType();
    }
  
    if (CurType->isDependentType())
      return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc,
                                                 VectorType::GenericVector);
  
    // vecSize is specified in bytes - convert to bits.
    if (!VecSize->isIntN(61)) {
      // Bit size will overflow uint64.
      Diag(AttrLoc, diag::err_attribute_size_too_large)
          << SizeExpr->getSourceRange() << "vector";
      return QualType();
    }
    uint64_t VectorSizeBits = VecSize->getZExtValue() * 8;
    unsigned TypeSize = static_cast<unsigned>(Context.getTypeSize(CurType));
  
    if (VectorSizeBits == 0) {
      Diag(AttrLoc, diag::err_attribute_zero_size)
          << SizeExpr->getSourceRange() << "vector";
      return QualType();
    }
  
    if (VectorSizeBits % TypeSize) {
      Diag(AttrLoc, diag::err_attribute_invalid_size)
          << SizeExpr->getSourceRange();
      return QualType();
    }
  
    if (VectorSizeBits / TypeSize > std::numeric_limits<uint32_t>::max()) {
      Diag(AttrLoc, diag::err_attribute_size_too_large)
          << SizeExpr->getSourceRange() << "vector";
      return QualType();
    }
  
    return Context.getVectorType(CurType, VectorSizeBits / TypeSize,
                                 VectorType::GenericVector);
  }
  
  /// Build an ext-vector type.
  ///
  /// Run the required checks for the extended vector type.
  QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize,
                                    SourceLocation AttrLoc) {
    // Unlike gcc's vector_size attribute, we do not allow vectors to be defined
    // in conjunction with complex types (pointers, arrays, functions, etc.).
    //
    // Additionally, OpenCL prohibits vectors of booleans (they're considered a
    // reserved data type under OpenCL v2.0 s6.1.4), we don't support selects
    // on bitvectors, and we have no well-defined ABI for bitvectors, so vectors
    // of bool aren't allowed.
    if ((!T->isDependentType() && !T->isIntegerType() &&
         !T->isRealFloatingType()) ||
        T->isBooleanType()) {
      Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << T;
      return QualType();
    }
  
    if (!ArraySize->isTypeDependent() && !ArraySize->isValueDependent()) {
      Optional<llvm::APSInt> vecSize = ArraySize->getIntegerConstantExpr(Context);
      if (!vecSize) {
        Diag(AttrLoc, diag::err_attribute_argument_type)
          << "ext_vector_type" << AANT_ArgumentIntegerConstant
          << ArraySize->getSourceRange();
        return QualType();
      }
  
      if (!vecSize->isIntN(32)) {
        Diag(AttrLoc, diag::err_attribute_size_too_large)
            << ArraySize->getSourceRange() << "vector";
        return QualType();
      }
      // Unlike gcc's vector_size attribute, the size is specified as the
      // number of elements, not the number of bytes.
      unsigned vectorSize = static_cast<unsigned>(vecSize->getZExtValue());
  
      if (vectorSize == 0) {
        Diag(AttrLoc, diag::err_attribute_zero_size)
            << ArraySize->getSourceRange() << "vector";
        return QualType();
      }
  
      return Context.getExtVectorType(T, vectorSize);
    }
  
    return Context.getDependentSizedExtVectorType(T, ArraySize, AttrLoc);
  }
  
  QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols,
                                 SourceLocation AttrLoc) {
    assert(Context.getLangOpts().MatrixTypes &&
           "Should never build a matrix type when it is disabled");
  
    // Check element type, if it is not dependent.
    if (!ElementTy->isDependentType() &&
        !MatrixType::isValidElementType(ElementTy)) {
      Diag(AttrLoc, diag::err_attribute_invalid_matrix_type) << ElementTy;
      return QualType();
    }
  
    if (NumRows->isTypeDependent() || NumCols->isTypeDependent() ||
        NumRows->isValueDependent() || NumCols->isValueDependent())
      return Context.getDependentSizedMatrixType(ElementTy, NumRows, NumCols,
                                                 AttrLoc);
  
    Optional<llvm::APSInt> ValueRows = NumRows->getIntegerConstantExpr(Context);
    Optional<llvm::APSInt> ValueColumns =
        NumCols->getIntegerConstantExpr(Context);
  
    auto const RowRange = NumRows->getSourceRange();
    auto const ColRange = NumCols->getSourceRange();
  
    // Both are row and column expressions are invalid.
    if (!ValueRows && !ValueColumns) {
      Diag(AttrLoc, diag::err_attribute_argument_type)
          << "matrix_type" << AANT_ArgumentIntegerConstant << RowRange
          << ColRange;
      return QualType();
    }
  
    // Only the row expression is invalid.
    if (!ValueRows) {
      Diag(AttrLoc, diag::err_attribute_argument_type)
          << "matrix_type" << AANT_ArgumentIntegerConstant << RowRange;
      return QualType();
    }
  
    // Only the column expression is invalid.
    if (!ValueColumns) {
      Diag(AttrLoc, diag::err_attribute_argument_type)
          << "matrix_type" << AANT_ArgumentIntegerConstant << ColRange;
      return QualType();
    }
  
    // Check the matrix dimensions.
    unsigned MatrixRows = static_cast<unsigned>(ValueRows->getZExtValue());
    unsigned MatrixColumns = static_cast<unsigned>(ValueColumns->getZExtValue());
    if (MatrixRows == 0 && MatrixColumns == 0) {
      Diag(AttrLoc, diag::err_attribute_zero_size)
          << "matrix" << RowRange << ColRange;
      return QualType();
    }
    if (MatrixRows == 0) {
      Diag(AttrLoc, diag::err_attribute_zero_size) << "matrix" << RowRange;
      return QualType();
    }
    if (MatrixColumns == 0) {
      Diag(AttrLoc, diag::err_attribute_zero_size) << "matrix" << ColRange;
      return QualType();
    }
    if (!ConstantMatrixType::isDimensionValid(MatrixRows)) {
      Diag(AttrLoc, diag::err_attribute_size_too_large)
          << RowRange << "matrix row";
      return QualType();
    }
    if (!ConstantMatrixType::isDimensionValid(MatrixColumns)) {
      Diag(AttrLoc, diag::err_attribute_size_too_large)
          << ColRange << "matrix column";
      return QualType();
    }
    return Context.getConstantMatrixType(ElementTy, MatrixRows, MatrixColumns);
  }
  
  bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
    if (T->isArrayType() || T->isFunctionType()) {
      Diag(Loc, diag::err_func_returning_array_function)
        << T->isFunctionType() << T;
      return true;
    }
  
    // Functions cannot return half FP.
    if (T->isHalfType() && !getLangOpts().HalfArgsAndReturns) {
      Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 1 <<
        FixItHint::CreateInsertion(Loc, "*");
      return true;
    }
  
    // Methods cannot return interface types. All ObjC objects are
    // passed by reference.
    if (T->isObjCObjectType()) {
      Diag(Loc, diag::err_object_cannot_be_passed_returned_by_value)
          << 0 << T << FixItHint::CreateInsertion(Loc, "*");
      return true;
    }
  
    if (T.hasNonTrivialToPrimitiveDestructCUnion() ||
        T.hasNonTrivialToPrimitiveCopyCUnion())
      checkNonTrivialCUnion(T, Loc, NTCUC_FunctionReturn,
                            NTCUK_Destruct|NTCUK_Copy);
  
    // C++2a [dcl.fct]p12:
    //   A volatile-qualified return type is deprecated
    if (T.isVolatileQualified() && getLangOpts().CPlusPlus20)
      Diag(Loc, diag::warn_deprecated_volatile_return) << T;
  
    return false;
  }
  
  /// Check the extended parameter information.  Most of the necessary
  /// checking should occur when applying the parameter attribute; the
  /// only other checks required are positional restrictions.
  static void checkExtParameterInfos(Sema &S, ArrayRef<QualType> paramTypes,
                      const FunctionProtoType::ExtProtoInfo &EPI,
                      llvm::function_ref<SourceLocation(unsigned)> getParamLoc) {
    assert(EPI.ExtParameterInfos && "shouldn't get here without param infos");
  
    bool hasCheckedSwiftCall = false;
    auto checkForSwiftCC = [&](unsigned paramIndex) {
      // Only do this once.
      if (hasCheckedSwiftCall) return;
      hasCheckedSwiftCall = true;
      if (EPI.ExtInfo.getCC() == CC_Swift) return;
      S.Diag(getParamLoc(paramIndex), diag::err_swift_param_attr_not_swiftcall)
        << getParameterABISpelling(EPI.ExtParameterInfos[paramIndex].getABI());
    };
  
    for (size_t paramIndex = 0, numParams = paramTypes.size();
            paramIndex != numParams; ++paramIndex) {
      switch (EPI.ExtParameterInfos[paramIndex].getABI()) {
      // Nothing interesting to check for orindary-ABI parameters.
      case ParameterABI::Ordinary:
        continue;
  
      // swift_indirect_result parameters must be a prefix of the function
      // arguments.
      case ParameterABI::SwiftIndirectResult:
        checkForSwiftCC(paramIndex);
        if (paramIndex != 0 &&
            EPI.ExtParameterInfos[paramIndex - 1].getABI()
              != ParameterABI::SwiftIndirectResult) {
          S.Diag(getParamLoc(paramIndex),
                 diag::err_swift_indirect_result_not_first);
        }
        continue;
  
      case ParameterABI::SwiftContext:
        checkForSwiftCC(paramIndex);
        continue;
  
      // swift_error parameters must be preceded by a swift_context parameter.
      case ParameterABI::SwiftErrorResult:
        checkForSwiftCC(paramIndex);
        if (paramIndex == 0 ||
            EPI.ExtParameterInfos[paramIndex - 1].getABI() !=
                ParameterABI::SwiftContext) {
          S.Diag(getParamLoc(paramIndex),
                 diag::err_swift_error_result_not_after_swift_context);
        }
        continue;
      }
      llvm_unreachable("bad ABI kind");
    }
  }
  
  QualType Sema::BuildFunctionType(QualType T,
                                   MutableArrayRef<QualType> ParamTypes,
                                   SourceLocation Loc, DeclarationName Entity,
                                   const FunctionProtoType::ExtProtoInfo &EPI) {
    bool Invalid = false;
  
    Invalid |= CheckFunctionReturnType(T, Loc);
  
    for (unsigned Idx = 0, Cnt = ParamTypes.size(); Idx < Cnt; ++Idx) {
      // FIXME: Loc is too inprecise here, should use proper locations for args.
      QualType ParamType = Context.getAdjustedParameterType(ParamTypes[Idx]);
      if (ParamType->isVoidType()) {
        Diag(Loc, diag::err_param_with_void_type);
        Invalid = true;
      } else if (ParamType->isHalfType() && !getLangOpts().HalfArgsAndReturns) {
        // Disallow half FP arguments.
        Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 0 <<
          FixItHint::CreateInsertion(Loc, "*");
        Invalid = true;
      }
  
      // C++2a [dcl.fct]p4:
      //   A parameter with volatile-qualified type is deprecated
      if (ParamType.isVolatileQualified() && getLangOpts().CPlusPlus20)
        Diag(Loc, diag::warn_deprecated_volatile_param) << ParamType;
  
      ParamTypes[Idx] = ParamType;
    }
  
    if (EPI.ExtParameterInfos) {
      checkExtParameterInfos(*this, ParamTypes, EPI,
                             [=](unsigned i) { return Loc; });
    }
  
    if (EPI.ExtInfo.getProducesResult()) {
      // This is just a warning, so we can't fail to build if we see it.
      checkNSReturnsRetainedReturnType(Loc, T);
    }
  
    if (Invalid)
      return QualType();
  
    return Context.getFunctionType(T, ParamTypes, EPI);
  }
  
  /// Build a member pointer type \c T Class::*.
  ///
  /// \param T the type to which the member pointer refers.
  /// \param Class the class type into which the member pointer points.
  /// \param Loc the location where this type begins
  /// \param Entity the name of the entity that will have this member pointer type
  ///
  /// \returns a member pointer type, if successful, or a NULL type if there was
  /// an error.
  QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
                                        SourceLocation Loc,
                                        DeclarationName Entity) {
    // Verify that we're not building a pointer to pointer to function with
    // exception specification.
    if (CheckDistantExceptionSpec(T)) {
      Diag(Loc, diag::err_distant_exception_spec);
      return QualType();
    }
  
    // C++ 8.3.3p3: A pointer to member shall not point to ... a member
    //   with reference type, or "cv void."
    if (T->isReferenceType()) {
      Diag(Loc, diag::err_illegal_decl_mempointer_to_reference)
        << getPrintableNameForEntity(Entity) << T;
      return QualType();
    }
  
    if (T->isVoidType()) {
      Diag(Loc, diag::err_illegal_decl_mempointer_to_void)
        << getPrintableNameForEntity(Entity);
      return QualType();
    }
  
    if (!Class->isDependentType() && !Class->isRecordType()) {
      Diag(Loc, diag::err_mempointer_in_nonclass_type) << Class;
      return QualType();
    }
  
    if (T->isFunctionType() && getLangOpts().OpenCL &&
        !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers",
                                              getLangOpts())) {
      Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0;
      return QualType();
    }
  
    // Adjust the default free function calling convention to the default method
    // calling convention.
    bool IsCtorOrDtor =
        (Entity.getNameKind() == DeclarationName::CXXConstructorName) ||
        (Entity.getNameKind() == DeclarationName::CXXDestructorName);
    if (T->isFunctionType())
      adjustMemberFunctionCC(T, /*IsStatic=*/false, IsCtorOrDtor, Loc);
  
    return Context.getMemberPointerType(T, Class.getTypePtr());
  }
  
  /// Build a block pointer type.
  ///
  /// \param T The type to which we'll be building a block pointer.
  ///
  /// \param Loc The source location, used for diagnostics.
  ///
  /// \param Entity The name of the entity that involves the block pointer
  /// type, if known.
  ///
  /// \returns A suitable block pointer type, if there are no
  /// errors. Otherwise, returns a NULL type.
  QualType Sema::BuildBlockPointerType(QualType T,
                                       SourceLocation Loc,
                                       DeclarationName Entity) {
    if (!T->isFunctionType()) {
      Diag(Loc, diag::err_nonfunction_block_type);
      return QualType();
    }
  
    if (checkQualifiedFunction(*this, T, Loc, QFK_BlockPointer))
      return QualType();
  
    if (getLangOpts().OpenCL)
      T = deduceOpenCLPointeeAddrSpace(*this, T);
  
    return Context.getBlockPointerType(T);
  }
  
  QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) {
    QualType QT = Ty.get();
    if (QT.isNull()) {
      if (TInfo) *TInfo = nullptr;
      return QualType();
    }
  
    TypeSourceInfo *DI = nullptr;
    if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) {
      QT = LIT->getType();
      DI = LIT->getTypeSourceInfo();
    }
  
    if (TInfo) *TInfo = DI;
    return QT;
  }
  
  static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
                                              Qualifiers::ObjCLifetime ownership,
                                              unsigned chunkIndex);
  
  /// Given that this is the declaration of a parameter under ARC,
  /// attempt to infer attributes and such for pointer-to-whatever
  /// types.
  static void inferARCWriteback(TypeProcessingState &state,
                                QualType &declSpecType) {
    Sema &S = state.getSema();
    Declarator &declarator = state.getDeclarator();
  
    // TODO: should we care about decl qualifiers?
  
    // Check whether the declarator has the expected form.  We walk
    // from the inside out in order to make the block logic work.
    unsigned outermostPointerIndex = 0;
    bool isBlockPointer = false;
    unsigned numPointers = 0;
    for (unsigned i = 0, e = declarator.getNumTypeObjects(); i != e; ++i) {
      unsigned chunkIndex = i;
      DeclaratorChunk &chunk = declarator.getTypeObject(chunkIndex);
      switch (chunk.Kind) {
      case DeclaratorChunk::Paren:
        // Ignore parens.
        break;
  
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::Pointer:
        // Count the number of pointers.  Treat references
        // interchangeably as pointers; if they're mis-ordered, normal
        // type building will discover that.
        outermostPointerIndex = chunkIndex;
        numPointers++;
        break;
  
      case DeclaratorChunk::BlockPointer:
        // If we have a pointer to block pointer, that's an acceptable
        // indirect reference; anything else is not an application of
        // the rules.
        if (numPointers != 1) return;
        numPointers++;
        outermostPointerIndex = chunkIndex;
        isBlockPointer = true;
  
        // We don't care about pointer structure in return values here.
        goto done;
  
      case DeclaratorChunk::Array: // suppress if written (id[])?
      case DeclaratorChunk::Function:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        return;
      }
    }
   done:
  
    // If we have *one* pointer, then we want to throw the qualifier on
    // the declaration-specifiers, which means that it needs to be a
    // retainable object type.
    if (numPointers == 1) {
      // If it's not a retainable object type, the rule doesn't apply.
      if (!declSpecType->isObjCRetainableType()) return;
  
      // If it already has lifetime, don't do anything.
      if (declSpecType.getObjCLifetime()) return;
  
      // Otherwise, modify the type in-place.
      Qualifiers qs;
  
      if (declSpecType->isObjCARCImplicitlyUnretainedType())
        qs.addObjCLifetime(Qualifiers::OCL_ExplicitNone);
      else
        qs.addObjCLifetime(Qualifiers::OCL_Autoreleasing);
      declSpecType = S.Context.getQualifiedType(declSpecType, qs);
  
    // If we have *two* pointers, then we want to throw the qualifier on
    // the outermost pointer.
    } else if (numPointers == 2) {
      // If we don't have a block pointer, we need to check whether the
      // declaration-specifiers gave us something that will turn into a
      // retainable object pointer after we slap the first pointer on it.
      if (!isBlockPointer && !declSpecType->isObjCObjectType())
        return;
  
      // Look for an explicit lifetime attribute there.
      DeclaratorChunk &chunk = declarator.getTypeObject(outermostPointerIndex);
      if (chunk.Kind != DeclaratorChunk::Pointer &&
          chunk.Kind != DeclaratorChunk::BlockPointer)
        return;
      for (const ParsedAttr &AL : chunk.getAttrs())
        if (AL.getKind() == ParsedAttr::AT_ObjCOwnership)
          return;
  
      transferARCOwnershipToDeclaratorChunk(state, Qualifiers::OCL_Autoreleasing,
                                            outermostPointerIndex);
  
    // Any other number of pointers/references does not trigger the rule.
    } else return;
  
    // TODO: mark whether we did this inference?
  }
  
  void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
                                       SourceLocation FallbackLoc,
                                       SourceLocation ConstQualLoc,
                                       SourceLocation VolatileQualLoc,
                                       SourceLocation RestrictQualLoc,
                                       SourceLocation AtomicQualLoc,
                                       SourceLocation UnalignedQualLoc) {
    if (!Quals)
      return;
  
    struct Qual {
      const char *Name;
      unsigned Mask;
      SourceLocation Loc;
    } const QualKinds[5] = {
      { "const", DeclSpec::TQ_const, ConstQualLoc },
      { "volatile", DeclSpec::TQ_volatile, VolatileQualLoc },
      { "restrict", DeclSpec::TQ_restrict, RestrictQualLoc },
      { "__unaligned", DeclSpec::TQ_unaligned, UnalignedQualLoc },
      { "_Atomic", DeclSpec::TQ_atomic, AtomicQualLoc }
    };
  
    SmallString<32> QualStr;
    unsigned NumQuals = 0;
    SourceLocation Loc;
    FixItHint FixIts[5];
  
    // Build a string naming the redundant qualifiers.
    for (auto &E : QualKinds) {
      if (Quals & E.Mask) {
        if (!QualStr.empty()) QualStr += ' ';
        QualStr += E.Name;
  
        // If we have a location for the qualifier, offer a fixit.
        SourceLocation QualLoc = E.Loc;
        if (QualLoc.isValid()) {
          FixIts[NumQuals] = FixItHint::CreateRemoval(QualLoc);
          if (Loc.isInvalid() ||
              getSourceManager().isBeforeInTranslationUnit(QualLoc, Loc))
            Loc = QualLoc;
        }
  
        ++NumQuals;
      }
    }
  
    Diag(Loc.isInvalid() ? FallbackLoc : Loc, DiagID)
      << QualStr << NumQuals << FixIts[0] << FixIts[1] << FixIts[2] << FixIts[3];
  }
  
  // Diagnose pointless type qualifiers on the return type of a function.
  static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
                                                    Declarator &D,
                                                    unsigned FunctionChunkIndex) {
    const DeclaratorChunk::FunctionTypeInfo &FTI =
        D.getTypeObject(FunctionChunkIndex).Fun;
    if (FTI.hasTrailingReturnType()) {
      S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
                                  RetTy.getLocalCVRQualifiers(),
                                  FTI.getTrailingReturnTypeLoc());
      return;
    }
  
    for (unsigned OuterChunkIndex = FunctionChunkIndex + 1,
                  End = D.getNumTypeObjects();
         OuterChunkIndex != End; ++OuterChunkIndex) {
      DeclaratorChunk &OuterChunk = D.getTypeObject(OuterChunkIndex);
      switch (OuterChunk.Kind) {
      case DeclaratorChunk::Paren:
        continue;
  
      case DeclaratorChunk::Pointer: {
        DeclaratorChunk::PointerTypeInfo &PTI = OuterChunk.Ptr;
        S.diagnoseIgnoredQualifiers(
            diag::warn_qual_return_type,
            PTI.TypeQuals,
            SourceLocation(),
            PTI.ConstQualLoc,
            PTI.VolatileQualLoc,
            PTI.RestrictQualLoc,
            PTI.AtomicQualLoc,
            PTI.UnalignedQualLoc);
        return;
      }
  
      case DeclaratorChunk::Function:
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::Array:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        // FIXME: We can't currently provide an accurate source location and a
        // fix-it hint for these.
        unsigned AtomicQual = RetTy->isAtomicType() ? DeclSpec::TQ_atomic : 0;
        S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
                                    RetTy.getCVRQualifiers() | AtomicQual,
                                    D.getIdentifierLoc());
        return;
      }
  
      llvm_unreachable("unknown declarator chunk kind");
    }
  
    // If the qualifiers come from a conversion function type, don't diagnose
    // them -- they're not necessarily redundant, since such a conversion
    // operator can be explicitly called as "x.operator const int()".
    if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId)
      return;
  
    // Just parens all the way out to the decl specifiers. Diagnose any qualifiers
    // which are present there.
    S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
                                D.getDeclSpec().getTypeQualifiers(),
                                D.getIdentifierLoc(),
                                D.getDeclSpec().getConstSpecLoc(),
                                D.getDeclSpec().getVolatileSpecLoc(),
                                D.getDeclSpec().getRestrictSpecLoc(),
                                D.getDeclSpec().getAtomicSpecLoc(),
                                D.getDeclSpec().getUnalignedSpecLoc());
  }
  
  static std::pair<QualType, TypeSourceInfo *>
  InventTemplateParameter(TypeProcessingState &state, QualType T,
                          TypeSourceInfo *TrailingTSI, AutoType *Auto,
                          InventedTemplateParameterInfo &Info) {
    Sema &S = state.getSema();
    Declarator &D = state.getDeclarator();
  
    const unsigned TemplateParameterDepth = Info.AutoTemplateParameterDepth;
    const unsigned AutoParameterPosition = Info.TemplateParams.size();
    const bool IsParameterPack = D.hasEllipsis();
  
    // If auto is mentioned in a lambda parameter or abbreviated function
    // template context, convert it to a template parameter type.
  
    // Create the TemplateTypeParmDecl here to retrieve the corresponding
    // template parameter type. Template parameters are temporarily added
    // to the TU until the associated TemplateDecl is created.
    TemplateTypeParmDecl *InventedTemplateParam =
        TemplateTypeParmDecl::Create(
            S.Context, S.Context.getTranslationUnitDecl(),
            /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(),
            /*NameLoc=*/D.getIdentifierLoc(),
            TemplateParameterDepth, AutoParameterPosition,
            S.InventAbbreviatedTemplateParameterTypeName(
                D.getIdentifier(), AutoParameterPosition), false,
            IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained());
    InventedTemplateParam->setImplicit();
    Info.TemplateParams.push_back(InventedTemplateParam);
  
    // Attach type constraints to the new parameter.
    if (Auto->isConstrained()) {
      if (TrailingTSI) {
        // The 'auto' appears in a trailing return type we've already built;
        // extract its type constraints to attach to the template parameter.
        AutoTypeLoc AutoLoc = TrailingTSI->getTypeLoc().getContainedAutoTypeLoc();
        TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), AutoLoc.getRAngleLoc());
        for (unsigned Idx = 0; Idx < AutoLoc.getNumArgs(); ++Idx)
          TAL.addArgument(AutoLoc.getArgLoc(Idx));
  
        S.AttachTypeConstraint(AutoLoc.getNestedNameSpecifierLoc(),
                               AutoLoc.getConceptNameInfo(),
                               AutoLoc.getNamedConcept(),
                               AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr,
                               InventedTemplateParam, D.getEllipsisLoc());
      } else {
        // The 'auto' appears in the decl-specifiers; we've not finished forming
        // TypeSourceInfo for it yet.
        TemplateIdAnnotation *TemplateId = D.getDeclSpec().getRepAsTemplateId();
        TemplateArgumentListInfo TemplateArgsInfo;
        if (TemplateId->LAngleLoc.isValid()) {
          ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
                                             TemplateId->NumArgs);
          S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
        }
        S.AttachTypeConstraint(
            D.getDeclSpec().getTypeSpecScope().getWithLocInContext(S.Context),
            DeclarationNameInfo(DeclarationName(TemplateId->Name),
                                TemplateId->TemplateNameLoc),
            cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl()),
            TemplateId->LAngleLoc.isValid() ? &TemplateArgsInfo : nullptr,
            InventedTemplateParam, D.getEllipsisLoc());
      }
    }
  
    // Replace the 'auto' in the function parameter with this invented
    // template type parameter.
    // FIXME: Retain some type sugar to indicate that this was written
    //  as 'auto'?
    QualType Replacement(InventedTemplateParam->getTypeForDecl(), 0);
    QualType NewT = state.ReplaceAutoType(T, Replacement);
    TypeSourceInfo *NewTSI =
        TrailingTSI ? S.ReplaceAutoTypeSourceInfo(TrailingTSI, Replacement)
                    : nullptr;
    return {NewT, NewTSI};
  }
  
  static TypeSourceInfo *
  GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
                                 QualType T, TypeSourceInfo *ReturnTypeInfo);
  
  static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
                                               TypeSourceInfo *&ReturnTypeInfo) {
    Sema &SemaRef = state.getSema();
    Declarator &D = state.getDeclarator();
    QualType T;
    ReturnTypeInfo = nullptr;
  
    // The TagDecl owned by the DeclSpec.
    TagDecl *OwnedTagDecl = nullptr;
  
    switch (D.getName().getKind()) {
    case UnqualifiedIdKind::IK_ImplicitSelfParam:
    case UnqualifiedIdKind::IK_OperatorFunctionId:
    case UnqualifiedIdKind::IK_Identifier:
    case UnqualifiedIdKind::IK_LiteralOperatorId:
    case UnqualifiedIdKind::IK_TemplateId:
      T = ConvertDeclSpecToType(state);
  
      if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
        OwnedTagDecl = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
        // Owned declaration is embedded in declarator.
        OwnedTagDecl->setEmbeddedInDeclarator(true);
      }
      break;
  
    case UnqualifiedIdKind::IK_ConstructorName:
    case UnqualifiedIdKind::IK_ConstructorTemplateId:
    case UnqualifiedIdKind::IK_DestructorName:
      // Constructors and destructors don't have return types. Use
      // "void" instead.
      T = SemaRef.Context.VoidTy;
      processTypeAttrs(state, T, TAL_DeclSpec,
                       D.getMutableDeclSpec().getAttributes());
      break;
  
    case UnqualifiedIdKind::IK_DeductionGuideName:
      // Deduction guides have a trailing return type and no type in their
      // decl-specifier sequence. Use a placeholder return type for now.
      T = SemaRef.Context.DependentTy;
      break;
  
    case UnqualifiedIdKind::IK_ConversionFunctionId:
      // The result type of a conversion function is the type that it
      // converts to.
      T = SemaRef.GetTypeFromParser(D.getName().ConversionFunctionId,
                                    &ReturnTypeInfo);
      break;
    }
  
    if (!D.getAttributes().empty())
      distributeTypeAttrsFromDeclarator(state, T);
  
    // Find the deduced type in this type. Look in the trailing return type if we
    // have one, otherwise in the DeclSpec type.
    // FIXME: The standard wording doesn't currently describe this.
    DeducedType *Deduced = T->getContainedDeducedType();
    bool DeducedIsTrailingReturnType = false;
    if (Deduced && isa<AutoType>(Deduced) && D.hasTrailingReturnType()) {
      QualType T = SemaRef.GetTypeFromParser(D.getTrailingReturnType());
      Deduced = T.isNull() ? nullptr : T->getContainedDeducedType();
      DeducedIsTrailingReturnType = true;
    }
  
    // C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
    if (Deduced) {
      AutoType *Auto = dyn_cast<AutoType>(Deduced);
      int Error = -1;
  
      // Is this a 'auto' or 'decltype(auto)' type (as opposed to __auto_type or
      // class template argument deduction)?
      bool IsCXXAutoType =
          (Auto && Auto->getKeyword() != AutoTypeKeyword::GNUAutoType);
      bool IsDeducedReturnType = false;
  
      switch (D.getContext()) {
      case DeclaratorContext::LambdaExpr:
        // Declared return type of a lambda-declarator is implicit and is always
        // 'auto'.
        break;
      case DeclaratorContext::ObjCParameter:
      case DeclaratorContext::ObjCResult:
        Error = 0;
        break;
      case DeclaratorContext::RequiresExpr:
        Error = 22;
        break;
      case DeclaratorContext::Prototype:
      case DeclaratorContext::LambdaExprParameter: {
        InventedTemplateParameterInfo *Info = nullptr;
        if (D.getContext() == DeclaratorContext::Prototype) {
          // With concepts we allow 'auto' in function parameters.
          if (!SemaRef.getLangOpts().CPlusPlus20 || !Auto ||
              Auto->getKeyword() != AutoTypeKeyword::Auto) {
            Error = 0;
            break;
          } else if (!SemaRef.getCurScope()->isFunctionDeclarationScope()) {
            Error = 21;
            break;
          }
  
          Info = &SemaRef.InventedParameterInfos.back();
        } else {
          // In C++14, generic lambdas allow 'auto' in their parameters.
          if (!SemaRef.getLangOpts().CPlusPlus14 || !Auto ||
              Auto->getKeyword() != AutoTypeKeyword::Auto) {
            Error = 16;
            break;
          }
          Info = SemaRef.getCurLambda();
          assert(Info && "No LambdaScopeInfo on the stack!");
        }
  
        // We'll deal with inventing template parameters for 'auto' in trailing
        // return types when we pick up the trailing return type when processing
        // the function chunk.
        if (!DeducedIsTrailingReturnType)
          T = InventTemplateParameter(state, T, nullptr, Auto, *Info).first;
        break;
      }
      case DeclaratorContext::Member: {
        if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
            D.isFunctionDeclarator())
          break;
        bool Cxx = SemaRef.getLangOpts().CPlusPlus;
        if (isa<ObjCContainerDecl>(SemaRef.CurContext)) {
          Error = 6; // Interface member.
        } else {
          switch (cast<TagDecl>(SemaRef.CurContext)->getTagKind()) {
          case TTK_Enum: llvm_unreachable("unhandled tag kind");
          case TTK_Struct: Error = Cxx ? 1 : 2; /* Struct member */ break;
          case TTK_Union:  Error = Cxx ? 3 : 4; /* Union member */ break;
          case TTK_Class:  Error = 5; /* Class member */ break;
          case TTK_Interface: Error = 6; /* Interface member */ break;
          }
        }
        if (D.getDeclSpec().isFriendSpecified())
          Error = 20; // Friend type
        break;
      }
      case DeclaratorContext::CXXCatch:
      case DeclaratorContext::ObjCCatch:
        Error = 7; // Exception declaration
        break;
      case DeclaratorContext::TemplateParam:
        if (isa<DeducedTemplateSpecializationType>(Deduced) &&
            !SemaRef.getLangOpts().CPlusPlus20)
          Error = 19; // Template parameter (until C++20)
        else if (!SemaRef.getLangOpts().CPlusPlus17)
          Error = 8; // Template parameter (until C++17)
        break;
      case DeclaratorContext::BlockLiteral:
        Error = 9; // Block literal
        break;
      case DeclaratorContext::TemplateArg:
        // Within a template argument list, a deduced template specialization
        // type will be reinterpreted as a template template argument.
        if (isa<DeducedTemplateSpecializationType>(Deduced) &&
            !D.getNumTypeObjects() &&
            D.getDeclSpec().getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier)
          break;
        LLVM_FALLTHROUGH;
      case DeclaratorContext::TemplateTypeArg:
        Error = 10; // Template type argument
        break;
      case DeclaratorContext::AliasDecl:
      case DeclaratorContext::AliasTemplate:
        Error = 12; // Type alias
        break;
      case DeclaratorContext::TrailingReturn:
      case DeclaratorContext::TrailingReturnVar:
        if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
          Error = 13; // Function return type
        IsDeducedReturnType = true;
        break;
      case DeclaratorContext::ConversionId:
        if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
          Error = 14; // conversion-type-id
        IsDeducedReturnType = true;
        break;
      case DeclaratorContext::FunctionalCast:
        if (isa<DeducedTemplateSpecializationType>(Deduced))
          break;
        LLVM_FALLTHROUGH;
      case DeclaratorContext::TypeName:
        Error = 15; // Generic
        break;
      case DeclaratorContext::File:
      case DeclaratorContext::Block:
      case DeclaratorContext::ForInit:
      case DeclaratorContext::SelectionInit:
      case DeclaratorContext::Condition:
        // FIXME: P0091R3 (erroneously) does not permit class template argument
        // deduction in conditions, for-init-statements, and other declarations
        // that are not simple-declarations.
        break;
      case DeclaratorContext::CXXNew:
        // FIXME: P0091R3 does not permit class template argument deduction here,
        // but we follow GCC and allow it anyway.
        if (!IsCXXAutoType && !isa<DeducedTemplateSpecializationType>(Deduced))
          Error = 17; // 'new' type
        break;
      case DeclaratorContext::KNRTypeList:
        Error = 18; // K&R function parameter
        break;
      }
  
      if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
        Error = 11;
  
      // In Objective-C it is an error to use 'auto' on a function declarator
      // (and everywhere for '__auto_type').
      if (D.isFunctionDeclarator() &&
          (!SemaRef.getLangOpts().CPlusPlus11 || !IsCXXAutoType))
        Error = 13;
  
      SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc();
      if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId)
        AutoRange = D.getName().getSourceRange();
  
      if (Error != -1) {
        unsigned Kind;
        if (Auto) {
          switch (Auto->getKeyword()) {
          case AutoTypeKeyword::Auto: Kind = 0; break;
          case AutoTypeKeyword::DecltypeAuto: Kind = 1; break;
          case AutoTypeKeyword::GNUAutoType: Kind = 2; break;
          }
        } else {
          assert(isa<DeducedTemplateSpecializationType>(Deduced) &&
                 "unknown auto type");
          Kind = 3;
        }
  
        auto *DTST = dyn_cast<DeducedTemplateSpecializationType>(Deduced);
        TemplateName TN = DTST ? DTST->getTemplateName() : TemplateName();
  
        SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed)
          << Kind << Error << (int)SemaRef.getTemplateNameKindForDiagnostics(TN)
          << QualType(Deduced, 0) << AutoRange;
        if (auto *TD = TN.getAsTemplateDecl())
          SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here);
  
        T = SemaRef.Context.IntTy;
        D.setInvalidType(true);
      } else if (Auto && D.getContext() != DeclaratorContext::LambdaExpr) {
        // If there was a trailing return type, we already got
        // warn_cxx98_compat_trailing_return_type in the parser.
        SemaRef.Diag(AutoRange.getBegin(),
                     D.getContext() == DeclaratorContext::LambdaExprParameter
                         ? diag::warn_cxx11_compat_generic_lambda
                     : IsDeducedReturnType
                         ? diag::warn_cxx11_compat_deduced_return_type
                         : diag::warn_cxx98_compat_auto_type_specifier)
            << AutoRange;
      }
    }
  
    if (SemaRef.getLangOpts().CPlusPlus &&
        OwnedTagDecl && OwnedTagDecl->isCompleteDefinition()) {
      // Check the contexts where C++ forbids the declaration of a new class
      // or enumeration in a type-specifier-seq.
      unsigned DiagID = 0;
      switch (D.getContext()) {
      case DeclaratorContext::TrailingReturn:
      case DeclaratorContext::TrailingReturnVar:
        // Class and enumeration definitions are syntactically not allowed in
        // trailing return types.
        llvm_unreachable("parser should not have allowed this");
        break;
      case DeclaratorContext::File:
      case DeclaratorContext::Member:
      case DeclaratorContext::Block:
      case DeclaratorContext::ForInit:
      case DeclaratorContext::SelectionInit:
      case DeclaratorContext::BlockLiteral:
      case DeclaratorContext::LambdaExpr:
        // C++11 [dcl.type]p3:
        //   A type-specifier-seq shall not define a class or enumeration unless
        //   it appears in the type-id of an alias-declaration (7.1.3) that is not
        //   the declaration of a template-declaration.
      case DeclaratorContext::AliasDecl:
        break;
      case DeclaratorContext::AliasTemplate:
        DiagID = diag::err_type_defined_in_alias_template;
        break;
      case DeclaratorContext::TypeName:
      case DeclaratorContext::FunctionalCast:
      case DeclaratorContext::ConversionId:
      case DeclaratorContext::TemplateParam:
      case DeclaratorContext::CXXNew:
      case DeclaratorContext::CXXCatch:
      case DeclaratorContext::ObjCCatch:
      case DeclaratorContext::TemplateArg:
      case DeclaratorContext::TemplateTypeArg:
        DiagID = diag::err_type_defined_in_type_specifier;
        break;
      case DeclaratorContext::Prototype:
      case DeclaratorContext::LambdaExprParameter:
      case DeclaratorContext::ObjCParameter:
      case DeclaratorContext::ObjCResult:
      case DeclaratorContext::KNRTypeList:
      case DeclaratorContext::RequiresExpr:
        // C++ [dcl.fct]p6:
        //   Types shall not be defined in return or parameter types.
        DiagID = diag::err_type_defined_in_param_type;
        break;
      case DeclaratorContext::Condition:
        // C++ 6.4p2:
        // The type-specifier-seq shall not contain typedef and shall not declare
        // a new class or enumeration.
        DiagID = diag::err_type_defined_in_condition;
        break;
      }
  
      if (DiagID != 0) {
        SemaRef.Diag(OwnedTagDecl->getLocation(), DiagID)
            << SemaRef.Context.getTypeDeclType(OwnedTagDecl);
        D.setInvalidType(true);
      }
    }
  
    assert(!T.isNull() && "This function should not return a null type");
    return T;
  }
  
  /// Produce an appropriate diagnostic for an ambiguity between a function
  /// declarator and a C++ direct-initializer.
  static void warnAboutAmbiguousFunction(Sema &S, Declarator &D,
                                         DeclaratorChunk &DeclType, QualType RT) {
    const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
    assert(FTI.isAmbiguous && "no direct-initializer / function ambiguity");
  
    // If the return type is void there is no ambiguity.
    if (RT->isVoidType())
      return;
  
    // An initializer for a non-class type can have at most one argument.
    if (!RT->isRecordType() && FTI.NumParams > 1)
      return;
  
    // An initializer for a reference must have exactly one argument.
    if (RT->isReferenceType() && FTI.NumParams != 1)
      return;
  
    // Only warn if this declarator is declaring a function at block scope, and
    // doesn't have a storage class (such as 'extern') specified.
    if (!D.isFunctionDeclarator() ||
        D.getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration ||
        !S.CurContext->isFunctionOrMethod() ||
        D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_unspecified)
      return;
  
    // Inside a condition, a direct initializer is not permitted. We allow one to
    // be parsed in order to give better diagnostics in condition parsing.
    if (D.getContext() == DeclaratorContext::Condition)
      return;
  
    SourceRange ParenRange(DeclType.Loc, DeclType.EndLoc);
  
    S.Diag(DeclType.Loc,
           FTI.NumParams ? diag::warn_parens_disambiguated_as_function_declaration
                         : diag::warn_empty_parens_are_function_decl)
        << ParenRange;
  
    // If the declaration looks like:
    //   T var1,
    //   f();
    // and name lookup finds a function named 'f', then the ',' was
    // probably intended to be a ';'.
    if (!D.isFirstDeclarator() && D.getIdentifier()) {
      FullSourceLoc Comma(D.getCommaLoc(), S.SourceMgr);
      FullSourceLoc Name(D.getIdentifierLoc(), S.SourceMgr);
      if (Comma.getFileID() != Name.getFileID() ||
          Comma.getSpellingLineNumber() != Name.getSpellingLineNumber()) {
        LookupResult Result(S, D.getIdentifier(), SourceLocation(),
                            Sema::LookupOrdinaryName);
        if (S.LookupName(Result, S.getCurScope()))
          S.Diag(D.getCommaLoc(), diag::note_empty_parens_function_call)
            << FixItHint::CreateReplacement(D.getCommaLoc(), ";")
            << D.getIdentifier();
        Result.suppressDiagnostics();
      }
    }
  
    if (FTI.NumParams > 0) {
      // For a declaration with parameters, eg. "T var(T());", suggest adding
      // parens around the first parameter to turn the declaration into a
      // variable declaration.
      SourceRange Range = FTI.Params[0].Param->getSourceRange();
      SourceLocation B = Range.getBegin();
      SourceLocation E = S.getLocForEndOfToken(Range.getEnd());
      // FIXME: Maybe we should suggest adding braces instead of parens
      // in C++11 for classes that don't have an initializer_list constructor.
      S.Diag(B, diag::note_additional_parens_for_variable_declaration)
        << FixItHint::CreateInsertion(B, "(")
        << FixItHint::CreateInsertion(E, ")");
    } else {
      // For a declaration without parameters, eg. "T var();", suggest replacing
      // the parens with an initializer to turn the declaration into a variable
      // declaration.
      const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
  
      // Empty parens mean value-initialization, and no parens mean
      // default initialization. These are equivalent if the default
      // constructor is user-provided or if zero-initialization is a
      // no-op.
      if (RD && RD->hasDefinition() &&
          (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor()))
        S.Diag(DeclType.Loc, diag::note_empty_parens_default_ctor)
          << FixItHint::CreateRemoval(ParenRange);
      else {
        std::string Init =
            S.getFixItZeroInitializerForType(RT, ParenRange.getBegin());
        if (Init.empty() && S.LangOpts.CPlusPlus11)
          Init = "{}";
        if (!Init.empty())
          S.Diag(DeclType.Loc, diag::note_empty_parens_zero_initialize)
            << FixItHint::CreateReplacement(ParenRange, Init);
      }
    }
  }
  
  /// Produce an appropriate diagnostic for a declarator with top-level
  /// parentheses.
  static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) {
    DeclaratorChunk &Paren = D.getTypeObject(D.getNumTypeObjects() - 1);
    assert(Paren.Kind == DeclaratorChunk::Paren &&
           "do not have redundant top-level parentheses");
  
    // This is a syntactic check; we're not interested in cases that arise
    // during template instantiation.
    if (S.inTemplateInstantiation())
      return;
  
    // Check whether this could be intended to be a construction of a temporary
    // object in C++ via a function-style cast.
    bool CouldBeTemporaryObject =
        S.getLangOpts().CPlusPlus && D.isExpressionContext() &&
        !D.isInvalidType() && D.getIdentifier() &&
        D.getDeclSpec().getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
        (T->isRecordType() || T->isDependentType()) &&
        D.getDeclSpec().getTypeQualifiers() == 0 && D.isFirstDeclarator();
  
    bool StartsWithDeclaratorId = true;
    for (auto &C : D.type_objects()) {
      switch (C.Kind) {
      case DeclaratorChunk::Paren:
        if (&C == &Paren)
          continue;
        LLVM_FALLTHROUGH;
      case DeclaratorChunk::Pointer:
        StartsWithDeclaratorId = false;
        continue;
  
      case DeclaratorChunk::Array:
        if (!C.Arr.NumElts)
          CouldBeTemporaryObject = false;
        continue;
  
      case DeclaratorChunk::Reference:
        // FIXME: Suppress the warning here if there is no initializer; we're
        // going to give an error anyway.
        // We assume that something like 'T (&x) = y;' is highly likely to not
        // be intended to be a temporary object.
        CouldBeTemporaryObject = false;
        StartsWithDeclaratorId = false;
        continue;
  
      case DeclaratorChunk::Function:
        // In a new-type-id, function chunks require parentheses.
        if (D.getContext() == DeclaratorContext::CXXNew)
          return;
        // FIXME: "A(f())" deserves a vexing-parse warning, not just a
        // redundant-parens warning, but we don't know whether the function
        // chunk was syntactically valid as an expression here.
        CouldBeTemporaryObject = false;
        continue;
  
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        // These cannot appear in expressions.
        CouldBeTemporaryObject = false;
        StartsWithDeclaratorId = false;
        continue;
      }
    }
  
    // FIXME: If there is an initializer, assume that this is not intended to be
    // a construction of a temporary object.
  
    // Check whether the name has already been declared; if not, this is not a
    // function-style cast.
    if (CouldBeTemporaryObject) {
      LookupResult Result(S, D.getIdentifier(), SourceLocation(),
                          Sema::LookupOrdinaryName);
      if (!S.LookupName(Result, S.getCurScope()))
        CouldBeTemporaryObject = false;
      Result.suppressDiagnostics();
    }
  
    SourceRange ParenRange(Paren.Loc, Paren.EndLoc);
  
    if (!CouldBeTemporaryObject) {
      // If we have A (::B), the parentheses affect the meaning of the program.
      // Suppress the warning in that case. Don't bother looking at the DeclSpec
      // here: even (e.g.) "int ::x" is visually ambiguous even though it's
      // formally unambiguous.
      if (StartsWithDeclaratorId && D.getCXXScopeSpec().isValid()) {
        for (NestedNameSpecifier *NNS = D.getCXXScopeSpec().getScopeRep(); NNS;
             NNS = NNS->getPrefix()) {
          if (NNS->getKind() == NestedNameSpecifier::Global)
            return;
        }
      }
  
      S.Diag(Paren.Loc, diag::warn_redundant_parens_around_declarator)
          << ParenRange << FixItHint::CreateRemoval(Paren.Loc)
          << FixItHint::CreateRemoval(Paren.EndLoc);
      return;
    }
  
    S.Diag(Paren.Loc, diag::warn_parens_disambiguated_as_variable_declaration)
        << ParenRange << D.getIdentifier();
    auto *RD = T->getAsCXXRecordDecl();
    if (!RD || !RD->hasDefinition() || RD->hasNonTrivialDestructor())
      S.Diag(Paren.Loc, diag::note_raii_guard_add_name)
          << FixItHint::CreateInsertion(Paren.Loc, " varname") << T
          << D.getIdentifier();
    // FIXME: A cast to void is probably a better suggestion in cases where it's
    // valid (when there is no initializer and we're not in a condition).
    S.Diag(D.getBeginLoc(), diag::note_function_style_cast_add_parentheses)
        << FixItHint::CreateInsertion(D.getBeginLoc(), "(")
        << FixItHint::CreateInsertion(S.getLocForEndOfToken(D.getEndLoc()), ")");
    S.Diag(Paren.Loc, diag::note_remove_parens_for_variable_declaration)
        << FixItHint::CreateRemoval(Paren.Loc)
        << FixItHint::CreateRemoval(Paren.EndLoc);
  }
  
  /// Helper for figuring out the default CC for a function declarator type.  If
  /// this is the outermost chunk, then we can determine the CC from the
  /// declarator context.  If not, then this could be either a member function
  /// type or normal function type.
  static CallingConv getCCForDeclaratorChunk(
      Sema &S, Declarator &D, const ParsedAttributesView &AttrList,
      const DeclaratorChunk::FunctionTypeInfo &FTI, unsigned ChunkIndex) {
    assert(D.getTypeObject(ChunkIndex).Kind == DeclaratorChunk::Function);
  
    // Check for an explicit CC attribute.
    for (const ParsedAttr &AL : AttrList) {
      switch (AL.getKind()) {
      CALLING_CONV_ATTRS_CASELIST : {
        // Ignore attributes that don't validate or can't apply to the
        // function type.  We'll diagnose the failure to apply them in
        // handleFunctionTypeAttr.
        CallingConv CC;
        if (!S.CheckCallingConvAttr(AL, CC) &&
            (!FTI.isVariadic || supportsVariadicCall(CC))) {
          return CC;
        }
        break;
      }
  
      default:
        break;
      }
    }
  
    bool IsCXXInstanceMethod = false;
  
    if (S.getLangOpts().CPlusPlus) {
      // Look inwards through parentheses to see if this chunk will form a
      // member pointer type or if we're the declarator.  Any type attributes
      // between here and there will override the CC we choose here.
      unsigned I = ChunkIndex;
      bool FoundNonParen = false;
      while (I && !FoundNonParen) {
        --I;
        if (D.getTypeObject(I).Kind != DeclaratorChunk::Paren)
          FoundNonParen = true;
      }
  
      if (FoundNonParen) {
        // If we're not the declarator, we're a regular function type unless we're
        // in a member pointer.
        IsCXXInstanceMethod =
            D.getTypeObject(I).Kind == DeclaratorChunk::MemberPointer;
      } else if (D.getContext() == DeclaratorContext::LambdaExpr) {
        // This can only be a call operator for a lambda, which is an instance
        // method.
        IsCXXInstanceMethod = true;
      } else {
        // We're the innermost decl chunk, so must be a function declarator.
        assert(D.isFunctionDeclarator());
  
        // If we're inside a record, we're declaring a method, but it could be
        // explicitly or implicitly static.
        IsCXXInstanceMethod =
            D.isFirstDeclarationOfMember() &&
            D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
            !D.isStaticMember();
      }
    }
  
    CallingConv CC = S.Context.getDefaultCallingConvention(FTI.isVariadic,
                                                           IsCXXInstanceMethod);
  
    // Attribute AT_OpenCLKernel affects the calling convention for SPIR
    // and AMDGPU targets, hence it cannot be treated as a calling
    // convention attribute. This is the simplest place to infer
    // calling convention for OpenCL kernels.
    if (S.getLangOpts().OpenCL) {
      for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
        if (AL.getKind() == ParsedAttr::AT_OpenCLKernel) {
          CC = CC_OpenCLKernel;
          break;
        }
      }
    }
  
    return CC;
  }
  
  namespace {
    /// A simple notion of pointer kinds, which matches up with the various
    /// pointer declarators.
    enum class SimplePointerKind {
      Pointer,
      BlockPointer,
      MemberPointer,
      Array,
    };
  } // end anonymous namespace
  
  IdentifierInfo *Sema::getNullabilityKeyword(NullabilityKind nullability) {
    switch (nullability) {
    case NullabilityKind::NonNull:
      if (!Ident__Nonnull)
        Ident__Nonnull = PP.getIdentifierInfo("_Nonnull");
      return Ident__Nonnull;
  
    case NullabilityKind::Nullable:
      if (!Ident__Nullable)
        Ident__Nullable = PP.getIdentifierInfo("_Nullable");
      return Ident__Nullable;
  
    case NullabilityKind::NullableResult:
      if (!Ident__Nullable_result)
        Ident__Nullable_result = PP.getIdentifierInfo("_Nullable_result");
      return Ident__Nullable_result;
  
    case NullabilityKind::Unspecified:
      if (!Ident__Null_unspecified)
        Ident__Null_unspecified = PP.getIdentifierInfo("_Null_unspecified");
      return Ident__Null_unspecified;
    }
    llvm_unreachable("Unknown nullability kind.");
  }
  
  /// Retrieve the identifier "NSError".
  IdentifierInfo *Sema::getNSErrorIdent() {
    if (!Ident_NSError)
      Ident_NSError = PP.getIdentifierInfo("NSError");
  
    return Ident_NSError;
  }
  
  /// Check whether there is a nullability attribute of any kind in the given
  /// attribute list.
  static bool hasNullabilityAttr(const ParsedAttributesView &attrs) {
    for (const ParsedAttr &AL : attrs) {
      if (AL.getKind() == ParsedAttr::AT_TypeNonNull ||
          AL.getKind() == ParsedAttr::AT_TypeNullable ||
          AL.getKind() == ParsedAttr::AT_TypeNullableResult ||
          AL.getKind() == ParsedAttr::AT_TypeNullUnspecified)
        return true;
    }
  
    return false;
  }
  
  namespace {
    /// Describes the kind of a pointer a declarator describes.
    enum class PointerDeclaratorKind {
      // Not a pointer.
      NonPointer,
      // Single-level pointer.
      SingleLevelPointer,
      // Multi-level pointer (of any pointer kind).
      MultiLevelPointer,
      // CFFooRef*
      MaybePointerToCFRef,
      // CFErrorRef*
      CFErrorRefPointer,
      // NSError**
      NSErrorPointerPointer,
    };
  
    /// Describes a declarator chunk wrapping a pointer that marks inference as
    /// unexpected.
    // These values must be kept in sync with diagnostics.
    enum class PointerWrappingDeclaratorKind {
      /// Pointer is top-level.
      None = -1,
      /// Pointer is an array element.
      Array = 0,
      /// Pointer is the referent type of a C++ reference.
      Reference = 1
    };
  } // end anonymous namespace
  
  /// Classify the given declarator, whose type-specified is \c type, based on
  /// what kind of pointer it refers to.
  ///
  /// This is used to determine the default nullability.
  static PointerDeclaratorKind
  classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator,
                            PointerWrappingDeclaratorKind &wrappingKind) {
    unsigned numNormalPointers = 0;
  
    // For any dependent type, we consider it a non-pointer.
    if (type->isDependentType())
      return PointerDeclaratorKind::NonPointer;
  
    // Look through the declarator chunks to identify pointers.
    for (unsigned i = 0, n = declarator.getNumTypeObjects(); i != n; ++i) {
      DeclaratorChunk &chunk = declarator.getTypeObject(i);
      switch (chunk.Kind) {
      case DeclaratorChunk::Array:
        if (numNormalPointers == 0)
          wrappingKind = PointerWrappingDeclaratorKind::Array;
        break;
  
      case DeclaratorChunk::Function:
      case DeclaratorChunk::Pipe:
        break;
  
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::MemberPointer:
        return numNormalPointers > 0 ? PointerDeclaratorKind::MultiLevelPointer
                                     : PointerDeclaratorKind::SingleLevelPointer;
  
      case DeclaratorChunk::Paren:
        break;
  
      case DeclaratorChunk::Reference:
        if (numNormalPointers == 0)
          wrappingKind = PointerWrappingDeclaratorKind::Reference;
        break;
  
      case DeclaratorChunk::Pointer:
        ++numNormalPointers;
        if (numNormalPointers > 2)
          return PointerDeclaratorKind::MultiLevelPointer;
        break;
      }
    }
  
    // Then, dig into the type specifier itself.
    unsigned numTypeSpecifierPointers = 0;
    do {
      // Decompose normal pointers.
      if (auto ptrType = type->getAs<PointerType>()) {
        ++numNormalPointers;
  
        if (numNormalPointers > 2)
          return PointerDeclaratorKind::MultiLevelPointer;
  
        type = ptrType->getPointeeType();
        ++numTypeSpecifierPointers;
        continue;
      }
  
      // Decompose block pointers.
      if (type->getAs<BlockPointerType>()) {
        return numNormalPointers > 0 ? PointerDeclaratorKind::MultiLevelPointer
                                     : PointerDeclaratorKind::SingleLevelPointer;
      }
  
      // Decompose member pointers.
      if (type->getAs<MemberPointerType>()) {
        return numNormalPointers > 0 ? PointerDeclaratorKind::MultiLevelPointer
                                     : PointerDeclaratorKind::SingleLevelPointer;
      }
  
      // Look at Objective-C object pointers.
      if (auto objcObjectPtr = type->getAs<ObjCObjectPointerType>()) {
        ++numNormalPointers;
        ++numTypeSpecifierPointers;
  
        // If this is NSError**, report that.
        if (auto objcClassDecl = objcObjectPtr->getInterfaceDecl()) {
          if (objcClassDecl->getIdentifier() == S.getNSErrorIdent() &&
              numNormalPointers == 2 && numTypeSpecifierPointers < 2) {
            return PointerDeclaratorKind::NSErrorPointerPointer;
          }
        }
  
        break;
      }
  
      // Look at Objective-C class types.
      if (auto objcClass = type->getAs<ObjCInterfaceType>()) {
        if (objcClass->getInterface()->getIdentifier() == S.getNSErrorIdent()) {
          if (numNormalPointers == 2 && numTypeSpecifierPointers < 2)
            return PointerDeclaratorKind::NSErrorPointerPointer;
        }
  
        break;
      }
  
      // If at this point we haven't seen a pointer, we won't see one.
      if (numNormalPointers == 0)
        return PointerDeclaratorKind::NonPointer;
  
      if (auto recordType = type->getAs<RecordType>()) {
        RecordDecl *recordDecl = recordType->getDecl();
  
        // If this is CFErrorRef*, report it as such.
        if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 &&
            S.isCFError(recordDecl)) {
          return PointerDeclaratorKind::CFErrorRefPointer;
        }
        break;
      }
  
      break;
    } while (true);
  
    switch (numNormalPointers) {
    case 0:
      return PointerDeclaratorKind::NonPointer;
  
    case 1:
      return PointerDeclaratorKind::SingleLevelPointer;
  
    case 2:
      return PointerDeclaratorKind::MaybePointerToCFRef;
  
    default:
      return PointerDeclaratorKind::MultiLevelPointer;
    }
  }
  
  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<ObjCBridgeAttr>())
        bridgedType = bridgeAttr->getBridgedType();
      else if (auto bridgeAttr = RD->getAttr<ObjCBridgeMutableAttr>())
        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
    // completeness checks.
    for (DeclContext *ctx = S.CurContext; ctx; ctx = ctx->getParent()) {
      if (ctx->isFunctionOrMethod())
        return FileID();
  
      if (ctx->isFileContext())
        break;
    }
  
    // We only care about the expansion location.
    loc = S.SourceMgr.getExpansionLoc(loc);
    FileID file = S.SourceMgr.getFileID(loc);
    if (file.isInvalid())
      return FileID();
  
    // Retrieve file information.
    bool invalid = false;
    const SrcMgr::SLocEntry &sloc = S.SourceMgr.getSLocEntry(file, &invalid);
    if (invalid || !sloc.isFile())
      return FileID();
  
    // We don't want to perform completeness checks on the main file or in
    // system headers.
    const SrcMgr::FileInfo &fileInfo = sloc.getFile();
    if (fileInfo.getIncludeLoc().isInvalid())
      return FileID();
    if (fileInfo.getFileCharacteristic() != SrcMgr::C_User &&
        S.Diags.getSuppressSystemWarnings()) {
      return FileID();
    }
  
    return file;
  }
  
  /// Creates a fix-it to insert a C-style nullability keyword at \p pointerLoc,
  /// taking into account whitespace before and after.
  template <typename DiagBuilderT>
  static void fixItNullability(Sema &S, DiagBuilderT &Diag,
                               SourceLocation PointerLoc,
                               NullabilityKind Nullability) {
    assert(PointerLoc.isValid());
    if (PointerLoc.isMacroID())
      return;
  
    SourceLocation FixItLoc = S.getLocForEndOfToken(PointerLoc);
    if (!FixItLoc.isValid() || FixItLoc == PointerLoc)
      return;
  
    const char *NextChar = S.SourceMgr.getCharacterData(FixItLoc);
    if (!NextChar)
      return;
  
    SmallString<32> InsertionTextBuf{" "};
    InsertionTextBuf += getNullabilitySpelling(Nullability);
    InsertionTextBuf += " ";
    StringRef InsertionText = InsertionTextBuf.str();
  
    if (isWhitespace(*NextChar)) {
      InsertionText = InsertionText.drop_back();
    } else if (NextChar[-1] == '[') {
      if (NextChar[0] == ']')
        InsertionText = InsertionText.drop_back().drop_front();
      else
        InsertionText = InsertionText.drop_front();
    } else if (!isIdentifierBody(NextChar[0], /*allow dollar*/true) &&
               !isIdentifierBody(NextChar[-1], /*allow dollar*/true)) {
      InsertionText = InsertionText.drop_back().drop_front();
    }
  
    Diag << FixItHint::CreateInsertion(FixItLoc, InsertionText);
  }
  
  static void emitNullabilityConsistencyWarning(Sema &S,
                                                SimplePointerKind PointerKind,
                                                SourceLocation PointerLoc,
                                                SourceLocation PointerEndLoc) {
    assert(PointerLoc.isValid());
  
    if (PointerKind == SimplePointerKind::Array) {
      S.Diag(PointerLoc, diag::warn_nullability_missing_array);
    } else {
      S.Diag(PointerLoc, diag::warn_nullability_missing)
        << static_cast<unsigned>(PointerKind);
    }
  
    auto FixItLoc = PointerEndLoc.isValid() ? PointerEndLoc : PointerLoc;
    if (FixItLoc.isMacroID())
      return;
  
    auto addFixIt = [&](NullabilityKind Nullability) {
      auto Diag = S.Diag(FixItLoc, diag::note_nullability_fix_it);
      Diag << static_cast<unsigned>(Nullability);
      Diag << static_cast<unsigned>(PointerKind);
      fixItNullability(S, Diag, FixItLoc, Nullability);
    };
    addFixIt(NullabilityKind::Nullable);
    addFixIt(NullabilityKind::NonNull);
  }
  
  /// Complains about missing nullability if the file containing \p pointerLoc
  /// has other uses of nullability (either the keywords or the \c assume_nonnull
  /// pragma).
  ///
  /// If the file has \e not seen other uses of nullability, this particular
  /// pointer is saved for possible later diagnosis. See recordNullabilitySeen().
  static void
  checkNullabilityConsistency(Sema &S, SimplePointerKind pointerKind,
                              SourceLocation pointerLoc,
                              SourceLocation pointerEndLoc = SourceLocation()) {
    // Determine which file we're performing consistency checking for.
    FileID file = getNullabilityCompletenessCheckFileID(S, pointerLoc);
    if (file.isInvalid())
      return;
  
    // If we haven't seen any type nullability in this file, we won't warn now
    // about anything.
    FileNullability &fileNullability = S.NullabilityMap[file];
    if (!fileNullability.SawTypeNullability) {
      // If this is the first pointer declarator in the file, and the appropriate
      // warning is on, record it in case we need to diagnose it retroactively.
      diag::kind diagKind;
      if (pointerKind == SimplePointerKind::Array)
        diagKind = diag::warn_nullability_missing_array;
      else
        diagKind = diag::warn_nullability_missing;
  
      if (fileNullability.PointerLoc.isInvalid() &&
          !S.Context.getDiagnostics().isIgnored(diagKind, pointerLoc)) {
        fileNullability.PointerLoc = pointerLoc;
        fileNullability.PointerEndLoc = pointerEndLoc;
        fileNullability.PointerKind = static_cast<unsigned>(pointerKind);
      }
  
      return;
    }
  
    // Complain about missing nullability.
    emitNullabilityConsistencyWarning(S, pointerKind, pointerLoc, pointerEndLoc);
  }
  
  /// Marks that a nullability feature has been used in the file containing
  /// \p loc.
  ///
  /// If this file already had pointer types in it that were missing nullability,
  /// the first such instance is retroactively diagnosed.
  ///
  /// \sa checkNullabilityConsistency
  static void recordNullabilitySeen(Sema &S, SourceLocation loc) {
    FileID file = getNullabilityCompletenessCheckFileID(S, loc);
    if (file.isInvalid())
      return;
  
    FileNullability &fileNullability = S.NullabilityMap[file];
    if (fileNullability.SawTypeNullability)
      return;
    fileNullability.SawTypeNullability = true;
  
    // If we haven't seen any type nullability before, now we have. Retroactively
    // diagnose the first unannotated pointer, if there was one.
    if (fileNullability.PointerLoc.isInvalid())
      return;
  
    auto kind = static_cast<SimplePointerKind>(fileNullability.PointerKind);
    emitNullabilityConsistencyWarning(S, kind, fileNullability.PointerLoc,
                                      fileNullability.PointerEndLoc);
  }
  
  /// Returns true if any of the declarator chunks before \p endIndex include a
  /// level of indirection: array, pointer, reference, or pointer-to-member.
  ///
  /// Because declarator chunks are stored in outer-to-inner order, testing
  /// every chunk before \p endIndex is testing all chunks that embed the current
  /// chunk as part of their type.
  ///
  /// It is legal to pass the result of Declarator::getNumTypeObjects() as the
  /// end index, in which case all chunks are tested.
  static bool hasOuterPointerLikeChunk(const Declarator &D, unsigned endIndex) {
    unsigned i = endIndex;
    while (i != 0) {
      // Walk outwards along the declarator chunks.
      --i;
      const DeclaratorChunk &DC = D.getTypeObject(i);
      switch (DC.Kind) {
      case DeclaratorChunk::Paren:
        break;
      case DeclaratorChunk::Array:
      case DeclaratorChunk::Pointer:
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::MemberPointer:
        return true;
      case DeclaratorChunk::Function:
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::Pipe:
        // These are invalid anyway, so just ignore.
        break;
      }
    }
    return false;
  }
  
  static bool IsNoDerefableChunk(DeclaratorChunk Chunk) {
    return (Chunk.Kind == DeclaratorChunk::Pointer ||
            Chunk.Kind == DeclaratorChunk::Array);
  }
  
  template<typename AttrT>
  static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &AL) {
    AL.setUsedAsTypeAttr();
    return ::new (Ctx) AttrT(Ctx, AL);
  }
  
  static Attr *createNullabilityAttr(ASTContext &Ctx, ParsedAttr &Attr,
                                     NullabilityKind NK) {
    switch (NK) {
    case NullabilityKind::NonNull:
      return createSimpleAttr<TypeNonNullAttr>(Ctx, Attr);
  
    case NullabilityKind::Nullable:
      return createSimpleAttr<TypeNullableAttr>(Ctx, Attr);
  
    case NullabilityKind::NullableResult:
      return createSimpleAttr<TypeNullableResultAttr>(Ctx, Attr);
  
    case NullabilityKind::Unspecified:
      return createSimpleAttr<TypeNullUnspecifiedAttr>(Ctx, Attr);
    }
    llvm_unreachable("unknown NullabilityKind");
  }
  
  // Diagnose whether this is a case with the multiple addr spaces.
  // Returns true if this is an invalid case.
  // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
  // by qualifiers for two or more different address spaces."
  static bool DiagnoseMultipleAddrSpaceAttributes(Sema &S, LangAS ASOld,
                                                  LangAS ASNew,
                                                  SourceLocation AttrLoc) {
    if (ASOld != LangAS::Default) {
      if (ASOld != ASNew) {
        S.Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
        return true;
      }
      // Emit a warning if they are identical; it's likely unintended.
      S.Diag(AttrLoc,
             diag::warn_attribute_address_multiple_identical_qualifiers);
    }
    return false;
  }
  
  static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
                                                  QualType declSpecType,
                                                  TypeSourceInfo *TInfo) {
    // The TypeSourceInfo that this function returns will not be a null type.
    // If there is an error, this function will fill in a dummy type as fallback.
    QualType T = declSpecType;
    Declarator &D = state.getDeclarator();
    Sema &S = state.getSema();
    ASTContext &Context = S.Context;
    const LangOptions &LangOpts = S.getLangOpts();
  
    // The name we're declaring, if any.
    DeclarationName Name;
    if (D.getIdentifier())
      Name = D.getIdentifier();
  
    // Does this declaration declare a typedef-name?
    bool IsTypedefName =
        D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef ||
        D.getContext() == DeclaratorContext::AliasDecl ||
        D.getContext() == DeclaratorContext::AliasTemplate;
  
    // Does T refer to a function type with a cv-qualifier or a ref-qualifier?
    bool IsQualifiedFunction = T->isFunctionProtoType() &&
        (!T->castAs<FunctionProtoType>()->getMethodQuals().empty() ||
         T->castAs<FunctionProtoType>()->getRefQualifier() != RQ_None);
  
    // If T is 'decltype(auto)', the only declarators we can have are parens
    // and at most one function declarator if this is a function declaration.
    // If T is a deduced class template specialization type, we can have no
    // declarator chunks at all.
    if (auto *DT = T->getAs<DeducedType>()) {
      const AutoType *AT = T->getAs<AutoType>();
      bool IsClassTemplateDeduction = isa<DeducedTemplateSpecializationType>(DT);
      if ((AT && AT->isDecltypeAuto()) || IsClassTemplateDeduction) {
        for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) {
          unsigned Index = E - I - 1;
          DeclaratorChunk &DeclChunk = D.getTypeObject(Index);
          unsigned DiagId = IsClassTemplateDeduction
                                ? diag::err_deduced_class_template_compound_type
                                : diag::err_decltype_auto_compound_type;
          unsigned DiagKind = 0;
          switch (DeclChunk.Kind) {
          case DeclaratorChunk::Paren:
            // FIXME: Rejecting this is a little silly.
            if (IsClassTemplateDeduction) {
              DiagKind = 4;
              break;
            }
            continue;
          case DeclaratorChunk::Function: {
            if (IsClassTemplateDeduction) {
              DiagKind = 3;
              break;
            }
            unsigned FnIndex;
            if (D.isFunctionDeclarationContext() &&
                D.isFunctionDeclarator(FnIndex) && FnIndex == Index)
              continue;
            DiagId = diag::err_decltype_auto_function_declarator_not_declaration;
            break;
          }
          case DeclaratorChunk::Pointer:
          case DeclaratorChunk::BlockPointer:
          case DeclaratorChunk::MemberPointer:
            DiagKind = 0;
            break;
          case DeclaratorChunk::Reference:
            DiagKind = 1;
            break;
          case DeclaratorChunk::Array:
            DiagKind = 2;
            break;
          case DeclaratorChunk::Pipe:
            break;
          }
  
          S.Diag(DeclChunk.Loc, DiagId) << DiagKind;
          D.setInvalidType(true);
          break;
        }
      }
    }
  
    // Determine whether we should infer _Nonnull on pointer types.
    Optional<NullabilityKind> inferNullability;
    bool inferNullabilityCS = false;
    bool inferNullabilityInnerOnly = false;
    bool inferNullabilityInnerOnlyComplete = false;
  
    // Are we in an assume-nonnull region?
    bool inAssumeNonNullRegion = false;
    SourceLocation assumeNonNullLoc = S.PP.getPragmaAssumeNonNullLoc();
    if (assumeNonNullLoc.isValid()) {
      inAssumeNonNullRegion = true;
      recordNullabilitySeen(S, assumeNonNullLoc);
    }
  
    // Whether to complain about missing nullability specifiers or not.
    enum {
      /// Never complain.
      CAMN_No,
      /// Complain on the inner pointers (but not the outermost
      /// pointer).
      CAMN_InnerPointers,
      /// Complain about any pointers that don't have nullability
      /// specified or inferred.
      CAMN_Yes
    } complainAboutMissingNullability = CAMN_No;
    unsigned NumPointersRemaining = 0;
    auto complainAboutInferringWithinChunk = PointerWrappingDeclaratorKind::None;
  
    if (IsTypedefName) {
      // For typedefs, we do not infer any nullability (the default),
      // and we only complain about missing nullability specifiers on
      // inner pointers.
      complainAboutMissingNullability = CAMN_InnerPointers;
  
      if (T->canHaveNullability(/*ResultIfUnknown*/false) &&
          !T->getNullability(S.Context)) {
        // Note that we allow but don't require nullability on dependent types.
        ++NumPointersRemaining;
      }
  
      for (unsigned i = 0, n = D.getNumTypeObjects(); i != n; ++i) {
        DeclaratorChunk &chunk = D.getTypeObject(i);
        switch (chunk.Kind) {
        case DeclaratorChunk::Array:
        case DeclaratorChunk::Function:
        case DeclaratorChunk::Pipe:
          break;
  
        case DeclaratorChunk::BlockPointer:
        case DeclaratorChunk::MemberPointer:
          ++NumPointersRemaining;
          break;
  
        case DeclaratorChunk::Paren:
        case DeclaratorChunk::Reference:
          continue;
  
        case DeclaratorChunk::Pointer:
          ++NumPointersRemaining;
          continue;
        }
      }
    } else {
      bool isFunctionOrMethod = false;
      switch (auto context = state.getDeclarator().getContext()) {
      case DeclaratorContext::ObjCParameter:
      case DeclaratorContext::ObjCResult:
      case DeclaratorContext::Prototype:
      case DeclaratorContext::TrailingReturn:
      case DeclaratorContext::TrailingReturnVar:
        isFunctionOrMethod = true;
        LLVM_FALLTHROUGH;
  
      case DeclaratorContext::Member:
        if (state.getDeclarator().isObjCIvar() && !isFunctionOrMethod) {
          complainAboutMissingNullability = CAMN_No;
          break;
        }
  
        // Weak properties are inferred to be nullable.
        if (state.getDeclarator().isObjCWeakProperty() && inAssumeNonNullRegion) {
          inferNullability = NullabilityKind::Nullable;
          break;
        }
  
        LLVM_FALLTHROUGH;
  
      case DeclaratorContext::File:
      case DeclaratorContext::KNRTypeList: {
        complainAboutMissingNullability = CAMN_Yes;
  
        // Nullability inference depends on the type and declarator.
        auto wrappingKind = PointerWrappingDeclaratorKind::None;
        switch (classifyPointerDeclarator(S, T, D, wrappingKind)) {
        case PointerDeclaratorKind::NonPointer:
        case PointerDeclaratorKind::MultiLevelPointer:
          // Cannot infer nullability.
          break;
  
        case PointerDeclaratorKind::SingleLevelPointer:
          // Infer _Nonnull if we are in an assumes-nonnull region.
          if (inAssumeNonNullRegion) {
            complainAboutInferringWithinChunk = wrappingKind;
            inferNullability = NullabilityKind::NonNull;
            inferNullabilityCS = (context == DeclaratorContext::ObjCParameter ||
                                  context == DeclaratorContext::ObjCResult);
          }
          break;
  
        case PointerDeclaratorKind::CFErrorRefPointer:
        case PointerDeclaratorKind::NSErrorPointerPointer:
          // Within a function or method signature, infer _Nullable at both
          // levels.
          if (isFunctionOrMethod && inAssumeNonNullRegion)
            inferNullability = NullabilityKind::Nullable;
          break;
  
        case PointerDeclaratorKind::MaybePointerToCFRef:
          if (isFunctionOrMethod) {
            // On pointer-to-pointer parameters marked cf_returns_retained or
            // cf_returns_not_retained, if the outer pointer is explicit then
            // infer the inner pointer as _Nullable.
            auto hasCFReturnsAttr =
                [](const ParsedAttributesView &AttrList) -> bool {
              return AttrList.hasAttribute(ParsedAttr::AT_CFReturnsRetained) ||
                     AttrList.hasAttribute(ParsedAttr::AT_CFReturnsNotRetained);
            };
            if (const auto *InnermostChunk = D.getInnermostNonParenChunk()) {
              if (hasCFReturnsAttr(D.getAttributes()) ||
                  hasCFReturnsAttr(InnermostChunk->getAttrs()) ||
                  hasCFReturnsAttr(D.getDeclSpec().getAttributes())) {
                inferNullability = NullabilityKind::Nullable;
                inferNullabilityInnerOnly = true;
              }
            }
          }
          break;
        }
        break;
      }
  
      case DeclaratorContext::ConversionId:
        complainAboutMissingNullability = CAMN_Yes;
        break;
  
      case DeclaratorContext::AliasDecl:
      case DeclaratorContext::AliasTemplate:
      case DeclaratorContext::Block:
      case DeclaratorContext::BlockLiteral:
      case DeclaratorContext::Condition:
      case DeclaratorContext::CXXCatch:
      case DeclaratorContext::CXXNew:
      case DeclaratorContext::ForInit:
      case DeclaratorContext::SelectionInit:
      case DeclaratorContext::LambdaExpr:
      case DeclaratorContext::LambdaExprParameter:
      case DeclaratorContext::ObjCCatch:
      case DeclaratorContext::TemplateParam:
      case DeclaratorContext::TemplateArg:
      case DeclaratorContext::TemplateTypeArg:
      case DeclaratorContext::TypeName:
      case DeclaratorContext::FunctionalCast:
      case DeclaratorContext::RequiresExpr:
        // Don't infer in these contexts.
        break;
      }
    }
  
    // Local function that returns true if its argument looks like a va_list.
    auto isVaList = [&S](QualType T) -> bool {
      auto *typedefTy = T->getAs<TypedefType>();
      if (!typedefTy)
        return false;
      TypedefDecl *vaListTypedef = S.Context.getBuiltinVaListDecl();
      do {
        if (typedefTy->getDecl() == vaListTypedef)
          return true;
        if (auto *name = typedefTy->getDecl()->getIdentifier())
          if (name->isStr("va_list"))
            return true;
        typedefTy = typedefTy->desugar()->getAs<TypedefType>();
      } while (typedefTy);
      return false;
    };
  
    // Local function that checks the nullability for a given pointer declarator.
    // Returns true if _Nonnull was inferred.
    auto inferPointerNullability =
        [&](SimplePointerKind pointerKind, SourceLocation pointerLoc,
            SourceLocation pointerEndLoc,
            ParsedAttributesView &attrs, AttributePool &Pool) -> ParsedAttr * {
      // We've seen a pointer.
      if (NumPointersRemaining > 0)
        --NumPointersRemaining;
  
      // If a nullability attribute is present, there's nothing to do.
      if (hasNullabilityAttr(attrs))
        return nullptr;
  
      // If we're supposed to infer nullability, do so now.
      if (inferNullability && !inferNullabilityInnerOnlyComplete) {
        ParsedAttr::Syntax syntax = inferNullabilityCS
                                        ? ParsedAttr::AS_ContextSensitiveKeyword
                                        : ParsedAttr::AS_Keyword;
        ParsedAttr *nullabilityAttr = Pool.create(
            S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
            nullptr, SourceLocation(), nullptr, 0, syntax);
  
        attrs.addAtEnd(nullabilityAttr);
  
        if (inferNullabilityCS) {
          state.getDeclarator().getMutableDeclSpec().getObjCQualifiers()
            ->setObjCDeclQualifier(ObjCDeclSpec::DQ_CSNullability);
        }
  
        if (pointerLoc.isValid() &&
            complainAboutInferringWithinChunk !=
              PointerWrappingDeclaratorKind::None) {
          auto Diag =
              S.Diag(pointerLoc, diag::warn_nullability_inferred_on_nested_type);
          Diag << static_cast<int>(complainAboutInferringWithinChunk);
          fixItNullability(S, Diag, pointerLoc, NullabilityKind::NonNull);
        }
  
        if (inferNullabilityInnerOnly)
          inferNullabilityInnerOnlyComplete = true;
        return nullabilityAttr;
      }
  
      // If we're supposed to complain about missing nullability, do so
      // now if it's truly missing.
      switch (complainAboutMissingNullability) {
      case CAMN_No:
        break;
  
      case CAMN_InnerPointers:
        if (NumPointersRemaining == 0)
          break;
        LLVM_FALLTHROUGH;
  
      case CAMN_Yes:
        checkNullabilityConsistency(S, pointerKind, pointerLoc, pointerEndLoc);
      }
      return nullptr;
    };
  
    // If the type itself could have nullability but does not, infer pointer
    // nullability and perform consistency checking.
    if (S.CodeSynthesisContexts.empty()) {
      if (T->canHaveNullability(/*ResultIfUnknown*/false) &&
          !T->getNullability(S.Context)) {
        if (isVaList(T)) {
          // Record that we've seen a pointer, but do nothing else.
          if (NumPointersRemaining > 0)
            --NumPointersRemaining;
        } else {
          SimplePointerKind pointerKind = SimplePointerKind::Pointer;
          if (T->isBlockPointerType())
            pointerKind = SimplePointerKind::BlockPointer;
          else if (T->isMemberPointerType())
            pointerKind = SimplePointerKind::MemberPointer;
  
          if (auto *attr = inferPointerNullability(
                  pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),
                  D.getDeclSpec().getEndLoc(),
                  D.getMutableDeclSpec().getAttributes(),
                  D.getMutableDeclSpec().getAttributePool())) {
            T = state.getAttributedType(
                createNullabilityAttr(Context, *attr, *inferNullability), T, T);
          }
        }
      }
  
      if (complainAboutMissingNullability == CAMN_Yes &&
          T->isArrayType() && !T->getNullability(S.Context) && !isVaList(T) &&
          D.isPrototypeContext() &&
          !hasOuterPointerLikeChunk(D, D.getNumTypeObjects())) {
        checkNullabilityConsistency(S, SimplePointerKind::Array,
                                    D.getDeclSpec().getTypeSpecTypeLoc());
      }
    }
  
    bool ExpectNoDerefChunk =
        state.getCurrentAttributes().hasAttribute(ParsedAttr::AT_NoDeref);
  
    // Walk the DeclTypeInfo, building the recursive type as we go.
    // DeclTypeInfos are ordered from the identifier out, which is
    // opposite of what we want :).
    for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
      unsigned chunkIndex = e - i - 1;
      state.setCurrentChunkIndex(chunkIndex);
      DeclaratorChunk &DeclType = D.getTypeObject(chunkIndex);
      IsQualifiedFunction &= DeclType.Kind == DeclaratorChunk::Paren;
      switch (DeclType.Kind) {
      case DeclaratorChunk::Paren:
        if (i == 0)
          warnAboutRedundantParens(S, D, T);
        T = S.BuildParenType(T);
        break;
      case DeclaratorChunk::BlockPointer:
        // If blocks are disabled, emit an error.
        if (!LangOpts.Blocks)
          S.Diag(DeclType.Loc, diag::err_blocks_disable) << LangOpts.OpenCL;
  
        // Handle pointer nullability.
        inferPointerNullability(SimplePointerKind::BlockPointer, DeclType.Loc,
                                DeclType.EndLoc, DeclType.getAttrs(),
                                state.getDeclarator().getAttributePool());
  
        T = S.BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
        if (DeclType.Cls.TypeQuals || LangOpts.OpenCL) {
          // OpenCL v2.0, s6.12.5 - Block variable declarations are implicitly
          // qualified with const.
          if (LangOpts.OpenCL)
            DeclType.Cls.TypeQuals |= DeclSpec::TQ_const;
          T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals);
        }
        break;
      case DeclaratorChunk::Pointer:
        // Verify that we're not building a pointer to pointer to function with
        // exception specification.
        if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) {
          S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
          D.setInvalidType(true);
          // Build the type anyway.
        }
  
        // Handle pointer nullability
        inferPointerNullability(SimplePointerKind::Pointer, DeclType.Loc,
                                DeclType.EndLoc, DeclType.getAttrs(),
                                state.getDeclarator().getAttributePool());
  
        if (LangOpts.ObjC && T->getAs<ObjCObjectType>()) {
          T = Context.getObjCObjectPointerType(T);
          if (DeclType.Ptr.TypeQuals)
            T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
          break;
        }
  
        // OpenCL v2.0 s6.9b - Pointer to image/sampler cannot be used.
        // OpenCL v2.0 s6.13.16.1 - Pointer to pipe cannot be used.
        // OpenCL v2.0 s6.12.5 - Pointers to Blocks are not allowed.
        if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) {
          if (T->isImageType() || T->isSamplerT() || T->isPipeType() ||
              T->isBlockPointerType()) {
            S.Diag(D.getIdentifierLoc(), diag::err_opencl_pointer_to_type) << T;
            D.setInvalidType(true);
          }
        }
  
        T = S.BuildPointerType(T, DeclType.Loc, Name);
        if (DeclType.Ptr.TypeQuals)
          T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
        break;
      case DeclaratorChunk::Reference: {
        // Verify that we're not building a reference to pointer to function with
        // exception specification.
        if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) {
          S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
          D.setInvalidType(true);
          // Build the type anyway.
        }
        T = S.BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name);
  
        if (DeclType.Ref.HasRestrict)
          T = S.BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict);
        break;
      }
      case DeclaratorChunk::Array: {
        // Verify that we're not building an array of pointers to function with
        // exception specification.
        if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) {
          S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
          D.setInvalidType(true);
          // Build the type anyway.
        }
        DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
        Expr *ArraySize = static_cast<Expr*>(ATI.NumElts);
        ArrayType::ArraySizeModifier ASM;
        if (ATI.isStar)
          ASM = ArrayType::Star;
        else if (ATI.hasStatic)
          ASM = ArrayType::Static;
        else
          ASM = ArrayType::Normal;
        if (ASM == ArrayType::Star && !D.isPrototypeContext()) {
          // FIXME: This check isn't quite right: it allows star in prototypes
          // for function definitions, and disallows some edge cases detailed
          // in http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00133.html
          S.Diag(DeclType.Loc, diag::err_array_star_outside_prototype);
          ASM = ArrayType::Normal;
          D.setInvalidType(true);
        }
  
        // C99 6.7.5.2p1: The optional type qualifiers and the keyword static
        // shall appear only in a declaration of a function parameter with an
        // array type, ...
        if (ASM == ArrayType::Static || ATI.TypeQuals) {
          if (!(D.isPrototypeContext() ||
                D.getContext() == DeclaratorContext::KNRTypeList)) {
            S.Diag(DeclType.Loc, diag::err_array_static_outside_prototype) <<
                (ASM == ArrayType::Static ? "'static'" : "type qualifier");
            // Remove the 'static' and the type qualifiers.
            if (ASM == ArrayType::Static)
              ASM = ArrayType::Normal;
            ATI.TypeQuals = 0;
            D.setInvalidType(true);
          }
  
          // C99 6.7.5.2p1: ... and then only in the outermost array type
          // derivation.
          if (hasOuterPointerLikeChunk(D, chunkIndex)) {
            S.Diag(DeclType.Loc, diag::err_array_static_not_outermost) <<
              (ASM == ArrayType::Static ? "'static'" : "type qualifier");
            if (ASM == ArrayType::Static)
              ASM = ArrayType::Normal;
            ATI.TypeQuals = 0;
            D.setInvalidType(true);
          }
        }
        const AutoType *AT = T->getContainedAutoType();
        // Allow arrays of auto if we are a generic lambda parameter.
        // i.e. [](auto (&array)[5]) { return array[0]; }; OK
        if (AT && D.getContext() != DeclaratorContext::LambdaExprParameter) {
          // We've already diagnosed this for decltype(auto).
          if (!AT->isDecltypeAuto())
            S.Diag(DeclType.Loc, diag::err_illegal_decl_array_of_auto)
                << getPrintableNameForEntity(Name) << T;
          T = QualType();
          break;
        }
  
        // Array parameters can be marked nullable as well, although it's not
        // necessary if they're marked 'static'.
        if (complainAboutMissingNullability == CAMN_Yes &&
            !hasNullabilityAttr(DeclType.getAttrs()) &&
            ASM != ArrayType::Static &&
            D.isPrototypeContext() &&
            !hasOuterPointerLikeChunk(D, chunkIndex)) {
          checkNullabilityConsistency(S, SimplePointerKind::Array, DeclType.Loc);
        }
  
        T = S.BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals,
                             SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
        break;
      }
      case DeclaratorChunk::Function: {
        // If the function declarator has a prototype (i.e. it is not () and
        // does not have a K&R-style identifier list), then the arguments are part
        // of the type, otherwise the argument list is ().
        DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
        IsQualifiedFunction =
            FTI.hasMethodTypeQualifiers() || FTI.hasRefQualifier();
  
        // Check for auto functions and trailing return type and adjust the
        // return type accordingly.
        if (!D.isInvalidType()) {
          // trailing-return-type is only required if we're declaring a function,
          // and not, for instance, a pointer to a function.
          if (D.getDeclSpec().hasAutoTypeSpec() &&
              !FTI.hasTrailingReturnType() && chunkIndex == 0) {
            if (!S.getLangOpts().CPlusPlus14) {
              S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
                     D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto
                         ? diag::err_auto_missing_trailing_return
                         : diag::err_deduced_return_type);
              T = Context.IntTy;
              D.setInvalidType(true);
            } else {
              S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
                     diag::warn_cxx11_compat_deduced_return_type);
            }
          } else if (FTI.hasTrailingReturnType()) {
            // T must be exactly 'auto' at this point. See CWG issue 681.
            if (isa<ParenType>(T)) {
              S.Diag(D.getBeginLoc(), diag::err_trailing_return_in_parens)
                  << T << D.getSourceRange();
              D.setInvalidType(true);
            } else if (D.getName().getKind() ==
                       UnqualifiedIdKind::IK_DeductionGuideName) {
              if (T != Context.DependentTy) {
                S.Diag(D.getDeclSpec().getBeginLoc(),
                       diag::err_deduction_guide_with_complex_decl)
                    << D.getSourceRange();
                D.setInvalidType(true);
              }
            } else if (D.getContext() != DeclaratorContext::LambdaExpr &&
                       (T.hasQualifiers() || !isa<AutoType>(T) ||
                        cast<AutoType>(T)->getKeyword() !=
                            AutoTypeKeyword::Auto ||
                        cast<AutoType>(T)->isConstrained())) {
              S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
                     diag::err_trailing_return_without_auto)
                  << T << D.getDeclSpec().getSourceRange();
              D.setInvalidType(true);
            }
            T = S.GetTypeFromParser(FTI.getTrailingReturnType(), &TInfo);
            if (T.isNull()) {
              // An error occurred parsing the trailing return type.
              T = Context.IntTy;
              D.setInvalidType(true);
            } else if (AutoType *Auto = T->getContainedAutoType()) {
              // If the trailing return type contains an `auto`, we may need to
              // invent a template parameter for it, for cases like
              // `auto f() -> C auto` or `[](auto (*p) -> auto) {}`.
              InventedTemplateParameterInfo *InventedParamInfo = nullptr;
              if (D.getContext() == DeclaratorContext::Prototype)
                InventedParamInfo = &S.InventedParameterInfos.back();
              else if (D.getContext() == DeclaratorContext::LambdaExprParameter)
                InventedParamInfo = S.getCurLambda();
              if (InventedParamInfo) {
                std::tie(T, TInfo) = InventTemplateParameter(
                    state, T, TInfo, Auto, *InventedParamInfo);
              }
            }
          } else {
            // This function type is not the type of the entity being declared,
            // so checking the 'auto' is not the responsibility of this chunk.
          }
        }
  
        // C99 6.7.5.3p1: The return type may not be a function or array type.
        // For conversion functions, we'll diagnose this particular error later.
        if (!D.isInvalidType() && (T->isArrayType() || T->isFunctionType()) &&
            (D.getName().getKind() !=
             UnqualifiedIdKind::IK_ConversionFunctionId)) {
          unsigned diagID = diag::err_func_returning_array_function;
          // Last processing chunk in block context means this function chunk
          // represents the block.
          if (chunkIndex == 0 &&
              D.getContext() == DeclaratorContext::BlockLiteral)
            diagID = diag::err_block_returning_array_function;
          S.Diag(DeclType.Loc, diagID) << T->isFunctionType() << T;
          T = Context.IntTy;
          D.setInvalidType(true);
        }
  
        // Do not allow returning half FP value.
        // FIXME: This really should be in BuildFunctionType.
        if (T->isHalfType()) {
          if (S.getLangOpts().OpenCL) {
            if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16",
                                                        S.getLangOpts())) {
              S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return)
                  << T << 0 /*pointer hint*/;
              D.setInvalidType(true);
            }
          } else if (!S.getLangOpts().HalfArgsAndReturns) {
            S.Diag(D.getIdentifierLoc(),
              diag::err_parameters_retval_cannot_have_fp16_type) << 1;
            D.setInvalidType(true);
          }
        }
  
        if (LangOpts.OpenCL) {
          // OpenCL v2.0 s6.12.5 - A pipe cannot be the return value of a
          // function. Disrespect this for SYCL.
          if (T->isPipeType()) {
            S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return)
                << T << 1 /*hint off*/;
            D.setInvalidType(true);
          }
        }
  
        if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) {
          // OpenCL v2.0 s6.12.5 - A block cannot be the return value of a
          // function.
          if (!T->isSampledImageType() &&
              (T->isBlockPointerType() || T->isImageType() || T->isSamplerT())) {
            S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return)
                << T << 1 /*hint off*/;
            D.setInvalidType(true);
          }
          // OpenCL doesn't support variadic functions and blocks
          // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf.
          // We also allow here any toolchain reserved identifiers.
          if (FTI.isVariadic &&
              !LangOpts.SYCLIsDevice &&
              !S.getOpenCLOptions().isAvailableOption(
                  "__cl_clang_variadic_functions", S.getLangOpts()) &&
              !(D.getIdentifier() &&
                ((D.getIdentifier()->getName() == "printf" &&
                  (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) ||
                 D.getIdentifier()->getName().startswith("__")))) {
            S.Diag(D.getIdentifierLoc(), diag::err_opencl_variadic_function);
            D.setInvalidType(true);
          }
        }
  
        // Methods cannot return interface types. All ObjC objects are
        // passed by reference.
        if (T->isObjCObjectType()) {
          SourceLocation DiagLoc, FixitLoc;
          if (TInfo) {
            DiagLoc = TInfo->getTypeLoc().getBeginLoc();
            FixitLoc = S.getLocForEndOfToken(TInfo->getTypeLoc().getEndLoc());
          } else {
            DiagLoc = D.getDeclSpec().getTypeSpecTypeLoc();
            FixitLoc = S.getLocForEndOfToken(D.getDeclSpec().getEndLoc());
          }
          S.Diag(DiagLoc, diag::err_object_cannot_be_passed_returned_by_value)
            << 0 << T
            << FixItHint::CreateInsertion(FixitLoc, "*");
  
          T = Context.getObjCObjectPointerType(T);
          if (TInfo) {
            TypeLocBuilder TLB;
            TLB.pushFullCopy(TInfo->getTypeLoc());
            ObjCObjectPointerTypeLoc TLoc = TLB.push<ObjCObjectPointerTypeLoc>(T);
            TLoc.setStarLoc(FixitLoc);
            TInfo = TLB.getTypeSourceInfo(Context, T);
          }
  
          D.setInvalidType(true);
        }
  
        // cv-qualifiers on return types are pointless except when the type is a
        // class type in C++.
        if ((T.getCVRQualifiers() || T->isAtomicType()) &&
            !(S.getLangOpts().CPlusPlus &&
              (T->isDependentType() || T->isRecordType()))) {
          if (T->isVoidType() && !S.getLangOpts().CPlusPlus &&
              D.getFunctionDefinitionKind() ==
                  FunctionDefinitionKind::Definition) {
            // [6.9.1/3] qualified void return is invalid on a C
            // function definition.  Apparently ok on declarations and
            // in C++ though (!)
            S.Diag(DeclType.Loc, diag::err_func_returning_qualified_void) << T;
          } else
            diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex);
  
          // C++2a [dcl.fct]p12:
          //   A volatile-qualified return type is deprecated
          if (T.isVolatileQualified() && S.getLangOpts().CPlusPlus20)
            S.Diag(DeclType.Loc, diag::warn_deprecated_volatile_return) << T;
        }
  
        // Objective-C ARC ownership qualifiers are ignored on the function
        // return type (by type canonicalization). Complain if this attribute
        // was written here.
        if (T.getQualifiers().hasObjCLifetime()) {
          SourceLocation AttrLoc;
          if (chunkIndex + 1 < D.getNumTypeObjects()) {
            DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1);
            for (const ParsedAttr &AL : ReturnTypeChunk.getAttrs()) {
              if (AL.getKind() == ParsedAttr::AT_ObjCOwnership) {
                AttrLoc = AL.getLoc();
                break;
              }
            }
          }
          if (AttrLoc.isInvalid()) {
            for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
              if (AL.getKind() == ParsedAttr::AT_ObjCOwnership) {
                AttrLoc = AL.getLoc();
                break;
              }
            }
          }
  
          if (AttrLoc.isValid()) {
            // The ownership attributes are almost always written via
            // the predefined
            // __strong/__weak/__autoreleasing/__unsafe_unretained.
            if (AttrLoc.isMacroID())
              AttrLoc =
                  S.SourceMgr.getImmediateExpansionRange(AttrLoc).getBegin();
  
            S.Diag(AttrLoc, diag::warn_arc_lifetime_result_type)
              << T.getQualifiers().getObjCLifetime();
          }
        }
  
        if (LangOpts.CPlusPlus && D.getDeclSpec().hasTagDefinition()) {
          // C++ [dcl.fct]p6:
          //   Types shall not be defined in return or parameter types.
          TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
          S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
            << Context.getTypeDeclType(Tag);
        }
  
        // Exception specs are not allowed in typedefs. Complain, but add it
        // anyway.
        if (IsTypedefName && FTI.getExceptionSpecType() && !LangOpts.CPlusPlus17)
          S.Diag(FTI.getExceptionSpecLocBeg(),
                 diag::err_exception_spec_in_typedef)
              << (D.getContext() == DeclaratorContext::AliasDecl ||
                  D.getContext() == DeclaratorContext::AliasTemplate);
  
        // If we see "T var();" or "T var(T());" at block scope, it is probably
        // an attempt to initialize a variable, not a function declaration.
        if (FTI.isAmbiguous)
          warnAboutAmbiguousFunction(S, D, DeclType, T);
  
        FunctionType::ExtInfo EI(
            getCCForDeclaratorChunk(S, D, DeclType.getAttrs(), FTI, chunkIndex));
  
        if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus &&
            !LangOpts.OpenCL && !LangOpts.SYCLIsDevice) {
          // Simple void foo(), where the incoming T is the result type.
          T = Context.getFunctionNoProtoType(T, EI);
        } else {
          // We allow a zero-parameter variadic function in C if the
          // function is marked with the "overloadable" attribute. Scan
          // for this attribute now.
          if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus)
            if (!D.getAttributes().hasAttribute(ParsedAttr::AT_Overloadable))
              S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_param);
  
          if (FTI.NumParams && FTI.Params[0].Param == nullptr) {
            // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
            // definition.
            S.Diag(FTI.Params[0].IdentLoc,
                   diag::err_ident_list_in_fn_declaration);
            D.setInvalidType(true);
            // Recover by creating a K&R-style function type.
            T = Context.getFunctionNoProtoType(T, EI);
            break;
          }
  
          FunctionProtoType::ExtProtoInfo EPI;
          EPI.ExtInfo = EI;
          EPI.Variadic = FTI.isVariadic;
          EPI.EllipsisLoc = FTI.getEllipsisLoc();
          EPI.HasTrailingReturn = FTI.hasTrailingReturnType();
          EPI.TypeQuals.addCVRUQualifiers(
              FTI.MethodQualifiers ? FTI.MethodQualifiers->getTypeQualifiers()
                                   : 0);
          EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None
                      : FTI.RefQualifierIsLValueRef? RQ_LValue
                      : RQ_RValue;
  
          // Otherwise, we have a function with a parameter list that is
          // potentially variadic.
          SmallVector<QualType, 16> ParamTys;
          ParamTys.reserve(FTI.NumParams);
  
          SmallVector<FunctionProtoType::ExtParameterInfo, 16>
            ExtParameterInfos(FTI.NumParams);
          bool HasAnyInterestingExtParameterInfos = false;
  
          for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) {
            ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
            QualType ParamTy = Param->getType();
            assert(!ParamTy.isNull() && "Couldn't parse type?");
  
            // Look for 'void'.  void is allowed only as a single parameter to a
            // function with no other parameters (C99 6.7.5.3p10).  We record
            // int(void) as a FunctionProtoType with an empty parameter list.
            if (ParamTy->isVoidType()) {
              // If this is something like 'float(int, void)', reject it.  'void'
              // is an incomplete type (C99 6.2.5p19) and function decls cannot
              // have parameters of incomplete type.
              if (FTI.NumParams != 1 || FTI.isVariadic) {
                S.Diag(FTI.Params[i].IdentLoc, diag::err_void_only_param);
                ParamTy = Context.IntTy;
                Param->setType(ParamTy);
              } else if (FTI.Params[i].Ident) {
                // Reject, but continue to parse 'int(void abc)'.
                S.Diag(FTI.Params[i].IdentLoc, diag::err_param_with_void_type);
                ParamTy = Context.IntTy;
                Param->setType(ParamTy);
              } else {
                // Reject, but continue to parse 'float(const void)'.
                if (ParamTy.hasQualifiers())
                  S.Diag(DeclType.Loc, diag::err_void_param_qualified);
  
                // Do not add 'void' to the list.
                break;
              }
            } else if (ParamTy->isHalfType()) {
              // Disallow half FP parameters.
              // FIXME: This really should be in BuildFunctionType.
              if (S.getLangOpts().OpenCL) {
                if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16",
                                                            S.getLangOpts())) {
                  S.Diag(Param->getLocation(), diag::err_opencl_invalid_param)
                      << ParamTy << 0;
                  D.setInvalidType();
                  Param->setInvalidDecl();
                }
              } else if (!S.getLangOpts().HalfArgsAndReturns) {
                S.Diag(Param->getLocation(),
                  diag::err_parameters_retval_cannot_have_fp16_type) << 0;
                D.setInvalidType();
              }
            } else if (!FTI.hasPrototype) {
              if (ParamTy->isPromotableIntegerType()) {
                ParamTy = Context.getPromotedIntegerType(ParamTy);
                Param->setKNRPromoted(true);
              } else if (const BuiltinType* BTy = ParamTy->getAs<BuiltinType>()) {
                if (BTy->getKind() == BuiltinType::Float) {
                  ParamTy = Context.DoubleTy;
                  Param->setKNRPromoted(true);
                }
              }
            } else if (S.getLangOpts().OpenCL && ParamTy->isBlockPointerType()) {
              // OpenCL 2.0 s6.12.5: A block cannot be a parameter of a function.
              S.Diag(Param->getLocation(), diag::err_opencl_invalid_param)
                  << ParamTy << 1 /*hint off*/;
              D.setInvalidType();
            }
  
            if (LangOpts.ObjCAutoRefCount && Param->hasAttr<NSConsumedAttr>()) {
              ExtParameterInfos[i] = ExtParameterInfos[i].withIsConsumed(true);
              HasAnyInterestingExtParameterInfos = true;
            }
  
            if (auto attr = Param->getAttr<ParameterABIAttr>()) {
              ExtParameterInfos[i] =
                ExtParameterInfos[i].withABI(attr->getABI());
              HasAnyInterestingExtParameterInfos = true;
            }
  
            if (Param->hasAttr<PassObjectSizeAttr>()) {
              ExtParameterInfos[i] = ExtParameterInfos[i].withHasPassObjectSize();
              HasAnyInterestingExtParameterInfos = true;
            }
  
            if (Param->hasAttr<NoEscapeAttr>()) {
              ExtParameterInfos[i] = ExtParameterInfos[i].withIsNoEscape(true);
              HasAnyInterestingExtParameterInfos = true;
            }
  
            ParamTys.push_back(ParamTy);
          }
  
          if (HasAnyInterestingExtParameterInfos) {
            EPI.ExtParameterInfos = ExtParameterInfos.data();
            checkExtParameterInfos(S, ParamTys, EPI,
                [&](unsigned i) { return FTI.Params[i].Param->getLocation(); });
          }
  
          SmallVector<QualType, 4> Exceptions;
          SmallVector<ParsedType, 2> DynamicExceptions;
          SmallVector<SourceRange, 2> DynamicExceptionRanges;
          Expr *NoexceptExpr = nullptr;
  
          if (FTI.getExceptionSpecType() == EST_Dynamic) {
            // FIXME: It's rather inefficient to have to split into two vectors
            // here.
            unsigned N = FTI.getNumExceptions();
            DynamicExceptions.reserve(N);
            DynamicExceptionRanges.reserve(N);
            for (unsigned I = 0; I != N; ++I) {
              DynamicExceptions.push_back(FTI.Exceptions[I].Ty);
              DynamicExceptionRanges.push_back(FTI.Exceptions[I].Range);
            }
          } else if (isComputedNoexcept(FTI.getExceptionSpecType())) {
            NoexceptExpr = FTI.NoexceptExpr;
          }
  
          S.checkExceptionSpecification(D.isFunctionDeclarationContext(),
                                        FTI.getExceptionSpecType(),
                                        DynamicExceptions,
                                        DynamicExceptionRanges,
                                        NoexceptExpr,
                                        Exceptions,
                                        EPI.ExceptionSpec);
  
          // FIXME: Set address space from attrs for C++ mode here.
          // OpenCLCPlusPlus: A class member function has an address space.
          auto IsClassMember = [&]() {
            return (!state.getDeclarator().getCXXScopeSpec().isEmpty() &&
                    state.getDeclarator()
                            .getCXXScopeSpec()
                            .getScopeRep()
                            ->getKind() == NestedNameSpecifier::TypeSpec) ||
                   state.getDeclarator().getContext() ==
                       DeclaratorContext::Member ||
                   state.getDeclarator().getContext() ==
                       DeclaratorContext::LambdaExpr;
          };
  
          if (state.getSema().getLangOpts().OpenCLCPlusPlus && IsClassMember()) {
            LangAS ASIdx = LangAS::Default;
            // Take address space attr if any and mark as invalid to avoid adding
            // them later while creating QualType.
            if (FTI.MethodQualifiers)
              for (ParsedAttr &attr : FTI.MethodQualifiers->getAttributes()) {
                LangAS ASIdxNew = attr.asOpenCLLangAS();
                if (DiagnoseMultipleAddrSpaceAttributes(S, ASIdx, ASIdxNew,
                                                        attr.getLoc()))
                  D.setInvalidType(true);
                else
                  ASIdx = ASIdxNew;
              }
            // If a class member function's address space is not set, set it to
            // __generic.
            LangAS AS =
                (ASIdx == LangAS::Default ? S.getDefaultCXXMethodAddrSpace()
                                          : ASIdx);
            EPI.TypeQuals.addAddressSpace(AS);
          }
          T = Context.getFunctionType(T, ParamTys, EPI);
        }
        break;
      }
      case DeclaratorChunk::MemberPointer: {
        // The scope spec must refer to a class, or be dependent.
        CXXScopeSpec &SS = DeclType.Mem.Scope();
        QualType ClsType;
  
        // Handle pointer nullability.
        inferPointerNullability(SimplePointerKind::MemberPointer, DeclType.Loc,
                                DeclType.EndLoc, DeclType.getAttrs(),
                                state.getDeclarator().getAttributePool());
  
        if (SS.isInvalid()) {
          // Avoid emitting extra errors if we already errored on the scope.
          D.setInvalidType(true);
        } else if (S.isDependentScopeSpecifier(SS) ||
                   dyn_cast_or_null<CXXRecordDecl>(S.computeDeclContext(SS))) {
          NestedNameSpecifier *NNS = SS.getScopeRep();
          NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
          switch (NNS->getKind()) {
          case NestedNameSpecifier::Identifier:
            ClsType = Context.getDependentNameType(ETK_None, NNSPrefix,
                                                   NNS->getAsIdentifier());
            break;
  
          case NestedNameSpecifier::Namespace:
          case NestedNameSpecifier::NamespaceAlias:
          case NestedNameSpecifier::Global:
          case NestedNameSpecifier::Super:
            llvm_unreachable("Nested-name-specifier must name a type");
  
          case NestedNameSpecifier::TypeSpec:
          case NestedNameSpecifier::TypeSpecWithTemplate:
            ClsType = QualType(NNS->getAsType(), 0);
            // Note: if the NNS has a prefix and ClsType is a nondependent
            // TemplateSpecializationType, then the NNS prefix is NOT included
            // in ClsType; hence we wrap ClsType into an ElaboratedType.
            // NOTE: in particular, no wrap occurs if ClsType already is an
            // Elaborated, DependentName, or DependentTemplateSpecialization.
            if (NNSPrefix && isa<TemplateSpecializationType>(NNS->getAsType()))
              ClsType = Context.getElaboratedType(ETK_None, NNSPrefix, ClsType);
            break;
          }
        } else {
          S.Diag(DeclType.Mem.Scope().getBeginLoc(),
               diag::err_illegal_decl_mempointer_in_nonclass)
            << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name")
            << DeclType.Mem.Scope().getRange();
          D.setInvalidType(true);
        }
  
        if (!ClsType.isNull())
          T = S.BuildMemberPointerType(T, ClsType, DeclType.Loc,
                                       D.getIdentifier());
        if (T.isNull()) {
          T = Context.IntTy;
          D.setInvalidType(true);
        } else if (DeclType.Mem.TypeQuals) {
          T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals);
        }
        break;
      }
  
      case DeclaratorChunk::Pipe: {
        T = S.BuildReadPipeType(T, DeclType.Loc);
        processTypeAttrs(state, T, TAL_DeclSpec,
                         D.getMutableDeclSpec().getAttributes());
        break;
      }
      }
  
      if (T.isNull()) {
        D.setInvalidType(true);
        T = Context.IntTy;
      }
  
      // See if there are any attributes on this declarator chunk.
      processTypeAttrs(state, T, TAL_DeclChunk, DeclType.getAttrs());
  
      if (DeclType.Kind != DeclaratorChunk::Paren) {
        if (ExpectNoDerefChunk && !IsNoDerefableChunk(DeclType))
          S.Diag(DeclType.Loc, diag::warn_noderef_on_non_pointer_or_array);
  
        ExpectNoDerefChunk = state.didParseNoDeref();
      }
    }
  
    if (ExpectNoDerefChunk)
      S.Diag(state.getDeclarator().getBeginLoc(),
             diag::warn_noderef_on_non_pointer_or_array);
  
    // GNU warning -Wstrict-prototypes
    //   Warn if a function declaration is without a prototype.
    //   This warning is issued for all kinds of unprototyped function
    //   declarations (i.e. function type typedef, function pointer etc.)
    //   C99 6.7.5.3p14:
    //   The empty list in a function declarator that is not part of a definition
    //   of that function specifies that no information about the number or types
    //   of the parameters is supplied.
    if (!LangOpts.CPlusPlus &&
        D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration) {
      bool IsBlock = false;
      for (const DeclaratorChunk &DeclType : D.type_objects()) {
        switch (DeclType.Kind) {
        case DeclaratorChunk::BlockPointer:
          IsBlock = true;
          break;
        case DeclaratorChunk::Function: {
          const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
          // We supress the warning when there's no LParen location, as this
          // indicates the declaration was an implicit declaration, which gets
          // warned about separately via -Wimplicit-function-declaration.
          if (FTI.NumParams == 0 && !FTI.isVariadic && FTI.getLParenLoc().isValid())
            S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
                << IsBlock
                << FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
          IsBlock = false;
          break;
        }
        default:
          break;
        }
      }
    }
  
    assert(!T.isNull() && "T must not be null after this point");
  
    if (LangOpts.CPlusPlus && T->isFunctionType()) {
      const FunctionProtoType *FnTy = T->getAs<FunctionProtoType>();
      assert(FnTy && "Why oh why is there not a FunctionProtoType here?");
  
      // C++ 8.3.5p4:
      //   A cv-qualifier-seq shall only be part of the function type
      //   for a nonstatic member function, the function type to which a pointer
      //   to member refers, or the top-level function type of a function typedef
      //   declaration.
      //
      // Core issue 547 also allows cv-qualifiers on function types that are
      // top-level template type arguments.
      enum { NonMember, Member, DeductionGuide } Kind = NonMember;
      if (D.getName().getKind() == UnqualifiedIdKind::IK_DeductionGuideName)
        Kind = DeductionGuide;
      else if (!D.getCXXScopeSpec().isSet()) {
        if ((D.getContext() == DeclaratorContext::Member ||
             D.getContext() == DeclaratorContext::LambdaExpr) &&
            !D.getDeclSpec().isFriendSpecified())
          Kind = Member;
      } else {
        DeclContext *DC = S.computeDeclContext(D.getCXXScopeSpec());
        if (!DC || DC->isRecord())
          Kind = Member;
      }
  
      // C++11 [dcl.fct]p6 (w/DR1417):
      // An attempt to specify a function type with a cv-qualifier-seq or a
      // ref-qualifier (including by typedef-name) is ill-formed unless it is:
      //  - the function type for a non-static member function,
      //  - the function type to which a pointer to member refers,
      //  - the top-level function type of a function typedef declaration or
      //    alias-declaration,
      //  - the type-id in the default argument of a type-parameter, or
      //  - the type-id of a template-argument for a type-parameter
      //
      // FIXME: Checking this here is insufficient. We accept-invalid on:
      //
      //   template<typename T> struct S { void f(T); };
      //   S<int() const> s;
      //
      // ... for instance.
      if (IsQualifiedFunction &&
          !(Kind == Member &&
            D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) &&
          !IsTypedefName && D.getContext() != DeclaratorContext::TemplateArg &&
          D.getContext() != DeclaratorContext::TemplateTypeArg) {
        SourceLocation Loc = D.getBeginLoc();
        SourceRange RemovalRange;
        unsigned I;
        if (D.isFunctionDeclarator(I)) {
          SmallVector<SourceLocation, 4> RemovalLocs;
          const DeclaratorChunk &Chunk = D.getTypeObject(I);
          assert(Chunk.Kind == DeclaratorChunk::Function);
  
          if (Chunk.Fun.hasRefQualifier())
            RemovalLocs.push_back(Chunk.Fun.getRefQualifierLoc());
  
          if (Chunk.Fun.hasMethodTypeQualifiers())
            Chunk.Fun.MethodQualifiers->forEachQualifier(
                [&](DeclSpec::TQ TypeQual, StringRef QualName,
                    SourceLocation SL) { RemovalLocs.push_back(SL); });
  
          if (!RemovalLocs.empty()) {
            llvm::sort(RemovalLocs,
                       BeforeThanCompare<SourceLocation>(S.getSourceManager()));
            RemovalRange = SourceRange(RemovalLocs.front(), RemovalLocs.back());
            Loc = RemovalLocs.front();
          }
        }
  
        S.Diag(Loc, diag::err_invalid_qualified_function_type)
          << Kind << D.isFunctionDeclarator() << T
          << getFunctionQualifiersAsString(FnTy)
          << FixItHint::CreateRemoval(RemovalRange);
  
        // Strip the cv-qualifiers and ref-qualifiers from the type.
        FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo();
        EPI.TypeQuals.removeCVRQualifiers();
        EPI.RefQualifier = RQ_None;
  
        T = Context.getFunctionType(FnTy->getReturnType(), FnTy->getParamTypes(),
                                    EPI);
        // Rebuild any parens around the identifier in the function type.
        for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
          if (D.getTypeObject(i).Kind != DeclaratorChunk::Paren)
            break;
          T = S.BuildParenType(T);
        }
      }
    }
  
    // Apply any undistributed attributes from the declarator.
    processTypeAttrs(state, T, TAL_DeclName, D.getAttributes());
  
    // Diagnose any ignored type attributes.
    state.diagnoseIgnoredTypeAttrs(T);
  
    // C++0x [dcl.constexpr]p9:
    //  A constexpr specifier used in an object declaration declares the object
    //  as const.
    if (D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr &&
        T->isObjectType())
      T.addConst();
  
    // C++2a [dcl.fct]p4:
    //   A parameter with volatile-qualified type is deprecated
    if (T.isVolatileQualified() && S.getLangOpts().CPlusPlus20 &&
        (D.getContext() == DeclaratorContext::Prototype ||
         D.getContext() == DeclaratorContext::LambdaExprParameter))
      S.Diag(D.getIdentifierLoc(), diag::warn_deprecated_volatile_param) << T;
  
    // If there was an ellipsis in the declarator, the declaration declares a
    // parameter pack whose type may be a pack expansion type.
    if (D.hasEllipsis()) {
      // C++0x [dcl.fct]p13:
      //   A declarator-id or abstract-declarator containing an ellipsis shall
      //   only be used in a parameter-declaration. Such a parameter-declaration
      //   is a parameter pack (14.5.3). [...]
      switch (D.getContext()) {
      case DeclaratorContext::Prototype:
      case DeclaratorContext::LambdaExprParameter:
      case DeclaratorContext::RequiresExpr:
        // C++0x [dcl.fct]p13:
        //   [...] When it is part of a parameter-declaration-clause, the
        //   parameter pack is a function parameter pack (14.5.3). The type T
        //   of the declarator-id of the function parameter pack shall contain
        //   a template parameter pack; each template parameter pack in T is
        //   expanded by the function parameter pack.
        //
        // We represent function parameter packs as function parameters whose
        // type is a pack expansion.
        if (!T->containsUnexpandedParameterPack() &&
            (!LangOpts.CPlusPlus20 || !T->getContainedAutoType())) {
          S.Diag(D.getEllipsisLoc(),
               diag::err_function_parameter_pack_without_parameter_packs)
            << T <<  D.getSourceRange();
          D.setEllipsisLoc(SourceLocation());
        } else {
          T = Context.getPackExpansionType(T, None, /*ExpectPackInType=*/false);
        }
        break;
      case DeclaratorContext::TemplateParam:
        // C++0x [temp.param]p15:
        //   If a template-parameter is a [...] is a parameter-declaration that
        //   declares a parameter pack (8.3.5), then the template-parameter is a
        //   template parameter pack (14.5.3).
        //
        // Note: core issue 778 clarifies that, if there are any unexpanded
        // parameter packs in the type of the non-type template parameter, then
        // it expands those parameter packs.
        if (T->containsUnexpandedParameterPack())
          T = Context.getPackExpansionType(T, None);
        else
          S.Diag(D.getEllipsisLoc(),
                 LangOpts.CPlusPlus11
                   ? diag::warn_cxx98_compat_variadic_templates
                   : diag::ext_variadic_templates);
        break;
  
      case DeclaratorContext::File:
      case DeclaratorContext::KNRTypeList:
      case DeclaratorContext::ObjCParameter: // FIXME: special diagnostic here?
      case DeclaratorContext::ObjCResult:    // FIXME: special diagnostic here?
      case DeclaratorContext::TypeName:
      case DeclaratorContext::FunctionalCast:
      case DeclaratorContext::CXXNew:
      case DeclaratorContext::AliasDecl:
      case DeclaratorContext::AliasTemplate:
      case DeclaratorContext::Member:
      case DeclaratorContext::Block:
      case DeclaratorContext::ForInit:
      case DeclaratorContext::SelectionInit:
      case DeclaratorContext::Condition:
      case DeclaratorContext::CXXCatch:
      case DeclaratorContext::ObjCCatch:
      case DeclaratorContext::BlockLiteral:
      case DeclaratorContext::LambdaExpr:
      case DeclaratorContext::ConversionId:
      case DeclaratorContext::TrailingReturn:
      case DeclaratorContext::TrailingReturnVar:
      case DeclaratorContext::TemplateArg:
      case DeclaratorContext::TemplateTypeArg:
        // FIXME: We may want to allow parameter packs in block-literal contexts
        // in the future.
        S.Diag(D.getEllipsisLoc(),
               diag::err_ellipsis_in_declarator_not_parameter);
        D.setEllipsisLoc(SourceLocation());
        break;
      }
    }
  
    assert(!T.isNull() && "T must not be null at the end of this function");
    if (D.isInvalidType())
      return Context.getTrivialTypeSourceInfo(T);
  
    return GetTypeSourceInfoForDeclarator(state, T, TInfo);
  }
  
  /// GetTypeForDeclarator - Convert the type for the specified
  /// declarator to Type instances.
  ///
  /// The result of this call will never be null, but the associated
  /// type may be a null type if there's an unrecoverable error.
  TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
    // Determine the type of the declarator. Not all forms of declarator
    // have a type.
  
    TypeProcessingState state(*this, D);
  
    TypeSourceInfo *ReturnTypeInfo = nullptr;
    QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
    if (D.isPrototypeContext() && getLangOpts().ObjCAutoRefCount)
      inferARCWriteback(state, T);
  
    return GetFullTypeForDeclarator(state, T, ReturnTypeInfo);
  }
  
  static void transferARCOwnershipToDeclSpec(Sema &S,
                                             QualType &declSpecTy,
                                             Qualifiers::ObjCLifetime ownership) {
    if (declSpecTy->isObjCRetainableType() &&
        declSpecTy.getObjCLifetime() == Qualifiers::OCL_None) {
      Qualifiers qs;
      qs.addObjCLifetime(ownership);
      declSpecTy = S.Context.getQualifiedType(declSpecTy, qs);
    }
  }
  
  static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
                                              Qualifiers::ObjCLifetime ownership,
                                              unsigned chunkIndex) {
    Sema &S = state.getSema();
    Declarator &D = state.getDeclarator();
  
    // Look for an explicit lifetime attribute.
    DeclaratorChunk &chunk = D.getTypeObject(chunkIndex);
    if (chunk.getAttrs().hasAttribute(ParsedAttr::AT_ObjCOwnership))
      return;
  
    const char *attrStr = nullptr;
    switch (ownership) {
    case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
    case Qualifiers::OCL_ExplicitNone: attrStr = "none"; break;
    case Qualifiers::OCL_Strong: attrStr = "strong"; break;
    case Qualifiers::OCL_Weak: attrStr = "weak"; break;
    case Qualifiers::OCL_Autoreleasing: attrStr = "autoreleasing"; break;
    }
  
    IdentifierLoc *Arg = new (S.Context) IdentifierLoc;
    Arg->Ident = &S.Context.Idents.get(attrStr);
    Arg->Loc = SourceLocation();
  
    ArgsUnion Args(Arg);
  
    // If there wasn't one, add one (with an invalid source location
    // so that we don't make an AttributedType for it).
    ParsedAttr *attr = D.getAttributePool().create(
        &S.Context.Idents.get("objc_ownership"), SourceLocation(),
        /*scope*/ nullptr, SourceLocation(),
        /*args*/ &Args, 1, ParsedAttr::AS_GNU);
    chunk.getAttrs().addAtEnd(attr);
    // TODO: mark whether we did this inference?
  }
  
  /// Used for transferring ownership in casts resulting in l-values.
  static void transferARCOwnership(TypeProcessingState &state,
                                   QualType &declSpecTy,
                                   Qualifiers::ObjCLifetime ownership) {
    Sema &S = state.getSema();
    Declarator &D = state.getDeclarator();
  
    int inner = -1;
    bool hasIndirection = false;
    for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
      DeclaratorChunk &chunk = D.getTypeObject(i);
      switch (chunk.Kind) {
      case DeclaratorChunk::Paren:
        // Ignore parens.
        break;
  
      case DeclaratorChunk::Array:
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::Pointer:
        if (inner != -1)
          hasIndirection = true;
        inner = i;
        break;
  
      case DeclaratorChunk::BlockPointer:
        if (inner != -1)
          transferARCOwnershipToDeclaratorChunk(state, ownership, i);
        return;
  
      case DeclaratorChunk::Function:
      case DeclaratorChunk::MemberPointer:
      case DeclaratorChunk::Pipe:
        return;
      }
    }
  
    if (inner == -1)
      return;
  
    DeclaratorChunk &chunk = D.getTypeObject(inner);
    if (chunk.Kind == DeclaratorChunk::Pointer) {
      if (declSpecTy->isObjCRetainableType())
        return transferARCOwnershipToDeclSpec(S, declSpecTy, ownership);
      if (declSpecTy->isObjCObjectType() && hasIndirection)
        return transferARCOwnershipToDeclaratorChunk(state, ownership, inner);
    } else {
      assert(chunk.Kind == DeclaratorChunk::Array ||
             chunk.Kind == DeclaratorChunk::Reference);
      return transferARCOwnershipToDeclSpec(S, declSpecTy, ownership);
    }
  }
  
  TypeSourceInfo *Sema::GetTypeForDeclaratorCast(Declarator &D, QualType FromTy) {
    TypeProcessingState state(*this, D);
  
    TypeSourceInfo *ReturnTypeInfo = nullptr;
    QualType declSpecTy = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
  
    if (getLangOpts().ObjC) {
      Qualifiers::ObjCLifetime ownership = Context.getInnerObjCOwnership(FromTy);
      if (ownership != Qualifiers::OCL_None)
        transferARCOwnership(state, declSpecTy, ownership);
    }
  
    return GetFullTypeForDeclarator(state, declSpecTy, ReturnTypeInfo);
  }
  
  static void fillAttributedTypeLoc(AttributedTypeLoc TL,
                                    TypeProcessingState &State) {
    TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
  }
  
  namespace {
    class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
      Sema &SemaRef;
      ASTContext &Context;
      TypeProcessingState &State;
      const DeclSpec &DS;
  
    public:
      TypeSpecLocFiller(Sema &S, ASTContext &Context, TypeProcessingState &State,
                        const DeclSpec &DS)
          : SemaRef(S), Context(Context), State(State), DS(DS) {}
  
      void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
        Visit(TL.getModifiedLoc());
        fillAttributedTypeLoc(TL, State);
      }
      void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
        Visit(TL.getInnerLoc());
        TL.setExpansionLoc(
            State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
      }
      void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
        Visit(TL.getUnqualifiedLoc());
      }
      void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
        TL.setNameLoc(DS.getTypeSpecTypeLoc());
      }
      void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
        TL.setNameLoc(DS.getTypeSpecTypeLoc());
        // FIXME. We should have DS.getTypeSpecTypeEndLoc(). But, it requires
        // addition field. What we have is good enough for dispay of location
        // of 'fixit' on interface name.
        TL.setNameEndLoc(DS.getEndLoc());
      }
      void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
        TypeSourceInfo *RepTInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &RepTInfo);
        TL.copy(RepTInfo->getTypeLoc());
      }
      void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
        TypeSourceInfo *RepTInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &RepTInfo);
        TL.copy(RepTInfo->getTypeLoc());
      }
      void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
        TypeSourceInfo *TInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
  
        // If we got no declarator info from previous Sema routines,
        // just fill with the typespec loc.
        if (!TInfo) {
          TL.initialize(Context, DS.getTypeSpecTypeNameLoc());
          return;
        }
  
        TypeLoc OldTL = TInfo->getTypeLoc();
        if (TInfo->getType()->getAs<ElaboratedType>()) {
          ElaboratedTypeLoc ElabTL = OldTL.castAs<ElaboratedTypeLoc>();
          TemplateSpecializationTypeLoc NamedTL = ElabTL.getNamedTypeLoc()
              .castAs<TemplateSpecializationTypeLoc>();
          TL.copy(NamedTL);
        } else {
          TL.copy(OldTL.castAs<TemplateSpecializationTypeLoc>());
          assert(TL.getRAngleLoc() == OldTL.castAs<TemplateSpecializationTypeLoc>().getRAngleLoc());
        }
  
      }
      void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
        assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr);
        TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
        TL.setParensRange(DS.getTypeofParensRange());
      }
      void VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
        assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType);
        TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
        TL.setParensRange(DS.getTypeofParensRange());
        assert(DS.getRepAsType());
        TypeSourceInfo *TInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
        TL.setUnderlyingTInfo(TInfo);
      }
      void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
        // FIXME: This holds only because we only have one unary transform.
        assert(DS.getTypeSpecType() == DeclSpec::TST_underlyingType);
        TL.setKWLoc(DS.getTypeSpecTypeLoc());
        TL.setParensRange(DS.getTypeofParensRange());
        assert(DS.getRepAsType());
        TypeSourceInfo *TInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
        TL.setUnderlyingTInfo(TInfo);
      }
      void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
        // By default, use the source location of the type specifier.
        TL.setBuiltinLoc(DS.getTypeSpecTypeLoc());
        if (TL.needsExtraLocalData()) {
          // Set info for the written builtin specifiers.
          TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs();
          // Try to have a meaningful source location.
          if (TL.getWrittenSignSpec() != TypeSpecifierSign::Unspecified)
            TL.expandBuiltinRange(DS.getTypeSpecSignLoc());
          if (TL.getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified)
            TL.expandBuiltinRange(DS.getTypeSpecWidthRange());
        }
      }
      void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
        ElaboratedTypeKeyword Keyword
          = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
        if (DS.getTypeSpecType() == TST_typename) {
          TypeSourceInfo *TInfo = nullptr;
          Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
          if (TInfo) {
            TL.copy(TInfo->getTypeLoc().castAs<ElaboratedTypeLoc>());
            return;
          }
        }
        TL.setElaboratedKeywordLoc(Keyword != ETK_None
                                   ? DS.getTypeSpecTypeLoc()
                                   : SourceLocation());
        const CXXScopeSpec& SS = DS.getTypeSpecScope();
        TL.setQualifierLoc(SS.getWithLocInContext(Context));
        Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
      }
      void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
        assert(DS.getTypeSpecType() == TST_typename);
        TypeSourceInfo *TInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
        assert(TInfo);
        TL.copy(TInfo->getTypeLoc().castAs<DependentNameTypeLoc>());
      }
      void VisitDependentTemplateSpecializationTypeLoc(
                                   DependentTemplateSpecializationTypeLoc TL) {
        assert(DS.getTypeSpecType() == TST_typename);
        TypeSourceInfo *TInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
        assert(TInfo);
        TL.copy(
            TInfo->getTypeLoc().castAs<DependentTemplateSpecializationTypeLoc>());
      }
      void VisitAutoTypeLoc(AutoTypeLoc TL) {
        assert(DS.getTypeSpecType() == TST_auto ||
               DS.getTypeSpecType() == TST_decltype_auto ||
               DS.getTypeSpecType() == TST_auto_type ||
               DS.getTypeSpecType() == TST_unspecified);
        TL.setNameLoc(DS.getTypeSpecTypeLoc());
        if (!DS.isConstrainedAuto())
          return;
        TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();
        if (!TemplateId)
          return;
        if (DS.getTypeSpecScope().isNotEmpty())
          TL.setNestedNameSpecifierLoc(
              DS.getTypeSpecScope().getWithLocInContext(Context));
        else
          TL.setNestedNameSpecifierLoc(NestedNameSpecifierLoc());
        TL.setTemplateKWLoc(TemplateId->TemplateKWLoc);
        TL.setConceptNameLoc(TemplateId->TemplateNameLoc);
        TL.setFoundDecl(nullptr);
        TL.setLAngleLoc(TemplateId->LAngleLoc);
        TL.setRAngleLoc(TemplateId->RAngleLoc);
        if (TemplateId->NumArgs == 0)
          return;
        TemplateArgumentListInfo TemplateArgsInfo;
        ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
                                           TemplateId->NumArgs);
        SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
        for (unsigned I = 0; I < TemplateId->NumArgs; ++I)
          TL.setArgLocInfo(I, TemplateArgsInfo.arguments()[I].getLocInfo());
      }
      void VisitTagTypeLoc(TagTypeLoc TL) {
        TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
      }
      void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
        // An AtomicTypeLoc can come from either an _Atomic(...) type specifier
        // or an _Atomic qualifier.
        if (DS.getTypeSpecType() == DeclSpec::TST_atomic) {
          TL.setKWLoc(DS.getTypeSpecTypeLoc());
          TL.setParensRange(DS.getTypeofParensRange());
  
          TypeSourceInfo *TInfo = nullptr;
          Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
          assert(TInfo);
          TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc());
        } else {
          TL.setKWLoc(DS.getAtomicSpecLoc());
          // No parens, to indicate this was spelled as an _Atomic qualifier.
          TL.setParensRange(SourceRange());
          Visit(TL.getValueLoc());
        }
      }
  
      void VisitPipeTypeLoc(PipeTypeLoc TL) {
        TL.setKWLoc(DS.getTypeSpecTypeLoc());
  
        TypeSourceInfo *TInfo = nullptr;
        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
        TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc());
      }
  
      void VisitExtIntTypeLoc(ExtIntTypeLoc TL) {
        TL.setNameLoc(DS.getTypeSpecTypeLoc());
      }
  
      void VisitDependentExtIntTypeLoc(DependentExtIntTypeLoc TL) {
        TL.setNameLoc(DS.getTypeSpecTypeLoc());
      }
  
      void VisitTypeLoc(TypeLoc TL) {
        // FIXME: add other typespec types and change this to an assert.
        TL.initialize(Context, DS.getTypeSpecTypeLoc());
      }
    };
  
    class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
      ASTContext &Context;
      TypeProcessingState &State;
      const DeclaratorChunk &Chunk;
  
    public:
      DeclaratorLocFiller(ASTContext &Context, TypeProcessingState &State,
                          const DeclaratorChunk &Chunk)
          : Context(Context), State(State), Chunk(Chunk) {}
  
      void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
        llvm_unreachable("qualified type locs not expected here!");
      }
      void VisitDecayedTypeLoc(DecayedTypeLoc TL) {
        llvm_unreachable("decayed type locs not expected here!");
      }
  
      void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
        fillAttributedTypeLoc(TL, State);
      }
      void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
        // nothing
      }
      void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::BlockPointer);
        TL.setCaretLoc(Chunk.Loc);
      }
      void VisitPointerTypeLoc(PointerTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Pointer);
        TL.setStarLoc(Chunk.Loc);
      }
      void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Pointer);
        TL.setStarLoc(Chunk.Loc);
      }
      void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::MemberPointer);
        const CXXScopeSpec& SS = Chunk.Mem.Scope();
        NestedNameSpecifierLoc NNSLoc = SS.getWithLocInContext(Context);
  
        const Type* ClsTy = TL.getClass();
        QualType ClsQT = QualType(ClsTy, 0);
        TypeSourceInfo *ClsTInfo = Context.CreateTypeSourceInfo(ClsQT, 0);
        // Now copy source location info into the type loc component.
        TypeLoc ClsTL = ClsTInfo->getTypeLoc();
        switch (NNSLoc.getNestedNameSpecifier()->getKind()) {
        case NestedNameSpecifier::Identifier:
          assert(isa<DependentNameType>(ClsTy) && "Unexpected TypeLoc");
          {
            DependentNameTypeLoc DNTLoc = ClsTL.castAs<DependentNameTypeLoc>();
            DNTLoc.setElaboratedKeywordLoc(SourceLocation());
            DNTLoc.setQualifierLoc(NNSLoc.getPrefix());
            DNTLoc.setNameLoc(NNSLoc.getLocalBeginLoc());
          }
          break;
  
        case NestedNameSpecifier::TypeSpec:
        case NestedNameSpecifier::TypeSpecWithTemplate:
          if (isa<ElaboratedType>(ClsTy)) {
            ElaboratedTypeLoc ETLoc = ClsTL.castAs<ElaboratedTypeLoc>();
            ETLoc.setElaboratedKeywordLoc(SourceLocation());
            ETLoc.setQualifierLoc(NNSLoc.getPrefix());
            TypeLoc NamedTL = ETLoc.getNamedTypeLoc();
            NamedTL.initializeFullCopy(NNSLoc.getTypeLoc());
          } else {
            ClsTL.initializeFullCopy(NNSLoc.getTypeLoc());
          }
          break;
  
        case NestedNameSpecifier::Namespace:
        case NestedNameSpecifier::NamespaceAlias:
        case NestedNameSpecifier::Global:
        case NestedNameSpecifier::Super:
          llvm_unreachable("Nested-name-specifier must name a type");
        }
  
        // Finally fill in MemberPointerLocInfo fields.
        TL.setStarLoc(Chunk.Mem.StarLoc);
        TL.setClassTInfo(ClsTInfo);
      }
      void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Reference);
        // 'Amp' is misleading: this might have been originally
        /// spelled with AmpAmp.
        TL.setAmpLoc(Chunk.Loc);
      }
      void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Reference);
        assert(!Chunk.Ref.LValueRef);
        TL.setAmpAmpLoc(Chunk.Loc);
      }
      void VisitArrayTypeLoc(ArrayTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Array);
        TL.setLBracketLoc(Chunk.Loc);
        TL.setRBracketLoc(Chunk.EndLoc);
        TL.setSizeExpr(static_cast<Expr*>(Chunk.Arr.NumElts));
      }
      void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Function);
        TL.setLocalRangeBegin(Chunk.Loc);
        TL.setLocalRangeEnd(Chunk.EndLoc);
  
        const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
        TL.setLParenLoc(FTI.getLParenLoc());
        TL.setRParenLoc(FTI.getRParenLoc());
        for (unsigned i = 0, e = TL.getNumParams(), tpi = 0; i != e; ++i) {
          ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
          TL.setParam(tpi++, Param);
        }
        TL.setExceptionSpecRange(FTI.getExceptionSpecRange());
      }
      void VisitParenTypeLoc(ParenTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Paren);
        TL.setLParenLoc(Chunk.Loc);
        TL.setRParenLoc(Chunk.EndLoc);
      }
      void VisitPipeTypeLoc(PipeTypeLoc TL) {
        assert(Chunk.Kind == DeclaratorChunk::Pipe);
        TL.setKWLoc(Chunk.Loc);
      }
      void VisitExtIntTypeLoc(ExtIntTypeLoc TL) {
        TL.setNameLoc(Chunk.Loc);
      }
      void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
        TL.setExpansionLoc(Chunk.Loc);
      }
      void VisitVectorTypeLoc(VectorTypeLoc TL) { TL.setNameLoc(Chunk.Loc); }
      void VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
        TL.setNameLoc(Chunk.Loc);
      }
      void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
        TL.setNameLoc(Chunk.Loc);
      }
      void
      VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
        TL.setNameLoc(Chunk.Loc);
      }
  
      void VisitTypeLoc(TypeLoc TL) {
        llvm_unreachable("unsupported TypeLoc kind in declarator!");
      }
    };
  } // end anonymous namespace
  
  static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) {
    SourceLocation Loc;
    switch (Chunk.Kind) {
    case DeclaratorChunk::Function:
    case DeclaratorChunk::Array:
    case DeclaratorChunk::Paren:
    case DeclaratorChunk::Pipe:
      llvm_unreachable("cannot be _Atomic qualified");
  
    case DeclaratorChunk::Pointer:
      Loc = Chunk.Ptr.AtomicQualLoc;
      break;
  
    case DeclaratorChunk::BlockPointer:
    case DeclaratorChunk::Reference:
    case DeclaratorChunk::MemberPointer:
      // FIXME: Provide a source location for the _Atomic keyword.
      break;
    }
  
    ATL.setKWLoc(Loc);
    ATL.setParensRange(SourceRange());
  }
  
  static void
  fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
                                   const ParsedAttributesView &Attrs) {
    for (const ParsedAttr &AL : Attrs) {
      if (AL.getKind() == ParsedAttr::AT_AddressSpace) {
        DASTL.setAttrNameLoc(AL.getLoc());
        DASTL.setAttrExprOperand(AL.getArgAsExpr(0));
        DASTL.setAttrOperandParensRange(SourceRange());
        return;
      }
    }
  
    llvm_unreachable(
        "no address_space attribute found at the expected location!");
  }
  
  static void fillMatrixTypeLoc(MatrixTypeLoc MTL,
                                const ParsedAttributesView &Attrs) {
    for (const ParsedAttr &AL : Attrs) {
      if (AL.getKind() == ParsedAttr::AT_MatrixType) {
        MTL.setAttrNameLoc(AL.getLoc());
        MTL.setAttrRowOperand(AL.getArgAsExpr(0));
        MTL.setAttrColumnOperand(AL.getArgAsExpr(1));
        MTL.setAttrOperandParensRange(SourceRange());
        return;
      }
    }
  
    llvm_unreachable("no matrix_type attribute found at the expected location!");
  }
  
  /// Create and instantiate a TypeSourceInfo with type source information.
  ///
  /// \param T QualType referring to the type as written in source code.
  ///
  /// \param ReturnTypeInfo For declarators whose return type does not show
  /// up in the normal place in the declaration specifiers (such as a C++
  /// conversion function), this pointer will refer to a type source information
  /// for that return type.
  static TypeSourceInfo *
  GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
                                 QualType T, TypeSourceInfo *ReturnTypeInfo) {
    Sema &S = State.getSema();
    Declarator &D = State.getDeclarator();
  
    TypeSourceInfo *TInfo = S.Context.CreateTypeSourceInfo(T);
    UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();
  
    // Handle parameter packs whose type is a pack expansion.
    if (isa<PackExpansionType>(T)) {
      CurrTL.castAs<PackExpansionTypeLoc>().setEllipsisLoc(D.getEllipsisLoc());
      CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
    }
  
    for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
      // An AtomicTypeLoc might be produced by an atomic qualifier in this
      // declarator chunk.
      if (AtomicTypeLoc ATL = CurrTL.getAs<AtomicTypeLoc>()) {
        fillAtomicQualLoc(ATL, D.getTypeObject(i));
        CurrTL = ATL.getValueLoc().getUnqualifiedLoc();
      }
  
      while (MacroQualifiedTypeLoc TL = CurrTL.getAs<MacroQualifiedTypeLoc>()) {
        TL.setExpansionLoc(
            State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
        CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
      }
  
      while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
        fillAttributedTypeLoc(TL, State);
        CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
      }
  
      while (DependentAddressSpaceTypeLoc TL =
                 CurrTL.getAs<DependentAddressSpaceTypeLoc>()) {
        fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());
        CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
      }
  
      if (MatrixTypeLoc TL = CurrTL.getAs<MatrixTypeLoc>())
        fillMatrixTypeLoc(TL, D.getTypeObject(i).getAttrs());
  
      // FIXME: Ordering here?
      while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())
        CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
  
      DeclaratorLocFiller(S.Context, State, D.getTypeObject(i)).Visit(CurrTL);
      CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
    }
  
    // If we have different source information for the return type, use
    // that.  This really only applies to C++ conversion functions.
    if (ReturnTypeInfo) {
      TypeLoc TL = ReturnTypeInfo->getTypeLoc();
      assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
      memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
    } else {
      TypeSpecLocFiller(S, S.Context, State, D.getDeclSpec()).Visit(CurrTL);
    }
  
    return TInfo;
  }
  
  /// Create a LocInfoType to hold the given QualType and TypeSourceInfo.
  ParsedType Sema::CreateParsedType(QualType T, TypeSourceInfo *TInfo) {
    // FIXME: LocInfoTypes are "transient", only needed for passing to/from Parser
    // and Sema during declaration parsing. Try deallocating/caching them when
    // it's appropriate, instead of allocating them and keeping them around.
    LocInfoType *LocT = (LocInfoType*)BumpAlloc.Allocate(sizeof(LocInfoType),
                                                         TypeAlignment);
    new (LocT) LocInfoType(T, TInfo);
    assert(LocT->getTypeClass() != T->getTypeClass() &&
           "LocInfoType's TypeClass conflicts with an existing Type class");
    return ParsedType::make(QualType(LocT, 0));
  }
  
  void LocInfoType::getAsStringInternal(std::string &Str,
                                        const PrintingPolicy &Policy) const {
    llvm_unreachable("LocInfoType leaked into the type system; an opaque TypeTy*"
           " was used directly instead of getting the QualType through"
           " GetTypeFromParser");
  }
  
  TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
    // C99 6.7.6: Type names have no identifier.  This is already validated by
    // the parser.
    assert(D.getIdentifier() == nullptr &&
           "Type name should have no identifier!");
  
    TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
    QualType T = TInfo->getType();
    if (D.isInvalidType())
      return true;
  
    // Make sure there are no unused decl attributes on the declarator.
    // We don't want to do this for ObjC parameters because we're going
    // to apply them to the actual parameter declaration.
    // Likewise, we don't want to do this for alias declarations, because
    // we are actually going to build a declaration from this eventually.
    if (D.getContext() != DeclaratorContext::ObjCParameter &&
        D.getContext() != DeclaratorContext::AliasDecl &&
        D.getContext() != DeclaratorContext::AliasTemplate)
      checkUnusedDeclAttributes(D);
  
    if (getLangOpts().CPlusPlus) {
      // Check that there are no default arguments (C++ only).
      CheckExtraCXXDefaultArguments(D);
    }
  
    return CreateParsedType(T, TInfo);
  }
  
  ParsedType Sema::ActOnObjCInstanceType(SourceLocation Loc) {
    QualType T = Context.getObjCInstanceType();
    TypeSourceInfo *TInfo = Context.getTrivialTypeSourceInfo(T, Loc);
    return CreateParsedType(T, TInfo);
  }
  
  //===----------------------------------------------------------------------===//
  // Type Attribute Processing
  //===----------------------------------------------------------------------===//
  
  /// Build an AddressSpace index from a constant expression and diagnose any
  /// errors related to invalid address_spaces. Returns true on successfully
  /// building an AddressSpace index.
  static bool BuildAddressSpaceIndex(Sema &S, LangAS &ASIdx,
                                     const Expr *AddrSpace,
                                     SourceLocation AttrLoc) {
    if (!AddrSpace->isValueDependent()) {
      Optional<llvm::APSInt> OptAddrSpace =
          AddrSpace->getIntegerConstantExpr(S.Context);
      if (!OptAddrSpace) {
        S.Diag(AttrLoc, diag::err_attribute_argument_type)
            << "'address_space'" << AANT_ArgumentIntegerConstant
            << AddrSpace->getSourceRange();
        return false;
      }
      llvm::APSInt &addrSpace = *OptAddrSpace;
  
      // Bounds checking.
      if (addrSpace.isSigned()) {
        if (addrSpace.isNegative()) {
          S.Diag(AttrLoc, diag::err_attribute_address_space_negative)
              << AddrSpace->getSourceRange();
          return false;
        }
        addrSpace.setIsSigned(false);
      }
  
      llvm::APSInt max(addrSpace.getBitWidth());
      max =
          Qualifiers::MaxAddressSpace - (unsigned)LangAS::FirstTargetAddressSpace;
      if (addrSpace > max) {
        S.Diag(AttrLoc, diag::err_attribute_address_space_too_high)
            << (unsigned)max.getZExtValue() << AddrSpace->getSourceRange();
        return false;
      }
  
      ASIdx =
          getLangASFromTargetAS(static_cast<unsigned>(addrSpace.getZExtValue()));
      return true;
    }
  
    // Default value for DependentAddressSpaceTypes
    ASIdx = LangAS::Default;
    return true;
  }
  
  /// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
  /// is uninstantiated. If instantiated it will apply the appropriate address
  /// space to the type. This function allows dependent template variables to be
  /// used in conjunction with the address_space attribute
  QualType Sema::BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
                                       SourceLocation AttrLoc) {
    if (!AddrSpace->isValueDependent()) {
      if (DiagnoseMultipleAddrSpaceAttributes(*this, T.getAddressSpace(), ASIdx,
                                              AttrLoc))
        return QualType();
  
      return Context.getAddrSpaceQualType(T, ASIdx);
    }
  
    // A check with similar intentions as checking if a type already has an
    // address space except for on a dependent types, basically if the
    // current type is already a DependentAddressSpaceType then its already
    // lined up to have another address space on it and we can't have
    // multiple address spaces on the one pointer indirection
    if (T->getAs<DependentAddressSpaceType>()) {
      Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
      return QualType();
    }
  
    return Context.getDependentAddressSpaceType(T, AddrSpace, AttrLoc);
  }
  
  QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
                                       SourceLocation AttrLoc) {
    LangAS ASIdx;
    if (!BuildAddressSpaceIndex(*this, ASIdx, AddrSpace, AttrLoc))
      return QualType();
    return BuildAddressSpaceAttr(T, ASIdx, AddrSpace, AttrLoc);
  }
  
  /// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
  /// specified type.  The attribute contains 1 argument, the id of the address
  /// space for the type.
  static void HandleAddressSpaceTypeAttribute(QualType &Type,
                                              const ParsedAttr &Attr,
                                              TypeProcessingState &State) {
    Sema &S = State.getSema();
  
    // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "A function type shall not be
    // qualified by an address-space qualifier."
    if (Type->isFunctionType()) {
      S.Diag(Attr.getLoc(), diag::err_attribute_address_function_type);
      Attr.setInvalid();
      return;
    }
  
    LangAS ASIdx;
    if (Attr.getKind() == ParsedAttr::AT_AddressSpace) {
  
      // Check the attribute arguments.
      if (Attr.getNumArgs() != 1) {
        S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
                                                                          << 1;
        Attr.setInvalid();
        return;
      }
  
      Expr *ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
      LangAS ASIdx;
      if (!BuildAddressSpaceIndex(S, ASIdx, ASArgExpr, Attr.getLoc())) {
        Attr.setInvalid();
        return;
      }
  
      ASTContext &Ctx = S.Context;
      auto *ASAttr =
          ::new (Ctx) AddressSpaceAttr(Ctx, Attr, static_cast<unsigned>(ASIdx));
  
      // If the expression is not value dependent (not templated), then we can
      // apply the address space qualifiers just to the equivalent type.
      // Otherwise, we make an AttributedType with the modified and equivalent
      // type the same, and wrap it in a DependentAddressSpaceType. When this
      // dependent type is resolved, the qualifier is added to the equivalent type
      // later.
      QualType T;
      if (!ASArgExpr->isValueDependent()) {
        QualType EquivType =
            S.BuildAddressSpaceAttr(Type, ASIdx, ASArgExpr, Attr.getLoc());
        if (EquivType.isNull()) {
          Attr.setInvalid();
          return;
        }
        T = State.getAttributedType(ASAttr, Type, EquivType);
      } else {
        T = State.getAttributedType(ASAttr, Type, Type);
        T = S.BuildAddressSpaceAttr(T, ASIdx, ASArgExpr, Attr.getLoc());
      }
  
      if (!T.isNull())
        Type = T;
      else
        Attr.setInvalid();
    } else {
      // The keyword-based type attributes imply which address space to use.
      ASIdx = Attr.asOpenCLLangAS();
      if (ASIdx == LangAS::Default)
        llvm_unreachable("Invalid address space");
  
      if (DiagnoseMultipleAddrSpaceAttributes(S, Type.getAddressSpace(), ASIdx,
                                              Attr.getLoc())) {
        Attr.setInvalid();
        return;
      }
  
      Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
    }
  }
  
  static void HandleSYCLFPGAPipeAttribute(QualType &Type, const ParsedAttr &Attr,
                                          TypeProcessingState &State) {
    Sema &S = State.getSema();
    ASTContext &Ctx = S.Context;
  
    // Check the attribute arguments.
    if (Attr.getNumArgs() != 1) {
      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
          << Attr << 1;
      Attr.setInvalid();
      return;
    }
  
    if (!Attr.isArgExpr(0)) {
      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
          << Attr << AANT_ArgumentString;
      Attr.setInvalid();
      return;
    }
  
    StringRef Str;
    if (auto *SL = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0))) {
      Str = SL->getString();
    } else {
      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
          << Attr << AANT_ArgumentString;
      Attr.setInvalid();
      return;
    }
  
    bool isReadOnlyPipe;
    if (Str == "write_only")
      isReadOnlyPipe = false;
    else if (Str == "read_only")
      isReadOnlyPipe = true;
    else {
      S.Diag(Attr.getLoc(), diag::err_pipe_attribute_arg_not_allowed) << Str;
      Attr.setInvalid();
      return;
    }
  
    auto *PipeAttr = ::new (Ctx) SYCLFPGAPipeAttr(Ctx, Attr, Str);
  
    // Apply pipe qualifiers just to the equivalent type, as the expression is not
    // value dependent (not templated).
    QualType EquivType = isReadOnlyPipe
                             ? S.BuildReadPipeType(Type, Attr.getLoc())
                             : S.BuildWritePipeType(Type, Attr.getLoc());
    if (EquivType.isNull()) {
      Attr.setInvalid();
      return;
    }
  
    QualType T = State.getAttributedType(PipeAttr, Type, EquivType);
    if (!T.isNull())
      Type = T;
    else
      Attr.setInvalid();
  }
  
  /// handleObjCOwnershipTypeAttr - Process an objc_ownership
  /// attribute on the specified type.
  ///
  /// Returns 'true' if the attribute was handled.
  static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
                                          ParsedAttr &attr, QualType &type) {
    bool NonObjCPointer = false;
  
    if (!type->isDependentType() && !type->isUndeducedType()) {
      if (const PointerType *ptr = type->getAs<PointerType>()) {
        QualType pointee = ptr->getPointeeType();
        if (pointee->isObjCRetainableType() || pointee->isPointerType())
          return false;
        // It is important not to lose the source info that there was an attribute
        // applied to non-objc pointer. We will create an attributed type but
        // its type will be the same as the original type.
        NonObjCPointer = true;
      } else if (!type->isObjCRetainableType()) {
        return false;
      }
  
      // Don't accept an ownership attribute in the declspec if it would
      // just be the return type of a block pointer.
      if (state.isProcessingDeclSpec()) {
        Declarator &D = state.getDeclarator();
        if (maybeMovePastReturnType(D, D.getNumTypeObjects(),
                                    /*onlyBlockPointers=*/true))
          return false;
      }
    }
  
    Sema &S = state.getSema();
    SourceLocation AttrLoc = attr.getLoc();
    if (AttrLoc.isMacroID())
      AttrLoc =
          S.getSourceManager().getImmediateExpansionRange(AttrLoc).getBegin();
  
    if (!attr.isArgIdent(0)) {
      S.Diag(AttrLoc, diag::err_attribute_argument_type) << attr
                                                         << AANT_ArgumentString;
      attr.setInvalid();
      return true;
    }
  
    IdentifierInfo *II = attr.getArgAsIdent(0)->Ident;
    Qualifiers::ObjCLifetime lifetime;
    if (II->isStr("none"))
      lifetime = Qualifiers::OCL_ExplicitNone;
    else if (II->isStr("strong"))
      lifetime = Qualifiers::OCL_Strong;
    else if (II->isStr("weak"))
      lifetime = Qualifiers::OCL_Weak;
    else if (II->isStr("autoreleasing"))
      lifetime = Qualifiers::OCL_Autoreleasing;
    else {
      S.Diag(AttrLoc, diag::warn_attribute_type_not_supported) << attr << II;
      attr.setInvalid();
      return true;
    }
  
    // Just ignore lifetime attributes other than __weak and __unsafe_unretained
    // outside of ARC mode.
    if (!S.getLangOpts().ObjCAutoRefCount &&
        lifetime != Qualifiers::OCL_Weak &&
        lifetime != Qualifiers::OCL_ExplicitNone) {
      return true;
    }
  
    SplitQualType underlyingType = type.split();
  
    // Check for redundant/conflicting ownership qualifiers.
    if (Qualifiers::ObjCLifetime previousLifetime
          = type.getQualifiers().getObjCLifetime()) {
      // If it's written directly, that's an error.
      if (S.Context.hasDirectOwnershipQualifier(type)) {
        S.Diag(AttrLoc, diag::err_attr_objc_ownership_redundant)
          << type;
        return true;
      }
  
      // Otherwise, if the qualifiers actually conflict, pull sugar off
      // and remove the ObjCLifetime qualifiers.
      if (previousLifetime != lifetime) {
        // It's possible to have multiple local ObjCLifetime qualifiers. We
        // can't stop after we reach a type that is directly qualified.
        const Type *prevTy = nullptr;
        while (!prevTy || prevTy != underlyingType.Ty) {
          prevTy = underlyingType.Ty;
          underlyingType = underlyingType.getSingleStepDesugaredType();
        }
        underlyingType.Quals.removeObjCLifetime();
      }
    }
  
    underlyingType.Quals.addObjCLifetime(lifetime);
  
    if (NonObjCPointer) {
      StringRef name = attr.getAttrName()->getName();
      switch (lifetime) {
      case Qualifiers::OCL_None:
      case Qualifiers::OCL_ExplicitNone:
        break;
      case Qualifiers::OCL_Strong: name = "__strong"; break;
      case Qualifiers::OCL_Weak: name = "__weak"; break;
      case Qualifiers::OCL_Autoreleasing: name = "__autoreleasing"; break;
      }
      S.Diag(AttrLoc, diag::warn_type_attribute_wrong_type) << name
        << TDS_ObjCObjOrBlock << type;
    }
  
    // Don't actually add the __unsafe_unretained qualifier in non-ARC files,
    // because having both 'T' and '__unsafe_unretained T' exist in the type
    // system causes unfortunate widespread consistency problems.  (For example,
    // they're not considered compatible types, and we mangle them identicially
    // as template arguments.)  These problems are all individually fixable,
    // but it's easier to just not add the qualifier and instead sniff it out
    // in specific places using isObjCInertUnsafeUnretainedType().
    //
    // Doing this does means we miss some trivial consistency checks that
    // would've triggered in ARC, but that's better than trying to solve all
    // the coexistence problems with __unsafe_unretained.
    if (!S.getLangOpts().ObjCAutoRefCount &&
        lifetime == Qualifiers::OCL_ExplicitNone) {
      type = state.getAttributedType(
          createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr),
          type, type);
      return true;
    }
  
    QualType origType = type;
    if (!NonObjCPointer)
      type = S.Context.getQualifiedType(underlyingType);
  
    // If we have a valid source location for the attribute, use an
    // AttributedType instead.
    if (AttrLoc.isValid()) {
      type = state.getAttributedType(::new (S.Context)
                                         ObjCOwnershipAttr(S.Context, attr, II),
                                     origType, type);
    }
  
    auto diagnoseOrDelay = [](Sema &S, SourceLocation loc,
                              unsigned diagnostic, QualType type) {
      if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
        S.DelayedDiagnostics.add(
            sema::DelayedDiagnostic::makeForbiddenType(
                S.getSourceManager().getExpansionLoc(loc),
                diagnostic, type, /*ignored*/ 0));
      } else {
        S.Diag(loc, diagnostic);
      }
    };
  
    // Sometimes, __weak isn't allowed.
    if (lifetime == Qualifiers::OCL_Weak &&
        !S.getLangOpts().ObjCWeak && !NonObjCPointer) {
  
      // Use a specialized diagnostic if the runtime just doesn't support them.
      unsigned diagnostic =
        (S.getLangOpts().ObjCWeakRuntime ? diag::err_arc_weak_disabled
                                         : diag::err_arc_weak_no_runtime);
  
      // In any case, delay the diagnostic until we know what we're parsing.
      diagnoseOrDelay(S, AttrLoc, diagnostic, type);
  
      attr.setInvalid();
      return true;
    }
  
    // Forbid __weak for class objects marked as
    // objc_arc_weak_reference_unavailable
    if (lifetime == Qualifiers::OCL_Weak) {
      if (const ObjCObjectPointerType *ObjT =
            type->getAs<ObjCObjectPointerType>()) {
        if (ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl()) {
          if (Class->isArcWeakrefUnavailable()) {
            S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class);
            S.Diag(ObjT->getInterfaceDecl()->getLocation(),
                   diag::note_class_declared);
          }
        }
      }
    }
  
    return true;
  }
  
  /// handleObjCGCTypeAttr - Process the __attribute__((objc_gc)) type
  /// attribute on the specified type.  Returns true to indicate that
  /// the attribute was handled, false to indicate that the type does
  /// not permit the attribute.
  static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
                                   QualType &type) {
    Sema &S = state.getSema();
  
    // Delay if this isn't some kind of pointer.
    if (!type->isPointerType() &&
        !type->isObjCObjectPointerType() &&
        !type->isBlockPointerType())
      return false;
  
    if (type.getObjCGCAttr() != Qualifiers::GCNone) {
      S.Diag(attr.getLoc(), diag::err_attribute_multiple_objc_gc);
      attr.setInvalid();
      return true;
    }
  
    // Check the attribute arguments.
    if (!attr.isArgIdent(0)) {
      S.Diag(attr.getLoc(), diag::err_attribute_argument_type)
          << attr << AANT_ArgumentString;
      attr.setInvalid();
      return true;
    }
    Qualifiers::GC GCAttr;
    if (attr.getNumArgs() > 1) {
      S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << attr
                                                                        << 1;
      attr.setInvalid();
      return true;
    }
  
    IdentifierInfo *II = attr.getArgAsIdent(0)->Ident;
    if (II->isStr("weak"))
      GCAttr = Qualifiers::Weak;
    else if (II->isStr("strong"))
      GCAttr = Qualifiers::Strong;
    else {
      S.Diag(attr.getLoc(), diag::warn_attribute_type_not_supported)
          << attr << II;
      attr.setInvalid();
      return true;
    }
  
    QualType origType = type;
    type = S.Context.getObjCGCQualType(origType, GCAttr);
  
    // Make an attributed type to preserve the source information.
    if (attr.getLoc().isValid())
      type = state.getAttributedType(
          ::new (S.Context) ObjCGCAttr(S.Context, attr, II), origType, type);
  
    return true;
  }
  
  namespace {
    /// A helper class to unwrap a type down to a function for the
    /// purposes of applying attributes there.
    ///
    /// Use:
    ///   FunctionTypeUnwrapper unwrapped(SemaRef, T);
    ///   if (unwrapped.isFunctionType()) {
    ///     const FunctionType *fn = unwrapped.get();
    ///     // change fn somehow
    ///     T = unwrapped.wrap(fn);
    ///   }
    struct FunctionTypeUnwrapper {
      enum WrapKind {
        Desugar,
        Attributed,
        Parens,
        Array,
        Pointer,
        BlockPointer,
        Reference,
        MemberPointer,
        MacroQualified,
      };
  
      QualType Original;
      const FunctionType *Fn;
      SmallVector<unsigned char /*WrapKind*/, 8> Stack;
  
      FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) {
        while (true) {
          const Type *Ty = T.getTypePtr();
          if (isa<FunctionType>(Ty)) {
            Fn = cast<FunctionType>(Ty);
            return;
          } else if (isa<ParenType>(Ty)) {
            T = cast<ParenType>(Ty)->getInnerType();
            Stack.push_back(Parens);
          } else if (isa<ConstantArrayType>(Ty) || isa<VariableArrayType>(Ty) ||
                     isa<IncompleteArrayType>(Ty)) {
            T = cast<ArrayType>(Ty)->getElementType();
            Stack.push_back(Array);
          } else if (isa<PointerType>(Ty)) {
            T = cast<PointerType>(Ty)->getPointeeType();
            Stack.push_back(Pointer);
          } else if (isa<BlockPointerType>(Ty)) {
            T = cast<BlockPointerType>(Ty)->getPointeeType();
            Stack.push_back(BlockPointer);
          } else if (isa<MemberPointerType>(Ty)) {
            T = cast<MemberPointerType>(Ty)->getPointeeType();
            Stack.push_back(MemberPointer);
          } else if (isa<ReferenceType>(Ty)) {
            T = cast<ReferenceType>(Ty)->getPointeeType();
            Stack.push_back(Reference);
          } else if (isa<AttributedType>(Ty)) {
            T = cast<AttributedType>(Ty)->getEquivalentType();
            Stack.push_back(Attributed);
          } else if (isa<MacroQualifiedType>(Ty)) {
            T = cast<MacroQualifiedType>(Ty)->getUnderlyingType();
            Stack.push_back(MacroQualified);
          } else {
            const Type *DTy = Ty->getUnqualifiedDesugaredType();
            if (Ty == DTy) {
              Fn = nullptr;
              return;
            }
  
            T = QualType(DTy, 0);
            Stack.push_back(Desugar);
          }
        }
      }
  
      bool isFunctionType() const { return (Fn != nullptr); }
      const FunctionType *get() const { return Fn; }
  
      QualType wrap(Sema &S, const FunctionType *New) {
        // If T wasn't modified from the unwrapped type, do nothing.
        if (New == get()) return Original;
  
        Fn = New;
        return wrap(S.Context, Original, 0);
      }
  
    private:
      QualType wrap(ASTContext &C, QualType Old, unsigned I) {
        if (I == Stack.size())
          return C.getQualifiedType(Fn, Old.getQualifiers());
  
        // Build up the inner type, applying the qualifiers from the old
        // type to the new type.
        SplitQualType SplitOld = Old.split();
  
        // As a special case, tail-recurse if there are no qualifiers.
        if (SplitOld.Quals.empty())
          return wrap(C, SplitOld.Ty, I);
        return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals);
      }
  
      QualType wrap(ASTContext &C, const Type *Old, unsigned I) {
        if (I == Stack.size()) return QualType(Fn, 0);
  
        switch (static_cast<WrapKind>(Stack[I++])) {
        case Desugar:
          // This is the point at which we potentially lose source
          // information.
          return wrap(C, Old->getUnqualifiedDesugaredType(), I);
  
        case Attributed:
          return wrap(C, cast<AttributedType>(Old)->getEquivalentType(), I);
  
        case Parens: {
          QualType New = wrap(C, cast<ParenType>(Old)->getInnerType(), I);
          return C.getParenType(New);
        }
  
        case MacroQualified:
          return wrap(C, cast<MacroQualifiedType>(Old)->getUnderlyingType(), I);
  
        case Array: {
          if (const auto *CAT = dyn_cast<ConstantArrayType>(Old)) {
            QualType New = wrap(C, CAT->getElementType(), I);
            return C.getConstantArrayType(New, CAT->getSize(), CAT->getSizeExpr(),
                                          CAT->getSizeModifier(),
                                          CAT->getIndexTypeCVRQualifiers());
          }
  
          if (const auto *VAT = dyn_cast<VariableArrayType>(Old)) {
            QualType New = wrap(C, VAT->getElementType(), I);
            return C.getVariableArrayType(
                New, VAT->getSizeExpr(), VAT->getSizeModifier(),
                VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
          }
  
          const auto *IAT = cast<IncompleteArrayType>(Old);
          QualType New = wrap(C, IAT->getElementType(), I);
          return C.getIncompleteArrayType(New, IAT->getSizeModifier(),
                                          IAT->getIndexTypeCVRQualifiers());
        }
  
        case Pointer: {
          QualType New = wrap(C, cast<PointerType>(Old)->getPointeeType(), I);
          return C.getPointerType(New);
        }
  
        case BlockPointer: {
          QualType New = wrap(C, cast<BlockPointerType>(Old)->getPointeeType(),I);
          return C.getBlockPointerType(New);
        }
  
        case MemberPointer: {
          const MemberPointerType *OldMPT = cast<MemberPointerType>(Old);
          QualType New = wrap(C, OldMPT->getPointeeType(), I);
          return C.getMemberPointerType(New, OldMPT->getClass());
        }
  
        case Reference: {
          const ReferenceType *OldRef = cast<ReferenceType>(Old);
          QualType New = wrap(C, OldRef->getPointeeType(), I);
          if (isa<LValueReferenceType>(OldRef))
            return C.getLValueReferenceType(New, OldRef->isSpelledAsLValue());
          else
            return C.getRValueReferenceType(New);
        }
        }
  
        llvm_unreachable("unknown wrapping kind");
      }
    };
  } // end anonymous namespace
  
  static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
                                               ParsedAttr &PAttr, QualType &Type) {
    Sema &S = State.getSema();
  
    Attr *A;
    switch (PAttr.getKind()) {
    default: llvm_unreachable("Unknown attribute kind");
    case ParsedAttr::AT_Ptr32:
      A = createSimpleAttr<Ptr32Attr>(S.Context, PAttr);
      break;
    case ParsedAttr::AT_Ptr64:
      A = createSimpleAttr<Ptr64Attr>(S.Context, PAttr);
      break;
    case ParsedAttr::AT_SPtr:
      A = createSimpleAttr<SPtrAttr>(S.Context, PAttr);
      break;
    case ParsedAttr::AT_UPtr:
      A = createSimpleAttr<UPtrAttr>(S.Context, PAttr);
      break;
    }
  
    std::bitset<attr::LastAttr> Attrs;
    attr::Kind NewAttrKind = A->getKind();
    QualType Desugared = Type;
    const AttributedType *AT = dyn_cast<AttributedType>(Type);
    while (AT) {
      Attrs[AT->getAttrKind()] = true;
      Desugared = AT->getModifiedType();
      AT = dyn_cast<AttributedType>(Desugared);
    }
  
    // You cannot specify duplicate type attributes, so if the attribute has
    // already been applied, flag it.
    if (Attrs[NewAttrKind]) {
      S.Diag(PAttr.getLoc(), diag::warn_duplicate_attribute_exact) << PAttr;
      return true;
    }
    Attrs[NewAttrKind] = true;
  
    // You cannot have both __sptr and __uptr on the same type, nor can you
    // have __ptr32 and __ptr64.
    if (Attrs[attr::Ptr32] && Attrs[attr::Ptr64]) {
      S.Diag(PAttr.getLoc(), diag::err_attributes_are_not_compatible)
          << "'__ptr32'"
          << "'__ptr64'";
      return true;
    } else if (Attrs[attr::SPtr] && Attrs[attr::UPtr]) {
      S.Diag(PAttr.getLoc(), diag::err_attributes_are_not_compatible)
          << "'__sptr'"
          << "'__uptr'";
      return true;
    }
  
    // Pointer type qualifiers can only operate on pointer types, but not
    // pointer-to-member types.
    //
    // FIXME: Should we really be disallowing this attribute if there is any
    // type sugar between it and the pointer (other than attributes)? Eg, this
    // disallows the attribute on a parenthesized pointer.
    // And if so, should we really allow *any* type attribute?
    if (!isa<PointerType>(Desugared)) {
      if (Type->isMemberPointerType())
        S.Diag(PAttr.getLoc(), diag::err_attribute_no_member_pointers) << PAttr;
      else
        S.Diag(PAttr.getLoc(), diag::err_attribute_pointers_only) << PAttr << 0;
      return true;
    }
  
    // Add address space to type based on its attributes.
    LangAS ASIdx = LangAS::Default;
    uint64_t PtrWidth = S.Context.getTargetInfo().getPointerWidth(0);
    if (PtrWidth == 32) {
      if (Attrs[attr::Ptr64])
        ASIdx = LangAS::ptr64;
      else if (Attrs[attr::UPtr])
        ASIdx = LangAS::ptr32_uptr;
    } else if (PtrWidth == 64 && Attrs[attr::Ptr32]) {
      if (Attrs[attr::UPtr])
        ASIdx = LangAS::ptr32_uptr;
      else
        ASIdx = LangAS::ptr32_sptr;
    }
  
    QualType Pointee = Type->getPointeeType();
    if (ASIdx != LangAS::Default)
      Pointee = S.Context.getAddrSpaceQualType(
          S.Context.removeAddrSpaceQualType(Pointee), ASIdx);
    Type = State.getAttributedType(A, Type, S.Context.getPointerType(Pointee));
    return false;
  }
  
  /// Map a nullability attribute kind to a nullability kind.
  static NullabilityKind mapNullabilityAttrKind(ParsedAttr::Kind kind) {
    switch (kind) {
    case ParsedAttr::AT_TypeNonNull:
      return NullabilityKind::NonNull;
  
    case ParsedAttr::AT_TypeNullable:
      return NullabilityKind::Nullable;
  
    case ParsedAttr::AT_TypeNullableResult:
      return NullabilityKind::NullableResult;
  
    case ParsedAttr::AT_TypeNullUnspecified:
      return NullabilityKind::Unspecified;
  
    default:
      llvm_unreachable("not a nullability attribute kind");
    }
  }
  
  /// Applies a nullability type specifier to the given type, if possible.
  ///
  /// \param state The type processing state.
  ///
  /// \param type The type to which the nullability specifier will be
  /// added. On success, this type will be updated appropriately.
  ///
  /// \param attr The attribute as written on the type.
  ///
  /// \param allowOnArrayType Whether to accept nullability specifiers on an
  /// array type (e.g., because it will decay to a pointer).
  ///
  /// \returns true if a problem has been diagnosed, false on success.
  static bool checkNullabilityTypeSpecifier(TypeProcessingState &state,
                                            QualType &type,
                                            ParsedAttr &attr,
                                            bool allowOnArrayType) {
    Sema &S = state.getSema();
  
    NullabilityKind nullability = mapNullabilityAttrKind(attr.getKind());
    SourceLocation nullabilityLoc = attr.getLoc();
    bool isContextSensitive = attr.isContextSensitiveKeywordAttribute();
  
    recordNullabilitySeen(S, nullabilityLoc);
  
    // Check for existing nullability attributes on the type.
    QualType desugared = type;
    while (auto attributed = dyn_cast<AttributedType>(desugared.getTypePtr())) {
      // Check whether there is already a null
      if (auto existingNullability = attributed->getImmediateNullability()) {
        // Duplicated nullability.
        if (nullability == *existingNullability) {
          S.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
            << DiagNullabilityKind(nullability, isContextSensitive)
            << FixItHint::CreateRemoval(nullabilityLoc);
  
          break;
        }
  
        // Conflicting nullability.
        S.Diag(nullabilityLoc, diag::err_nullability_conflicting)
          << DiagNullabilityKind(nullability, isContextSensitive)
          << DiagNullabilityKind(*existingNullability, false);
        return true;
      }
  
      desugared = attributed->getModifiedType();
    }
  
    // If there is already a different nullability specifier, complain.
    // This (unlike the code above) looks through typedefs that might
    // have nullability specifiers on them, which means we cannot
    // provide a useful Fix-It.
    if (auto existingNullability = desugared->getNullability(S.Context)) {
      if (nullability != *existingNullability) {
        S.Diag(nullabilityLoc, diag::err_nullability_conflicting)
          << DiagNullabilityKind(nullability, isContextSensitive)
          << DiagNullabilityKind(*existingNullability, false);
  
        // Try to find the typedef with the existing nullability specifier.
        if (auto typedefType = desugared->getAs<TypedefType>()) {
          TypedefNameDecl *typedefDecl = typedefType->getDecl();
          QualType underlyingType = typedefDecl->getUnderlyingType();
          if (auto typedefNullability
                = AttributedType::stripOuterNullability(underlyingType)) {
            if (*typedefNullability == *existingNullability) {
              S.Diag(typedefDecl->getLocation(), diag::note_nullability_here)
                << DiagNullabilityKind(*existingNullability, false);
            }
          }
        }
  
        return true;
      }
    }
  
    // If this definitely isn't a pointer type, reject the specifier.
    if (!desugared->canHaveNullability() &&
        !(allowOnArrayType && desugared->isArrayType())) {
      S.Diag(nullabilityLoc, diag::err_nullability_nonpointer)
        << DiagNullabilityKind(nullability, isContextSensitive) << type;
      return true;
    }
  
    // For the context-sensitive keywords/Objective-C property
    // attributes, require that the type be a single-level pointer.
    if (isContextSensitive) {
      // Make sure that the pointee isn't itself a pointer type.
      const Type *pointeeType = nullptr;
      if (desugared->isArrayType())
        pointeeType = desugared->getArrayElementTypeNoTypeQual();
      else if (desugared->isAnyPointerType())
        pointeeType = desugared->getPointeeType().getTypePtr();
  
      if (pointeeType && (pointeeType->isAnyPointerType() ||
                          pointeeType->isObjCObjectPointerType() ||
                          pointeeType->isMemberPointerType())) {
        S.Diag(nullabilityLoc, diag::err_nullability_cs_multilevel)
          << DiagNullabilityKind(nullability, true)
          << type;
        S.Diag(nullabilityLoc, diag::note_nullability_type_specifier)
          << DiagNullabilityKind(nullability, false)
          << type
          << FixItHint::CreateReplacement(nullabilityLoc,
                                          getNullabilitySpelling(nullability));
        return true;
      }
    }
  
    // Form the attributed type.
    type = state.getAttributedType(
        createNullabilityAttr(S.Context, attr, nullability), type, type);
    return false;
  }
  
  /// Check the application of the Objective-C '__kindof' qualifier to
  /// the given type.
  static bool checkObjCKindOfType(TypeProcessingState &state, QualType &type,
                                  ParsedAttr &attr) {
    Sema &S = state.getSema();
  
    if (isa<ObjCTypeParamType>(type)) {
      // Build the attributed type to record where __kindof occurred.
      type = state.getAttributedType(
          createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, type);
      return false;
    }
  
    // Find out if it's an Objective-C object or object pointer type;
    const ObjCObjectPointerType *ptrType = type->getAs<ObjCObjectPointerType>();
    const ObjCObjectType *objType = ptrType ? ptrType->getObjectType()
                                            : type->getAs<ObjCObjectType>();
  
    // If not, we can't apply __kindof.
    if (!objType) {
      // FIXME: Handle dependent types that aren't yet object types.
      S.Diag(attr.getLoc(), diag::err_objc_kindof_nonobject)
        << type;
      return true;
    }
  
    // Rebuild the "equivalent" type, which pushes __kindof down into
    // the object type.
    // There is no need to apply kindof on an unqualified id type.
    QualType equivType = S.Context.getObjCObjectType(
        objType->getBaseType(), objType->getTypeArgsAsWritten(),
        objType->getProtocols(),
        /*isKindOf=*/objType->isObjCUnqualifiedId() ? false : true);
  
    // If we started with an object pointer type, rebuild it.
    if (ptrType) {
      equivType = S.Context.getObjCObjectPointerType(equivType);
      if (auto nullability = type->getNullability(S.Context)) {
        // We create a nullability attribute from the __kindof attribute.
        // Make sure that will make sense.
        assert(attr.getAttributeSpellingListIndex() == 0 &&
               "multiple spellings for __kindof?");
        Attr *A = createNullabilityAttr(S.Context, attr, *nullability);
        A->setImplicit(true);
        equivType = state.getAttributedType(A, equivType, equivType);
      }
    }
  
    // Build the attributed type to record where __kindof occurred.
    type = state.getAttributedType(
        createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, equivType);
    return false;
  }
  
  /// Distribute a nullability type attribute that cannot be applied to
  /// the type specifier to a pointer, block pointer, or member pointer
  /// declarator, complaining if necessary.
  ///
  /// \returns true if the nullability annotation was distributed, false
  /// otherwise.
  static bool distributeNullabilityTypeAttr(TypeProcessingState &state,
                                            QualType type, ParsedAttr &attr) {
    Declarator &declarator = state.getDeclarator();
  
    /// Attempt to move the attribute to the specified chunk.
    auto moveToChunk = [&](DeclaratorChunk &chunk, bool inFunction) -> bool {
      // If there is already a nullability attribute there, don't add
      // one.
      if (hasNullabilityAttr(chunk.getAttrs()))
        return false;
  
      // Complain about the nullability qualifier being in the wrong
      // place.
      enum {
        PK_Pointer,
        PK_BlockPointer,
        PK_MemberPointer,
        PK_FunctionPointer,
        PK_MemberFunctionPointer,
      } pointerKind
        = chunk.Kind == DeclaratorChunk::Pointer ? (inFunction ? PK_FunctionPointer
                                                               : PK_Pointer)
          : chunk.Kind == DeclaratorChunk::BlockPointer ? PK_BlockPointer
          : inFunction? PK_MemberFunctionPointer : PK_MemberPointer;
  
      auto diag = state.getSema().Diag(attr.getLoc(),
                                       diag::warn_nullability_declspec)
        << DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()),
                               attr.isContextSensitiveKeywordAttribute())
        << type
        << static_cast<unsigned>(pointerKind);
  
      // FIXME: MemberPointer chunks don't carry the location of the *.
      if (chunk.Kind != DeclaratorChunk::MemberPointer) {
        diag << FixItHint::CreateRemoval(attr.getLoc())
             << FixItHint::CreateInsertion(
                    state.getSema().getPreprocessor().getLocForEndOfToken(
                        chunk.Loc),
                    " " + attr.getAttrName()->getName().str() + " ");
      }
  
      moveAttrFromListToList(attr, state.getCurrentAttributes(),
                             chunk.getAttrs());
      return true;
    };
  
    // Move it to the outermost pointer, member pointer, or block
    // pointer declarator.
    for (unsigned i = state.getCurrentChunkIndex(); i != 0; --i) {
      DeclaratorChunk &chunk = declarator.getTypeObject(i-1);
      switch (chunk.Kind) {
      case DeclaratorChunk::Pointer:
      case DeclaratorChunk::BlockPointer:
      case DeclaratorChunk::MemberPointer:
        return moveToChunk(chunk, false);
  
      case DeclaratorChunk::Paren:
      case DeclaratorChunk::Array:
        continue;
  
      case DeclaratorChunk::Function:
        // Try to move past the return type to a function/block/member
        // function pointer.
        if (DeclaratorChunk *dest = maybeMovePastReturnType(
                                      declarator, i,
                                      /*onlyBlockPointers=*/false)) {
          return moveToChunk(*dest, true);
        }
  
        return false;
  
      // Don't walk through these.
      case DeclaratorChunk::Reference:
      case DeclaratorChunk::Pipe:
        return false;
      }
    }
  
    return false;
  }
  
  static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
    assert(!Attr.isInvalid());
    switch (Attr.getKind()) {
    default:
      llvm_unreachable("not a calling convention attribute");
    case ParsedAttr::AT_CDecl:
      return createSimpleAttr<CDeclAttr>(Ctx, Attr);
    case ParsedAttr::AT_FastCall:
      return createSimpleAttr<FastCallAttr>(Ctx, Attr);
    case ParsedAttr::AT_StdCall:
      return createSimpleAttr<StdCallAttr>(Ctx, Attr);
    case ParsedAttr::AT_ThisCall:
      return createSimpleAttr<ThisCallAttr>(Ctx, Attr);
    case ParsedAttr::AT_RegCall:
      return createSimpleAttr<RegCallAttr>(Ctx, Attr);
    case ParsedAttr::AT_Pascal:
      return createSimpleAttr<PascalAttr>(Ctx, Attr);
    case ParsedAttr::AT_SwiftCall:
      return createSimpleAttr<SwiftCallAttr>(Ctx, Attr);
    case ParsedAttr::AT_VectorCall:
      return createSimpleAttr<VectorCallAttr>(Ctx, Attr);
    case ParsedAttr::AT_AArch64VectorPcs:
      return createSimpleAttr<AArch64VectorPcsAttr>(Ctx, Attr);
    case ParsedAttr::AT_Pcs: {
      // The attribute may have had a fixit applied where we treated an
      // identifier as a string literal.  The contents of the string are valid,
      // but the form may not be.
      StringRef Str;
      if (Attr.isArgExpr(0))
        Str = cast<StringLiteral>(Attr.getArgAsExpr(0))->getString();
      else
        Str = Attr.getArgAsIdent(0)->Ident->getName();
      PcsAttr::PCSType Type;
      if (!PcsAttr::ConvertStrToPCSType(Str, Type))
        llvm_unreachable("already validated the attribute");
      return ::new (Ctx) PcsAttr(Ctx, Attr, Type);
    }
    case ParsedAttr::AT_IntelOclBicc:
      return createSimpleAttr<IntelOclBiccAttr>(Ctx, Attr);
    case ParsedAttr::AT_MSABI:
      return createSimpleAttr<MSABIAttr>(Ctx, Attr);
    case ParsedAttr::AT_SysVABI:
      return createSimpleAttr<SysVABIAttr>(Ctx, Attr);
    case ParsedAttr::AT_PreserveMost:
      return createSimpleAttr<PreserveMostAttr>(Ctx, Attr);
    case ParsedAttr::AT_PreserveAll:
      return createSimpleAttr<PreserveAllAttr>(Ctx, Attr);
    }
    llvm_unreachable("unexpected attribute kind!");
  }
  
  /// Process an individual function attribute.  Returns true to
  /// indicate that the attribute was handled, false if it wasn't.
  static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
                                     QualType &type) {
    Sema &S = state.getSema();
  
    FunctionTypeUnwrapper unwrapped(S, type);
  
    if (attr.getKind() == ParsedAttr::AT_NoReturn) {
      if (S.CheckAttrNoArgs(attr))
        return true;
  
      // Delay if this is not a function type.
      if (!unwrapped.isFunctionType())
        return false;
  
      // Otherwise we can process right away.
      FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withNoReturn(true);
      type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
      return true;
    }
  
    if (attr.getKind() == ParsedAttr::AT_CmseNSCall) {
      // Delay if this is not a function type.
      if (!unwrapped.isFunctionType())
        return false;
  
      // Ignore if we don't have CMSE enabled.
      if (!S.getLangOpts().Cmse) {
        S.Diag(attr.getLoc(), diag::warn_attribute_ignored) << attr;
        attr.setInvalid();
        return true;
      }
  
      // Otherwise we can process right away.
      FunctionType::ExtInfo EI =
          unwrapped.get()->getExtInfo().withCmseNSCall(true);
      type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
      return true;
    }
  
    // ns_returns_retained is not always a type attribute, but if we got
    // here, we're treating it as one right now.
    if (attr.getKind() == ParsedAttr::AT_NSReturnsRetained) {
      if (attr.getNumArgs()) return true;
  
      // Delay if this is not a function type.
      if (!unwrapped.isFunctionType())
        return false;
  
      // Check whether the return type is reasonable.
      if (S.checkNSReturnsRetainedReturnType(attr.getLoc(),
                                             unwrapped.get()->getReturnType()))
        return true;
  
      // Only actually change the underlying type in ARC builds.
      QualType origType = type;
      if (state.getSema().getLangOpts().ObjCAutoRefCount) {
        FunctionType::ExtInfo EI
          = unwrapped.get()->getExtInfo().withProducesResult(true);
        type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
      }
      type = state.getAttributedType(
          createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr),
          origType, type);
      return true;
    }
  
    if (attr.getKind() == ParsedAttr::AT_AnyX86NoCallerSavedRegisters) {
      if (S.CheckAttrTarget(attr) || S.CheckAttrNoArgs(attr))
        return true;
  
      // Delay if this is not a function type.
      if (!unwrapped.isFunctionType())
        return false;
  
      FunctionType::ExtInfo EI =
          unwrapped.get()->getExtInfo().withNoCallerSavedRegs(true);
      type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
      return true;
    }
  
    if (attr.getKind() == ParsedAttr::AT_AnyX86NoCfCheck) {
      if (!S.getLangOpts().CFProtectionBranch) {
        S.Diag(attr.getLoc(), diag::warn_nocf_check_attribute_ignored);
        attr.setInvalid();
        return true;
      }
  
      if (S.CheckAttrTarget(attr) || S.CheckAttrNoArgs(attr))
        return true;
  
      // If this is not a function type, warning will be asserted by subject
      // check.
      if (!unwrapped.isFunctionType())
        return true;
  
      FunctionType::ExtInfo EI =
        unwrapped.get()->getExtInfo().withNoCfCheck(true);
      type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
      return true;
    }
  
    if (attr.getKind() == ParsedAttr::AT_Regparm) {
      unsigned value;
      if (S.CheckRegparmAttr(attr, value))
        return true;
  
      // Delay if this is not a function type.
      if (!unwrapped.isFunctionType())
        return false;
  
      // Diagnose regparm with fastcall.
      const FunctionType *fn = unwrapped.get();
      CallingConv CC = fn->getCallConv();
      if (CC == CC_X86FastCall) {
        S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
          << FunctionType::getNameForCallConv(CC)
          << "regparm";
        attr.setInvalid();
        return true;
      }
  
      FunctionType::ExtInfo EI =
        unwrapped.get()->getExtInfo().withRegParm(value);
      type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
      return true;
    }
  
    if (attr.getKind() == ParsedAttr::AT_NoThrow) {
      // Delay if this is not a function type.
      if (!unwrapped.isFunctionType())
        return false;
  
      if (S.CheckAttrNoArgs(attr)) {
        attr.setInvalid();
        return true;
      }
  
      // Otherwise we can process right away.
      auto *Proto = unwrapped.get()->castAs<FunctionProtoType>();
  
      // MSVC ignores nothrow if it is in conflict with an explicit exception
      // specification.
      if (Proto->hasExceptionSpec()) {
        switch (Proto->getExceptionSpecType()) {
        case EST_None:
          llvm_unreachable("This doesn't have an exception spec!");
  
        case EST_DynamicNone:
        case EST_BasicNoexcept:
        case EST_NoexceptTrue:
        case EST_NoThrow:
          // Exception spec doesn't conflict with nothrow, so don't warn.
          LLVM_FALLTHROUGH;
        case EST_Unparsed:
        case EST_Uninstantiated:
        case EST_DependentNoexcept:
        case EST_Unevaluated:
          // We don't have enough information to properly determine if there is a
          // conflict, so suppress the warning.
          break;
        case EST_Dynamic:
        case EST_MSAny:
        case EST_NoexceptFalse:
          S.Diag(attr.getLoc(), diag::warn_nothrow_attribute_ignored);
          break;
        }
        return true;
      }
  
      type = unwrapped.wrap(
          S, S.Context
                 .getFunctionTypeWithExceptionSpec(
                     QualType{Proto, 0},
                     FunctionProtoType::ExceptionSpecInfo{EST_NoThrow})
                 ->getAs<FunctionType>());
      return true;
    }
  
    // Delay if the type didn't work out to a function.
    if (!unwrapped.isFunctionType()) return false;
  
    // Otherwise, a calling convention.
    CallingConv CC;
    if (S.CheckCallingConvAttr(attr, CC))
      return true;
  
    const FunctionType *fn = unwrapped.get();
    CallingConv CCOld = fn->getCallConv();
    Attr *CCAttr = getCCTypeAttr(S.Context, attr);
  
    if (CCOld != CC) {
      // Error out on when there's already an attribute on the type
      // and the CCs don't match.
      if (S.getCallingConvAttributedType(type)) {
        S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
          << FunctionType::getNameForCallConv(CC)
          << FunctionType::getNameForCallConv(CCOld);
        attr.setInvalid();
        return true;
      }
    }
  
    // Diagnose use of variadic functions with calling conventions that
    // don't support them (e.g. because they're callee-cleanup).
    // We delay warning about this on unprototyped function declarations
    // until after redeclaration checking, just in case we pick up a
    // prototype that way.  And apparently we also "delay" warning about
    // unprototyped function types in general, despite not necessarily having
    // much ability to diagnose it later.
    if (!supportsVariadicCall(CC)) {
      const FunctionProtoType *FnP = dyn_cast<FunctionProtoType>(fn);
      // Disable these diagnostics for SYCL
      if (FnP && FnP->isVariadic() && !S.getLangOpts().SYCLIsDevice) {
        // stdcall and fastcall are ignored with a warning for GCC and MS
        // compatibility.
        if (CC == CC_X86StdCall || CC == CC_X86FastCall)
          return S.Diag(attr.getLoc(), diag::warn_cconv_unsupported)
                 << FunctionType::getNameForCallConv(CC)
                 << (int)Sema::CallingConventionIgnoredReason::VariadicFunction;
  
        attr.setInvalid();
        return S.Diag(attr.getLoc(), diag::err_cconv_varargs)
               << FunctionType::getNameForCallConv(CC);
      }
    }
  
    // Also diagnose fastcall with regparm.
    if (CC == CC_X86FastCall && fn->getHasRegParm()) {
      S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
          << "regparm" << FunctionType::getNameForCallConv(CC_X86FastCall);
      attr.setInvalid();
      return true;
    }
  
    // Modify the CC from the wrapped function type, wrap it all back, and then
    // wrap the whole thing in an AttributedType as written.  The modified type
    // might have a different CC if we ignored the attribute.
    QualType Equivalent;
    if (CCOld == CC) {
      Equivalent = type;
    } else {
      auto EI = unwrapped.get()->getExtInfo().withCallingConv(CC);
      Equivalent =
        unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
    }
    type = state.getAttributedType(CCAttr, type, Equivalent);
    return true;
  }
  
  bool Sema::hasExplicitCallingConv(QualType T) {
    const AttributedType *AT;
  
    // Stop if we'd be stripping off a typedef sugar node to reach the
    // AttributedType.
    while ((AT = T->getAs<AttributedType>()) &&
           AT->getAs<TypedefType>() == T->getAs<TypedefType>()) {
      if (AT->isCallingConv())
        return true;
      T = AT->getModifiedType();
    }
    return false;
  }
  
  void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor,
                                    SourceLocation Loc) {
    FunctionTypeUnwrapper Unwrapped(*this, T);
    const FunctionType *FT = Unwrapped.get();
    bool IsVariadic = (isa<FunctionProtoType>(FT) &&
                       cast<FunctionProtoType>(FT)->isVariadic());
    CallingConv CurCC = FT->getCallConv();
    CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic);
  
    if (CurCC == ToCC)
      return;
  
    // MS compiler ignores explicit calling convention attributes on structors. We
    // should do the same.
    if (Context.getTargetInfo().getCXXABI().isMicrosoft() && IsCtorOrDtor) {
      // Issue a warning on ignored calling convention -- except of __stdcall.
      // Again, this is what MS compiler does.
      if (CurCC != CC_X86StdCall)
        Diag(Loc, diag::warn_cconv_unsupported)
            << FunctionType::getNameForCallConv(CurCC)
            << (int)Sema::CallingConventionIgnoredReason::ConstructorDestructor;
    // Default adjustment.
    } else {
      // Only adjust types with the default convention.  For example, on Windows
      // we should adjust a __cdecl type to __thiscall for instance methods, and a
      // __thiscall type to __cdecl for static methods.
      CallingConv DefaultCC =
          Context.getDefaultCallingConvention(IsVariadic, IsStatic);
  
      if (CurCC != DefaultCC || DefaultCC == ToCC)
        return;
  
      if (hasExplicitCallingConv(T))
        return;
    }
  
    FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(ToCC));
    QualType Wrapped = Unwrapped.wrap(*this, FT);
    T = Context.getAdjustedType(T, Wrapped);
  }
  
  /// HandleVectorSizeAttribute - this attribute is only applicable to integral
  /// and float scalars, although arrays, pointers, and function return values are
  /// allowed in conjunction with this construct. Aggregates with this attribute
  /// are invalid, even if they are of the same size as a corresponding scalar.
  /// The raw attribute should contain precisely 1 argument, the vector size for
  /// the variable, measured in bytes. If curType and rawAttr are well formed,
  /// this routine will return a new vector type.
  static void HandleVectorSizeAttr(QualType &CurType, const ParsedAttr &Attr,
                                   Sema &S) {
    // Check the attribute arguments.
    if (Attr.getNumArgs() != 1) {
      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
                                                                        << 1;
      Attr.setInvalid();
      return;
    }
  
    Expr *SizeExpr = Attr.getArgAsExpr(0);
    QualType T = S.BuildVectorType(CurType, SizeExpr, Attr.getLoc());
    if (!T.isNull())
      CurType = T;
    else
      Attr.setInvalid();
  }
  
  /// Process the OpenCL-like ext_vector_type attribute when it occurs on
  /// a type.
  static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
                                      Sema &S) {
    // check the attribute arguments.
    if (Attr.getNumArgs() != 1) {
      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
                                                                        << 1;
      return;
    }
  
    Expr *SizeExpr = Attr.getArgAsExpr(0);
    QualType T = S.BuildExtVectorType(CurType, SizeExpr, Attr.getLoc());
    if (!T.isNull())
      CurType = T;
  }
  
  static bool isPermittedNeonBaseType(QualType &Ty,
                                      VectorType::VectorKind VecKind, Sema &S) {
    const BuiltinType *BTy = Ty->getAs<BuiltinType>();
    if (!BTy)
      return false;
  
    llvm::Triple Triple = S.Context.getTargetInfo().getTriple();
  
    // Signed poly is mathematically wrong, but has been baked into some ABIs by
    // now.
    bool IsPolyUnsigned = Triple.getArch() == llvm::Triple::aarch64 ||
                          Triple.getArch() == llvm::Triple::aarch64_32 ||
                          Triple.getArch() == llvm::Triple::aarch64_be;
    if (VecKind == VectorType::NeonPolyVector) {
      if (IsPolyUnsigned) {
        // AArch64 polynomial vectors are unsigned.
        return BTy->getKind() == BuiltinType::UChar ||
               BTy->getKind() == BuiltinType::UShort ||
               BTy->getKind() == BuiltinType::ULong ||
               BTy->getKind() == BuiltinType::ULongLong;
      } else {
        // AArch32 polynomial vectors are signed.
        return BTy->getKind() == BuiltinType::SChar ||
               BTy->getKind() == BuiltinType::Short ||
               BTy->getKind() == BuiltinType::LongLong;
      }
    }
  
    // Non-polynomial vector types: the usual suspects are allowed, as well as
    // float64_t on AArch64.
    if ((Triple.isArch64Bit() || Triple.getArch() == llvm::Triple::aarch64_32) &&
        BTy->getKind() == BuiltinType::Double)
      return true;
  
    return BTy->getKind() == BuiltinType::SChar ||
           BTy->getKind() == BuiltinType::UChar ||
           BTy->getKind() == BuiltinType::Short ||
           BTy->getKind() == BuiltinType::UShort ||
           BTy->getKind() == BuiltinType::Int ||
           BTy->getKind() == BuiltinType::UInt ||
           BTy->getKind() == BuiltinType::Long ||
           BTy->getKind() == BuiltinType::ULong ||
           BTy->getKind() == BuiltinType::LongLong ||
           BTy->getKind() == BuiltinType::ULongLong ||
           BTy->getKind() == BuiltinType::Float ||
           BTy->getKind() == BuiltinType::Half ||
           BTy->getKind() == BuiltinType::BFloat16;
  }
  
  static bool verifyValidIntegerConstantExpr(Sema &S, const ParsedAttr &Attr,
                                             llvm::APSInt &Result) {
    const auto *AttrExpr = Attr.getArgAsExpr(0);
    if (!AttrExpr->isTypeDependent() && !AttrExpr->isValueDependent()) {
      if (Optional<llvm::APSInt> Res =
              AttrExpr->getIntegerConstantExpr(S.Context)) {
        Result = *Res;
        return true;
      }
    }
    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
        << Attr << AANT_ArgumentIntegerConstant << AttrExpr->getSourceRange();
    Attr.setInvalid();
    return false;
  }
  
  /// HandleNeonVectorTypeAttr - The "neon_vector_type" and
  /// "neon_polyvector_type" attributes are used to create vector types that
  /// are mangled according to ARM's ABI.  Otherwise, these types are identical
  /// to those created with the "vector_size" attribute.  Unlike "vector_size"
  /// the argument to these Neon attributes is the number of vector elements,
  /// not the vector size in bytes.  The vector width and element type must
  /// match one of the standard Neon vector types.
  static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
                                       Sema &S, VectorType::VectorKind VecKind) {
    // Target must have NEON (or MVE, whose vectors are similar enough
    // not to need a separate attribute)
    if (!S.Context.getTargetInfo().hasFeature("neon") &&
        !S.Context.getTargetInfo().hasFeature("mve")) {
      S.Diag(Attr.getLoc(), diag::err_attribute_unsupported)
          << Attr << "'neon' or 'mve'";
      Attr.setInvalid();
      return;
    }
    // Check the attribute arguments.
    if (Attr.getNumArgs() != 1) {
      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
                                                                        << 1;
      Attr.setInvalid();
      return;
    }
    // The number of elements must be an ICE.
    llvm::APSInt numEltsInt(32);
    if (!verifyValidIntegerConstantExpr(S, Attr, numEltsInt))
      return;
  
    // Only certain element types are supported for Neon vectors.
    if (!isPermittedNeonBaseType(CurType, VecKind, S)) {
      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
      Attr.setInvalid();
      return;
    }
  
    // The total size of the vector must be 64 or 128 bits.
    unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
    unsigned numElts = static_cast<unsigned>(numEltsInt.getZExtValue());
    unsigned vecSize = typeSize * numElts;
    if (vecSize != 64 && vecSize != 128) {
      S.Diag(Attr.getLoc(), diag::err_attribute_bad_neon_vector_size) << CurType;
      Attr.setInvalid();
      return;
    }
  
    CurType = S.Context.getVectorType(CurType, numElts, VecKind);
  }
  
  /// HandleArmSveVectorBitsTypeAttr - The "arm_sve_vector_bits" attribute is
  /// used to create fixed-length versions of sizeless SVE types defined by
  /// the ACLE, such as svint32_t and svbool_t.
  static void HandleArmSveVectorBitsTypeAttr(QualType &CurType, ParsedAttr &Attr,
                                             Sema &S) {
    // Target must have SVE.
    if (!S.Context.getTargetInfo().hasFeature("sve")) {
      S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr << "'sve'";
      Attr.setInvalid();
      return;
    }
  
    // Attribute is unsupported if '-msve-vector-bits=<bits>' isn't specified.
    if (!S.getLangOpts().ArmSveVectorBits) {
      S.Diag(Attr.getLoc(), diag::err_attribute_arm_feature_sve_bits_unsupported)
          << Attr;
      Attr.setInvalid();
      return;
    }
  
    // Check the attribute arguments.
    if (Attr.getNumArgs() != 1) {
      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
          << Attr << 1;
      Attr.setInvalid();
      return;
    }
  
    // The vector size must be an integer constant expression.
    llvm::APSInt SveVectorSizeInBits(32);
    if (!verifyValidIntegerConstantExpr(S, Attr, SveVectorSizeInBits))
      return;
  
    unsigned VecSize = static_cast<unsigned>(SveVectorSizeInBits.getZExtValue());
  
    // The attribute vector size must match -msve-vector-bits.
    if (VecSize != S.getLangOpts().ArmSveVectorBits) {
      S.Diag(Attr.getLoc(), diag::err_attribute_bad_sve_vector_size)
          << VecSize << S.getLangOpts().ArmSveVectorBits;
      Attr.setInvalid();
      return;
    }
  
    // Attribute can only be attached to a single SVE vector or predicate type.
    if (!CurType->isVLSTBuiltinType()) {
      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_sve_type)
          << Attr << CurType;
      Attr.setInvalid();
      return;
    }
  
    const auto *BT = CurType->castAs<BuiltinType>();
  
    QualType EltType = CurType->getSveEltType(S.Context);
    unsigned TypeSize = S.Context.getTypeSize(EltType);
    VectorType::VectorKind VecKind = VectorType::SveFixedLengthDataVector;
    if (BT->getKind() == BuiltinType::SveBool) {
      // Predicates are represented as i8.
      VecSize /= S.Context.getCharWidth() * S.Context.getCharWidth();
      VecKind = VectorType::SveFixedLengthPredicateVector;
    } else
      VecSize /= TypeSize;
    CurType = S.Context.getVectorType(EltType, VecSize, VecKind);
  }
  
  static void HandleArmMveStrictPolymorphismAttr(TypeProcessingState &State,
                                                 QualType &CurType,
                                                 ParsedAttr &Attr) {
    const VectorType *VT = dyn_cast<VectorType>(CurType);
    if (!VT || VT->getVectorKind() != VectorType::NeonVector) {
      State.getSema().Diag(Attr.getLoc(),
                           diag::err_attribute_arm_mve_polymorphism);
      Attr.setInvalid();
      return;
    }
  
    CurType =
        State.getAttributedType(createSimpleAttr<ArmMveStrictPolymorphismAttr>(
                                    State.getSema().Context, Attr),
                                CurType, CurType);
  }
  
  /// Handle OpenCL Access Qualifier Attribute.
  static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr,
                                     Sema &S) {
    // OpenCL v2.0 s6.6 - Access qualifier can be used only for image and pipe type.
    if (!(CurType->isImageType() || CurType->isPipeType())) {
      S.Diag(Attr.getLoc(), diag::err_opencl_invalid_access_qualifier);
      Attr.setInvalid();
      return;
    }
  
    if (const TypedefType* TypedefTy = CurType->getAs<TypedefType>()) {
      QualType BaseTy = TypedefTy->desugar();
  
      std::string PrevAccessQual;
      if (BaseTy->isPipeType()) {
        if (TypedefTy->getDecl()->hasAttr<OpenCLAccessAttr>()) {
          OpenCLAccessAttr *Attr =
              TypedefTy->getDecl()->getAttr<OpenCLAccessAttr>();
          PrevAccessQual = Attr->getSpelling();
        } else {
          PrevAccessQual = "read_only";
        }
      } else if (const BuiltinType* ImgType = BaseTy->getAs<BuiltinType>()) {
  
        switch (ImgType->getKind()) {
          #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
        case BuiltinType::Id:                                          \
          PrevAccessQual = #Access;                                    \
          break;
          #include "clang/Basic/OpenCLImageTypes.def"
        default:
          llvm_unreachable("Unable to find corresponding image type.");
        }
      } else {
        llvm_unreachable("unexpected type");
      }
      StringRef AttrName = Attr.getAttrName()->getName();
      if (PrevAccessQual == AttrName.ltrim("_")) {
        // Duplicated qualifiers
        S.Diag(Attr.getLoc(), diag::warn_duplicate_declspec)
           << AttrName << Attr.getRange();
      } else {
        // Contradicting qualifiers
        S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers);
      }
  
      S.Diag(TypedefTy->getDecl()->getBeginLoc(),
             diag::note_opencl_typedef_access_qualifier) << PrevAccessQual;
    } else if (CurType->isPipeType()) {
      if (Attr.getSemanticSpelling() == OpenCLAccessAttr::Keyword_write_only) {
        QualType ElemType = CurType->castAs<PipeType>()->getElementType();
        CurType = S.Context.getWritePipeType(ElemType);
      }
    }
  }
  
  /// HandleMatrixTypeAttr - "matrix_type" attribute, like ext_vector_type
  static void HandleMatrixTypeAttr(QualType &CurType, const ParsedAttr &Attr,
                                   Sema &S) {
    if (!S.getLangOpts().MatrixTypes) {
      S.Diag(Attr.getLoc(), diag::err_builtin_matrix_disabled);
      return;
    }
  
    if (Attr.getNumArgs() != 2) {
      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
          << Attr << 2;
      return;
    }
  
    Expr *RowsExpr = Attr.getArgAsExpr(0);
    Expr *ColsExpr = Attr.getArgAsExpr(1);
    QualType T = S.BuildMatrixType(CurType, RowsExpr, ColsExpr, Attr.getLoc());
    if (!T.isNull())
      CurType = T;
  }
  
  static void HandleLifetimeBoundAttr(TypeProcessingState &State,
                                      QualType &CurType,
                                      ParsedAttr &Attr) {
    if (State.getDeclarator().isDeclarationOfFunction()) {
      CurType = State.getAttributedType(
          createSimpleAttr<LifetimeBoundAttr>(State.getSema().Context, Attr),
          CurType, CurType);
    }
  }
  
  static bool isAddressSpaceKind(const ParsedAttr &attr) {
    auto attrKind = attr.getKind();
  
    return attrKind == ParsedAttr::AT_AddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLPrivateAddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLGlobalAddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLGlobalHostAddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLLocalAddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLConstantAddressSpace ||
           attrKind == ParsedAttr::AT_OpenCLGenericAddressSpace;
  }
  
  static void processTypeAttrs(TypeProcessingState &state, QualType &type,
                               TypeAttrLocation TAL,
                               ParsedAttributesView &attrs) {
    // Scan through and apply attributes to this type where it makes sense.  Some
    // attributes (such as __address_space__, __vector_size__, etc) apply to the
    // type, but others can be present in the type specifiers even though they
    // apply to the decl.  Here we apply type attributes and ignore the rest.
  
    // This loop modifies the list pretty frequently, but we still need to make
    // sure we visit every element once. Copy the attributes list, and iterate
    // over that.
    ParsedAttributesView AttrsCopy{attrs};
  
    state.setParsedNoDeref(false);
  
    for (ParsedAttr &attr : AttrsCopy) {
  
      // Skip attributes that were marked to be invalid.
      if (attr.isInvalid())
        continue;
  
      if (attr.isCXX11Attribute()) {
        // [[gnu::...]] attributes are treated as declaration attributes, so may
        // not appertain to a DeclaratorChunk. If we handle them as type
        // attributes, accept them in that position and diagnose the GCC
        // incompatibility.
        if (attr.isGNUScope()) {
          bool IsTypeAttr = attr.isTypeAttr();
          if (TAL == TAL_DeclChunk) {
            state.getSema().Diag(attr.getLoc(),
                                 IsTypeAttr
                                     ? diag::warn_gcc_ignores_type_attr
                                     : diag::warn_cxx11_gnu_attribute_on_type)
                << attr;
            if (!IsTypeAttr)
              continue;
          }
        } else if (TAL != TAL_DeclChunk && !isAddressSpaceKind(attr)) {
          // Otherwise, only consider type processing for a C++11 attribute if
          // it's actually been applied to a type.
          // We also allow C++11 address_space and
          // OpenCL language address space attributes to pass through.
          continue;
        }
      }
  
      // If this is an attribute we can handle, do so now,
      // otherwise, add it to the FnAttrs list for rechaining.
      switch (attr.getKind()) {
      default:
        // A C++11 attribute on a declarator chunk must appertain to a type.
        if (attr.isCXX11Attribute() && TAL == TAL_DeclChunk &&
            (!state.isProcessingLambdaExpr() ||
             !attr.supportsNonconformingLambdaSyntax())) {
          state.getSema().Diag(attr.getLoc(), diag::err_attribute_not_type_attr)
              << attr;
          attr.setUsedAsTypeAttr();
        }
        break;
  
      case ParsedAttr::UnknownAttribute:
        if (attr.isCXX11Attribute() && TAL == TAL_DeclChunk)
          state.getSema().Diag(attr.getLoc(),
                               diag::warn_unknown_attribute_ignored)
              << attr << attr.getRange();
        break;
  
      case ParsedAttr::IgnoredAttribute:
        break;
  
      case ParsedAttr::AT_MayAlias:
        // FIXME: This attribute needs to actually be handled, but if we ignore
        // it it breaks large amounts of Linux software.
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_OpenCLPrivateAddressSpace:
      case ParsedAttr::AT_OpenCLGlobalAddressSpace:
      case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
      case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
      case ParsedAttr::AT_OpenCLLocalAddressSpace:
      case ParsedAttr::AT_OpenCLConstantAddressSpace:
      case ParsedAttr::AT_OpenCLGenericAddressSpace:
      case ParsedAttr::AT_AddressSpace:
        HandleAddressSpaceTypeAttribute(type, attr, state);
        attr.setUsedAsTypeAttr();
        break;
      OBJC_POINTER_TYPE_ATTRS_CASELIST:
        if (!handleObjCPointerTypeAttr(state, attr, type))
          distributeObjCPointerTypeAttr(state, attr, type);
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_VectorSize:
        HandleVectorSizeAttr(type, attr, state.getSema());
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_ExtVectorType:
        HandleExtVectorTypeAttr(type, attr, state.getSema());
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_NeonVectorType:
        HandleNeonVectorTypeAttr(type, attr, state.getSema(),
                                 VectorType::NeonVector);
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_NeonPolyVectorType:
        HandleNeonVectorTypeAttr(type, attr, state.getSema(),
                                 VectorType::NeonPolyVector);
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_ArmSveVectorBits:
        HandleArmSveVectorBitsTypeAttr(type, attr, state.getSema());
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_ArmMveStrictPolymorphism: {
        HandleArmMveStrictPolymorphismAttr(state, type, attr);
        attr.setUsedAsTypeAttr();
        break;
      }
      case ParsedAttr::AT_OpenCLAccess:
        HandleOpenCLAccessAttr(type, attr, state.getSema());
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_SYCLFPGAPipe:
        HandleSYCLFPGAPipeAttribute(type, attr, state);
        attr.setUsedAsTypeAttr();
        break;
      case ParsedAttr::AT_LifetimeBound:
        if (TAL == TAL_DeclChunk)
          HandleLifetimeBoundAttr(state, type, attr);
        break;
  
      case ParsedAttr::AT_NoDeref: {
        ASTContext &Ctx = state.getSema().Context;
        type = state.getAttributedType(createSimpleAttr<NoDerefAttr>(Ctx, attr),
                                       type, type);
        attr.setUsedAsTypeAttr();
        state.setParsedNoDeref(true);
        break;
      }
  
      case ParsedAttr::AT_MatrixType:
        HandleMatrixTypeAttr(type, attr, state.getSema());
        attr.setUsedAsTypeAttr();
        break;
  
      MS_TYPE_ATTRS_CASELIST:
        if (!handleMSPointerTypeQualifierAttr(state, attr, type))
          attr.setUsedAsTypeAttr();
        break;
  
  
      NULLABILITY_TYPE_ATTRS_CASELIST:
        // Either add nullability here or try to distribute it.  We
        // don't want to distribute the nullability specifier past any
        // dependent type, because that complicates the user model.
        if (type->canHaveNullability() || type->isDependentType() ||
            type->isArrayType() ||
            !distributeNullabilityTypeAttr(state, type, attr)) {
          unsigned endIndex;
          if (TAL == TAL_DeclChunk)
            endIndex = state.getCurrentChunkIndex();
          else
            endIndex = state.getDeclarator().getNumTypeObjects();
          bool allowOnArrayType =
              state.getDeclarator().isPrototypeContext() &&
              !hasOuterPointerLikeChunk(state.getDeclarator(), endIndex);
          if (checkNullabilityTypeSpecifier(
                state,
                type,
                attr,
                allowOnArrayType)) {
            attr.setInvalid();
          }
  
          attr.setUsedAsTypeAttr();
        }
        break;
  
      case ParsedAttr::AT_ObjCKindOf:
        // '__kindof' must be part of the decl-specifiers.
        switch (TAL) {
        case TAL_DeclSpec:
          break;
  
        case TAL_DeclChunk:
        case TAL_DeclName:
          state.getSema().Diag(attr.getLoc(),
                               diag::err_objc_kindof_wrong_position)
              << FixItHint::CreateRemoval(attr.getLoc())
              << FixItHint::CreateInsertion(
                     state.getDeclarator().getDeclSpec().getBeginLoc(),
                     "__kindof ");
          break;
        }
  
        // Apply it regardless.
        if (checkObjCKindOfType(state, type, attr))
          attr.setInvalid();
        break;
  
      case ParsedAttr::AT_NoThrow:
      // Exception Specifications aren't generally supported in C mode throughout
      // clang, so revert to attribute-based handling for C.
        if (!state.getSema().getLangOpts().CPlusPlus)
          break;
        LLVM_FALLTHROUGH;
      FUNCTION_TYPE_ATTRS_CASELIST:
        attr.setUsedAsTypeAttr();
  
        // Never process function type attributes as part of the
        // declaration-specifiers.
        if (TAL == TAL_DeclSpec)
          distributeFunctionTypeAttrFromDeclSpec(state, attr, type);
  
        // Otherwise, handle the possible delays.
        else if (!handleFunctionTypeAttr(state, attr, type))
          distributeFunctionTypeAttr(state, attr, type);
        break;
      case ParsedAttr::AT_AcquireHandle: {
        if (!type->isFunctionType())
          return;
  
        if (attr.getNumArgs() != 1) {
          state.getSema().Diag(attr.getLoc(),
                               diag::err_attribute_wrong_number_arguments)
              << attr << 1;
          attr.setInvalid();
          return;
        }
  
        StringRef HandleType;
        if (!state.getSema().checkStringLiteralArgumentAttr(attr, 0, HandleType))
          return;
        type = state.getAttributedType(
            AcquireHandleAttr::Create(state.getSema().Context, HandleType, attr),
            type, type);
        attr.setUsedAsTypeAttr();
        break;
      }
      }
  
      // Handle attributes that are defined in a macro. We do not want this to be
      // applied to ObjC builtin attributes.
      if (isa<AttributedType>(type) && attr.hasMacroIdentifier() &&
          !type.getQualifiers().hasObjCLifetime() &&
          !type.getQualifiers().hasObjCGCAttr() &&
          attr.getKind() != ParsedAttr::AT_ObjCGC &&
          attr.getKind() != ParsedAttr::AT_ObjCOwnership) {
        const IdentifierInfo *MacroII = attr.getMacroIdentifier();
        type = state.getSema().Context.getMacroQualifiedType(type, MacroII);
        state.setExpansionLocForMacroQualifiedType(
            cast<MacroQualifiedType>(type.getTypePtr()),
            attr.getMacroExpansionLoc());
      }
    }
  
    if (!state.getSema().getLangOpts().OpenCL ||
        type.getAddressSpace() != LangAS::Default)
      return;
  }
  
  void Sema::completeExprArrayBound(Expr *E) {
    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
        if (isTemplateInstantiation(Var->getTemplateSpecializationKind())) {
          auto *Def = Var->getDefinition();
          if (!Def) {
            SourceLocation PointOfInstantiation = E->getExprLoc();
            runWithSufficientStackSpace(PointOfInstantiation, [&] {
              InstantiateVariableDefinition(PointOfInstantiation, Var);
            });
            Def = Var->getDefinition();
  
            // If we don't already have a point of instantiation, and we managed
            // to instantiate a definition, this is the point of instantiation.
            // Otherwise, we don't request an end-of-TU instantiation, so this is
            // not a point of instantiation.
            // FIXME: Is this really the right behavior?
            if (Var->getPointOfInstantiation().isInvalid() && Def) {
              assert(Var->getTemplateSpecializationKind() ==
                         TSK_ImplicitInstantiation &&
                     "explicit instantiation with no point of instantiation");
              Var->setTemplateSpecializationKind(
                  Var->getTemplateSpecializationKind(), PointOfInstantiation);
            }
          }
  
          // Update the type to the definition's type both here and within the
          // expression.
          if (Def) {
            DRE->setDecl(Def);
            QualType T = Def->getType();
            DRE->setType(T);
            // FIXME: Update the type on all intervening expressions.
            E->setType(T);
          }
  
          // We still go on to try to complete the type independently, as it
          // may also require instantiations or diagnostics if it remains
          // incomplete.
        }
      }
    }
  }
  
  QualType Sema::getCompletedType(Expr *E) {
    // Incomplete array types may be completed by the initializer attached to
    // their definitions. For static data members of class templates and for
    // variable templates, we need to instantiate the definition to get this
    // initializer and complete the type.
    if (E->getType()->isIncompleteArrayType())
      completeExprArrayBound(E);
  
    // FIXME: Are there other cases which require instantiating something other
    // than the type to complete the type of an expression?
  
    return E->getType();
  }
  
  /// Ensure that the type of the given expression is complete.
  ///
  /// This routine checks whether the expression \p E has a complete type. If the
  /// expression refers to an instantiable construct, that instantiation is
  /// performed as needed to complete its type. Furthermore
  /// Sema::RequireCompleteType is called for the expression's type (or in the
  /// case of a reference type, the referred-to type).
  ///
  /// \param E The expression whose type is required to be complete.
  /// \param Kind Selects which completeness rules should be applied.
  /// \param Diagnoser The object that will emit a diagnostic if the type is
  /// incomplete.
  ///
  /// \returns \c true if the type of \p E is incomplete and diagnosed, \c false
  /// otherwise.
  bool Sema::RequireCompleteExprType(Expr *E, CompleteTypeKind Kind,
                                     TypeDiagnoser &Diagnoser) {
    return RequireCompleteType(E->getExprLoc(), getCompletedType(E), Kind,
                               Diagnoser);
  }
  
  bool Sema::RequireCompleteExprType(Expr *E, unsigned DiagID) {
    BoundTypeDiagnoser<> Diagnoser(DiagID);
    return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser);
  }
  
  /// Ensure that the type T is a complete type.
  ///
  /// This routine checks whether the type @p T is complete in any
  /// context where a complete type is required. If @p T is a complete
  /// type, returns false. If @p T is a class template specialization,
  /// this routine then attempts to perform class template
  /// instantiation. If instantiation fails, or if @p T is incomplete
  /// and cannot be completed, issues the diagnostic @p diag (giving it
  /// the type @p T) and returns true.
  ///
  /// @param Loc  The location in the source that the incomplete type
  /// diagnostic should refer to.
  ///
  /// @param T  The type that this routine is examining for completeness.
  ///
  /// @param Kind Selects which completeness rules should be applied.
  ///
  /// @returns @c true if @p T is incomplete and a diagnostic was emitted,
  /// @c false otherwise.
  bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
                                 CompleteTypeKind Kind,
                                 TypeDiagnoser &Diagnoser) {
    if (RequireCompleteTypeImpl(Loc, T, Kind, &Diagnoser))
      return true;
    if (const TagType *Tag = T->getAs<TagType>()) {
      if (!Tag->getDecl()->isCompleteDefinitionRequired()) {
        Tag->getDecl()->setCompleteDefinitionRequired();
        Consumer.HandleTagDeclRequiredDefinition(Tag->getDecl());
      }
    }
    return false;
  }
  
  bool Sema::hasStructuralCompatLayout(Decl *D, Decl *Suggested) {
    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
    if (!Suggested)
      return false;
  
    // FIXME: Add a specific mode for C11 6.2.7/1 in StructuralEquivalenceContext
    // and isolate from other C++ specific checks.
    StructuralEquivalenceContext Ctx(
        D->getASTContext(), Suggested->getASTContext(), NonEquivalentDecls,
        StructuralEquivalenceKind::Default,
        false /*StrictTypeSpelling*/, true /*Complain*/,
        true /*ErrorOnTagTypeMismatch*/);
    return Ctx.IsEquivalent(D, Suggested);
  }
  
  /// Determine whether there is any declaration of \p D that was ever a
  ///        definition (perhaps before module merging) and is currently visible.
  /// \param D The definition of the entity.
  /// \param Suggested Filled in with the declaration that should be made visible
  ///        in order to provide a definition of this entity.
  /// \param OnlyNeedComplete If \c true, we only need the type to be complete,
  ///        not defined. This only matters for enums with a fixed underlying
  ///        type, since in all other cases, a type is complete if and only if it
  ///        is defined.
  bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested,
                                  bool OnlyNeedComplete) {
    // Easy case: if we don't have modules, all declarations are visible.
    if (!getLangOpts().Modules && !getLangOpts().ModulesLocalVisibility)
      return true;
  
    // If this definition was instantiated from a template, map back to the
    // pattern from which it was instantiated.
    if (isa<TagDecl>(D) && cast<TagDecl>(D)->isBeingDefined()) {
      // We're in the middle of defining it; this definition should be treated
      // as visible.
      return true;
    } else if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
      if (auto *Pattern = RD->getTemplateInstantiationPattern())
        RD = Pattern;
      D = RD->getDefinition();
    } else if (auto *ED = dyn_cast<EnumDecl>(D)) {
      if (auto *Pattern = ED->getTemplateInstantiationPattern())
        ED = Pattern;
      if (OnlyNeedComplete && (ED->isFixed() || getLangOpts().MSVCCompat)) {
        // If the enum has a fixed underlying type, it may have been forward
        // declared. In -fms-compatibility, `enum Foo;` will also forward declare
        // the enum and assign it the underlying type of `int`. Since we're only
        // looking for a complete type (not a definition), any visible declaration
        // of it will do.
        *Suggested = nullptr;
        for (auto *Redecl : ED->redecls()) {
          if (isVisible(Redecl))
            return true;
          if (Redecl->isThisDeclarationADefinition() ||
              (Redecl->isCanonicalDecl() && !*Suggested))
            *Suggested = Redecl;
        }
        return false;
      }
      D = ED->getDefinition();
    } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
      if (auto *Pattern = FD->getTemplateInstantiationPattern())
        FD = Pattern;
      D = FD->getDefinition();
    } else if (auto *VD = dyn_cast<VarDecl>(D)) {
      if (auto *Pattern = VD->getTemplateInstantiationPattern())
        VD = Pattern;
      D = VD->getDefinition();
    }
    assert(D && "missing definition for pattern of instantiated definition");
  
    *Suggested = D;
  
    auto DefinitionIsVisible = [&] {
      // The (primary) definition might be in a visible module.
      if (isVisible(D))
        return true;
  
      // A visible module might have a merged definition instead.
      if (D->isModulePrivate() ? hasMergedDefinitionInCurrentModule(D)
                               : hasVisibleMergedDefinition(D)) {
        if (CodeSynthesisContexts.empty() &&
            !getLangOpts().ModulesLocalVisibility) {
          // Cache the fact that this definition is implicitly visible because
          // there is a visible merged definition.
          D->setVisibleDespiteOwningModule();
        }
        return true;
      }
  
      return false;
    };
  
    if (DefinitionIsVisible())
      return true;
  
    // The external source may have additional definitions of this entity that are
    // visible, so complete the redeclaration chain now and ask again.
    if (auto *Source = Context.getExternalSource()) {
      Source->CompleteRedeclChain(D);
      return DefinitionIsVisible();
    }
  
    return false;
  }
  
  /// Locks in the inheritance model for the given class and all of its bases.
  static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
    RD = RD->getMostRecentNonInjectedDecl();
    if (!RD->hasAttr<MSInheritanceAttr>()) {
      MSInheritanceModel IM;
      bool BestCase = false;
      switch (S.MSPointerToMemberRepresentationMethod) {
      case LangOptions::PPTMK_BestCase:
        BestCase = true;
        IM = RD->calculateInheritanceModel();
        break;
      case LangOptions::PPTMK_FullGeneralitySingleInheritance:
        IM = MSInheritanceModel::Single;
        break;
      case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
        IM = MSInheritanceModel::Multiple;
        break;
      case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
        IM = MSInheritanceModel::Unspecified;
        break;
      }
  
      SourceRange Loc = S.ImplicitMSInheritanceAttrLoc.isValid()
                            ? S.ImplicitMSInheritanceAttrLoc
                            : RD->getSourceRange();
      RD->addAttr(MSInheritanceAttr::CreateImplicit(
          S.getASTContext(), BestCase, Loc, AttributeCommonInfo::AS_Microsoft,
          MSInheritanceAttr::Spelling(IM)));
      S.Consumer.AssignInheritanceModel(RD);
    }
  }
  
  /// The implementation of RequireCompleteType
  bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
                                     CompleteTypeKind Kind,
                                     TypeDiagnoser *Diagnoser) {
    // FIXME: Add this assertion to make sure we always get instantiation points.
    //  assert(!Loc.isInvalid() && "Invalid location in RequireCompleteType");
    // FIXME: Add this assertion to help us flush out problems with
    // checking for dependent types and type-dependent expressions.
    //
    //  assert(!T->isDependentType() &&
    //         "Can't ask whether a dependent type is complete");
  
    if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
      if (!MPTy->getClass()->isDependentType()) {
        if (getLangOpts().CompleteMemberPointers &&
            !MPTy->getClass()->getAsCXXRecordDecl()->isBeingDefined() &&
            RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), Kind,
                                diag::err_memptr_incomplete))
          return true;
  
        // We lock in the inheritance model once somebody has asked us to ensure
        // that a pointer-to-member type is complete.
        if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
          (void)isCompleteType(Loc, QualType(MPTy->getClass(), 0));
          assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());
        }
      }
    }
  
    NamedDecl *Def = nullptr;
    bool AcceptSizeless = (Kind == CompleteTypeKind::AcceptSizeless);
    bool Incomplete = (T->isIncompleteType(&Def) ||
                       (!AcceptSizeless && T->isSizelessBuiltinType()));
  
    // Check that any necessary explicit specializations are visible. For an
    // enum, we just need the declaration, so don't check this.
    if (Def && !isa<EnumDecl>(Def))
      checkSpecializationVisibility(Loc, Def);
  
    // If we have a complete type, we're done.
    if (!Incomplete) {
      // If we know about the definition but it is not visible, complain.
      NamedDecl *SuggestedDef = nullptr;
      if (Def &&
          !hasVisibleDefinition(Def, &SuggestedDef, /*OnlyNeedComplete*/true)) {
        // If the user is going to see an error here, recover by making the
        // definition visible.
        bool TreatAsComplete = Diagnoser && !isSFINAEContext();
        if (Diagnoser && SuggestedDef)
          diagnoseMissingImport(Loc, SuggestedDef, MissingImportKind::Definition,
                                /*Recover*/TreatAsComplete);
        return !TreatAsComplete;
      } else if (Def && !TemplateInstCallbacks.empty()) {
        CodeSynthesisContext TempInst;
        TempInst.Kind = CodeSynthesisContext::Memoization;
        TempInst.Template = Def;
        TempInst.Entity = Def;
        TempInst.PointOfInstantiation = Loc;
        atTemplateBegin(TemplateInstCallbacks, *this, TempInst);
        atTemplateEnd(TemplateInstCallbacks, *this, TempInst);
      }
  
      return false;
    }
  
    TagDecl *Tag = dyn_cast_or_null<TagDecl>(Def);
    ObjCInterfaceDecl *IFace = dyn_cast_or_null<ObjCInterfaceDecl>(Def);
  
    // Give the external source a chance to provide a definition of the type.
    // This is kept separate from completing the redeclaration chain so that
    // external sources such as LLDB can avoid synthesizing a type definition
    // unless it's actually needed.
    if (Tag || IFace) {
      // Avoid diagnosing invalid decls as incomplete.
      if (Def->isInvalidDecl())
        return true;
  
      // Give the external AST source a chance to complete the type.
      if (auto *Source = Context.getExternalSource()) {
        if (Tag && Tag->hasExternalLexicalStorage())
            Source->CompleteType(Tag);
        if (IFace && IFace->hasExternalLexicalStorage())
            Source->CompleteType(IFace);
        // If the external source completed the type, go through the motions
        // again to ensure we're allowed to use the completed type.
        if (!T->isIncompleteType())
          return RequireCompleteTypeImpl(Loc, T, Kind, Diagnoser);
      }
    }
  
    // If we have a class template specialization or a class member of a
    // class template specialization, or an array with known size of such,
    // try to instantiate it.
    if (auto *RD = dyn_cast_or_null<CXXRecordDecl>(Tag)) {
      bool Instantiated = false;
      bool Diagnosed = false;
      if (RD->isDependentContext()) {
        // Don't try to instantiate a dependent class (eg, a member template of
        // an instantiated class template specialization).
        // FIXME: Can this ever happen?
      } else if (auto *ClassTemplateSpec =
              dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
        if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
          runWithSufficientStackSpace(Loc, [&] {
            Diagnosed = InstantiateClassTemplateSpecialization(
                Loc, ClassTemplateSpec, TSK_ImplicitInstantiation,
                /*Complain=*/Diagnoser);
          });
          Instantiated = true;
        }
      } else {
        CXXRecordDecl *Pattern = RD->getInstantiatedFromMemberClass();
        if (!RD->isBeingDefined() && Pattern) {
          MemberSpecializationInfo *MSI = RD->getMemberSpecializationInfo();
          assert(MSI && "Missing member specialization information?");
          // This record was instantiated from a class within a template.
          if (MSI->getTemplateSpecializationKind() !=
              TSK_ExplicitSpecialization) {
            runWithSufficientStackSpace(Loc, [&] {
              Diagnosed = InstantiateClass(Loc, RD, Pattern,
                                           getTemplateInstantiationArgs(RD),
                                           TSK_ImplicitInstantiation,
                                           /*Complain=*/Diagnoser);
            });
            Instantiated = true;
          }
        }
      }
  
      if (Instantiated) {
        // Instantiate* might have already complained that the template is not
        // defined, if we asked it to.
        if (Diagnoser && Diagnosed)
          return true;
        // If we instantiated a definition, check that it's usable, even if
        // instantiation produced an error, so that repeated calls to this
        // function give consistent answers.
        if (!T->isIncompleteType())
          return RequireCompleteTypeImpl(Loc, T, Kind, Diagnoser);
      }
    }
  
    // FIXME: If we didn't instantiate a definition because of an explicit
    // specialization declaration, check that it's visible.
  
    if (!Diagnoser)
      return true;
  
    Diagnoser->diagnose(*this, Loc, T);
  
    // If the type was a forward declaration of a class/struct/union
    // type, produce a note.
    if (Tag && !Tag->isInvalidDecl() && !Tag->getLocation().isInvalid())
      Diag(Tag->getLocation(),
           Tag->isBeingDefined() ? diag::note_type_being_defined
                                 : diag::note_forward_declaration)
        << Context.getTagDeclType(Tag);
  
    // If the Objective-C class was a forward declaration, produce a note.
    if (IFace && !IFace->isInvalidDecl() && !IFace->getLocation().isInvalid())
      Diag(IFace->getLocation(), diag::note_forward_class);
  
    // If we have external information that we can use to suggest a fix,
    // produce a note.
    if (ExternalSource)
      ExternalSource->MaybeDiagnoseMissingCompleteType(Loc, T);
  
    return true;
  }
  
  bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
                                 CompleteTypeKind Kind, unsigned DiagID) {
    BoundTypeDiagnoser<> Diagnoser(DiagID);
    return RequireCompleteType(Loc, T, Kind, Diagnoser);
  }
  
  /// Get diagnostic %select index for tag kind for
  /// literal type diagnostic message.
  /// WARNING: Indexes apply to particular diagnostics only!
  ///
  /// \returns diagnostic %select index.
  static unsigned getLiteralDiagFromTagKind(TagTypeKind Tag) {
    switch (Tag) {
    case TTK_Struct: return 0;
    case TTK_Interface: return 1;
    case TTK_Class:  return 2;
    default: llvm_unreachable("Invalid tag kind for literal type diagnostic!");
    }
  }
  
  /// Ensure that the type T is a literal type.
  ///
  /// This routine checks whether the type @p T is a literal type. If @p T is an
  /// incomplete type, an attempt is made to complete it. If @p T is a literal
  /// type, or @p AllowIncompleteType is true and @p T is an incomplete type,
  /// returns false. Otherwise, this routine issues the diagnostic @p PD (giving
  /// it the type @p T), along with notes explaining why the type is not a
  /// literal type, and returns true.
  ///
  /// @param Loc  The location in the source that the non-literal type
  /// diagnostic should refer to.
  ///
  /// @param T  The type that this routine is examining for literalness.
  ///
  /// @param Diagnoser Emits a diagnostic if T is not a literal type.
  ///
  /// @returns @c true if @p T is not a literal type and a diagnostic was emitted,
  /// @c false otherwise.
  bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
                                TypeDiagnoser &Diagnoser) {
    assert(!T->isDependentType() && "type should not be dependent");
  
    QualType ElemType = Context.getBaseElementType(T);
    if ((isCompleteType(Loc, ElemType) || ElemType->isVoidType()) &&
        T->isLiteralType(Context))
      return false;
  
    Diagnoser.diagnose(*this, Loc, T);
  
    if (T->isVariableArrayType())
      return true;
  
    const RecordType *RT = ElemType->getAs<RecordType>();
    if (!RT)
      return true;
  
    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
  
    // A partially-defined class type can't be a literal type, because a literal
    // class type must have a trivial destructor (which can't be checked until
    // the class definition is complete).
    if (RequireCompleteType(Loc, ElemType, diag::note_non_literal_incomplete, T))
      return true;
  
    // [expr.prim.lambda]p3:
    //   This class type is [not] a literal type.
    if (RD->isLambda() && !getLangOpts().CPlusPlus17) {
      Diag(RD->getLocation(), diag::note_non_literal_lambda);
      return true;
    }
  
    // If the class has virtual base classes, then it's not an aggregate, and
    // cannot have any constexpr constructors or a trivial default constructor,
    // so is non-literal. This is better to diagnose than the resulting absence
    // of constexpr constructors.
    if (RD->getNumVBases()) {
      Diag(RD->getLocation(), diag::note_non_literal_virtual_base)
        << getLiteralDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases();
      for (const auto &I : RD->vbases())
        Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here)
            << I.getSourceRange();
    } else if (!RD->isAggregate() && !RD->hasConstexprNonCopyMoveConstructor() &&
               !RD->hasTrivialDefaultConstructor()) {
      Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors) << RD;
    } else if (RD->hasNonLiteralTypeFieldsOrBases()) {
      for (const auto &I : RD->bases()) {
        if (!I.getType()->isLiteralType(Context)) {
          Diag(I.getBeginLoc(), diag::note_non_literal_base_class)
              << RD << I.getType() << I.getSourceRange();
          return true;
        }
      }
      for (const auto *I : RD->fields()) {
        if (!I->getType()->isLiteralType(Context) ||
            I->getType().isVolatileQualified()) {
          Diag(I->getLocation(), diag::note_non_literal_field)
            << RD << I << I->getType()
            << I->getType().isVolatileQualified();
          return true;
        }
      }
    } else if (getLangOpts().CPlusPlus20 ? !RD->hasConstexprDestructor()
                                         : !RD->hasTrivialDestructor()) {
      // All fields and bases are of literal types, so have trivial or constexpr
      // destructors. If this class's destructor is non-trivial / non-constexpr,
      // it must be user-declared.
      CXXDestructorDecl *Dtor = RD->getDestructor();
      assert(Dtor && "class has literal fields and bases but no dtor?");
      if (!Dtor)
        return true;
  
      if (getLangOpts().CPlusPlus20) {
        Diag(Dtor->getLocation(), diag::note_non_literal_non_constexpr_dtor)
            << RD;
      } else {
        Diag(Dtor->getLocation(), Dtor->isUserProvided()
                                      ? diag::note_non_literal_user_provided_dtor
                                      : diag::note_non_literal_nontrivial_dtor)
            << RD;
        if (!Dtor->isUserProvided())
          SpecialMemberIsTrivial(Dtor, CXXDestructor, TAH_IgnoreTrivialABI,
                                 /*Diagnose*/ true);
      }
    }
  
    return true;
  }
  
  bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID) {
    BoundTypeDiagnoser<> Diagnoser(DiagID);
    return RequireLiteralType(Loc, T, Diagnoser);
  }
  
  /// Retrieve a version of the type 'T' that is elaborated by Keyword, qualified
  /// by the nested-name-specifier contained in SS, and that is (re)declared by
  /// OwnedTagDecl, which is nullptr if this is not a (re)declaration.
  QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
                                   const CXXScopeSpec &SS, QualType T,
                                   TagDecl *OwnedTagDecl) {
    if (T.isNull())
      return T;
    NestedNameSpecifier *NNS;
    if (SS.isValid())
      NNS = SS.getScopeRep();
    else {
      if (Keyword == ETK_None)
        return T;
      NNS = nullptr;
    }
    return Context.getElaboratedType(Keyword, NNS, T, OwnedTagDecl);
  }
  
  QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) {
    assert(!E->hasPlaceholderType() && "unexpected placeholder");
  
    if (!getLangOpts().CPlusPlus && E->refersToBitField())
      Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield) << 2;
  
    if (!E->isTypeDependent()) {
      QualType T = E->getType();
      if (const TagType *TT = T->getAs<TagType>())
        DiagnoseUseOfDecl(TT->getDecl(), E->getExprLoc());
    }
    return Context.getTypeOfExprType(E);
  }
  
  /// getDecltypeForParenthesizedExpr - Given an expr, will return the type for
  /// that expression, as in [dcl.type.simple]p4 but without taking id-expressions
  /// and class member access into account.
  QualType Sema::getDecltypeForParenthesizedExpr(Expr *E) {
    // C++11 [dcl.type.simple]p4:
    //   [...]
    QualType T = E->getType();
    switch (E->getValueKind()) {
    //     - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the
    //       type of e;
    case VK_XValue:
      return Context.getRValueReferenceType(T);
    //     - otherwise, if e is an lvalue, decltype(e) is T&, where T is the
    //       type of e;
    case VK_LValue:
      return Context.getLValueReferenceType(T);
    //  - otherwise, decltype(e) is the type of e.
    case VK_RValue:
      return T;
    }
    llvm_unreachable("Unknown value kind");
  }
  
  /// getDecltypeForExpr - Given an expr, will return the decltype for
  /// that expression, according to the rules in C++11
  /// [dcl.type.simple]p4 and C++11 [expr.lambda.prim]p18.
  static QualType getDecltypeForExpr(Sema &S, Expr *E) {
    if (E->isTypeDependent())
      return S.Context.DependentTy;
  
    // C++11 [dcl.type.simple]p4:
    //   The type denoted by decltype(e) is defined as follows:
  
    // C++20:
    //     - if E is an unparenthesized id-expression naming a non-type
    //       template-parameter (13.2), decltype(E) is the type of the
    //       template-parameter after performing any necessary type deduction
    // Note that this does not pick up the implicit 'const' for a template
    // parameter object. This rule makes no difference before C++20 so we apply
    // it unconditionally.
    if (const auto *SNTTPE = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
      return SNTTPE->getParameterType(S.Context);
  
    //     - if e is an unparenthesized id-expression or an unparenthesized class
    //       member access (5.2.5), decltype(e) is the type of the entity named
    //       by e. If there is no such entity, or if e names a set of overloaded
    //       functions, the program is ill-formed;
    //
    // We apply the same rules for Objective-C ivar and property references.
    if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
      const ValueDecl *VD = DRE->getDecl();
      if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD))
        return TPO->getType().getUnqualifiedType();
      return VD->getType();
    } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
      if (const ValueDecl *VD = ME->getMemberDecl())
        if (isa<FieldDecl>(VD) || isa<VarDecl>(VD))
          return VD->getType();
    } else if (const ObjCIvarRefExpr *IR = dyn_cast<ObjCIvarRefExpr>(E)) {
      return IR->getDecl()->getType();
    } else if (const ObjCPropertyRefExpr *PR = dyn_cast<ObjCPropertyRefExpr>(E)) {
      if (PR->isExplicitProperty())
        return PR->getExplicitProperty()->getType();
    } else if (auto *PE = dyn_cast<PredefinedExpr>(E)) {
      return PE->getType();
    }
  
    // C++11 [expr.lambda.prim]p18:
    //   Every occurrence of decltype((x)) where x is a possibly
    //   parenthesized id-expression that names an entity of automatic
    //   storage duration is treated as if x were transformed into an
    //   access to a corresponding data member of the closure type that
    //   would have been declared if x were an odr-use of the denoted
    //   entity.
    using namespace sema;
    if (S.getCurLambda()) {
      if (isa<ParenExpr>(E)) {
        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
          if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
            QualType T = S.getCapturedDeclRefType(Var, DRE->getLocation());
            if (!T.isNull())
              return S.Context.getLValueReferenceType(T);
          }
        }
      }
    }
  
    return S.getDecltypeForParenthesizedExpr(E);
  }
  
  QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc,
                                   bool AsUnevaluated) {
    assert(!E->hasPlaceholderType() && "unexpected placeholder");
  
    if (AsUnevaluated && CodeSynthesisContexts.empty() &&
        !E->isInstantiationDependent() && E->HasSideEffects(Context, false)) {
      // The expression operand for decltype is in an unevaluated expression
      // context, so side effects could result in unintended consequences.
      // Exclude instantiation-dependent expressions, because 'decltype' is often
      // used to build SFINAE gadgets.
      Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context);
    }
  
    return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
  }
  
  QualType Sema::BuildUnaryTransformType(QualType BaseType,
                                         UnaryTransformType::UTTKind UKind,
                                         SourceLocation Loc) {
    switch (UKind) {
    case UnaryTransformType::EnumUnderlyingType:
      if (!BaseType->isDependentType() && !BaseType->isEnumeralType()) {
        Diag(Loc, diag::err_only_enums_have_underlying_types);
        return QualType();
      } else {
        QualType Underlying = BaseType;
        if (!BaseType->isDependentType()) {
          // The enum could be incomplete if we're parsing its definition or
          // recovering from an error.
          NamedDecl *FwdDecl = nullptr;
          if (BaseType->isIncompleteType(&FwdDecl)) {
            Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
            Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
            return QualType();
          }
  
          EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
          assert(ED && "EnumType has no EnumDecl");
  
          DiagnoseUseOfDecl(ED, Loc);
  
          Underlying = ED->getIntegerType();
          assert(!Underlying.isNull());
        }
        return Context.getUnaryTransformType(BaseType, Underlying,
                                          UnaryTransformType::EnumUnderlyingType);
      }
    }
    llvm_unreachable("unknown unary transform type");
  }
  
  QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
    if (!T->isDependentType()) {
      // FIXME: It isn't entirely clear whether incomplete atomic types
      // are allowed or not; for simplicity, ban them for the moment.
      if (RequireCompleteType(Loc, T, diag::err_atomic_specifier_bad_type, 0))
        return QualType();
  
      int DisallowedKind = -1;
      if (T->isArrayType())
        DisallowedKind = 1;
      else if (T->isFunctionType())
        DisallowedKind = 2;
      else if (T->isReferenceType())
        DisallowedKind = 3;
      else if (T->isAtomicType())
        DisallowedKind = 4;
      else if (T.hasQualifiers())
        DisallowedKind = 5;
      else if (T->isSizelessType())
        DisallowedKind = 6;
      else if (!T.isTriviallyCopyableType(Context))
        // Some other non-trivially-copyable type (probably a C++ class)
        DisallowedKind = 7;
      else if (T->isExtIntType()) {
          DisallowedKind = 8;
      }
  
      if (DisallowedKind != -1) {
        Diag(Loc, diag::err_atomic_specifier_bad_type) << DisallowedKind << T;
        return QualType();
      }
  
      // FIXME: Do we need any handling for ARC here?
    }
  
    // Build the pointer type.
    return Context.getAtomicType(T);
  }
  