diff options
Diffstat (limited to 'lib/AST/ASTContext.cpp')
| -rw-r--r-- | lib/AST/ASTContext.cpp | 584 | 
1 files changed, 363 insertions, 221 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 21b6f36e9aa77..0d69eb90abaf6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1,9 +1,8 @@  //===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===//  // @@ -95,38 +94,18 @@  using namespace clang; -unsigned ASTContext::NumImplicitDefaultConstructors; -unsigned ASTContext::NumImplicitDefaultConstructorsDeclared; -unsigned ASTContext::NumImplicitCopyConstructors; -unsigned ASTContext::NumImplicitCopyConstructorsDeclared; -unsigned ASTContext::NumImplicitMoveConstructors; -unsigned ASTContext::NumImplicitMoveConstructorsDeclared; -unsigned ASTContext::NumImplicitCopyAssignmentOperators; -unsigned ASTContext::NumImplicitCopyAssignmentOperatorsDeclared; -unsigned ASTContext::NumImplicitMoveAssignmentOperators; -unsigned ASTContext::NumImplicitMoveAssignmentOperatorsDeclared; -unsigned ASTContext::NumImplicitDestructors; -unsigned ASTContext::NumImplicitDestructorsDeclared; -  enum FloatingRank {    Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank  };  RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { -  if (!CommentsLoaded && ExternalSource) { -    ExternalSource->ReadComments(); - -#ifndef NDEBUG -    ArrayRef<RawComment *> RawComments = Comments.getComments(); -    assert(std::is_sorted(RawComments.begin(), RawComments.end(), -                          BeforeThanCompare<RawComment>(SourceMgr))); -#endif - -    CommentsLoaded = true; -  } -    assert(D); +  // If we already tried to load comments but there are none, +  // we won't find anything. +  if (CommentsLoaded && Comments.getComments().empty()) +    return nullptr; +    // User can not attach documentation to implicit declarations.    if (D->isImplicit())      return nullptr; @@ -176,12 +155,6 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {        isa<TemplateTemplateParmDecl>(D))      return nullptr; -  ArrayRef<RawComment *> RawComments = Comments.getComments(); - -  // If there are no comments anywhere, we won't find anything. -  if (RawComments.empty()) -    return nullptr; -    // Find declaration location.    // For Objective-C declarations we generally don't expect to have multiple    // declarators, thus use declaration starting location as the "declaration @@ -220,6 +193,23 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {    if (DeclLoc.isInvalid() || !DeclLoc.isFileID())      return nullptr; +  if (!CommentsLoaded && ExternalSource) { +    ExternalSource->ReadComments(); + +#ifndef NDEBUG +    ArrayRef<RawComment *> RawComments = Comments.getComments(); +    assert(std::is_sorted(RawComments.begin(), RawComments.end(), +                          BeforeThanCompare<RawComment>(SourceMgr))); +#endif + +    CommentsLoaded = true; +  } + +  ArrayRef<RawComment *> RawComments = Comments.getComments(); +  // If there are no comments anywhere, we won't find anything. +  if (RawComments.empty()) +    return nullptr; +    // Find the comment that occurs just after this declaration.    ArrayRef<RawComment *>::iterator Comment;    { @@ -238,12 +228,11 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {      if (Found) {        Comment = MaybeBeforeDecl + 1; -      assert(Comment == std::lower_bound(RawComments.begin(), RawComments.end(), -                                         &CommentAtDeclLoc, Compare)); +      assert(Comment == +             llvm::lower_bound(RawComments, &CommentAtDeclLoc, Compare));      } else {        // Slow path. -      Comment = std::lower_bound(RawComments.begin(), RawComments.end(), -                                 &CommentAtDeclLoc, Compare); +      Comment = llvm::lower_bound(RawComments, &CommentAtDeclLoc, Compare);      }    } @@ -265,6 +254,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {          SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second)            == SourceMgr.getLineNumber(CommentBeginDecomp.first,                                       CommentBeginDecomp.second)) { +      (**Comment).setAttached();        return *Comment;      }    } @@ -306,6 +296,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {    if (Text.find_first_of(";{}#@") != StringRef::npos)      return nullptr; +  (**Comment).setAttached();    return *Comment;  } @@ -835,6 +826,9 @@ ASTContext::~ASTContext() {    for (const auto &Value : ModuleInitializers)      Value.second->~PerModuleInitializers(); + +  for (APValue *Value : APValueCleanups) +    Value->~APValue();  }  class ASTContext::ParentMap { @@ -913,7 +907,7 @@ void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {    Parents.reset();  } -void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { +void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {    Deallocations.push_back({Callback, Data});  } @@ -1391,24 +1385,6 @@ ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst,    TemplateOrInstantiation[Inst] = TSI;  } -FunctionDecl *ASTContext::getClassScopeSpecializationPattern( -                                                     const FunctionDecl *FD){ -  assert(FD && "Specialization is 0"); -  llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos -    = ClassScopeSpecializationPattern.find(FD); -  if (Pos == ClassScopeSpecializationPattern.end()) -    return nullptr; - -  return Pos->second; -} - -void ASTContext::setClassScopeSpecializationPattern(FunctionDecl *FD, -                                        FunctionDecl *Pattern) { -  assert(FD && "Specialization is 0"); -  assert(Pattern && "Class scope specialization pattern is 0"); -  ClassScopeSpecializationPattern[FD] = Pattern; -} -  NamedDecl *  ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) {    auto Pos = InstantiatedFromUsingDecl.find(UUD); @@ -1548,8 +1524,14 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {      return Target->getHalfFormat();    case BuiltinType::Float:      return Target->getFloatFormat();    case BuiltinType::Double:     return Target->getDoubleFormat(); -  case BuiltinType::LongDouble: return Target->getLongDoubleFormat(); -  case BuiltinType::Float128:   return Target->getFloat128Format(); +  case BuiltinType::LongDouble: +    if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) +      return AuxTarget->getLongDoubleFormat(); +    return Target->getLongDoubleFormat(); +  case BuiltinType::Float128: +    if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) +      return AuxTarget->getFloat128Format(); +    return Target->getFloat128Format();    }  } @@ -1610,8 +1592,10 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {        if (BaseT.getQualifiers().hasUnaligned())          Align = Target->getCharWidth();        if (const auto *VD = dyn_cast<VarDecl>(D)) { -        if (VD->hasGlobalStorage() && !ForAlignof) -          Align = std::max(Align, getTargetInfo().getMinGlobalAlign()); +        if (VD->hasGlobalStorage() && !ForAlignof) { +          uint64_t TypeSize = getTypeSize(T.getTypePtr()); +          Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); +        }        }      } @@ -1916,8 +1900,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {        break;      case BuiltinType::Float16:      case BuiltinType::Half: -      Width = Target->getHalfWidth(); -      Align = Target->getHalfAlign(); +      if (Target->hasFloat16Type() || !getLangOpts().OpenMP || +          !getLangOpts().OpenMPIsDevice) { +        Width = Target->getHalfWidth(); +        Align = Target->getHalfAlign(); +      } else { +        assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && +               "Expected OpenMP device compilation."); +        Width = AuxTarget->getHalfWidth(); +        Align = AuxTarget->getHalfAlign(); +      }        break;      case BuiltinType::Float:        Width = Target->getFloatWidth(); @@ -1928,12 +1920,27 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {        Align = Target->getDoubleAlign();        break;      case BuiltinType::LongDouble: -      Width = Target->getLongDoubleWidth(); -      Align = Target->getLongDoubleAlign(); +      if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && +          (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() || +           Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) { +        Width = AuxTarget->getLongDoubleWidth(); +        Align = AuxTarget->getLongDoubleAlign(); +      } else { +        Width = Target->getLongDoubleWidth(); +        Align = Target->getLongDoubleAlign(); +      }        break;      case BuiltinType::Float128: -      Width = Target->getFloat128Width(); -      Align = Target->getFloat128Align(); +      if (Target->hasFloat128Type() || !getLangOpts().OpenMP || +          !getLangOpts().OpenMPIsDevice) { +        Width = Target->getFloat128Width(); +        Align = Target->getFloat128Align(); +      } else { +        assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && +               "Expected OpenMP device compilation."); +        Width = AuxTarget->getFloat128Width(); +        Align = AuxTarget->getFloat128Align(); +      }        break;      case BuiltinType::NullPtr:        Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t) @@ -2057,6 +2064,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {    case Type::Paren:      return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr()); +  case Type::MacroQualified: +    return getTypeInfo( +        cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr()); +    case Type::ObjCTypeParam:      return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr()); @@ -2134,7 +2145,7 @@ unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {      const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());      UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());    } else { -    UnadjustedAlign = getTypeAlign(T); +    UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType());    }    MemoizedUnadjustedAlign[T] = UnadjustedAlign; @@ -2233,7 +2244,8 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {  /// getAlignOfGlobalVar - Return the alignment in bits that should be given  /// to a global variable of the specified type.  unsigned ASTContext::getAlignOfGlobalVar(QualType T) const { -  return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign()); +  uint64_t TypeSize = getTypeSize(T.getTypePtr()); +  return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign(TypeSize));  }  /// getAlignOfGlobalVarInChars - Return the alignment in characters that @@ -2574,7 +2586,7 @@ ASTContext::getBlockVarCopyInit(const VarDecl*VD) const {    return {nullptr, false};  } -/// Set the copy inialization expression of a block var decl. +/// Set the copy initialization expression of a block var decl.  void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr,                                       bool CanThrow) {    assert(VD && CopyExpr && "Passed null params"); @@ -2763,6 +2775,12 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(      return getParenType(          getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI)); +  // Might be wrapped in a macro qualified type. +  if (const auto *MQT = dyn_cast<MacroQualifiedType>(Orig)) +    return getMacroQualifiedType( +        getFunctionTypeWithExceptionSpec(MQT->getUnderlyingType(), ESI), +        MQT->getMacroIdentifier()); +    // Might have a calling-convention attribute.    if (const auto *AT = dyn_cast<AttributedType>(Orig))      return getAttributedType( @@ -2772,7 +2790,7 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(    // Anything else must be a function type. Rebuild it with the new exception    // specification. -  const auto *Proto = cast<FunctionProtoType>(Orig); +  const auto *Proto = Orig->getAs<FunctionProtoType>();    return getFunctionType(        Proto->getReturnType(), Proto->getParamTypes(),        Proto->getExtProtoInfo().withExceptionSpec(ESI)); @@ -3739,7 +3757,10 @@ QualType ASTContext::getFunctionTypeInternal(          break;        } -      case EST_DynamicNone: case EST_BasicNoexcept: case EST_NoexceptTrue: +      case EST_DynamicNone: +      case EST_BasicNoexcept: +      case EST_NoexceptTrue: +      case EST_NoThrow:          CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;          break; @@ -3938,7 +3959,7 @@ QualType ASTContext::getAttributedType(attr::Kind attrKind,    QualType canon = getCanonicalType(equivalentType);    type = new (*this, TypeAlignment) -           AttributedType(canon, attrKind, modifiedType, equivalentType); +      AttributedType(canon, attrKind, modifiedType, equivalentType);    Types.push_back(type);    AttributedTypes.InsertNode(type, insertPos); @@ -4219,6 +4240,19 @@ ASTContext::getParenType(QualType InnerType) const {    return QualType(T, 0);  } +QualType +ASTContext::getMacroQualifiedType(QualType UnderlyingTy, +                                  const IdentifierInfo *MacroII) const { +  QualType Canon = UnderlyingTy; +  if (!Canon.isCanonical()) +    Canon = getCanonicalType(UnderlyingTy); + +  auto *newType = new (*this, TypeAlignment) +      MacroQualifiedType(UnderlyingTy, Canon, MacroII); +  Types.push_back(newType); +  return QualType(newType, 0); +} +  QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,                                            NestedNameSpecifier *NNS,                                            const IdentifierInfo *Name, @@ -4356,7 +4390,13 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,    llvm::FoldingSetNodeID ID;    PackExpansionType::Profile(ID, Pattern, NumExpansions); -  assert(Pattern->containsUnexpandedParameterPack() && +  // A deduced type can deduce to a pack, eg +  //   auto ...x = some_pack; +  // That declaration isn't (yet) valid, but is created as part of building an +  // init-capture pack: +  //   [...x = some_pack] {} +  assert((Pattern->containsUnexpandedParameterPack() || +          Pattern->getContainedDeducedType()) &&           "Pack expansions must expand one or more parameter packs");    void *InsertPos = nullptr;    PackExpansionType *T @@ -4856,19 +4896,20 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,  /// deduced to the given type, or to the canonical undeduced 'auto' type, or the  /// canonical deduced-but-dependent 'auto' type.  QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, -                                 bool IsDependent) const { +                                 bool IsDependent, bool IsPack) const { +  assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack");    if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent)      return getAutoDeductType();    // Look in the folding set for an existing type.    void *InsertPos = nullptr;    llvm::FoldingSetNodeID ID; -  AutoType::Profile(ID, DeducedType, Keyword, IsDependent); +  AutoType::Profile(ID, DeducedType, Keyword, IsDependent, IsPack);    if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))      return QualType(AT, 0);    auto *AT = new (*this, TypeAlignment) -      AutoType(DeducedType, Keyword, IsDependent); +      AutoType(DeducedType, Keyword, IsDependent, IsPack);    Types.push_back(AT);    if (InsertPos)      AutoTypes.InsertNode(AT, InsertPos); @@ -4930,7 +4971,7 @@ QualType ASTContext::getAutoDeductType() const {    if (AutoDeductTy.isNull())      AutoDeductTy = QualType(        new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto, -                                          /*dependent*/false), +                                          /*dependent*/false, /*pack*/false),        0);    return AutoDeductTy;  } @@ -5218,6 +5259,11 @@ ASTContext::getNameForTemplate(TemplateName Name,      return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);    } +  case TemplateName::AssumedTemplate: { +    AssumedTemplateStorage *Storage = Name.getAsAssumedTemplateName(); +    return DeclarationNameInfo(Storage->getDeclName(), NameLoc); +  } +    case TemplateName::DependentTemplate: {      DependentTemplateName *DTN = Name.getAsDependentTemplateName();      DeclarationName DName; @@ -5265,7 +5311,8 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {    }    case TemplateName::OverloadedTemplate: -    llvm_unreachable("cannot canonicalize overloaded template"); +  case TemplateName::AssumedTemplate: +    llvm_unreachable("cannot canonicalize unresolved template");    case TemplateName::DependentTemplate: {      DependentTemplateName *DTN = Name.getAsDependentTemplateName(); @@ -5609,6 +5656,12 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const {    return -1;  } +int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const { +  if (&getFloatTypeSemantics(LHS) == &getFloatTypeSemantics(RHS)) +    return 0; +  return getFloatingTypeOrder(LHS, RHS); +} +  /// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This  /// routine will assert if passed a built-in type that isn't an integer or enum,  /// or if it is not canonicalized. @@ -6283,12 +6336,13 @@ void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,    // Encode type qualifer, 'in', 'inout', etc. for the parameter.    getObjCEncodingForTypeQualifier(QT, S);    // Encode parameter type. -  getObjCEncodingForTypeImpl(T, S, true, true, nullptr, -                             true     /*OutermostType*/, -                             false    /*EncodingProperty*/, -                             false    /*StructField*/, -                             Extended /*EncodeBlockParameters*/, -                             Extended /*EncodeClassNames*/); +  ObjCEncOptions Options = ObjCEncOptions() +                               .setExpandPointedToStructures() +                               .setExpandStructures() +                               .setIsOutermostType(); +  if (Extended) +    Options.setEncodeBlockParameters().setEncodeClassNames(); +  getObjCEncodingForTypeImpl(T, S, Options, /*Field=*/nullptr);  }  /// getObjCEncodingForMethodDecl - Return the encoded type for this method @@ -6480,9 +6534,12 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S,    // directly pointed to, and expanding embedded structures. Note that    // these rules are sufficient to prevent recursive encoding of the    // same type. -  getObjCEncodingForTypeImpl(T, S, true, true, Field, -                             true /* outermost type */, false, false, -                             false, false, false, NotEncodedT); +  getObjCEncodingForTypeImpl(T, S, +                             ObjCEncOptions() +                                 .setExpandPointedToStructures() +                                 .setExpandStructures() +                                 .setIsOutermostType(), +                             Field, NotEncodedT);  }  void ASTContext::getObjCEncodingForPropertyType(QualType T, @@ -6490,9 +6547,13 @@ void ASTContext::getObjCEncodingForPropertyType(QualType T,    // Encode result type.    // GCC has some special rules regarding encoding of properties which    // closely resembles encoding of ivars. -  getObjCEncodingForTypeImpl(T, S, true, true, nullptr, -                             true /* outermost type */, -                             true /* encoding property */); +  getObjCEncodingForTypeImpl(T, S, +                             ObjCEncOptions() +                                 .setExpandPointedToStructures() +                                 .setExpandStructures() +                                 .setIsOutermostType() +                                 .setEncodingProperty(), +                             /*Field=*/nullptr);  }  static char getObjCEncodingForPrimitiveKind(const ASTContext *C, @@ -6639,16 +6700,9 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,  }  // FIXME: Use SmallString for accumulating string. -void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, -                                            bool ExpandPointedToStructures, -                                            bool ExpandStructures, +void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, +                                            const ObjCEncOptions Options,                                              const FieldDecl *FD, -                                            bool OutermostType, -                                            bool EncodingProperty, -                                            bool StructField, -                                            bool EncodeBlockParameters, -                                            bool EncodeClassNames, -                                            bool EncodePointerToObjCTypedef,                                              QualType *NotEncodedT) const {    CanQualType CT = getCanonicalType(T);    switch (CT->getTypeClass()) { @@ -6665,14 +6719,16 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,    case Type::Complex: {      const auto *CT = T->castAs<ComplexType>();      S += 'j'; -    getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr); +    getObjCEncodingForTypeImpl(CT->getElementType(), S, ObjCEncOptions(), +                               /*Field=*/nullptr);      return;    }    case Type::Atomic: {      const auto *AT = T->castAs<AtomicType>();      S += 'A'; -    getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr); +    getObjCEncodingForTypeImpl(AT->getValueType(), S, ObjCEncOptions(), +                               /*Field=*/nullptr);      return;    } @@ -6698,11 +6754,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      // the pointer itself gets ignored, _unless_ we are looking at a typedef!      // Also, do not emit the 'r' for anything but the outermost type!      if (isa<TypedefType>(T.getTypePtr())) { -      if (OutermostType && T.isConstQualified()) { +      if (Options.IsOutermostType() && T.isConstQualified()) {          isReadOnly = true;          S += 'r';        } -    } else if (OutermostType) { +    } else if (Options.IsOutermostType()) {        QualType P = PointeeTy;        while (P->getAs<PointerType>())          P = P->getAs<PointerType>()->getPointeeType(); @@ -6742,9 +6798,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      S += '^';      getLegacyIntegralTypeEncoding(PointeeTy); -    getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures, -                               nullptr, false, false, false, false, false, false, -                               NotEncodedT); +    ObjCEncOptions NewOptions; +    if (Options.ExpandPointedToStructures()) +      NewOptions.setExpandStructures(); +    getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions, +                               /*Field=*/nullptr, NotEncodedT);      return;    } @@ -6753,12 +6811,13 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,    case Type::VariableArray: {      const auto *AT = cast<ArrayType>(CT); -    if (isa<IncompleteArrayType>(AT) && !StructField) { +    if (isa<IncompleteArrayType>(AT) && !Options.IsStructField()) {        // Incomplete arrays are encoded as a pointer to the array element.        S += '^'; -      getObjCEncodingForTypeImpl(AT->getElementType(), S, -                                 false, ExpandStructures, FD); +      getObjCEncodingForTypeImpl( +          AT->getElementType(), S, +          Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD);      } else {        S += '['; @@ -6771,10 +6830,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,          S += '0';        } -      getObjCEncodingForTypeImpl(AT->getElementType(), S, -                                 false, ExpandStructures, FD, -                                 false, false, false, false, false, false, -                                 NotEncodedT); +      getObjCEncodingForTypeImpl( +          AT->getElementType(), S, +          Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD, +          NotEncodedT);        S += ']';      }      return; @@ -6800,7 +6859,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      } else {        S += '?';      } -    if (ExpandStructures) { +    if (Options.ExpandStructures()) {        S += '=';        if (!RDecl->isUnion()) {          getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT); @@ -6814,16 +6873,16 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,            // Special case bit-fields.            if (Field->isBitField()) { -            getObjCEncodingForTypeImpl(Field->getType(), S, false, true, +            getObjCEncodingForTypeImpl(Field->getType(), S, +                                       ObjCEncOptions().setExpandStructures(),                                         Field);            } else {              QualType qt = Field->getType();              getLegacyIntegralTypeEncoding(qt); -            getObjCEncodingForTypeImpl(qt, S, false, true, -                                       FD, /*OutermostType*/false, -                                       /*EncodingProperty*/false, -                                       /*StructField*/true, -                                       false, false, false, NotEncodedT); +            getObjCEncodingForTypeImpl( +                qt, S, +                ObjCEncOptions().setExpandStructures().setIsStructField(), FD, +                NotEncodedT);            }          }        } @@ -6835,26 +6894,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,    case Type::BlockPointer: {      const auto *BT = T->castAs<BlockPointerType>();      S += "@?"; // Unlike a pointer-to-function, which is "^?". -    if (EncodeBlockParameters) { +    if (Options.EncodeBlockParameters()) {        const auto *FT = BT->getPointeeType()->castAs<FunctionType>();        S += '<';        // Block return type -      getObjCEncodingForTypeImpl( -          FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures, -          FD, false /* OutermostType */, EncodingProperty, -          false /* StructField */, EncodeBlockParameters, EncodeClassNames, false, -                                 NotEncodedT); +      getObjCEncodingForTypeImpl(FT->getReturnType(), S, +                                 Options.forComponentType(), FD, NotEncodedT);        // Block self        S += "@?";        // Block parameters        if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {          for (const auto &I : FPT->param_types()) -          getObjCEncodingForTypeImpl( -              I, S, ExpandPointedToStructures, ExpandStructures, FD, -              false /* OutermostType */, EncodingProperty, -              false /* StructField */, EncodeBlockParameters, EncodeClassNames, -                                     false, NotEncodedT); +          getObjCEncodingForTypeImpl(I, S, Options.forComponentType(), FD, +                                     NotEncodedT);        }        S += '>';      } @@ -6882,18 +6935,19 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      ObjCInterfaceDecl *OI = T->castAs<ObjCObjectType>()->getInterface();      S += '{';      S += OI->getObjCRuntimeNameAsString(); -    if (ExpandStructures) { +    if (Options.ExpandStructures()) {        S += '=';        SmallVector<const ObjCIvarDecl*, 32> Ivars;        DeepCollectObjCIvars(OI, true, Ivars);        for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {          const FieldDecl *Field = Ivars[i];          if (Field->isBitField()) -          getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field); +          getObjCEncodingForTypeImpl(Field->getType(), S, +                                     ObjCEncOptions().setExpandStructures(), +                                     Field);          else -          getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD, -                                     false, false, false, false, false, -                                     EncodePointerToObjCTypedef, +          getObjCEncodingForTypeImpl(Field->getType(), S, +                                     ObjCEncOptions().setExpandStructures(), FD,                                       NotEncodedT);        }      } @@ -6910,17 +6964,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {        // FIXME: Consider if we need to output qualifiers for 'Class<p>'. -      // Since this is a binary compatibility issue, need to consult with runtime -      // folks. Fortunately, this is a *very* obscure construct. +      // Since this is a binary compatibility issue, need to consult with +      // runtime folks. Fortunately, this is a *very* obscure construct.        S += '#';        return;      }      if (OPT->isObjCQualifiedIdType()) { -      getObjCEncodingForTypeImpl(getObjCIdType(), S, -                                 ExpandPointedToStructures, -                                 ExpandStructures, FD); -      if (FD || EncodingProperty || EncodeClassNames) { +      getObjCEncodingForTypeImpl( +          getObjCIdType(), S, +          Options.keepingOnly(ObjCEncOptions() +                                  .setExpandPointedToStructures() +                                  .setExpandStructures()), +          FD); +      if (FD || Options.EncodingProperty() || Options.EncodeClassNames()) {          // Note that we do extended encoding of protocol qualifer list          // Only when doing ivar or property encoding.          S += '"'; @@ -6934,39 +6991,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,        return;      } -    QualType PointeeTy = OPT->getPointeeType(); -    if (!EncodingProperty && -        isa<TypedefType>(PointeeTy.getTypePtr()) && -        !EncodePointerToObjCTypedef) { -      // Another historical/compatibility reason. -      // We encode the underlying type which comes out as -      // {...}; -      S += '^'; -      if (FD && OPT->getInterfaceDecl()) { -        // Prevent recursive encoding of fields in some rare cases. -        ObjCInterfaceDecl *OI = OPT->getInterfaceDecl(); -        SmallVector<const ObjCIvarDecl*, 32> Ivars; -        DeepCollectObjCIvars(OI, true, Ivars); -        for (unsigned i = 0, e = Ivars.size(); i != e; ++i) { -          if (Ivars[i] == FD) { -            S += '{'; -            S += OI->getObjCRuntimeNameAsString(); -            S += '}'; -            return; -          } -        } -      } -      getObjCEncodingForTypeImpl(PointeeTy, S, -                                 false, ExpandPointedToStructures, -                                 nullptr, -                                 false, false, false, false, false, -                                 /*EncodePointerToObjCTypedef*/true); -      return; -    } -      S += '@';      if (OPT->getInterfaceDecl() && -        (FD || EncodingProperty || EncodeClassNames)) { +        (FD || Options.EncodingProperty() || Options.EncodeClassNames())) {        S += '"';        S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();        for (const auto *I : OPT->quals()) { @@ -6980,7 +7007,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,    }    // gcc just blithely ignores member pointers. -  // FIXME: we shoul do better than that.  'M' is available. +  // FIXME: we should do better than that.  'M' is available.    case Type::MemberPointer:    // This matches gcc's encoding, even though technically it is insufficient.    //FIXME. We should do a better job than gcc. @@ -7142,11 +7169,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,        } else {          QualType qt = field->getType();          getLegacyIntegralTypeEncoding(qt); -        getObjCEncodingForTypeImpl(qt, S, false, true, FD, -                                   /*OutermostType*/false, -                                   /*EncodingProperty*/false, -                                   /*StructField*/true, -                                   false, false, false, NotEncodedT); +        getObjCEncodingForTypeImpl( +            qt, S, ObjCEncOptions().setExpandStructures().setIsStructField(), +            FD, NotEncodedT);  #ifndef NDEBUG          CurOffs += getTypeSize(field->getType());  #endif @@ -7606,6 +7631,13 @@ ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,    return TemplateName(OT);  } +/// Retrieve a template name representing an unqualified-id that has been +/// assumed to name a template for ADL purposes. +TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const { +  auto *OT = new (*this) AssumedTemplateStorage(Name); +  return TemplateName(OT); +} +  /// Retrieve the template name that represents a qualified  /// template name such as \c std::vector.  TemplateName @@ -8581,7 +8613,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,      if (lproto->isVariadic() != rproto->isVariadic())        return {}; -    if (lproto->getTypeQuals() != rproto->getTypeQuals()) +    if (lproto->getMethodQuals() != rproto->getMethodQuals())        return {};      SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos; @@ -9246,7 +9278,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,    // Read the prefixed modifiers first.    bool Done = false;    #ifndef NDEBUG -  bool IsSpecialLong = false; +  bool IsSpecial = false;    #endif    while (!Done) {      switch (*Str++) { @@ -9265,26 +9297,26 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,        Unsigned = true;        break;      case 'L': -      assert(!IsSpecialLong && "Can't use 'L' with 'W' or 'N' modifiers"); +      assert(!IsSpecial && "Can't use 'L' with 'W', 'N', 'Z' or 'O' modifiers");        assert(HowLong <= 2 && "Can't have LLLL modifier");        ++HowLong;        break;      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(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");        assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!");        #ifndef NDEBUG -      IsSpecialLong = true; +      IsSpecial = true;        #endif        if (Context.getTargetInfo().getLongWidth() == 32)          ++HowLong;        break;      case 'W':        // This modifier represents int64 type. -      assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!"); +      assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");        assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");        #ifndef NDEBUG -      IsSpecialLong = true; +      IsSpecial = true;        #endif        switch (Context.getTargetInfo().getInt64Type()) {        default: @@ -9297,6 +9329,38 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,          break;        }        break; +    case 'Z': +      // This modifier represents int32 type. +      assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!"); +      assert(HowLong == 0 && "Can't use both 'L' and 'Z' modifiers!"); +      #ifndef NDEBUG +      IsSpecial = true; +      #endif +      switch (Context.getTargetInfo().getIntTypeByWidth(32, true)) { +      default: +        llvm_unreachable("Unexpected integer type"); +      case TargetInfo::SignedInt: +        HowLong = 0; +        break; +      case TargetInfo::SignedLong: +        HowLong = 1; +        break; +      case TargetInfo::SignedLongLong: +        HowLong = 2; +        break; +      } +      break; +    case 'O': +      assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!"); +      assert(HowLong == 0 && "Can't use both 'L' and 'O' modifiers!"); +      #ifndef NDEBUG +      IsSpecial = true; +      #endif +      if (Context.getLangOpts().OpenCL) +        HowLong = 1; +      else +        HowLong = 2; +      break;      }    } @@ -9518,6 +9582,10 @@ QualType ASTContext::GetBuiltinType(unsigned Id,                                      GetBuiltinTypeError &Error,                                      unsigned *IntegerConstantArgs) const {    const char *TypeStr = BuiltinInfo.getTypeString(Id); +  if (TypeStr[0] == '\0') { +    Error = GE_Missing_type; +    return {}; +  }    SmallVector<QualType, 8> ArgTypes; @@ -9553,10 +9621,12 @@ QualType ASTContext::GetBuiltinType(unsigned Id,    assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&           "'.' should only occur at end of builtin type list!"); -  FunctionType::ExtInfo EI(CC_C); +  bool Variadic = (TypeStr[0] == '.'); + +  FunctionType::ExtInfo EI(getDefaultCallingConvention( +      Variadic, /*IsCXXMethod=*/false, /*IsBuiltin=*/true));    if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true); -  bool Variadic = (TypeStr[0] == '.');    // We really shouldn't be making a no-proto type here.    if (ArgTypes.empty() && Variadic && !getLangOpts().CPlusPlus) @@ -9784,12 +9854,12 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {        return false;    } else if (isa<PragmaCommentDecl>(D))      return true; -  else if (isa<OMPThreadPrivateDecl>(D)) -    return true;    else if (isa<PragmaDetectMismatchDecl>(D))      return true;    else if (isa<OMPThreadPrivateDecl>(D))      return !D->getDeclContext()->isDependentContext(); +  else if (isa<OMPAllocateDecl>(D)) +    return !D->getDeclContext()->isDependentContext();    else if (isa<OMPDeclareReductionDecl>(D))      return !D->getDeclContext()->isDependentContext();    else if (isa<ImportDecl>(D)) @@ -9931,34 +10001,39 @@ void ASTContext::forEachMultiversionedFunctionVersion(  }  CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, -                                                    bool IsCXXMethod) const { +                                                    bool IsCXXMethod, +                                                    bool IsBuiltin) const {    // Pass through to the C++ ABI object    if (IsCXXMethod)      return ABI->getDefaultMethodCallConv(IsVariadic); -  switch (LangOpts.getDefaultCallingConv()) { -  case LangOptions::DCC_None: -    break; -  case LangOptions::DCC_CDecl: -    return CC_C; -  case LangOptions::DCC_FastCall: -    if (getTargetInfo().hasFeature("sse2") && !IsVariadic) -      return CC_X86FastCall; -    break; -  case LangOptions::DCC_StdCall: -    if (!IsVariadic) -      return CC_X86StdCall; -    break; -  case LangOptions::DCC_VectorCall: -    // __vectorcall cannot be applied to variadic functions. -    if (!IsVariadic) -      return CC_X86VectorCall; -    break; -  case LangOptions::DCC_RegCall: -    // __regcall cannot be applied to variadic functions. -    if (!IsVariadic) -      return CC_X86RegCall; -    break; +  // Builtins ignore user-specified default calling convention and remain the +  // Target's default calling convention. +  if (!IsBuiltin) { +    switch (LangOpts.getDefaultCallingConv()) { +    case LangOptions::DCC_None: +      break; +    case LangOptions::DCC_CDecl: +      return CC_C; +    case LangOptions::DCC_FastCall: +      if (getTargetInfo().hasFeature("sse2") && !IsVariadic) +        return CC_X86FastCall; +      break; +    case LangOptions::DCC_StdCall: +      if (!IsVariadic) +        return CC_X86StdCall; +      break; +    case LangOptions::DCC_VectorCall: +      // __vectorcall cannot be applied to variadic functions. +      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);  } @@ -9978,8 +10053,10 @@ VTableContextBase *ASTContext::getVTableContext() {    return VTContext.get();  } -MangleContext *ASTContext::createMangleContext() { -  switch (Target->getCXXABI().getKind()) { +MangleContext *ASTContext::createMangleContext(const TargetInfo *T) { +  if (!T) +    T = Target; +  switch (T->getCXXABI().getKind()) {    case TargetCXXABI::GenericAArch64:    case TargetCXXABI::GenericItanium:    case TargetCXXABI::GenericARM: @@ -10010,8 +10087,7 @@ size_t ASTContext::getSideTableAllocatedMemory() const {           llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) +           llvm::capacity_in_bytes(OverriddenMethods) +           llvm::capacity_in_bytes(Types) + -         llvm::capacity_in_bytes(VariableArrayTypes) + -         llvm::capacity_in_bytes(ClassScopeSpecializationPattern); +         llvm::capacity_in_bytes(VariableArrayTypes);  }  /// getIntTypeForBitwidth - @@ -10140,6 +10216,31 @@ ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,    return MaterializedTemporaryValues.lookup(E);  } +QualType ASTContext::getStringLiteralArrayType(QualType EltTy, +                                               unsigned Length) const { +  // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). +  if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) +    EltTy = EltTy.withConst(); + +  EltTy = adjustStringLiteralBaseType(EltTy); + +  // Get an array type for the string, according to C99 6.4.5. This includes +  // the null terminator character. +  return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1), +                              ArrayType::Normal, /*IndexTypeQuals*/ 0); +} + +StringLiteral * +ASTContext::getPredefinedStringLiteralFromCache(StringRef Key) const { +  StringLiteral *&Result = StringLiteralCache[Key]; +  if (!Result) +    Result = StringLiteral::Create( +        *this, Key, StringLiteral::Ascii, +        /*Pascal*/ false, getStringLiteralArrayType(CharTy, Key.size()), +        SourceLocation()); +  return Result; +} +  bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {    const llvm::Triple &T = getTargetInfo().getTriple();    if (!T.isOSDarwin()) @@ -10485,7 +10586,13 @@ unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {  }  FixedPointSemantics ASTContext::getFixedPointSemantics(QualType Ty) const { -  assert(Ty->isFixedPointType()); +  assert((Ty->isFixedPointType() || Ty->isIntegerType()) && +         "Can only get the fixed point semantics for a " +         "fixed point or integer type."); +  if (Ty->isIntegerType()) +    return FixedPointSemantics::GetIntegerSemantics(getIntWidth(Ty), +                                                    Ty->isSignedIntegerType()); +    bool isSigned = Ty->isSignedFixedPointType();    return FixedPointSemantics(        static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned, @@ -10502,3 +10609,38 @@ APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {    assert(Ty->isFixedPointType());    return APFixedPoint::getMin(getFixedPointSemantics(Ty));  } + +QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const { +  assert(Ty->isUnsignedFixedPointType() && +         "Expected unsigned fixed point type"); +  const auto *BTy = Ty->getAs<BuiltinType>(); + +  switch (BTy->getKind()) { +  case BuiltinType::UShortAccum: +    return ShortAccumTy; +  case BuiltinType::UAccum: +    return AccumTy; +  case BuiltinType::ULongAccum: +    return LongAccumTy; +  case BuiltinType::SatUShortAccum: +    return SatShortAccumTy; +  case BuiltinType::SatUAccum: +    return SatAccumTy; +  case BuiltinType::SatULongAccum: +    return SatLongAccumTy; +  case BuiltinType::UShortFract: +    return ShortFractTy; +  case BuiltinType::UFract: +    return FractTy; +  case BuiltinType::ULongFract: +    return LongFractTy; +  case BuiltinType::SatUShortFract: +    return SatShortFractTy; +  case BuiltinType::SatUFract: +    return SatFractTy; +  case BuiltinType::SatULongFract: +    return SatLongFractTy; +  default: +    llvm_unreachable("Unexpected unsigned fixed point type"); +  } +}  | 
