diff options
Diffstat (limited to 'lib/AST/ASTContext.cpp')
| -rw-r--r-- | lib/AST/ASTContext.cpp | 687 | 
1 files changed, 520 insertions, 167 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c60373c5a90a..dd96148edb27 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1,4 +1,4 @@ -//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===// +//===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -13,33 +13,83 @@  #include "clang/AST/ASTContext.h"  #include "CXXABI.h" +#include "clang/AST/APValue.h"  #include "clang/AST/ASTMutationListener.h" +#include "clang/AST/ASTTypeTraits.h"  #include "clang/AST/Attr.h" +#include "clang/AST/AttrIterator.h"  #include "clang/AST/CharUnits.h"  #include "clang/AST/Comment.h" -#include "clang/AST/CommentCommandTraits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h"  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclContextInternals.h"  #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h"  #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclarationName.h"  #include "clang/AST/Expr.h"  #include "clang/AST/ExprCXX.h"  #include "clang/AST/ExternalASTSource.h"  #include "clang/AST/Mangle.h"  #include "clang/AST/MangleNumberingContext.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/RawCommentList.h"  #include "clang/AST/RecordLayout.h"  #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h"  #include "clang/AST/TypeLoc.h" +#include "clang/AST/UnresolvedSet.h"  #include "clang/AST/VTableBuilder.h" +#include "clang/Basic/AddressSpaces.h"  #include "clang/Basic/Builtins.h" +#include "clang/Basic/CommentOptions.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/Linkage.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/SanitizerBlacklist.h" +#include "clang/Basic/SourceLocation.h"  #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Basic/TargetCXXABI.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/XRayLists.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h"  #include "llvm/ADT/Triple.h"  #include "llvm/Support/Capacity.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <cstdlib>  #include <map> +#include <memory> +#include <string> +#include <tuple> +#include <utility>  using namespace clang; @@ -57,7 +107,7 @@ unsigned ASTContext::NumImplicitDestructors;  unsigned ASTContext::NumImplicitDestructorsDeclared;  enum FloatingRank { -  HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank +  Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank  };  RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { @@ -256,11 +306,10 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {    return *Comment;  } -namespace {  /// If we have a 'templated' declaration for a template, adjust 'D' to  /// refer to the actual template.  /// If we have an implicit instantiation, adjust 'D' to refer to template. -const Decl *adjustDeclToTemplate(const Decl *D) { +static const Decl *adjustDeclToTemplate(const Decl *D) {    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {      // Is this function declaration part of a function template?      if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) @@ -327,7 +376,6 @@ const Decl *adjustDeclToTemplate(const Decl *D) {    // FIXME: Adjust alias templates?    return D;  } -} // anonymous namespace  const RawComment *ASTContext::getRawCommentForAnyRedecl(                                                  const Decl *D, @@ -697,8 +745,8 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {    llvm_unreachable("Invalid CXXABI type!");  } -static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T, -                                             const LangOptions &LOpts) { +static const LangASMap *getAddressSpaceMap(const TargetInfo &T, +                                           const LangOptions &LOpts) {    if (LOpts.FakeAddressSpaceMap) {      // The fake address space map must have a distinct entry for each      // language-specific address space. @@ -707,6 +755,7 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,        1, // opencl_global        3, // opencl_local        2, // opencl_constant +      0, // opencl_private        4, // opencl_generic        5, // cuda_device        6, // cuda_constant @@ -736,25 +785,12 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,                         Builtin::Context &builtins)      : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()),        DependentTemplateSpecializationTypes(this_()), -      SubstTemplateTemplateParmPacks(this_()), -      GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr), -      UInt128Decl(nullptr), BuiltinVaListDecl(nullptr), -      BuiltinMSVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), -      ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), -      CFConstantStringTagDecl(nullptr), CFConstantStringTypeDecl(nullptr), -      ObjCInstanceTypeDecl(nullptr), FILEDecl(nullptr), jmp_bufDecl(nullptr), -      sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr), -      BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), -      cudaConfigureCallDecl(nullptr), FirstLocalImport(), LastLocalImport(), -      ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr), -      TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), +      SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts),        SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),        XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,                                          LangOpts.XRayNeverInstrumentFiles, SM)), -      AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),        PrintingPolicy(LOpts), Idents(idents), Selectors(sels), -      BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr), -      Listener(nullptr), Comments(SM), CommentsLoaded(false), +      BuiltinInfo(builtins), DeclarationNames(*this), Comments(SM),        CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) {    TUDecl = TranslationUnitDecl::Create(*this);  } @@ -1093,6 +1129,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,    // GNU extension, __float128 for IEEE quadruple precision    InitBuiltinType(Float128Ty,          BuiltinType::Float128); +  // C11 extension ISO/IEC TS 18661-3 +  InitBuiltinType(Float16Ty,           BuiltinType::Float16); +    // GNU extension, 128-bit integers.    InitBuiltinType(Int128Ty,            BuiltinType::Int128);    InitBuiltinType(UnsignedInt128Ty,    BuiltinType::UInt128); @@ -1182,7 +1221,14 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,    ObjCSuperType = QualType();    // void * type -  VoidPtrTy = getPointerType(VoidTy); +  if (LangOpts.OpenCLVersion >= 200) { +    auto Q = VoidTy.getQualifiers(); +    Q.setAddressSpace(LangAS::opencl_generic); +    VoidPtrTy = getPointerType(getCanonicalType( +        getQualifiedType(VoidTy.getUnqualifiedType(), Q))); +  } else { +    VoidPtrTy = getPointerType(VoidTy); +  }    // nullptr type (C++0x 2.14.7)    InitBuiltinType(NullPtrTy,           BuiltinType::NullPtr); @@ -1209,7 +1255,7 @@ AttrVec& ASTContext::getDeclAttrs(const Decl *D) {  }  /// \brief Erase the attributes corresponding to the given declaration. -void ASTContext::eraseDeclAttrs(const Decl *D) {  +void ASTContext::eraseDeclAttrs(const Decl *D) {    llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D);    if (Pos != DeclAttrs.end()) {      Pos->second->~AttrVec(); @@ -1332,35 +1378,27 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,  ASTContext::overridden_cxx_method_iterator  ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { -  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = -      OverriddenMethods.find(Method->getCanonicalDecl()); -  if (Pos == OverriddenMethods.end()) -    return nullptr; -  return Pos->second.begin(); +  return overridden_methods(Method).begin();  }  ASTContext::overridden_cxx_method_iterator  ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { -  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = -      OverriddenMethods.find(Method->getCanonicalDecl()); -  if (Pos == OverriddenMethods.end()) -    return nullptr; -  return Pos->second.end(); +  return overridden_methods(Method).end();  }  unsigned  ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const { -  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = -      OverriddenMethods.find(Method->getCanonicalDecl()); -  if (Pos == OverriddenMethods.end()) -    return 0; -  return Pos->second.size(); +  auto Range = overridden_methods(Method); +  return Range.end() - Range.begin();  }  ASTContext::overridden_method_range  ASTContext::overridden_methods(const CXXMethodDecl *Method) const { -  return overridden_method_range(overridden_methods_begin(Method), -                                 overridden_methods_end(Method)); +  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = +      OverriddenMethods.find(Method->getCanonicalDecl()); +  if (Pos == OverriddenMethods.end()) +    return overridden_method_range(nullptr, nullptr); +  return overridden_method_range(Pos->second.begin(), Pos->second.end());  }  void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,  @@ -1413,7 +1451,9 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {    assert(BT && "Not a floating point type!");    switch (BT->getKind()) {    default: llvm_unreachable("Not a floating point type!"); -  case BuiltinType::Half:       return Target->getHalfFormat(); +  case BuiltinType::Float16: +  case BuiltinType::Half: +    return Target->getHalfFormat();    case BuiltinType::Float:      return Target->getFloatFormat();    case BuiltinType::Double:     return Target->getDoubleFormat();    case BuiltinType::LongDouble: return Target->getLongDoubleFormat(); @@ -1450,7 +1490,6 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {    // else about the declaration and its type.    if (UseAlignAttrOnly) {      // do nothing -    } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {      QualType T = VD->getType();      if (const ReferenceType *RT = T->getAs<ReferenceType>()) { @@ -1624,6 +1663,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {    uint64_t Width = 0;    unsigned Align = 8;    bool AlignIsRequired = false; +  unsigned AS = 0;    switch (T->getTypeClass()) {  #define TYPE(Class, Base)  #define ABSTRACT_TYPE(Class, Base) @@ -1690,7 +1730,6 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {        Width = 0;        Align = 8;        break; -      case BuiltinType::Bool:        Width = Target->getBoolWidth();        Align = Target->getBoolAlign(); @@ -1740,6 +1779,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {        Width = 128;        Align = 128; // int128_t is 128-bit aligned on all targets.        break; +    case BuiltinType::Float16:      case BuiltinType::Half:        Width = Target->getHalfWidth();        Align = Target->getHalfAlign(); @@ -1770,60 +1810,48 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {        Width = Target->getPointerWidth(0);         Align = Target->getPointerAlign(0);        break; -    case BuiltinType::OCLSampler: { -      auto AS = getTargetAddressSpace(LangAS::opencl_constant); -      Width = Target->getPointerWidth(AS); -      Align = Target->getPointerAlign(AS); -      break; -    } +    case BuiltinType::OCLSampler:      case BuiltinType::OCLEvent:      case BuiltinType::OCLClkEvent:      case BuiltinType::OCLQueue:      case BuiltinType::OCLReserveID: -      // Currently these types are pointers to opaque types. -      Width = Target->getPointerWidth(0); -      Align = Target->getPointerAlign(0); -      break;  #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \      case BuiltinType::Id:  #include "clang/Basic/OpenCLImageTypes.def" -      { -        auto AS = getTargetAddressSpace(Target->getOpenCLImageAddrSpace()); -        Width = Target->getPointerWidth(AS); -        Align = Target->getPointerAlign(AS); -      } +      AS = getTargetAddressSpace( +          Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T))); +      Width = Target->getPointerWidth(AS); +      Align = Target->getPointerAlign(AS); +      break;      }      break;    case Type::ObjCObjectPointer:      Width = Target->getPointerWidth(0);      Align = Target->getPointerAlign(0);      break; -  case Type::BlockPointer: { -    unsigned AS = getTargetAddressSpace( -        cast<BlockPointerType>(T)->getPointeeType()); +  case Type::BlockPointer: +    AS = getTargetAddressSpace(cast<BlockPointerType>(T)->getPointeeType());      Width = Target->getPointerWidth(AS);      Align = Target->getPointerAlign(AS);      break; -  }    case Type::LValueReference: -  case Type::RValueReference: { +  case Type::RValueReference:      // alignof and sizeof should never enter this code path here, so we go      // the pointer route. -    unsigned AS = getTargetAddressSpace( -        cast<ReferenceType>(T)->getPointeeType()); +    AS = getTargetAddressSpace(cast<ReferenceType>(T)->getPointeeType());      Width = Target->getPointerWidth(AS);      Align = Target->getPointerAlign(AS);      break; -  } -  case Type::Pointer: { -    unsigned AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType()); +  case Type::Pointer: +    AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType());      Width = Target->getPointerWidth(AS);      Align = Target->getPointerAlign(AS);      break; -  }    case Type::MemberPointer: {      const MemberPointerType *MPT = cast<MemberPointerType>(T); -    std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT); +    CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT); +    Width = MPI.Width; +    Align = MPI.Align;      break;    }    case Type::Complex: { @@ -1938,11 +1966,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {    }    break; -  case Type::Pipe: { +  case Type::Pipe:      Width = Target->getPointerWidth(getTargetAddressSpace(LangAS::opencl_global));      Align = Target->getPointerAlign(getTargetAddressSpace(LangAS::opencl_global)); -  } - +    break;    }    assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2"); @@ -2055,7 +2082,6 @@ CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const {  /// super class and then collects all ivars, including those synthesized for  /// current class. This routine is used for implementation of current class  /// when all ivars, declared and synthesized are known. -///  void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,                                        bool leafClass,                              SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const { @@ -2107,6 +2133,171 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,    }  } +static bool unionHasUniqueObjectRepresentations(const ASTContext &Context, +                                                const RecordDecl *RD) { +  assert(RD->isUnion() && "Must be union type"); +  CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl()); + +  for (const auto *Field : RD->fields()) { +    if (!Context.hasUniqueObjectRepresentations(Field->getType())) +      return false; +    CharUnits FieldSize = Context.getTypeSizeInChars(Field->getType()); +    if (FieldSize != UnionSize) +      return false; +  } +  return true; +} + +bool isStructEmpty(QualType Ty) { +  const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl(); + +  if (!RD->field_empty()) +    return false; + +  if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) +    return ClassDecl->isEmpty(); + +  return true; +} + +static llvm::Optional<int64_t> +structHasUniqueObjectRepresentations(const ASTContext &Context, +                                     const RecordDecl *RD) { +  assert(!RD->isUnion() && "Must be struct/class type"); +  const auto &Layout = Context.getASTRecordLayout(RD); + +  int64_t CurOffsetInBits = 0; +  if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) { +    if (ClassDecl->isDynamicClass()) +      return llvm::None; + +    SmallVector<std::pair<QualType, int64_t>, 4> Bases; +    for (const auto Base : ClassDecl->bases()) { +      // Empty types can be inherited from, and non-empty types can potentially +      // have tail padding, so just make sure there isn't an error. +      if (!isStructEmpty(Base.getType())) { +        llvm::Optional<int64_t> Size = structHasUniqueObjectRepresentations( +            Context, Base.getType()->getAs<RecordType>()->getDecl()); +        if (!Size) +          return llvm::None; +        Bases.emplace_back(Base.getType(), Size.getValue()); +      } +    } + +    std::sort( +        Bases.begin(), Bases.end(), [&](const std::pair<QualType, int64_t> &L, +                                        const std::pair<QualType, int64_t> &R) { +          return Layout.getBaseClassOffset(L.first->getAsCXXRecordDecl()) < +                 Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl()); +        }); + +    for (const auto Base : Bases) { +      int64_t BaseOffset = Context.toBits( +          Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl())); +      int64_t BaseSize = Base.second; +      if (BaseOffset != CurOffsetInBits) +        return llvm::None; +      CurOffsetInBits = BaseOffset + BaseSize; +    } +  } + +  for (const auto *Field : RD->fields()) { +    if (!Field->getType()->isReferenceType() && +        !Context.hasUniqueObjectRepresentations(Field->getType())) +      return llvm::None; + +    int64_t FieldSizeInBits = +        Context.toBits(Context.getTypeSizeInChars(Field->getType())); +    if (Field->isBitField()) { +      int64_t BitfieldSize = Field->getBitWidthValue(Context); + +      if (BitfieldSize > FieldSizeInBits) +        return llvm::None; +      FieldSizeInBits = BitfieldSize; +    } + +    int64_t FieldOffsetInBits = Context.getFieldOffset(Field); + +    if (FieldOffsetInBits != CurOffsetInBits) +      return llvm::None; + +    CurOffsetInBits = FieldSizeInBits + FieldOffsetInBits; +  } + +  return CurOffsetInBits; +} + +bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const { +  // C++17 [meta.unary.prop]: +  //   The predicate condition for a template specialization +  //   has_unique_object_representations<T> shall be +  //   satisfied if and only if: +  //     (9.1) - T is trivially copyable, and +  //     (9.2) - any two objects of type T with the same value have the same +  //     object representation, where two objects +  //   of array or non-union class type are considered to have the same value +  //   if their respective sequences of +  //   direct subobjects have the same values, and two objects of union type +  //   are considered to have the same +  //   value if they have the same active member and the corresponding members +  //   have the same value. +  //   The set of scalar types for which this condition holds is +  //   implementation-defined. [ Note: If a type has padding +  //   bits, the condition does not hold; otherwise, the condition holds true +  //   for unsigned integral types. -- end note ] +  assert(!Ty.isNull() && "Null QualType sent to unique object rep check"); + +  // Arrays are unique only if their element type is unique. +  if (Ty->isArrayType()) +    return hasUniqueObjectRepresentations(getBaseElementType(Ty)); + +  // (9.1) - T is trivially copyable... +  if (!Ty.isTriviallyCopyableType(*this)) +    return false; + +  // All integrals and enums are unique. +  if (Ty->isIntegralOrEnumerationType()) +    return true; + +  // All other pointers are unique. +  if (Ty->isPointerType()) +    return true; + +  if (Ty->isMemberPointerType()) { +    const MemberPointerType *MPT = Ty->getAs<MemberPointerType>(); +    return !ABI->getMemberPointerInfo(MPT).HasPadding; +  } + +  if (Ty->isRecordType()) { +    const RecordDecl *Record = Ty->getAs<RecordType>()->getDecl(); + +    if (Record->isInvalidDecl()) +      return false; + +    if (Record->isUnion()) +      return unionHasUniqueObjectRepresentations(*this, Record); + +    Optional<int64_t> StructSize = +        structHasUniqueObjectRepresentations(*this, Record); + +    return StructSize && +           StructSize.getValue() == static_cast<int64_t>(getTypeSize(Ty)); +  } + +  // FIXME: More cases to handle here (list by rsmith): +  // vectors (careful about, eg, vector of 3 foo) +  // _Complex int and friends +  // _Atomic T +  // Obj-C block pointers +  // Obj-C object pointers +  // and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t, +  // clk_event_t, queue_t, reserve_id_t) +  // There're also Obj-C class types and the Obj-C selector type, but I think it +  // makes sense for those to return false here. + +  return false; +} +  unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {    unsigned count = 0;      // Count ivars declared in class extension. @@ -2139,7 +2330,8 @@ bool ASTContext::isSentinelNullExpr(const Expr *E) {    return false;  } -/// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists. +/// \brief Get the implementation of ObjCInterfaceDecl, or nullptr if none +/// exists.  ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {    llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator      I = ObjCImpls.find(D); @@ -2147,7 +2339,9 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D)      return cast<ObjCImplementationDecl>(I->second);    return nullptr;  } -/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. + +/// \brief Get the implementation of ObjCCategoryDecl, or nullptr if none +/// exists.  ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {    llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator      I = ObjCImpls.find(D); @@ -2162,6 +2356,7 @@ void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,    assert(IFaceD && ImplD && "Passed null params");    ObjCImpls[IFaceD] = ImplD;  } +  /// \brief Set the implementation of ObjCCategoryDecl.  void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,                             ObjCCategoryImplDecl *ImplD) { @@ -2195,7 +2390,7 @@ const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(    return nullptr;  } -/// \brief Get the copy initialization expression of VarDecl,or NULL if  +/// \brief Get the copy initialization expression of VarDecl, or nullptr if  /// none exists.  Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {    assert(VD && "Passed null params"); @@ -2280,8 +2475,8 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {    return QualType(eq, fastQuals);  } -QualType -ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const { +QualType ASTContext::getAddrSpaceQualType(QualType T, +                                          LangAS AddressSpace) const {    QualType CanT = getCanonicalType(T);    if (CanT.getAddressSpace() == AddressSpace)      return T; @@ -2300,6 +2495,27 @@ ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const {    return getExtQualType(TypeNode, Quals);  } +QualType ASTContext::removeAddrSpaceQualType(QualType T) const { +  // If we are composing extended qualifiers together, merge together +  // into one ExtQuals node. +  QualifierCollector Quals; +  const Type *TypeNode = Quals.strip(T); + +  // If the qualifier doesn't have an address space just return it. +  if (!Quals.hasAddressSpace()) +    return T; + +  Quals.removeAddressSpace(); + +  // Removal of the address space can mean there are no longer any +  // non-fast qualifiers, so creating an ExtQualType isn't possible (asserts) +  // or required. +  if (Quals.hasNonFastQualifiers()) +    return getExtQualType(TypeNode, Quals); +  else +    return QualType(TypeNode, Quals.getFastQualifiers()); +} +  QualType ASTContext::getObjCGCQualType(QualType T,                                         Qualifiers::GC GCAttr) const {    QualType CanT = getCanonicalType(T); @@ -2393,7 +2609,7 @@ static QualType getFunctionTypeWithExceptionSpec(  bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,                                                            QualType U) {    return hasSameType(T, U) || -         (getLangOpts().CPlusPlus1z && +         (getLangOpts().CPlusPlus17 &&            hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),                        getFunctionTypeWithExceptionSpec(*this, U, EST_None)));  } @@ -2750,6 +2966,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {    case Type::Vector:    case Type::ExtVector:    case Type::DependentSizedExtVector: +  case Type::DependentAddressSpace:    case Type::ObjCObject:    case Type::ObjCInterface:    case Type::ObjCObjectPointer: @@ -3098,6 +3315,41 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,    return QualType(New, 0);  } +QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,  +                                                  Expr *AddrSpaceExpr,  +                                                  SourceLocation AttrLoc) const { +  assert(AddrSpaceExpr->isInstantiationDependent());  + +  QualType canonPointeeType = getCanonicalType(PointeeType); + +  void *insertPos = nullptr; +  llvm::FoldingSetNodeID ID; +  DependentAddressSpaceType::Profile(ID, *this, canonPointeeType, +                                     AddrSpaceExpr); + +  DependentAddressSpaceType *canonTy = +    DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos); + +  if (!canonTy) { +    canonTy = new (*this, TypeAlignment) +      DependentAddressSpaceType(*this, canonPointeeType,  +                                QualType(), AddrSpaceExpr, AttrLoc); +    DependentAddressSpaceTypes.InsertNode(canonTy, insertPos); +    Types.push_back(canonTy); +  } +     +  if (canonPointeeType == PointeeType && +      canonTy->getAddrSpaceExpr() == AddrSpaceExpr) +    return QualType(canonTy, 0);      + +  DependentAddressSpaceType *sugaredType +    = new (*this, TypeAlignment) +        DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),  +                                  AddrSpaceExpr, AttrLoc); +  Types.push_back(sugaredType); +  return QualType(sugaredType, 0);   +} +  /// \brief Determine whether \p T is canonical as the result type of a function.  static bool isCanonicalResultType(QualType T) {    return T.isCanonical() && @@ -3106,7 +3358,6 @@ static bool isCanonicalResultType(QualType T) {  }  /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. -///  QualType  ASTContext::getFunctionNoProtoType(QualType ResultTy,                                     const FunctionType::ExtInfo &Info) const { @@ -3222,7 +3473,7 @@ QualType ASTContext::getFunctionTypeInternal(      Unique = true;    } -  bool NoexceptInType = getLangOpts().CPlusPlus1z; +  bool NoexceptInType = getLangOpts().CPlusPlus17;    bool IsCanonicalExceptionSpec =        isCanonicalExceptionSpecification(EPI.ExceptionSpec, NoexceptInType); @@ -3358,7 +3609,7 @@ QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {    llvm::FoldingSetNodeID ID;    PipeType::Profile(ID, T, ReadOnly); -  void *InsertPos = 0; +  void *InsertPos = nullptr;    if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos))      return QualType(PT, 0); @@ -3986,7 +4237,7 @@ SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) {  QualType ASTContext::getObjCObjectType(QualType BaseType,                                         ObjCProtocolDecl * const *Protocols,                                         unsigned NumProtocols) const { -  return getObjCObjectType(BaseType, { }, +  return getObjCObjectType(BaseType, {},                             llvm::makeArrayRef(Protocols, NumProtocols),                             /*isKindOf=*/false);  } @@ -4123,13 +4374,13 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,      // FIXME: Check for protocols to which the class type is already      // known to conform. -    return getObjCObjectType(type, { }, protocols, false); +    return getObjCObjectType(type, {}, protocols, false);    }    // id<protocol-list>    if (type->isObjCIdType()) {      const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>(); -    type = getObjCObjectType(ObjCBuiltinIdTy, { }, protocols, +    type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols,                                   objPtr->isKindOfType());      return getObjCObjectPointerType(type);    } @@ -4137,7 +4388,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,    // Class<protocol-list>    if (type->isObjCClassType()) {      const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>(); -    type = getObjCObjectType(ObjCBuiltinClassTy, { }, protocols, +    type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols,                                   objPtr->isKindOfType());      return getObjCObjectPointerType(type);    } @@ -4512,7 +4763,7 @@ QualType ASTContext::getAutoRRefDeductType() const {  /// getTagDeclType - Return the unique reference to the type for the  /// specified TagDecl (struct/union/class/enum) decl.  QualType ASTContext::getTagDeclType(const TagDecl *Decl) const { -  assert (Decl); +  assert(Decl);    // FIXME: What is the design on getTagDeclType when it requires casting    // away const?  mutable?    return getTypeDeclType(const_cast<TagDecl*>(Decl)); @@ -4569,6 +4820,13 @@ QualType ASTContext::getPointerDiffType() const {    return getFromTargetType(Target->getPtrDiffType(0));  } +/// \brief Return the unique unsigned counterpart of "ptrdiff_t" +/// integer type. The standard (C11 7.21.6.1p7) refers to this type +/// in the definition of %tu format specifier. +QualType ASTContext::getUnsignedPointerDiffType() const { +  return getFromTargetType(Target->getUnsignedPtrDiffType(0)); +} +  /// \brief Return the unique type for "pid_t" defined in  /// <sys/types.h>. We need this to compute the correct type for vfork().  QualType ASTContext::getProcessIDType() const { @@ -5051,6 +5309,7 @@ static FloatingRank getFloatingRank(QualType T) {    assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");    switch (T->getAs<BuiltinType>()->getKind()) {    default: llvm_unreachable("getFloatingRank(): not a floating type"); +  case BuiltinType::Float16:    return Float16Rank;    case BuiltinType::Half:       return HalfRank;    case BuiltinType::Float:      return FloatRank;    case BuiltinType::Double:     return DoubleRank; @@ -5068,6 +5327,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,    FloatingRank EltRank = getFloatingRank(Size);    if (Domain->isComplexType()) {      switch (EltRank) { +    case Float16Rank:      case HalfRank: llvm_unreachable("Complex half is not supported");      case FloatRank:      return FloatComplexTy;      case DoubleRank:     return DoubleComplexTy; @@ -5078,6 +5338,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,    assert(Domain->isRealFloatingType() && "Unknown domain!");    switch (EltRank) { +  case Float16Rank:    return HalfTy;    case HalfRank:       return HalfTy;    case FloatRank:      return FloatTy;    case DoubleRank:     return DoubleTy; @@ -5455,6 +5716,46 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {    return getTagDeclType(BlockDescriptorExtendedType);  } +TargetInfo::OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const { +  auto BT = dyn_cast<BuiltinType>(T); + +  if (!BT) { +    if (isa<PipeType>(T)) +      return TargetInfo::OCLTK_Pipe; + +    return TargetInfo::OCLTK_Default; +  } + +  switch (BT->getKind()) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \ +  case BuiltinType::Id:                                                        \ +    return TargetInfo::OCLTK_Image; +#include "clang/Basic/OpenCLImageTypes.def" + +  case BuiltinType::OCLClkEvent: +    return TargetInfo::OCLTK_ClkEvent; + +  case BuiltinType::OCLEvent: +    return TargetInfo::OCLTK_Event; + +  case BuiltinType::OCLQueue: +    return TargetInfo::OCLTK_Queue; + +  case BuiltinType::OCLReserveID: +    return TargetInfo::OCLTK_ReserveID; + +  case BuiltinType::OCLSampler: +    return TargetInfo::OCLTK_Sampler; + +  default: +    return TargetInfo::OCLTK_Default; +  } +} + +LangAS ASTContext::getOpenCLTypeAddrSpace(const Type *T) const { +  return Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T)); +} +  /// BlockRequiresCopying - Returns true if byref variable "D" of type "Ty"  /// requires copy/dispose. Note that this must match the logic  /// in buildByrefHelpers. @@ -5497,7 +5798,6 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,  bool ASTContext::getByrefLifetime(QualType Ty,                                Qualifiers::ObjCLifetime &LifeTime,                                bool &HasByrefExtendedLayout) const { -      if (!getLangOpts().ObjC1 ||        getLangOpts().getGC() != LangOptions::NonGC)      return false; @@ -5565,14 +5865,14 @@ ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {    // In almost all cases, it's a weak definition.    auto *First = VD->getFirstDecl(); -  if (!First->isConstexpr() || First->isInlineSpecified() || -      !VD->isStaticDataMember()) +  if (First->isInlineSpecified() || !First->isStaticDataMember())      return InlineVariableDefinitionKind::Weak;    // If there's a file-context declaration in this translation unit, it's a    // non-discardable definition.    for (auto *D : VD->redecls()) -    if (D->getLexicalDeclContext()->isFileContext()) +    if (D->getLexicalDeclContext()->isFileContext() && +        !D->isInlineSpecified() && (D->isConstexpr() || First->isConstexpr()))        return InlineVariableDefinitionKind::Strong;    // If we've not seen one yet, we don't know. @@ -5602,7 +5902,6 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {    // Compute size of all parameters.    // Start with computing size of a pointer in number of bytes.    // FIXME: There might(should) be a better way of doing this computation! -  SourceLocation Loc;    CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);    CharUnits ParmOffset = PtrSize;    for (auto PI : Decl->parameters()) { @@ -5610,7 +5909,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {      CharUnits sz = getObjCEncodingTypeSize(PType);      if (sz.isZero())        continue; -    assert (sz.isPositive() && "BlockExpr - Incomplete param type"); +    assert(sz.isPositive() && "BlockExpr - Incomplete param type");      ParmOffset += sz;    }    // Size of the argument frame @@ -5710,7 +6009,6 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,    // Compute size of all parameters.    // Start with computing size of a pointer in number of bytes.    // FIXME: There might(should) be a better way of doing this computation! -  SourceLocation Loc;    CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);    // The first two arguments (self and _cmd) are pointers; account for    // their size. @@ -5722,8 +6020,8 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,      if (sz.isZero())        continue; -    assert (sz.isPositive() &&  -        "getObjCEncodingForMethodDecl - Incomplete param type"); +    assert(sz.isPositive() &&  +           "getObjCEncodingForMethodDecl - Incomplete param type");      ParmOffset += sz;    }    S += charUnitsToString(ParmOffset); @@ -5870,7 +6168,6 @@ ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,  /// Another legacy compatibility encoding: 32-bit longs are encoded as  /// 'l' or 'L' , but not always.  For typedefs, we need to use  /// 'i' or 'I' instead if encoding a struct field, or a pointer! -///  void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const {    if (isa<TypedefType>(PointeeTy.getTypePtr())) {      if (const BuiltinType *BT = PointeeTy->getAs<BuiltinType>()) { @@ -5935,6 +6232,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,      case BuiltinType::LongDouble: return 'D';      case BuiltinType::NullPtr:    return '*'; // like char* +    case BuiltinType::Float16:      case BuiltinType::Float128:      case BuiltinType::Half:        // FIXME: potentially need @encodes for these! @@ -6176,9 +6474,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,            = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {          const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();          llvm::raw_string_ostream OS(S); -        TemplateSpecializationType::PrintTemplateArgumentList(OS, -                                            TemplateArgs.asArray(), -                                            (*this).getPrintingPolicy()); +        printTemplateArgumentList(OS, TemplateArgs.asArray(), +                                  getPrintingPolicy());        }      } else {        S += '?'; @@ -6370,10 +6667,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,    case Type::Vector:    case Type::ExtVector:    // Until we have a coherent encoding of these three types, issue warning. -    { if (NotEncodedT) -        *NotEncodedT = T; -      return; -    } +    if (NotEncodedT) +      *NotEncodedT = T; +    return;    // We could see an undeduced auto type here during error recovery.    // Just ignore it. @@ -6557,7 +6853,7 @@ void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,  TypedefDecl *ASTContext::getObjCIdDecl() const {    if (!ObjCIdDecl) { -    QualType T = getObjCObjectType(ObjCBuiltinIdTy, { }, { }); +    QualType T = getObjCObjectType(ObjCBuiltinIdTy, {}, {});      T = getObjCObjectPointerType(T);      ObjCIdDecl = buildImplicitTypedef(T, "id");    } @@ -6574,7 +6870,7 @@ TypedefDecl *ASTContext::getObjCSelDecl() const {  TypedefDecl *ASTContext::getObjCClassDecl() const {    if (!ObjCClassDecl) { -    QualType T = getObjCObjectType(ObjCBuiltinClassTy, { }, { }); +    QualType T = getObjCObjectType(ObjCBuiltinClassTy, {}, {});      T = getObjCObjectPointerType(T);      ObjCClassDecl = buildImplicitTypedef(T, "Class");    } @@ -7236,7 +7532,7 @@ bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,                                                        QualType rhs) {    const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>();    const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>(); -  assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible"); +  assert((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");    for (auto *lhsProto : lhsQID->quals()) {      bool match = false; @@ -7374,7 +7670,6 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,  /// canAssignObjCInterfaces - Return true if the two interface types are  /// compatible for assignment from RHS to LHS.  This handles validation of any  /// protocol qualifiers on the LHS or RHS. -///  bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,                                           const ObjCObjectPointerType *RHSOPT) {    const ObjCObjectType* LHS = LHSOPT->getObjectType(); @@ -7480,7 +7775,6 @@ bool ASTContext::canAssignObjCInterfacesInBlockPointer(  static int compareObjCProtocolsByName(ObjCProtocolDecl * const *lhs,                                        ObjCProtocolDecl * const *rhs) {    return (*lhs)->getName().compare((*rhs)->getName()); -  }  /// getIntersectionOfProtocols - This routine finds the intersection of set @@ -7649,7 +7943,7 @@ QualType ASTContext::areCommonBaseCompatible(        } else if (LHS->isSpecialized() != RHS->isSpecialized()) {          // If only one has type arguments, the result will not have type          // arguments. -        LHSTypeArgs = { }; +        LHSTypeArgs = {};          anyChanges = true;        } @@ -7700,7 +7994,7 @@ QualType ASTContext::areCommonBaseCompatible(        } else if (LHS->isSpecialized() != RHS->isSpecialized()) {          // If only one has type arguments, the result will not have type          // arguments. -        RHSTypeArgs = { }; +        RHSTypeArgs = {};          anyChanges = true;        } @@ -7962,9 +8256,17 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,      if (lproto->getTypeQuals() != rproto->getTypeQuals())        return QualType(); -    if (!doFunctionTypesMatchOnExtParameterInfos(rproto, lproto)) +    SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos; +    bool canUseLeft, canUseRight; +    if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight, +                               newParamInfos))        return QualType(); +    if (!canUseLeft) +      allLTypes = false; +    if (!canUseRight) +      allRTypes = false; +      // Check parameter type compatibility      SmallVector<QualType, 10> types;      for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) { @@ -7995,6 +8297,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,      FunctionProtoType::ExtProtoInfo EPI = lproto->getExtProtoInfo();      EPI.ExtInfo = einfo; +    EPI.ExtParameterInfos = +        newParamInfos.empty() ? nullptr : newParamInfos.data();      return getFunctionType(retType, types, EPI);    } @@ -8328,7 +8632,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,      return QualType();    } -  case Type::ObjCObjectPointer: { +  case Type::ObjCObjectPointer:      if (OfBlockPointer) {        if (canAssignObjCInterfacesInBlockPointer(                                            LHS->getAs<ObjCObjectPointerType>(), @@ -8342,38 +8646,59 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,        return LHS;      return QualType(); -  }    case Type::Pipe: -  {      assert(LHS != RHS &&             "Equivalent pipe types should have already been handled!");      return QualType();    } -  }    llvm_unreachable("Invalid Type::Class!");  } -bool ASTContext::doFunctionTypesMatchOnExtParameterInfos( -                   const FunctionProtoType *firstFnType, -                   const FunctionProtoType *secondFnType) { +bool ASTContext::mergeExtParameterInfo( +    const FunctionProtoType *FirstFnType, const FunctionProtoType *SecondFnType, +    bool &CanUseFirst, bool &CanUseSecond, +    SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos) { +  assert(NewParamInfos.empty() && "param info list not empty"); +  CanUseFirst = CanUseSecond = true; +  bool FirstHasInfo = FirstFnType->hasExtParameterInfos(); +  bool SecondHasInfo = SecondFnType->hasExtParameterInfos(); +    // Fast path: if the first type doesn't have ext parameter infos, -  // we match if and only if they second type also doesn't have them. -  if (!firstFnType->hasExtParameterInfos()) -    return !secondFnType->hasExtParameterInfos(); +  // we match if and only if the second type also doesn't have them. +  if (!FirstHasInfo && !SecondHasInfo) +    return true; -  // Otherwise, we can only match if the second type has them. -  if (!secondFnType->hasExtParameterInfos()) -    return false; +  bool NeedParamInfo = false; +  size_t E = FirstHasInfo ? FirstFnType->getExtParameterInfos().size() +                          : SecondFnType->getExtParameterInfos().size(); -  auto firstEPI = firstFnType->getExtParameterInfos(); -  auto secondEPI = secondFnType->getExtParameterInfos(); -  assert(firstEPI.size() == secondEPI.size()); +  for (size_t I = 0; I < E; ++I) { +    FunctionProtoType::ExtParameterInfo FirstParam, SecondParam; +    if (FirstHasInfo) +      FirstParam = FirstFnType->getExtParameterInfo(I); +    if (SecondHasInfo) +      SecondParam = SecondFnType->getExtParameterInfo(I); -  for (size_t i = 0, n = firstEPI.size(); i != n; ++i) { -    if (firstEPI[i] != secondEPI[i]) +    // Cannot merge unless everything except the noescape flag matches. +    if (FirstParam.withIsNoEscape(false) != SecondParam.withIsNoEscape(false))        return false; + +    bool FirstNoEscape = FirstParam.isNoEscape(); +    bool SecondNoEscape = SecondParam.isNoEscape(); +    bool IsNoEscape = FirstNoEscape && SecondNoEscape; +    NewParamInfos.push_back(FirstParam.withIsNoEscape(IsNoEscape)); +    if (NewParamInfos.back().getOpaqueValue()) +      NeedParamInfo = true; +    if (FirstNoEscape != IsNoEscape) +      CanUseFirst = false; +    if (SecondNoEscape != IsNoEscape) +      CanUseSecond = false;    } + +  if (!NeedParamInfo) +    NewParamInfos.clear(); +    return true;  } @@ -8502,7 +8827,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {    }  } -ASTMutationListener::~ASTMutationListener() { } +ASTMutationListener::~ASTMutationListener() = default;  void ASTMutationListener::DeducedReturnType(const FunctionDecl *FD,                                              QualType ReturnType) {} @@ -8554,7 +8879,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,        assert(HowLong <= 2 && "Can't have LLLL modifier");        ++HowLong;        break; -    case 'N': { +    case 'N':        // 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise.        assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");        assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!"); @@ -8564,7 +8889,6 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,        if (Context.getTargetInfo().getLongWidth() == 32)          ++HowLong;        break; -    }      case 'W':        // This modifier represents int64 type.        assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!"); @@ -8719,10 +9043,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,      Type = Context.getComplexType(ElementType);      break;    }   -  case 'Y' : { +  case 'Y':      Type = Context.getPointerDiffType();      break; -  }    case 'P':      Type = Context.getFILEType();      if (Type.isNull()) { @@ -8767,8 +9090,8 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,        char *End;        unsigned AddrSpace = strtoul(Str, &End, 10);        if (End != Str && AddrSpace != 0) { -        Type = Context.getAddrSpaceQualType( -            Type, AddrSpace + LangAS::FirstTargetAddressSpace); +        Type = Context.getAddrSpaceQualType(Type, +                                            getLangASFromTargetAS(AddrSpace));          Str = End;        }        if (c == '*') @@ -8860,6 +9183,12 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,    if (!FD->isExternallyVisible())      return GVA_Internal; +  // Non-user-provided functions get emitted as weak definitions with every +  // use, no matter whether they've been explicitly instantiated etc. +  if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) +    if (!MD->isUserProvided()) +      return GVA_DiscardableODR; +    GVALinkage External;    switch (FD->getTemplateSpecializationKind()) {    case TSK_Undeclared: @@ -8912,7 +9241,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,  }  static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context, -                                                GVALinkage L, const Decl *D) { +                                                const Decl *D, GVALinkage L) {    // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx    // dllexport/dllimport on inline functions.    if (D->hasAttr<DLLImportAttr>()) { @@ -8931,25 +9260,37 @@ static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,    return L;  } -GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { -  auto L = adjustGVALinkageForAttributes( -      *this, basicGVALinkageForFunction(*this, FD), FD); -  auto EK = ExternalASTSource::EK_ReplyHazy; -  if (auto *Ext = getExternalSource()) -    EK = Ext->hasExternalDefinitions(FD); -  switch (EK) { +/// Adjust the GVALinkage for a declaration based on what an external AST source +/// knows about whether there can be other definitions of this declaration. +static GVALinkage +adjustGVALinkageForExternalDefinitionKind(const ASTContext &Ctx, const Decl *D, +                                          GVALinkage L) { +  ExternalASTSource *Source = Ctx.getExternalSource(); +  if (!Source) +    return L; + +  switch (Source->hasExternalDefinitions(D)) {    case ExternalASTSource::EK_Never: +    // Other translation units rely on us to provide the definition.      if (L == GVA_DiscardableODR)        return GVA_StrongODR;      break; +    case ExternalASTSource::EK_Always:      return GVA_AvailableExternally; +    case ExternalASTSource::EK_ReplyHazy:      break;    }    return L;  } +GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { +  return adjustGVALinkageForExternalDefinitionKind(*this, FD, +           adjustGVALinkageForAttributes(*this, FD, +             basicGVALinkageForFunction(*this, FD))); +} +  static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,                                               const VarDecl *VD) {    if (!VD->isExternallyVisible()) @@ -9028,8 +9369,9 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,  }  GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { -  return adjustGVALinkageForAttributes( -      *this, basicGVALinkageForVariable(*this, VD), VD); +  return adjustGVALinkageForExternalDefinitionKind(*this, VD, +           adjustGVALinkageForAttributes(*this, VD, +             basicGVALinkageForVariable(*this, VD)));  }  bool ASTContext::DeclMustBeEmitted(const Decl *D) { @@ -9112,9 +9454,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {      return false;    // Variables that can be needed in other TUs are required. -  if (!isDiscardableGVALinkage(GetGVALinkageForVariable(VD))) +  auto Linkage = GetGVALinkageForVariable(VD); +  if (!isDiscardableGVALinkage(Linkage))      return true; +  // We never need to emit a variable that is available in another TU. +  if (Linkage == GVA_AvailableExternally) +    return false; +    // Variables that have destruction with side-effects are required.    if (VD->getType().isDestructedType())      return true; @@ -9148,7 +9495,7 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,    case LangOptions::DCC_CDecl:      return CC_C;    case LangOptions::DCC_FastCall: -    if (getTargetInfo().hasFeature("sse2")) +    if (getTargetInfo().hasFeature("sse2") && !IsVariadic)        return CC_X86FastCall;      break;    case LangOptions::DCC_StdCall: @@ -9160,6 +9507,11 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,      if (!IsVariadic)        return CC_X86VectorCall;      break; +  case LangOptions::DCC_RegCall: +    // __regcall cannot be applied to variadic functions. +    if (!IsVariadic) +      return CC_X86RegCall; +    break;    }    return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown);  } @@ -9196,7 +9548,7 @@ MangleContext *ASTContext::createMangleContext() {    llvm_unreachable("Unsupported ABI");  } -CXXABI::~CXXABI() {} +CXXABI::~CXXABI() = default;  size_t ASTContext::getSideTableAllocatedMemory() const {    return ASTRecordLayouts.getMemorySize() + @@ -9359,9 +9711,7 @@ bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {    return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits);  } -namespace { - -ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap( +static ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(      ASTContext::ParentMapPointers::mapped_type U) {    if (const auto *D = U.dyn_cast<const Decl *>())      return ast_type_traits::DynTypedNode::create(*D); @@ -9370,6 +9720,8 @@ ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(    return *U.get<ast_type_traits::DynTypedNode *>();  } +namespace { +  /// Template specializations to abstract away from pointers and TypeLocs.  /// @{  template <typename T> @@ -9410,7 +9762,9 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {      }    private: -    typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase; +    friend class RecursiveASTVisitor<ParentMapASTVisitor>; + +    using VisitorBase = RecursiveASTVisitor<ParentMapASTVisitor>;      ParentMapASTVisitor(ASTContext::ParentMapPointers *Parents,                          ASTContext::ParentMapOtherNodes *OtherParents) @@ -9419,6 +9773,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {      bool shouldVisitTemplateInstantiations() const {        return true;      } +      bool shouldVisitImplicitCode() const {        return true;      } @@ -9508,11 +9863,9 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {      ASTContext::ParentMapPointers *Parents;      ASTContext::ParentMapOtherNodes *OtherParents;      llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; - -    friend class RecursiveASTVisitor<ParentMapASTVisitor>;    }; -} // anonymous namespace +} // namespace  template <typename NodeTy, typename MapTy>  static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node, @@ -9568,25 +9921,25 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,      if (!hasSameType(DeclVar->getType(), ImplVar->getType()))        return false;    } +    return (MethodDecl->isVariadic() == MethodImpl->isVariadic()); -    }  uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const { -  unsigned AS; +  LangAS AS;    if (QT->getUnqualifiedDesugaredType()->isNullPtrType()) -    AS = 0; +    AS = LangAS::Default;    else      AS = QT->getPointeeType().getAddressSpace();    return getTargetInfo().getNullPointerValue(AS);  } -unsigned ASTContext::getTargetAddressSpace(unsigned AS) const { -  if (AS >= LangAS::FirstTargetAddressSpace) -    return AS - LangAS::FirstTargetAddressSpace; +unsigned ASTContext::getTargetAddressSpace(LangAS AS) const { +  if (isTargetAddressSpace(AS)) +    return toTargetAddressSpace(AS);    else -    return (*AddrSpaceMap)[AS]; +    return (*AddrSpaceMap)[(unsigned)AS];  }  // Explicitly instantiate this in case a Redeclarable<T> is used from a TU that  | 
