diff options
Diffstat (limited to 'lib/AST/ASTContext.cpp')
| -rw-r--r-- | lib/AST/ASTContext.cpp | 816 | 
1 files changed, 533 insertions, 283 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 176aec53a2520..a03cf9e7d47bf 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -25,13 +25,16 @@  #include "clang/AST/ExprCXX.h"  #include "clang/AST/ExternalASTSource.h"  #include "clang/AST/Mangle.h" +#include "clang/AST/MangleNumberingContext.h"  #include "clang/AST/RecordLayout.h" +#include "clang/AST/RecursiveASTVisitor.h"  #include "clang/AST/TypeLoc.h"  #include "clang/Basic/Builtins.h"  #include "clang/Basic/SourceManager.h"  #include "clang/Basic/TargetInfo.h"  #include "llvm/ADT/SmallString.h"  #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h"  #include "llvm/Support/Capacity.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h" @@ -132,8 +135,14 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {        isa<RedeclarableTemplateDecl>(D) ||        isa<ClassTemplateSpecializationDecl>(D))      DeclLoc = D->getLocStart(); -  else +  else {      DeclLoc = D->getLocation(); +    // If location of the typedef name is in a macro, it is because being +    // declared via a macro. Try using declaration's starting location +    // as the "declaration location". +    if (DeclLoc.isMacroID() && isa<TypedefDecl>(D)) +      DeclLoc = D->getLocStart(); +  }    // If the declaration doesn't map directly to a location in a file, we    // can't find the comment. @@ -175,7 +184,8 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {    // First check whether we have a trailing comment.    if (Comment != RawComments.end() &&        (*Comment)->isDocumentation() && (*Comment)->isTrailingComment() && -      (isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D))) { +      (isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) || +       isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) {      std::pair<FileID, unsigned> CommentBeginDecomp        = SourceMgr.getDecomposedLoc((*Comment)->getSourceRange().getBegin());      // Check that Doxygen trailing comment comes after the declaration, starts @@ -220,7 +230,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {    // There should be no other declarations or preprocessor directives between    // comment and declaration. -  if (Text.find_first_of(",;{}#@") != StringRef::npos) +  if (Text.find_first_of(";{}#@") != StringRef::npos)      return NULL;    return *Comment; @@ -406,9 +416,16 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,  } +comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const { +  const RawComment *RC = getRawCommentForDeclNoCache(D); +  return RC ? RC->parse(*this, 0, D) : 0; +} +  comments::FullComment *ASTContext::getCommentForDecl(                                                const Decl *D,                                                const Preprocessor *PP) const { +  if (D->isInvalidDecl()) +    return NULL;    D = adjustDeclToTemplate(D);    const Decl *Canonical = D->getCanonicalDecl(); @@ -679,6 +696,19 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,    }  } +static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, +                                          const LangOptions &LangOpts) { +  switch (LangOpts.getAddressSpaceMapMangling()) { +  case LangOptions::ASMM_Target: +    return TI.useAddressSpaceMapMangling(); +  case LangOptions::ASMM_On: +    return true; +  case LangOptions::ASMM_Off: +    return false; +  } +  llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything."); +} +  ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,                         const TargetInfo *t,                         IdentifierTable &idents, SelectorTable &sels, @@ -690,7 +720,7 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,      DependentTemplateSpecializationTypes(this_()),      SubstTemplateTemplateParmPacks(this_()),      GlobalNestedNameSpecifier(0),  -    Int128Decl(0), UInt128Decl(0), +    Int128Decl(0), UInt128Decl(0), Float128StubDecl(0),      BuiltinVaListDecl(0),      ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0),      BOOLDecl(0), @@ -709,8 +739,7 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,      ExternalSource(0), Listener(0),      Comments(SM), CommentsLoaded(false),      CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), -    LastSDM(0, 0), -    UniqueBlockByRefTypeID(0) +    LastSDM(0, 0)  {    if (size_reserve > 0) Types.reserve(size_reserve);    TUDecl = TranslationUnitDecl::Create(*this); @@ -726,10 +755,12 @@ ASTContext::~ASTContext() {    // FIXME: Is this the ideal solution?    ReleaseDeclContextMaps(); -  // Call all of the deallocation functions. -  for (unsigned I = 0, N = Deallocations.size(); I != N; ++I) -    Deallocations[I].first(Deallocations[I].second); -   +  // Call all of the deallocation functions on all of their targets. +  for (DeallocationMap::const_iterator I = Deallocations.begin(), +           E = Deallocations.end(); I != E; ++I) +    for (unsigned J = 0, N = I->second.size(); J != N; ++J) +      (I->first)((I->second)[J]); +    // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed    // because they can contain DenseMaps.    for (llvm::DenseMap<const ObjCContainerDecl*, @@ -750,10 +781,16 @@ ASTContext::~ASTContext() {                                                      AEnd = DeclAttrs.end();         A != AEnd; ++A)      A->second->~AttrVec(); + +  for (llvm::DenseMap<const DeclContext *, MangleNumberingContext *>::iterator +           I = MangleNumberingContexts.begin(), +           E = MangleNumberingContexts.end(); +       I != E; ++I) +    delete I->second;  }  void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { -  Deallocations.push_back(std::make_pair(Callback, Data)); +  Deallocations[Callback].push_back(Data);  }  void @@ -848,6 +885,20 @@ TypedefDecl *ASTContext::getUInt128Decl() const {    return UInt128Decl;  } +TypeDecl *ASTContext::getFloat128StubType() const { +  assert(LangOpts.CPlusPlus && "should only be called for c++"); +  if (!Float128StubDecl) { +    Float128StubDecl = CXXRecordDecl::Create(const_cast<ASTContext &>(*this),  +                                             TTK_Struct, +                                             getTranslationUnitDecl(), +                                             SourceLocation(), +                                             SourceLocation(), +                                             &Idents.get("__float128")); +  } +   +  return Float128StubDecl; +} +  void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {    BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);    R = CanQualType::CreateUnsafe(QualType(Ty, 0)); @@ -863,6 +914,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {    ABI.reset(createCXXABI(Target));    AddrSpaceMap = getAddressSpaceMap(Target, LangOpts); +  AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);    // C99 6.2.5p19.    InitBuiltinType(VoidTy,              BuiltinType::Void); @@ -897,13 +949,17 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) {    InitBuiltinType(Int128Ty,            BuiltinType::Int128);    InitBuiltinType(UnsignedInt128Ty,    BuiltinType::UInt128); -  if (LangOpts.CPlusPlus && LangOpts.WChar) { // C++ 3.9.1p5 -    if (TargetInfo::isTypeSigned(Target.getWCharType())) -      InitBuiltinType(WCharTy,           BuiltinType::WChar_S); -    else  // -fshort-wchar makes wchar_t be unsigned. -      InitBuiltinType(WCharTy,           BuiltinType::WChar_U); -  } else // C99 (or C++ using -fno-wchar) -    WCharTy = getFromTargetType(Target.getWCharType()); +  // C++ 3.9.1p5 +  if (TargetInfo::isTypeSigned(Target.getWCharType())) +    InitBuiltinType(WCharTy,           BuiltinType::WChar_S); +  else  // -fshort-wchar makes wchar_t be unsigned. +    InitBuiltinType(WCharTy,           BuiltinType::WChar_U); +  if (LangOpts.CPlusPlus && LangOpts.WChar) +    WideCharTy = WCharTy; +  else { +    // C99 (or C++ using -fno-wchar). +    WideCharTy = getFromTargetType(Target.getWCharType()); +  }    WIntTy = getFromTargetType(Target.getWIntType()); @@ -1008,13 +1064,20 @@ void ASTContext::eraseDeclAttrs(const Decl *D) {    }  } +// FIXME: Remove ?  MemberSpecializationInfo *  ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) {    assert(Var->isStaticDataMember() && "Not a static data member"); -  llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>::iterator Pos -    = InstantiatedFromStaticDataMember.find(Var); -  if (Pos == InstantiatedFromStaticDataMember.end()) -    return 0; +  return getTemplateOrSpecializationInfo(Var) +      .dyn_cast<MemberSpecializationInfo *>(); +} + +ASTContext::TemplateOrSpecializationInfo +ASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) { +  llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos = +      TemplateOrInstantiation.find(Var); +  if (Pos == TemplateOrInstantiation.end()) +    return TemplateOrSpecializationInfo();    return Pos->second;  } @@ -1025,10 +1088,16 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,                                            SourceLocation PointOfInstantiation) {    assert(Inst->isStaticDataMember() && "Not a static data member");    assert(Tmpl->isStaticDataMember() && "Not a static data member"); -  assert(!InstantiatedFromStaticDataMember[Inst] && -         "Already noted what static data member was instantiated from"); -  InstantiatedFromStaticDataMember[Inst]  -    = new (*this) MemberSpecializationInfo(Tmpl, TSK, PointOfInstantiation); +  setTemplateOrSpecializationInfo(Inst, new (*this) MemberSpecializationInfo( +                                            Tmpl, TSK, PointOfInstantiation)); +} + +void +ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst, +                                            TemplateOrSpecializationInfo TSI) { +  assert(!TemplateOrInstantiation[Inst] && +         "Already noted what the variable was instantiated from"); +  TemplateOrInstantiation[Inst] = TSI;  }  FunctionDecl *ASTContext::getClassScopeSpecializationPattern( @@ -1105,38 +1174,6 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,    InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;  } -bool ASTContext::ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,  -                                    const FieldDecl *LastFD) const { -  return (FD->isBitField() && LastFD && !LastFD->isBitField() && -          FD->getBitWidthValue(*this) == 0); -} - -bool ASTContext::ZeroBitfieldFollowsBitfield(const FieldDecl *FD, -                                             const FieldDecl *LastFD) const { -  return (FD->isBitField() && LastFD && LastFD->isBitField() && -          FD->getBitWidthValue(*this) == 0 && -          LastFD->getBitWidthValue(*this) != 0); -} - -bool ASTContext::BitfieldFollowsBitfield(const FieldDecl *FD, -                                         const FieldDecl *LastFD) const { -  return (FD->isBitField() && LastFD && LastFD->isBitField() && -          FD->getBitWidthValue(*this) && -          LastFD->getBitWidthValue(*this)); -} - -bool ASTContext::NonBitfieldFollowsBitfield(const FieldDecl *FD, -                                         const FieldDecl *LastFD) const { -  return (!FD->isBitField() && LastFD && LastFD->isBitField() && -          LastFD->getBitWidthValue(*this)); -} - -bool ASTContext::BitfieldFollowsNonBitfield(const FieldDecl *FD, -                                             const FieldDecl *LastFD) const { -  return (FD->isBitField() && LastFD && !LastFD->isBitField() && -          FD->getBitWidthValue(*this)); -} -  ASTContext::overridden_cxx_method_iterator  ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {    llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos @@ -1224,12 +1261,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {    }  } -/// getDeclAlign - Return a conservative estimate of the alignment of the -/// specified decl.  Note that bitfields do not have a valid alignment, so -/// this method will assert on them. -/// If @p RefAsPointee, references are treated like their underlying type -/// (for alignof), else they're treated like pointers (for CodeGen). -CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const { +CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {    unsigned Align = Target->getCharWidth();    bool UseAlignAttrOnly = false; @@ -1262,7 +1294,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {    } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {      QualType T = VD->getType();      if (const ReferenceType* RT = T->getAs<ReferenceType>()) { -      if (RefAsPointee) +      if (ForAlignof)          T = RT->getPointeeType();        else          T = getPointerType(RT->getPointeeType()); @@ -1270,14 +1302,15 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {      if (!T->isIncompleteType() && !T->isFunctionType()) {        // Adjust alignments of declarations with array type by the        // large-array alignment on the target. -      unsigned MinWidth = Target->getLargeArrayMinWidth(); -      const ArrayType *arrayType; -      if (MinWidth && (arrayType = getAsArrayType(T))) { -        if (isa<VariableArrayType>(arrayType)) -          Align = std::max(Align, Target->getLargeArrayAlign()); -        else if (isa<ConstantArrayType>(arrayType) && -                 MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType))) -          Align = std::max(Align, Target->getLargeArrayAlign()); +      if (const ArrayType *arrayType = getAsArrayType(T)) { +        unsigned MinWidth = Target->getLargeArrayMinWidth(); +        if (!ForAlignof && MinWidth) { +          if (isa<VariableArrayType>(arrayType)) +            Align = std::max(Align, Target->getLargeArrayAlign()); +          else if (isa<ConstantArrayType>(arrayType) && +                   MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType))) +            Align = std::max(Align, Target->getLargeArrayAlign()); +        }          // Walk through any array types while we're at it.          T = getBaseElementType(arrayType); @@ -1294,24 +1327,27 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {      // a max-field-alignment constraint (#pragma pack).  So calculate      // the actual alignment of the field within the struct, and then      // (as we're expected to) constrain that by the alignment of the type. -    if (const FieldDecl *field = dyn_cast<FieldDecl>(VD)) { -      // So calculate the alignment of the field. -      const ASTRecordLayout &layout = getASTRecordLayout(field->getParent()); - -      // Start with the record's overall alignment. -      unsigned fieldAlign = toBits(layout.getAlignment()); - -      // Use the GCD of that and the offset within the record. -      uint64_t offset = layout.getFieldOffset(field->getFieldIndex()); -      if (offset > 0) { -        // Alignment is always a power of 2, so the GCD will be a power of 2, -        // which means we get to do this crazy thing instead of Euclid's. -        uint64_t lowBitOfOffset = offset & (~offset + 1); -        if (lowBitOfOffset < fieldAlign) -          fieldAlign = static_cast<unsigned>(lowBitOfOffset); -      } +    if (const FieldDecl *Field = dyn_cast<FieldDecl>(VD)) { +      const RecordDecl *Parent = Field->getParent(); +      // We can only produce a sensible answer if the record is valid. +      if (!Parent->isInvalidDecl()) { +        const ASTRecordLayout &Layout = getASTRecordLayout(Parent); + +        // Start with the record's overall alignment. +        unsigned FieldAlign = toBits(Layout.getAlignment()); + +        // Use the GCD of that and the offset within the record. +        uint64_t Offset = Layout.getFieldOffset(Field->getFieldIndex()); +        if (Offset > 0) { +          // Alignment is always a power of 2, so the GCD will be a power of 2, +          // which means we get to do this crazy thing instead of Euclid's. +          uint64_t LowBitOfOffset = Offset & (~Offset + 1); +          if (LowBitOfOffset < FieldAlign) +            FieldAlign = static_cast<unsigned>(LowBitOfOffset); +        } -      Align = std::min(Align, fieldAlign); +        Align = std::min(Align, FieldAlign); +      }      }    } @@ -1339,8 +1375,30 @@ ASTContext::getTypeInfoDataSizeInChars(QualType T) const {    return sizeAndAlign;  } +/// getConstantArrayInfoInChars - Performing the computation in CharUnits +/// instead of in bits prevents overflowing the uint64_t for some large arrays. +std::pair<CharUnits, CharUnits> +static getConstantArrayInfoInChars(const ASTContext &Context, +                                   const ConstantArrayType *CAT) { +  std::pair<CharUnits, CharUnits> EltInfo = +      Context.getTypeInfoInChars(CAT->getElementType()); +  uint64_t Size = CAT->getSize().getZExtValue(); +  assert((Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity()) <= +              (uint64_t)(-1)/Size) && +         "Overflow in array type char size evaluation"); +  uint64_t Width = EltInfo.first.getQuantity() * Size; +  unsigned Align = EltInfo.second.getQuantity(); +  if (!Context.getTargetInfo().getCXXABI().isMicrosoft() || +      Context.getTargetInfo().getPointerWidth(0) == 64) +    Width = llvm::RoundUpToAlignment(Width, Align); +  return std::make_pair(CharUnits::fromQuantity(Width), +                        CharUnits::fromQuantity(Align)); +} +  std::pair<CharUnits, CharUnits>  ASTContext::getTypeInfoInChars(const Type *T) const { +  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) +    return getConstantArrayInfoInChars(*this, CAT);    std::pair<uint64_t, unsigned> Info = getTypeInfo(T);    return std::make_pair(toCharUnitsFromBits(Info.first),                          toCharUnitsFromBits(Info.second)); @@ -1376,6 +1434,10 @@ ASTContext::getTypeInfoImpl(const Type *T) const {  #define ABSTRACT_TYPE(Class, Base)  #define NON_CANONICAL_TYPE(Class, Base)  #define DEPENDENT_TYPE(Class, Base) case Type::Class: +#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)                       \ +  case Type::Class:                                                            \ +  assert(!T->isDependentType() && "should not see dependent types here");      \ +  return getTypeInfo(cast<Class##Type>(T)->desugar().getTypePtr());  #include "clang/AST/TypeNodes.def"      llvm_unreachable("Should not see dependent types"); @@ -1401,7 +1463,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const {             "Overflow in array type bit size evaluation");      Width = EltInfo.first*Size;      Align = EltInfo.second; -    Width = llvm::RoundUpToAlignment(Width, Align); +    if (!getTargetInfo().getCXXABI().isMicrosoft() || +        getTargetInfo().getPointerWidth(0) == 64) +      Width = llvm::RoundUpToAlignment(Width, Align);      break;    }    case Type::ExtVector: @@ -1568,6 +1632,8 @@ ASTContext::getTypeInfoImpl(const Type *T) const {    }    case Type::ObjCObject:      return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr()); +  case Type::Decayed: +    return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());    case Type::ObjCInterface: {      const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);      const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); @@ -1624,20 +1690,6 @@ ASTContext::getTypeInfoImpl(const Type *T) const {      break;    } -  case Type::TypeOfExpr: -    return getTypeInfo(cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType() -                         .getTypePtr()); - -  case Type::TypeOf: -    return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr()); - -  case Type::Decltype: -    return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType() -                        .getTypePtr()); - -  case Type::UnaryTransform: -    return getTypeInfo(cast<UnaryTransformType>(T)->getUnderlyingType()); -    case Type::Elaborated:      return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr()); @@ -1645,18 +1697,6 @@ ASTContext::getTypeInfoImpl(const Type *T) const {      return getTypeInfo(                    cast<AttributedType>(T)->getEquivalentType().getTypePtr()); -  case Type::TemplateSpecialization: { -    assert(getCanonicalType(T) != T && -           "Cannot request the size of a dependent type"); -    const TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T); -    // A type alias template specialization may refer to a typedef with the -    // aligned attribute on it. -    if (TST->isTypeAlias()) -      return getTypeInfo(TST->getAliasedType().getTypePtr()); -    else -      return getTypeInfo(getCanonicalType(T)); -  } -    case Type::Atomic: {      // Start with the base type information.      std::pair<uint64_t, unsigned> Info @@ -1696,10 +1736,10 @@ int64_t ASTContext::toBits(CharUnits CharSize) const {  /// getTypeSizeInChars - Return the size of the specified type, in characters.  /// This method does not work on incomplete types.  CharUnits ASTContext::getTypeSizeInChars(QualType T) const { -  return toCharUnitsFromBits(getTypeSize(T)); +  return getTypeInfoInChars(T).first;  }  CharUnits ASTContext::getTypeSizeInChars(const Type *T) const { -  return toCharUnitsFromBits(getTypeSize(T)); +  return getTypeInfoInChars(T).first;  }  /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in  @@ -1718,6 +1758,9 @@ CharUnits ASTContext::getTypeAlignInChars(const Type *T) const {  unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {    unsigned ABIAlign = getTypeAlign(T); +  if (Target->getTriple().getArch() == llvm::Triple::xcore) +    return ABIAlign;  // Never overalign on XCore. +    // Double and long long should be naturally aligned if possible.    if (const ComplexType* CT = T->getAs<ComplexType>())      T = CT->getElementType().getTypePtr(); @@ -2042,10 +2085,7 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,      const FunctionProtoType *FPT = cast<FunctionProtoType>(T);      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();      EPI.ExtInfo = Info; -    Result = getFunctionType(FPT->getResultType(), -                             ArrayRef<QualType>(FPT->arg_type_begin(), -                                                FPT->getNumArgs()), -                             EPI); +    Result = getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI);    }    return cast<FunctionType>(Result.getTypePtr()); @@ -2053,12 +2093,18 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,  void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,                                                   QualType ResultType) { -  // FIXME: Need to inform serialization code about this! -  for (FD = FD->getMostRecentDecl(); FD; FD = FD->getPreviousDecl()) { +  FD = FD->getMostRecentDecl(); +  while (true) {      const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();      FD->setType(getFunctionType(ResultType, FPT->getArgTypes(), EPI)); +    if (FunctionDecl *Next = FD->getPreviousDecl()) +      FD = Next; +    else +      break;    } +  if (ASTMutationListener *L = getASTMutationListener()) +    L->DeducedReturnType(FD, ResultType);  }  /// getComplexType - Return the uniqued reference to the type for a complex @@ -2117,6 +2163,45 @@ QualType ASTContext::getPointerType(QualType T) const {    return QualType(New, 0);  } +QualType ASTContext::getDecayedType(QualType T) const { +  assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); + +  llvm::FoldingSetNodeID ID; +  DecayedType::Profile(ID, T); +  void *InsertPos = 0; +  if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos)) +    return QualType(DT, 0); + +  QualType Decayed; + +  // C99 6.7.5.3p7: +  //   A declaration of a parameter as "array of type" shall be +  //   adjusted to "qualified pointer to type", where the type +  //   qualifiers (if any) are those specified within the [ and ] of +  //   the array type derivation. +  if (T->isArrayType()) +    Decayed = getArrayDecayedType(T); + +  // C99 6.7.5.3p8: +  //   A declaration of a parameter as "function returning type" +  //   shall be adjusted to "pointer to function returning type", as +  //   in 6.3.2.1. +  if (T->isFunctionType()) +    Decayed = getPointerType(T); + +  QualType Canonical = getCanonicalType(Decayed); + +  // Get the new insert position for the node we care about. +  DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos); +  assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + +  DecayedType *New = +      new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); +  Types.push_back(New); +  DecayedTypes.InsertNode(New, InsertPos); +  return QualType(New, 0); +} +  /// getBlockPointerType - Return the uniqued reference to the type for  /// a pointer to the specified block.  QualType ASTContext::getBlockPointerType(QualType T) const { @@ -2676,9 +2761,8 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,  QualType  ASTContext::getFunctionNoProtoType(QualType ResultTy,                                     const FunctionType::ExtInfo &Info) const { -  const CallingConv DefaultCC = Info.getCC(); -  const CallingConv CallConv = (LangOpts.MRTD && DefaultCC == CC_Default) ? -                               CC_X86StdCall : DefaultCC; +  const CallingConv CallConv = Info.getCC(); +    // Unique functions, to guarantee there is only one function of a particular    // structure.    llvm::FoldingSetNodeID ID; @@ -2690,11 +2774,8 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,      return QualType(FT, 0);    QualType Canonical; -  if (!ResultTy.isCanonical() || -      getCanonicalCallConv(CallConv) != CallConv) { -    Canonical = -      getFunctionNoProtoType(getCanonicalType(ResultTy), -                     Info.withCallingConv(getCanonicalCallConv(CallConv))); +  if (!ResultTy.isCanonical()) { +    Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), Info);      // Get the new insert position for the node we care about.      FunctionNoProtoType *NewIP = @@ -2743,14 +2824,10 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,      if (!ArgArray[i].isCanonicalAsParam())        isCanonical = false; -  const CallingConv DefaultCC = EPI.ExtInfo.getCC(); -  const CallingConv CallConv = (LangOpts.MRTD && DefaultCC == CC_Default) ? -                               CC_X86StdCall : DefaultCC; -    // If this type isn't canonical, get the canonical version of it.    // The exception spec is not part of the canonical type.    QualType Canonical; -  if (!isCanonical || getCanonicalCallConv(CallConv) != CallConv) { +  if (!isCanonical) {      SmallVector<QualType, 16> CanonicalArgs;      CanonicalArgs.reserve(NumArgs);      for (unsigned i = 0; i != NumArgs; ++i) @@ -2760,8 +2837,6 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,      CanonicalEPI.HasTrailingReturn = false;      CanonicalEPI.ExceptionSpecType = EST_None;      CanonicalEPI.NumExceptions = 0; -    CanonicalEPI.ExtInfo -      = CanonicalEPI.ExtInfo.withCallingConv(getCanonicalCallConv(CallConv));      // Result types do not have ARC lifetime qualifiers.      QualType CanResultTy = getCanonicalType(ResultTy); @@ -2803,7 +2878,6 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,    FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment);    FunctionProtoType::ExtProtoInfo newEPI = EPI; -  newEPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallConv);    new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI);    Types.push_back(FTP);    FunctionProtoTypes.InsertNode(FTP, InsertPos); @@ -2856,13 +2930,11 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {           "Template type parameter types are always available.");    if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) { -    assert(!Record->getPreviousDecl() && -           "struct/union has previous declaration"); +    assert(Record->isFirstDecl() && "struct/union has previous declaration");      assert(!NeedsInjectedClassNameType(Record));      return getRecordType(Record);    } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) { -    assert(!Enum->getPreviousDecl() && -           "enum has previous declaration"); +    assert(Enum->isFirstDecl() && "enum has previous declaration");      return getEnumType(Enum);    } else if (const UnresolvedUsingTypenameDecl *Using =                 dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) { @@ -4104,22 +4176,9 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {  }  QualType ASTContext::getAdjustedParameterType(QualType T) const { -  // C99 6.7.5.3p7: -  //   A declaration of a parameter as "array of type" shall be -  //   adjusted to "qualified pointer to type", where the type -  //   qualifiers (if any) are those specified within the [ and ] of -  //   the array type derivation. -  if (T->isArrayType()) -    return getArrayDecayedType(T); -   -  // C99 6.7.5.3p8: -  //   A declaration of a parameter as "function returning type" -  //   shall be adjusted to "pointer to function returning type", as -  //   in 6.3.2.1. -  if (T->isFunctionType()) -    return getPointerType(T); -   -  return T;   +  if (T->isArrayType() || T->isFunctionType()) +    return getDecayedType(T); +  return T;  }  QualType ASTContext::getSignatureParameterType(QualType T) const { @@ -4364,12 +4423,27 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {    return Qualifiers::OCL_None;  } +static const Type *getIntegerTypeForEnum(const EnumType *ET) { +  // Incomplete enum types are not treated as integer types. +  // FIXME: In C++, enum types are never integer types. +  if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) +    return ET->getDecl()->getIntegerType().getTypePtr(); +  return NULL; +} +  /// getIntegerTypeOrder - Returns the highest ranked integer type:  /// C99 6.3.1.8p1.  If LHS > RHS, return 1.  If LHS == RHS, return 0. If  /// LHS < RHS, return -1.  int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {    const Type *LHSC = getCanonicalType(LHS).getTypePtr();    const Type *RHSC = getCanonicalType(RHS).getTypePtr(); + +  // Unwrap enums to their underlying type. +  if (const EnumType *ET = dyn_cast<EnumType>(LHSC)) +    LHSC = getIntegerTypeForEnum(ET); +  if (const EnumType *ET = dyn_cast<EnumType>(RHSC)) +    RHSC = getIntegerTypeForEnum(ET); +    if (LHSC == RHSC) return 0;    bool LHSUnsigned = LHSC->isUnsignedIntegerType(); @@ -4484,7 +4558,7 @@ QualType ASTContext::getBlockDescriptorType() const {      UnsignedLongTy,    }; -  const char *FieldNames[] = { +  static const char *const FieldNames[] = {      "reserved",      "Size"    }; @@ -4525,7 +4599,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {      getPointerType(VoidPtrTy)    }; -  const char *FieldNames[] = { +  static const char *const FieldNames[] = {      "reserved",      "Size",      "CopyFuncPtr", @@ -4910,6 +4984,10 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,    if (PD->isReadOnly()) {      S += ",R"; +    if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) +      S += ",C"; +    if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) +      S += ",&";    } else {      switch (PD->getSetterKind()) {      case ObjCPropertyDecl::Assign: break; @@ -5200,12 +5278,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      } else {        S += '['; -      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { -        if (getTypeSize(CAT->getElementType()) == 0) -          S += '0'; -        else -          S += llvm::utostr(CAT->getSize().getZExtValue()); -      } else { +      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) +        S += llvm::utostr(CAT->getSize().getZExtValue()); +      else {          //Variable length arrays are encoded as a regular array with 0 elements.          assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&                 "Unknown array type!"); @@ -5384,6 +5459,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,        // 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 (cast<FieldDecl>(Ivars[i]) == FD) { +            S += '{'; +            S += OI->getIdentifier()->getName(); +            S += '}'; +            return; +          } +        } +      }        getObjCEncodingForTypeImpl(PointeeTy, S,                                   false, ExpandPointedToStructures,                                   NULL, @@ -5484,7 +5573,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,        if (base->isEmpty())          continue;        uint64_t offs = toBits(layout.getVBaseClassOffset(base)); -      if (FieldOrBaseOffsets.find(offs) == FieldOrBaseOffsets.end()) +      if (offs >= uint64_t(toBits(layout.getNonVirtualSize())) && +          FieldOrBaseOffsets.find(offs) == FieldOrBaseOffsets.end())          FieldOrBaseOffsets.insert(FieldOrBaseOffsets.end(),                                    std::make_pair(offs, base));      } @@ -6267,6 +6357,8 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,  CanQualType ASTContext::getFromTargetType(unsigned Type) const {    switch (Type) {    case TargetInfo::NoInt: return CanQualType(); +  case TargetInfo::SignedChar: return SignedCharTy; +  case TargetInfo::UnsignedChar: return UnsignedCharTy;    case TargetInfo::SignedShort: return ShortTy;    case TargetInfo::UnsignedShort: return UnsignedShortTy;    case TargetInfo::SignedInt: return IntTy; @@ -6369,15 +6461,6 @@ ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,    return false;  } -/// QualifiedIdConformsQualifiedId - compare id<pr,...> with id<pr1,...> -/// return true if lhs's protocols conform to rhs's protocol; false -/// otherwise. -bool ASTContext::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) { -  if (lhs->isObjCQualifiedIdType() && rhs->isObjCQualifiedIdType()) -    return ObjCQualifiedIdTypesAreCompatible(lhs, rhs, false); -  return false; -} -  /// ObjCQualifiedClassTypesAreCompatible - compare  Class<pr,...> and  /// Class<pr1, ...>.  bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,  @@ -6890,7 +6973,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,    FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo();    // Compatible functions must have compatible calling conventions -  if (!isSameCallConv(lbaseInfo.getCC(), rbaseInfo.getCC())) +  if (lbaseInfo.getCC() != rbaseInfo.getCC())      return QualType();    // Regparm is part of the calling convention. @@ -7000,10 +7083,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,      FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo();      EPI.ExtInfo = einfo; -    return getFunctionType(retType, -                           ArrayRef<QualType>(proto->arg_type_begin(), -                                              proto->getNumArgs()), -                           EPI); +    return getFunctionType(retType, proto->getArgTypes(), EPI);    }    if (allLTypes) return lhs; @@ -7351,11 +7431,8 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {        if (const FunctionProtoType *FPT = cast<FunctionProtoType>(F)) {          FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();          EPI.ExtInfo = getFunctionExtInfo(LHS); -        QualType ResultType -          = getFunctionType(OldReturnType, -                            ArrayRef<QualType>(FPT->arg_type_begin(), -                                               FPT->getNumArgs()), -                            EPI); +        QualType ResultType = +            getFunctionType(OldReturnType, FPT->getArgTypes(), EPI);          return ResultType;        }      } @@ -7407,7 +7484,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {  //===----------------------------------------------------------------------===//  unsigned ASTContext::getIntWidth(QualType T) const { -  if (const EnumType *ET = dyn_cast<EnumType>(T)) +  if (const EnumType *ET = T->getAs<EnumType>())      T = ET->getDecl()->getIntegerType();    if (T->isBooleanType())      return 1; @@ -7450,6 +7527,8 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {  ASTMutationListener::~ASTMutationListener() { } +void ASTMutationListener::DeducedReturnType(const FunctionDecl *FD, +                                            QualType ReturnType) {}  //===----------------------------------------------------------------------===//  //                          Builtin Type Computation @@ -7507,6 +7586,11 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,             "Bad modifiers used with 'v'!");      Type = Context.VoidTy;      break; +  case 'h': +    assert(HowLong == 0 && !Signed && !Unsigned && +           "Bad modifiers used with 'f'!"); +    Type = Context.HalfTy; +    break;    case 'f':      assert(HowLong == 0 && !Signed && !Unsigned &&             "Bad modifiers used with 'f'!"); @@ -7734,7 +7818,7 @@ QualType ASTContext::GetBuiltinType(unsigned Id,    assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&           "'.' should only occur at end of builtin type list!"); -  FunctionType::ExtInfo EI; +  FunctionType::ExtInfo EI(CC_C);    if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true);    bool Variadic = (TypeStr[0] == '.'); @@ -7751,36 +7835,30 @@ QualType ASTContext::GetBuiltinType(unsigned Id,  }  GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) { -  GVALinkage External = GVA_StrongExternal; - -  Linkage L = FD->getLinkage(); -  switch (L) { -  case NoLinkage: -  case InternalLinkage: -  case UniqueExternalLinkage: +  if (!FD->isExternallyVisible())      return GVA_Internal; -     -  case ExternalLinkage: -    switch (FD->getTemplateSpecializationKind()) { -    case TSK_Undeclared: -    case TSK_ExplicitSpecialization: -      External = GVA_StrongExternal; -      break; -    case TSK_ExplicitInstantiationDefinition: -      return GVA_ExplicitTemplateInstantiation; +  GVALinkage External = GVA_StrongExternal; +  switch (FD->getTemplateSpecializationKind()) { +  case TSK_Undeclared: +  case TSK_ExplicitSpecialization: +    External = GVA_StrongExternal; +    break; -    case TSK_ExplicitInstantiationDeclaration: -    case TSK_ImplicitInstantiation: -      External = GVA_TemplateInstantiation; -      break; -    } +  case TSK_ExplicitInstantiationDefinition: +    return GVA_ExplicitTemplateInstantiation; + +  case TSK_ExplicitInstantiationDeclaration: +  case TSK_ImplicitInstantiation: +    External = GVA_TemplateInstantiation; +    break;    }    if (!FD->isInlined())      return External; -     -  if (!getLangOpts().CPlusPlus || FD->hasAttr<GNUInlineAttr>()) { + +  if ((!getLangOpts().CPlusPlus && !getLangOpts().MicrosoftMode) || +      FD->hasAttr<GNUInlineAttr>()) {      // GNU or C99 inline semantics. Determine whether this symbol should be      // externally visible.      if (FD->isInlineDefinitionExternallyVisible()) @@ -7804,37 +7882,23 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {  }  GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { -  // If this is a static data member, compute the kind of template -  // specialization. Otherwise, this variable is not part of a -  // template. -  TemplateSpecializationKind TSK = TSK_Undeclared; -  if (VD->isStaticDataMember()) -    TSK = VD->getTemplateSpecializationKind(); - -  Linkage L = VD->getLinkage(); - -  switch (L) { -  case NoLinkage: -  case InternalLinkage: -  case UniqueExternalLinkage: +  if (!VD->isExternallyVisible())      return GVA_Internal; -  case ExternalLinkage: -    switch (TSK) { -    case TSK_Undeclared: -    case TSK_ExplicitSpecialization: -      return GVA_StrongExternal; +  switch (VD->getTemplateSpecializationKind()) { +  case TSK_Undeclared: +  case TSK_ExplicitSpecialization: +    return GVA_StrongExternal; -    case TSK_ExplicitInstantiationDeclaration: -      llvm_unreachable("Variable should not be instantiated"); -      // Fall through to treat this like any other instantiation. -         -    case TSK_ExplicitInstantiationDefinition: -      return GVA_ExplicitTemplateInstantiation; +  case TSK_ExplicitInstantiationDeclaration: +    llvm_unreachable("Variable should not be instantiated"); +  // Fall through to treat this like any other instantiation. -    case TSK_ImplicitInstantiation: -      return GVA_TemplateInstantiation;       -    } +  case TSK_ExplicitInstantiationDefinition: +    return GVA_ExplicitTemplateInstantiation; + +  case TSK_ImplicitInstantiation: +    return GVA_TemplateInstantiation;    }    llvm_unreachable("Invalid Linkage!"); @@ -7918,16 +7982,13 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {    return false;  } -CallingConv ASTContext::getDefaultCXXMethodCallConv(bool isVariadic) { +CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, +                                                    bool IsCXXMethod) const {    // Pass through to the C++ ABI object -  return ABI->getDefaultMethodCallConv(isVariadic); -} +  if (IsCXXMethod) +    return ABI->getDefaultMethodCallConv(IsVariadic); -CallingConv ASTContext::getCanonicalCallConv(CallingConv CC) const { -  if (CC == CC_C && !LangOpts.MRTD && -      getTargetInfo().getCXXABI().isMemberFunctionCCDefault()) -    return CC_Default; -  return CC; +  return (LangOpts.MRTD && !IsVariadic) ? CC_X86StdCall : CC_C;  }  bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const { @@ -7941,9 +8002,9 @@ MangleContext *ASTContext::createMangleContext() {    case TargetCXXABI::GenericItanium:    case TargetCXXABI::GenericARM:    case TargetCXXABI::iOS: -    return createItaniumMangleContext(*this, getDiagnostics()); +    return ItaniumMangleContext::create(*this, getDiagnostics());    case TargetCXXABI::Microsoft: -    return createMicrosoftMangleContext(*this, getDiagnostics()); +    return MicrosoftMangleContext::create(*this, getDiagnostics());    }    llvm_unreachable("Unsupported ABI");  } @@ -7951,45 +8012,77 @@ MangleContext *ASTContext::createMangleContext() {  CXXABI::~CXXABI() {}  size_t ASTContext::getSideTableAllocatedMemory() const { -  return ASTRecordLayouts.getMemorySize() -    + llvm::capacity_in_bytes(ObjCLayouts) -    + llvm::capacity_in_bytes(KeyFunctions) -    + llvm::capacity_in_bytes(ObjCImpls) -    + llvm::capacity_in_bytes(BlockVarCopyInits) -    + llvm::capacity_in_bytes(DeclAttrs) -    + llvm::capacity_in_bytes(InstantiatedFromStaticDataMember) -    + llvm::capacity_in_bytes(InstantiatedFromUsingDecl) -    + llvm::capacity_in_bytes(InstantiatedFromUsingShadowDecl) -    + 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); -} - -void ASTContext::addUnnamedTag(const TagDecl *Tag) { -  // FIXME: This mangling should be applied to function local classes too -  if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl() || -      !isa<CXXRecordDecl>(Tag->getParent()) || Tag->getLinkage() != ExternalLinkage) -    return; +  return ASTRecordLayouts.getMemorySize() + +         llvm::capacity_in_bytes(ObjCLayouts) + +         llvm::capacity_in_bytes(KeyFunctions) + +         llvm::capacity_in_bytes(ObjCImpls) + +         llvm::capacity_in_bytes(BlockVarCopyInits) + +         llvm::capacity_in_bytes(DeclAttrs) + +         llvm::capacity_in_bytes(TemplateOrInstantiation) + +         llvm::capacity_in_bytes(InstantiatedFromUsingDecl) + +         llvm::capacity_in_bytes(InstantiatedFromUsingShadowDecl) + +         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); +} + +/// getIntTypeForBitwidth - +/// sets integer QualTy according to specified details: +/// bitwidth, signed/unsigned. +/// Returns empty type if there is no appropriate target types. +QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth, +                                           unsigned Signed) const { +  TargetInfo::IntType Ty = getTargetInfo().getIntTypeByWidth(DestWidth, Signed); +  CanQualType QualTy = getFromTargetType(Ty); +  if (!QualTy && DestWidth == 128) +    return Signed ? Int128Ty : UnsignedInt128Ty; +  return QualTy; +} + +/// getRealTypeForBitwidth - +/// sets floating point QualTy according to specified bitwidth. +/// Returns empty type if there is no appropriate target types. +QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const { +  TargetInfo::RealType Ty = getTargetInfo().getRealTypeByWidth(DestWidth); +  switch (Ty) { +  case TargetInfo::Float: +    return FloatTy; +  case TargetInfo::Double: +    return DoubleTy; +  case TargetInfo::LongDouble: +    return LongDoubleTy; +  case TargetInfo::NoFloat: +    return QualType(); +  } -  std::pair<llvm::DenseMap<const DeclContext *, unsigned>::iterator, bool> P = -    UnnamedMangleContexts.insert(std::make_pair(Tag->getParent(), 0)); -  UnnamedMangleNumbers.insert(std::make_pair(Tag, P.first->second++)); +  llvm_unreachable("Unhandled TargetInfo::RealType value");  } -int ASTContext::getUnnamedTagManglingNumber(const TagDecl *Tag) const { -  llvm::DenseMap<const TagDecl *, unsigned>::const_iterator I = -    UnnamedMangleNumbers.find(Tag); -  return I != UnnamedMangleNumbers.end() ? I->second : -1; +void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) { +  if (Number > 1) +    MangleNumbers[ND] = Number;  } -unsigned ASTContext::getLambdaManglingNumber(CXXMethodDecl *CallOperator) { -  CXXRecordDecl *Lambda = CallOperator->getParent(); -  return LambdaMangleContexts[Lambda->getDeclContext()] -           .getManglingNumber(CallOperator); +unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const { +  llvm::DenseMap<const NamedDecl *, unsigned>::const_iterator I = +    MangleNumbers.find(ND); +  return I != MangleNumbers.end() ? I->second : 1;  } +MangleNumberingContext & +ASTContext::getManglingNumberContext(const DeclContext *DC) { +  assert(LangOpts.CPlusPlus);  // We don't need mangling numbers for plain C. +  MangleNumberingContext *&MCtx = MangleNumberingContexts[DC]; +  if (!MCtx) +    MCtx = createMangleNumberingContext(); +  return *MCtx; +} + +MangleNumberingContext *ASTContext::createMangleNumberingContext() const { +  return ABI->createMangleNumberingContext(); +}  void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {    ParamIndices[D] = index; @@ -8001,3 +8094,160 @@ unsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const {           "ParmIndices lacks entry set by ParmVarDecl");    return I->second;  } + +APValue * +ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, +                                          bool MayCreate) { +  assert(E && E->getStorageDuration() == SD_Static && +         "don't need to cache the computed value for this temporary"); +  if (MayCreate) +    return &MaterializedTemporaryValues[E]; + +  llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I = +      MaterializedTemporaryValues.find(E); +  return I == MaterializedTemporaryValues.end() ? 0 : &I->second; +} + +bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { +  const llvm::Triple &T = getTargetInfo().getTriple(); +  if (!T.isOSDarwin()) +    return false; + +  if (!(T.isiOS() && T.isOSVersionLT(7)) && +      !(T.isMacOSX() && T.isOSVersionLT(10, 9))) +    return false; + +  QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); +  CharUnits sizeChars = getTypeSizeInChars(AtomicTy); +  uint64_t Size = sizeChars.getQuantity(); +  CharUnits alignChars = getTypeAlignInChars(AtomicTy); +  unsigned Align = alignChars.getQuantity(); +  unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth(); +  return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits); +} + +namespace { + +  /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their +  /// parents as defined by the \c RecursiveASTVisitor. +  /// +  /// Note that the relationship described here is purely in terms of AST +  /// traversal - there are other relationships (for example declaration context) +  /// in the AST that are better modeled by special matchers. +  /// +  /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes. +  class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> { + +  public: +    /// \brief Builds and returns the translation unit's parent map. +    /// +    ///  The caller takes ownership of the returned \c ParentMap. +    static ASTContext::ParentMap *buildMap(TranslationUnitDecl &TU) { +      ParentMapASTVisitor Visitor(new ASTContext::ParentMap); +      Visitor.TraverseDecl(&TU); +      return Visitor.Parents; +    } + +  private: +    typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase; + +    ParentMapASTVisitor(ASTContext::ParentMap *Parents) : Parents(Parents) { +    } + +    bool shouldVisitTemplateInstantiations() const { +      return true; +    } +    bool shouldVisitImplicitCode() const { +      return true; +    } +    // Disables data recursion. We intercept Traverse* methods in the RAV, which +    // are not triggered during data recursion. +    bool shouldUseDataRecursionFor(clang::Stmt *S) const { +      return false; +    } + +    template <typename T> +    bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { +      if (Node == NULL) +        return true; +      if (ParentStack.size() > 0) +        // FIXME: Currently we add the same parent multiple times, for example +        // when we visit all subexpressions of template instantiations; this is +        // suboptimal, bug benign: the only way to visit those is with +        // hasAncestor / hasParent, and those do not create new matches. +        // The plan is to enable DynTypedNode to be storable in a map or hash +        // map. The main problem there is to implement hash functions / +        // comparison operators for all types that DynTypedNode supports that +        // do not have pointer identity. +        (*Parents)[Node].push_back(ParentStack.back()); +      ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); +      bool Result = (this ->* traverse) (Node); +      ParentStack.pop_back(); +      return Result; +    } + +    bool TraverseDecl(Decl *DeclNode) { +      return TraverseNode(DeclNode, &VisitorBase::TraverseDecl); +    } + +    bool TraverseStmt(Stmt *StmtNode) { +      return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); +    } + +    ASTContext::ParentMap *Parents; +    llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; + +    friend class RecursiveASTVisitor<ParentMapASTVisitor>; +  }; + +} // end namespace + +ASTContext::ParentVector +ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { +  assert(Node.getMemoizationData() && +         "Invariant broken: only nodes that support memoization may be " +         "used in the parent map."); +  if (!AllParents) { +    // We always need to run over the whole translation unit, as +    // hasAncestor can escape any subtree. +    AllParents.reset( +        ParentMapASTVisitor::buildMap(*getTranslationUnitDecl())); +  } +  ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData()); +  if (I == AllParents->end()) { +    return ParentVector(); +  } +  return I->second; +} + +bool +ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, +                                const ObjCMethodDecl *MethodImpl) { +  // No point trying to match an unavailable/deprecated mothod. +  if (MethodDecl->hasAttr<UnavailableAttr>() +      || MethodDecl->hasAttr<DeprecatedAttr>()) +    return false; +  if (MethodDecl->getObjCDeclQualifier() != +      MethodImpl->getObjCDeclQualifier()) +    return false; +  if (!hasSameType(MethodDecl->getResultType(), +                   MethodImpl->getResultType())) +    return false; +   +  if (MethodDecl->param_size() != MethodImpl->param_size()) +    return false; +   +  for (ObjCMethodDecl::param_const_iterator IM = MethodImpl->param_begin(), +       IF = MethodDecl->param_begin(), EM = MethodImpl->param_end(), +       EF = MethodDecl->param_end(); +       IM != EM && IF != EF; ++IM, ++IF) { +    const ParmVarDecl *DeclVar = (*IF); +    const ParmVarDecl *ImplVar = (*IM); +    if (ImplVar->getObjCDeclQualifier() != DeclVar->getObjCDeclQualifier()) +      return false; +    if (!hasSameType(DeclVar->getType(), ImplVar->getType())) +      return false; +  } +  return (MethodDecl->isVariadic() == MethodImpl->isVariadic()); +   +}  | 
