diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTContext.cpp | 419 |
1 files changed, 243 insertions, 176 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index bccdae9..6b864d0 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -699,9 +699,10 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T, 1, // opencl_global 2, // opencl_local 3, // opencl_constant - 4, // cuda_device - 5, // cuda_constant - 6 // cuda_shared + 4, // opencl_generic + 5, // cuda_device + 6, // cuda_constant + 7 // cuda_shared }; return &FakeAddrSpaceMap; } else { @@ -722,35 +723,28 @@ static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything."); } -ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM, +ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins) - : FunctionProtoTypes(this_()), - TemplateSpecializationTypes(this_()), - DependentTemplateSpecializationTypes(this_()), - SubstTemplateTemplateParmPacks(this_()), - GlobalNestedNameSpecifier(nullptr), - Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr), - BuiltinVaListDecl(nullptr), - ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr), - ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), - CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr), - FILEDecl(nullptr), - jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr), - BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), - cudaConfigureCallDecl(nullptr), - NullTypeSourceInfo(QualType()), - FirstLocalImport(), LastLocalImport(), - SourceMgr(SM), LangOpts(LOpts), - AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts), - Idents(idents), Selectors(sels), - BuiltinInfo(builtins), - DeclarationNames(*this), - ExternalSource(nullptr), Listener(nullptr), - Comments(SM), CommentsLoaded(false), - CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), - LastSDM(nullptr, 0) -{ + : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), + DependentTemplateSpecializationTypes(this_()), + SubstTemplateTemplateParmPacks(this_()), + GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr), + UInt128Decl(nullptr), Float128StubDecl(nullptr), + BuiltinVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), + ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), + CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr), + FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), + ucontext_tDecl(nullptr), BlockDescriptorType(nullptr), + BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr), + FirstLocalImport(), LastLocalImport(), + SourceMgr(SM), LangOpts(LOpts), + SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFile, SM)), + AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts), + Idents(idents), Selectors(sels), BuiltinInfo(builtins), + DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr), + Comments(SM), CommentsLoaded(false), + CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) { TUDecl = TranslationUnitDecl::Create(*this); } @@ -1413,9 +1407,9 @@ 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)); + TypeInfo Info = getTypeInfo(T); + return std::make_pair(toCharUnitsFromBits(Info.Width), + toCharUnitsFromBits(Info.Align)); } std::pair<CharUnits, CharUnits> @@ -1423,14 +1417,23 @@ ASTContext::getTypeInfoInChars(QualType T) const { return getTypeInfoInChars(T.getTypePtr()); } -std::pair<uint64_t, unsigned> ASTContext::getTypeInfo(const Type *T) const { - TypeInfoMap::iterator it = MemoizedTypeInfo.find(T); - if (it != MemoizedTypeInfo.end()) - return it->second; +bool ASTContext::isAlignmentRequired(const Type *T) const { + return getTypeInfo(T).AlignIsRequired; +} + +bool ASTContext::isAlignmentRequired(QualType T) const { + return isAlignmentRequired(T.getTypePtr()); +} + +TypeInfo ASTContext::getTypeInfo(const Type *T) const { + TypeInfoMap::iterator I = MemoizedTypeInfo.find(T); + if (I != MemoizedTypeInfo.end()) + return I->second; - std::pair<uint64_t, unsigned> Info = getTypeInfoImpl(T); - MemoizedTypeInfo.insert(std::make_pair(T, Info)); - return Info; + // This call can invalidate MemoizedTypeInfo[T], so we need a second lookup. + TypeInfo TI = getTypeInfoImpl(T); + MemoizedTypeInfo[T] = TI; + return TI; } /// getTypeInfoImpl - Return the size of the specified type, in bits. This @@ -1439,10 +1442,10 @@ std::pair<uint64_t, unsigned> ASTContext::getTypeInfo(const Type *T) const { /// FIXME: Pointers into different addr spaces could have different sizes and /// alignment requirements: getPointerInfo should take an AddrSpace, this /// should take a QualType, &c. -std::pair<uint64_t, unsigned> -ASTContext::getTypeInfoImpl(const Type *T) const { - uint64_t Width=0; - unsigned Align=8; +TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { + uint64_t Width = 0; + unsigned Align = 8; + bool AlignIsRequired = false; switch (T->getTypeClass()) { #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) @@ -1471,12 +1474,12 @@ ASTContext::getTypeInfoImpl(const Type *T) const { case Type::ConstantArray: { const ConstantArrayType *CAT = cast<ConstantArrayType>(T); - std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType()); + TypeInfo EltInfo = getTypeInfo(CAT->getElementType()); uint64_t Size = CAT->getSize().getZExtValue(); - assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && + assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && "Overflow in array type bit size evaluation"); - Width = EltInfo.first*Size; - Align = EltInfo.second; + Width = EltInfo.Width * Size; + Align = EltInfo.Align; if (!getTargetInfo().getCXXABI().isMicrosoft() || getTargetInfo().getPointerWidth(0) == 64) Width = llvm::RoundUpToAlignment(Width, Align); @@ -1485,8 +1488,8 @@ ASTContext::getTypeInfoImpl(const Type *T) const { case Type::ExtVector: case Type::Vector: { const VectorType *VT = cast<VectorType>(T); - std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(VT->getElementType()); - Width = EltInfo.first*VT->getNumElements(); + TypeInfo EltInfo = getTypeInfo(VT->getElementType()); + Width = EltInfo.Width * VT->getNumElements(); Align = Width; // If the alignment is not a power of 2, round up to the next power of 2. // This happens for non-power-of-2 length vectors. @@ -1638,10 +1641,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const { case Type::Complex: { // Complex types have the same alignment as their elements, but twice the // size. - std::pair<uint64_t, unsigned> EltInfo = - getTypeInfo(cast<ComplexType>(T)->getElementType()); - Width = EltInfo.first*2; - Align = EltInfo.second; + TypeInfo EltInfo = getTypeInfo(cast<ComplexType>(T)->getElementType()); + Width = EltInfo.Width * 2; + Align = EltInfo.Align; break; } case Type::ObjCObject: @@ -1692,16 +1694,18 @@ ASTContext::getTypeInfoImpl(const Type *T) const { case Type::Typedef: { const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl(); - std::pair<uint64_t, unsigned> Info - = getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); + TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); // If the typedef has an aligned attribute on it, it overrides any computed // alignment we have. This violates the GCC documentation (which says that // attribute(aligned) can only round up) but matches its implementation. - if (unsigned AttrAlign = Typedef->getMaxAlignment()) + if (unsigned AttrAlign = Typedef->getMaxAlignment()) { Align = AttrAlign; - else - Align = Info.second; - Width = Info.first; + AlignIsRequired = true; + } else { + Align = Info.Align; + AlignIsRequired = Info.AlignIsRequired; + } + Width = Info.Width; break; } @@ -1714,10 +1718,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const { case Type::Atomic: { // Start with the base type information. - std::pair<uint64_t, unsigned> Info - = getTypeInfo(cast<AtomicType>(T)->getValueType()); - Width = Info.first; - Align = Info.second; + TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType()); + Width = Info.Width; + Align = Info.Align; // If the size of the type doesn't exceed the platform's max // atomic promotion width, make the size and alignment more @@ -1735,7 +1738,7 @@ ASTContext::getTypeInfoImpl(const Type *T) const { } assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2"); - return std::make_pair(Width, Align); + return TypeInfo(Width, Align, AlignIsRequired); } /// toCharUnitsFromBits - Convert a size in bits to a size in characters. @@ -1771,13 +1774,12 @@ CharUnits ASTContext::getTypeAlignInChars(const Type *T) const { /// alignment in cases where it is beneficial for performance to overalign /// a data type. unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { - unsigned ABIAlign = getTypeAlign(T); + TypeInfo TI = getTypeInfo(T); + unsigned ABIAlign = TI.Align; if (Target->getTriple().getArch() == llvm::Triple::xcore) return ABIAlign; // Never overalign on XCore. - const TypedefType *TT = T->getAs<TypedefType>(); - // Double and long long should be naturally aligned if possible. T = T->getBaseElementTypeUnsafe(); if (const ComplexType *CT = T->getAs<ComplexType>()) @@ -1787,7 +1789,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { T->isSpecificBuiltinType(BuiltinType::ULongLong)) // Don't increase the alignment if an alignment attribute was specified on a // typedef declaration. - if (!TT || !TT->getDecl()->getMaxAlignment()) + if (!TI.AlignIsRequired) return std::max(ABIAlign, (unsigned)getTypeSize(T)); return ABIAlign; @@ -2110,6 +2112,62 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD, L->DeducedReturnType(FD, ResultType); } +/// Get a function type and produce the equivalent function type with the +/// specified exception specification. Type sugar that can be present on a +/// declaration of a function with an exception specification is permitted +/// and preserved. Other type sugar (for instance, typedefs) is not. +static QualType getFunctionTypeWithExceptionSpec( + ASTContext &Context, QualType Orig, + const FunctionProtoType::ExceptionSpecInfo &ESI) { + // Might have some parens. + if (auto *PT = dyn_cast<ParenType>(Orig)) + return Context.getParenType( + getFunctionTypeWithExceptionSpec(Context, PT->getInnerType(), ESI)); + + // Might have a calling-convention attribute. + if (auto *AT = dyn_cast<AttributedType>(Orig)) + return Context.getAttributedType( + AT->getAttrKind(), + getFunctionTypeWithExceptionSpec(Context, AT->getModifiedType(), ESI), + getFunctionTypeWithExceptionSpec(Context, AT->getEquivalentType(), + ESI)); + + // Anything else must be a function type. Rebuild it with the new exception + // specification. + const FunctionProtoType *Proto = cast<FunctionProtoType>(Orig); + return Context.getFunctionType( + Proto->getReturnType(), Proto->getParamTypes(), + Proto->getExtProtoInfo().withExceptionSpec(ESI)); +} + +void ASTContext::adjustExceptionSpec( + FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI, + bool AsWritten) { + // Update the type. + QualType Updated = + getFunctionTypeWithExceptionSpec(*this, FD->getType(), ESI); + FD->setType(Updated); + + if (!AsWritten) + return; + + // Update the type in the type source information too. + if (TypeSourceInfo *TSInfo = FD->getTypeSourceInfo()) { + // If the type and the type-as-written differ, we may need to update + // the type-as-written too. + if (TSInfo->getType() != FD->getType()) + Updated = getFunctionTypeWithExceptionSpec(*this, TSInfo->getType(), ESI); + + // FIXME: When we get proper type location information for exceptions, + // we'll also have to rebuild the TypeSourceInfo. For now, we just patch + // up the TypeSourceInfo; + assert(TypeLoc::getFullDataSizeForType(Updated) == + TypeLoc::getFullDataSizeForType(TSInfo->getType()) && + "TypeLoc size mismatch from updating exception specification"); + TSInfo->overrideType(Updated); + } +} + /// getComplexType - Return the uniqued reference to the type for a complex /// number with the specified element type. QualType ASTContext::getComplexType(QualType T) const { @@ -2840,7 +2898,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, // Determine whether the type being created is already canonical or not. bool isCanonical = - EPI.ExceptionSpecType == EST_None && isCanonicalResultType(ResultTy) && + EPI.ExceptionSpec.Type == EST_None && isCanonicalResultType(ResultTy) && !EPI.HasTrailingReturn; for (unsigned i = 0; i != NumArgs && isCanonical; ++i) if (!ArgArray[i].isCanonicalAsParam()) @@ -2857,8 +2915,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI; CanonicalEPI.HasTrailingReturn = false; - CanonicalEPI.ExceptionSpecType = EST_None; - CanonicalEPI.NumExceptions = 0; + CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo(); // Result types do not have ARC lifetime qualifiers. QualType CanResultTy = getCanonicalType(ResultTy); @@ -2886,13 +2943,13 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, // specification. size_t Size = sizeof(FunctionProtoType) + NumArgs * sizeof(QualType); - if (EPI.ExceptionSpecType == EST_Dynamic) { - Size += EPI.NumExceptions * sizeof(QualType); - } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { + if (EPI.ExceptionSpec.Type == EST_Dynamic) { + Size += EPI.ExceptionSpec.Exceptions.size() * sizeof(QualType); + } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) { Size += sizeof(Expr*); - } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { + } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) { Size += 2 * sizeof(FunctionDecl*); - } else if (EPI.ExceptionSpecType == EST_Unevaluated) { + } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) { Size += sizeof(FunctionDecl*); } if (EPI.ConsumedParameters) @@ -4099,7 +4156,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { case TemplateArgument::Declaration: { ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl()); - return TemplateArgument(D, Arg.isDeclForReferenceParam()); + return TemplateArgument(D, Arg.getParamTypeForDecl()); } case TemplateArgument::NullPtr: @@ -4188,7 +4245,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { } case NestedNameSpecifier::Global: - // The global specifier is canonical and unique. + case NestedNameSpecifier::Super: + // The global specifier and __super specifer are canonical and unique. return NNS; } @@ -4414,7 +4472,11 @@ unsigned ASTContext::getIntegerRank(const Type *T) const { QualType ASTContext::isPromotableBitField(Expr *E) const { if (E->isTypeDependent() || E->isValueDependent()) return QualType(); - + + // FIXME: We should not do this unless E->refersToBitField() is true. This + // matters in C where getSourceBitField() will find bit-fields for various + // cases where the source expression is not a bit-field designator. + FieldDecl *Field = E->getSourceBitField(); // FIXME: conditional bit-fields? if (!Field) return QualType(); @@ -4423,9 +4485,20 @@ QualType ASTContext::isPromotableBitField(Expr *E) const { uint64_t BitWidth = Field->getBitWidthValue(*this); uint64_t IntSize = getTypeSize(IntTy); - // GCC extension compatibility: if the bit-field size is less than or equal - // to the size of int, it gets promoted no matter what its type is. - // For instance, unsigned long bf : 4 gets promoted to signed int. + // C++ [conv.prom]p5: + // A prvalue for an integral bit-field can be converted to a prvalue of type + // int if int can represent all the values of the bit-field; otherwise, it + // can be converted to unsigned int if unsigned int can represent all the + // values of the bit-field. If the bit-field is larger yet, no integral + // promotion applies to it. + // C11 6.3.1.1/2: + // [For a bit-field of type _Bool, int, signed int, or unsigned int:] + // If an int can represent all values of the original type (as restricted by + // the width, for a bit-field), the value is converted to an int; otherwise, + // it is converted to an unsigned int. + // + // FIXME: C does not permit promotion of a 'long : 3' bitfield to int. + // We perform that promotion here to match GCC and C++. if (BitWidth < IntSize) return IntTy; @@ -4433,9 +4506,10 @@ QualType ASTContext::isPromotableBitField(Expr *E) const { return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy; // Types bigger than int are not subject to promotions, and therefore act - // like the base type. - // FIXME: This doesn't quite match what gcc does, but what gcc does here - // is ridiculous. + // like the base type. GCC has some weird bugs in this area that we + // deliberately do not follow (GCC follows a pre-standard resolution to + // C's DR315 which treats bit-width as being part of the type, and this leaks + // into their semantics in some cases). return QualType(); } @@ -5090,13 +5164,15 @@ void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const { } void ASTContext::getObjCEncodingForType(QualType T, std::string& S, - const FieldDecl *Field) const { + const FieldDecl *Field, + QualType *NotEncodedT) const { // We follow the behavior of gcc, expanding structures which are // 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 */); + true /* outermost type */, false, false, + false, false, false, NotEncodedT); } void ASTContext::getObjCEncodingForPropertyType(QualType T, @@ -5222,7 +5298,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, bool StructField, bool EncodeBlockParameters, bool EncodeClassNames, - bool EncodePointerToObjCTypedef) const { + bool EncodePointerToObjCTypedef, + QualType *NotEncodedT) const { CanQualType CT = getCanonicalType(T); switch (CT->getTypeClass()) { case Type::Builtin: @@ -5238,16 +5315,14 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, case Type::Complex: { const ComplexType *CT = T->castAs<ComplexType>(); S += 'j'; - getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr, - false, false); + getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr); return; } case Type::Atomic: { const AtomicType *AT = T->castAs<AtomicType>(); S += 'A'; - getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr, - false, false); + getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr); return; } @@ -5318,7 +5393,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getLegacyIntegralTypeEncoding(PointeeTy); getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures, - nullptr); + nullptr, false, false, false, false, false, false, + NotEncodedT); return; } @@ -5346,7 +5422,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } getObjCEncodingForTypeImpl(AT->getElementType(), S, - false, ExpandStructures, FD); + false, ExpandStructures, FD, + false, false, false, false, false, false, + NotEncodedT); S += ']'; } return; @@ -5378,7 +5456,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, if (ExpandStructures) { S += '='; if (!RDecl->isUnion()) { - getObjCEncodingForStructureImpl(RDecl, S, FD); + getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT); } else { for (const auto *Field : RDecl->fields()) { if (FD) { @@ -5397,7 +5475,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getObjCEncodingForTypeImpl(qt, S, false, true, FD, /*OutermostType*/false, /*EncodingProperty*/false, - /*StructField*/true); + /*StructField*/true, + false, false, false, NotEncodedT); } } } @@ -5417,7 +5496,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getObjCEncodingForTypeImpl( FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures, FD, false /* OutermostType */, EncodingProperty, - false /* StructField */, EncodeBlockParameters, EncodeClassNames); + false /* StructField */, EncodeBlockParameters, EncodeClassNames, false, + NotEncodedT); // Block self S += "@?"; // Block parameters @@ -5426,7 +5506,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getObjCEncodingForTypeImpl( I, S, ExpandPointedToStructures, ExpandStructures, FD, false /* OutermostType */, EncodingProperty, - false /* StructField */, EncodeBlockParameters, EncodeClassNames); + false /* StructField */, EncodeBlockParameters, EncodeClassNames, + false, NotEncodedT); } S += '>'; } @@ -5468,7 +5549,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, else getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD, false, false, false, false, false, - EncodePointerToObjCTypedef); + EncodePointerToObjCTypedef, + NotEncodedT); } S += '}'; return; @@ -5555,19 +5637,21 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, // gcc just blithely ignores member pointers. // FIXME: we shoul do better than that. 'M' is available. case Type::MemberPointer: - return; - + // This matches gcc's encoding, even though technically it is insufficient. + //FIXME. We should do a better job than gcc. case Type::Vector: case Type::ExtVector: - // This matches gcc's encoding, even though technically it is - // insufficient. - // FIXME. We should do a better job than gcc. - return; - + // Until we have a coherent encoding of these three types, issue warning. + { if (NotEncodedT) + *NotEncodedT = T; + return; + } + + // We could see an undeduced auto type here during error recovery. + // Just ignore it. case Type::Auto: - // We could see an undeduced auto type here during error recovery. - // Just ignore it. return; + #define ABSTRACT_TYPE(KIND, BASE) #define TYPE(KIND, BASE) @@ -5586,7 +5670,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, std::string &S, const FieldDecl *FD, - bool includeVBases) const { + bool includeVBases, + QualType *NotEncodedT) const { assert(RDecl && "Expected non-null RecordDecl"); assert(!RDecl->isUnion() && "Should not be called for unions"); if (!RDecl->getDefinition()) @@ -5610,12 +5695,11 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, } unsigned i = 0; - for (RecordDecl::field_iterator Field = RDecl->field_begin(), - FieldEnd = RDecl->field_end(); - Field != FieldEnd; ++Field, ++i) { + for (auto *Field : RDecl->fields()) { uint64_t offs = layout.getFieldOffset(i); FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), - std::make_pair(offs, *Field)); + std::make_pair(offs, Field)); + ++i; } if (CXXRec && includeVBases) { @@ -5691,7 +5775,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, // in the initial structure. Note that this differs from gcc which // expands virtual bases each time one is encountered in the hierarchy, // making the encoding type bigger than it really is. - getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false); + getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false, + NotEncodedT); assert(!base->isEmpty()); #ifndef NDEBUG CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize()); @@ -5715,7 +5800,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, getObjCEncodingForTypeImpl(qt, S, false, true, FD, /*OutermostType*/false, /*EncodingProperty*/false, - /*StructField*/true); + /*StructField*/true, + false, false, false, NotEncodedT); #ifndef NDEBUG CurOffs += getTypeSize(field->getType()); #endif @@ -6654,11 +6740,9 @@ void getIntersectionOfProtocols(ASTContext &Context, llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSInheritedProtocols; Context.CollectInheritedProtocols(RHS->getInterface(), RHSInheritedProtocols); - for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = - RHSInheritedProtocols.begin(), - E = RHSInheritedProtocols.end(); I != E; ++I) - if (InheritedProtocolSet.count((*I))) - IntersectionOfProtocols.push_back((*I)); + for (ObjCProtocolDecl *ProtDecl : RHSInheritedProtocols) + if (InheritedProtocolSet.count(ProtDecl)) + IntersectionOfProtocols.push_back(ProtDecl); } } @@ -6708,58 +6792,40 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS, if (LHS->getNumProtocols() == 0) return true; - // Okay, we know the LHS has protocol qualifiers. If the RHS doesn't, - // more detailed analysis is required. - if (RHS->getNumProtocols() == 0) { - // OK, if LHS is a superclass of RHS *and* - // this superclass is assignment compatible with LHS. - // false otherwise. - bool IsSuperClass = - LHS->getInterface()->isSuperClassOf(RHS->getInterface()); - if (IsSuperClass) { - // OK if conversion of LHS to SuperClass results in narrowing of types - // ; i.e., SuperClass may implement at least one of the protocols - // in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok. - // But not SuperObj<P1,P2,P3> = lhs<P1,P2>. - llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols; - CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols); - // If super class has no protocols, it is not a match. - if (SuperClassInheritedProtocols.empty()) - return false; + // Okay, we know the LHS has protocol qualifiers. But RHS may or may not. + // More detailed analysis is required. + // OK, if LHS is same or a superclass of RHS *and* + // this LHS, or as RHS's super class is assignment compatible with LHS. + bool IsSuperClass = + LHS->getInterface()->isSuperClassOf(RHS->getInterface()); + if (IsSuperClass) { + // OK if conversion of LHS to SuperClass results in narrowing of types + // ; i.e., SuperClass may implement at least one of the protocols + // in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok. + // But not SuperObj<P1,P2,P3> = lhs<P1,P2>. + llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols; + CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols); + // Also, if RHS has explicit quelifiers, include them for comparing with LHS's + // qualifiers. + for (auto *RHSPI : RHS->quals()) + SuperClassInheritedProtocols.insert(RHSPI->getCanonicalDecl()); + // If there is no protocols associated with RHS, it is not a match. + if (SuperClassInheritedProtocols.empty()) + return false; - for (const auto *LHSProto : LHS->quals()) { - bool SuperImplementsProtocol = false; - for (auto *SuperClassProto : SuperClassInheritedProtocols) { - if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { - SuperImplementsProtocol = true; - break; - } + for (const auto *LHSProto : LHS->quals()) { + bool SuperImplementsProtocol = false; + for (auto *SuperClassProto : SuperClassInheritedProtocols) + if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { + SuperImplementsProtocol = true; + break; } - if (!SuperImplementsProtocol) - return false; - } - return true; - } - return false; - } - - for (const auto *LHSPI : LHS->quals()) { - bool RHSImplementsProtocol = false; - - // If the RHS doesn't implement the protocol on the left, the types - // are incompatible. - for (auto *RHSPI : RHS->quals()) { - if (RHSPI->lookupProtocolNamed(LHSPI->getIdentifier())) { - RHSImplementsProtocol = true; - break; - } + if (!SuperImplementsProtocol) + return false; } - // FIXME: For better diagnostics, consider passing back the protocol name. - if (!RHSImplementsProtocol) - return false; + return true; } - // The RHS implements all protocols listed on the LHS. - return true; + return false; } bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) { @@ -7895,7 +7961,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // We never need to emit an uninstantiated function template. if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) return false; - } else + } else if (isa<OMPThreadPrivateDecl>(D)) + return true; + else return false; // If this is a member of a class template, we do not need to emit it. @@ -8236,7 +8304,7 @@ namespace { } // end namespace -ASTContext::ParentVector +ArrayRef<ast_type_traits::DynTypedNode> ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { assert(Node.getMemoizationData() && "Invariant broken: only nodes that support memoization may be " @@ -8249,13 +8317,12 @@ ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { } ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData()); if (I == AllParents->end()) { - return ParentVector(); + return None; } - if (I->second.is<ast_type_traits::DynTypedNode *>()) { - return ParentVector(1, *I->second.get<ast_type_traits::DynTypedNode *>()); + if (auto *N = I->second.dyn_cast<ast_type_traits::DynTypedNode *>()) { + return llvm::makeArrayRef(N, 1); } - const auto &Parents = *I->second.get<ParentVector *>(); - return ParentVector(Parents.begin(), Parents.end()); + return *I->second.get<ParentVector *>(); } bool |