diff options
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 501 |
1 files changed, 314 insertions, 187 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 64386967b2206..6aad4d1d570b2 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -58,7 +58,7 @@ unsigned ASTContext::NumImplicitDestructors; unsigned ASTContext::NumImplicitDestructorsDeclared; enum FloatingRank { - HalfRank, FloatRank, DoubleRank, LongDoubleRank + HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank }; RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { @@ -633,9 +633,8 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( NTTP->getPosition(), nullptr, T, TInfo, - ExpandedTypes.data(), - ExpandedTypes.size(), - ExpandedTInfos.data()); + ExpandedTypes, + ExpandedTInfos); } else { Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(), SourceLocation(), @@ -734,16 +733,16 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr), - UInt128Decl(nullptr), Float128StubDecl(nullptr), - BuiltinVaListDecl(nullptr), BuiltinMSVaListDecl(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(), ExternCContext(nullptr), - MakeIntegerSeqDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), + UInt128Decl(nullptr), BuiltinVaListDecl(nullptr), + BuiltinMSVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), + ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), + CFConstantStringTagDecl(nullptr), CFConstantStringTypeDecl(nullptr), + ObjCInstanceTypeDecl(nullptr), FILEDecl(nullptr), jmp_bufDecl(nullptr), + sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr), + BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), + cudaConfigureCallDecl(nullptr), FirstLocalImport(), LastLocalImport(), + ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr), + TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), @@ -816,7 +815,7 @@ void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { void ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) { - ExternalSource = Source; + ExternalSource = std::move(Source); } void ASTContext::PrintStats() const { @@ -928,6 +927,14 @@ ASTContext::getMakeIntegerSeqDecl() const { return MakeIntegerSeqDecl; } +BuiltinTemplateDecl * +ASTContext::getTypePackElementDecl() const { + if (!TypePackElementDecl) + TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element, + getTypePackElementName()); + return TypePackElementDecl; +} + RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK) const { SourceLocation Loc; @@ -966,14 +973,6 @@ TypedefDecl *ASTContext::getUInt128Decl() const { return UInt128Decl; } -TypeDecl *ASTContext::getFloat128StubType() const { - assert(LangOpts.CPlusPlus && "should only be called for c++"); - if (!Float128StubDecl) - Float128StubDecl = buildImplicitRecord("__float128"); - - return Float128StubDecl; -} - void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) { BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K); R = CanQualType::CreateUnsafe(QualType(Ty, 0)); @@ -1022,6 +1021,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, InitBuiltinType(DoubleTy, BuiltinType::Double); InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble); + // GNU extension, __float128 for IEEE quadruple precision + InitBuiltinType(Float128Ty, BuiltinType::Float128); + // GNU extension, 128-bit integers. InitBuiltinType(Int128Ty, BuiltinType::Int128); InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128); @@ -1083,26 +1085,17 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, FloatComplexTy = getComplexType(FloatTy); DoubleComplexTy = getComplexType(DoubleTy); LongDoubleComplexTy = getComplexType(LongDoubleTy); + Float128ComplexTy = getComplexType(Float128Ty); // Builtin types for 'id', 'Class', and 'SEL'. InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId); InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); - if (LangOpts.OpenCL) { - InitBuiltinType(OCLImage1dTy, BuiltinType::OCLImage1d); - InitBuiltinType(OCLImage1dArrayTy, BuiltinType::OCLImage1dArray); - InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer); - InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d); - InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray); - InitBuiltinType(OCLImage2dDepthTy, BuiltinType::OCLImage2dDepth); - InitBuiltinType(OCLImage2dArrayDepthTy, BuiltinType::OCLImage2dArrayDepth); - InitBuiltinType(OCLImage2dMSAATy, BuiltinType::OCLImage2dMSAA); - InitBuiltinType(OCLImage2dArrayMSAATy, BuiltinType::OCLImage2dArrayMSAA); - InitBuiltinType(OCLImage2dMSAADepthTy, BuiltinType::OCLImage2dMSAADepth); - InitBuiltinType(OCLImage2dArrayMSAADepthTy, - BuiltinType::OCLImage2dArrayMSAADepth); - InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d); + if (LangOpts.OpenCL) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + InitBuiltinType(SingletonId, BuiltinType::Id); +#include "clang/Basic/OpenCLImageTypes.def" InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); @@ -1268,34 +1261,37 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, ASTContext::overridden_cxx_method_iterator ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { - llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos - = OverriddenMethods.find(Method->getCanonicalDecl()); + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = + OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) return nullptr; - return Pos->second.begin(); } ASTContext::overridden_cxx_method_iterator ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { - llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos - = OverriddenMethods.find(Method->getCanonicalDecl()); + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = + OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) return nullptr; - return Pos->second.end(); } unsigned ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const { - llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos - = OverriddenMethods.find(Method->getCanonicalDecl()); + llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = + OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) return 0; - return Pos->second.size(); } +ASTContext::overridden_method_range +ASTContext::overridden_methods(const CXXMethodDecl *Method) const { + return overridden_method_range(overridden_methods_begin(Method), + overridden_methods_end(Method)); +} + void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, const CXXMethodDecl *Overridden) { assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl()); @@ -1350,6 +1346,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { case BuiltinType::Float: return Target->getFloatFormat(); case BuiltinType::Double: return Target->getDoubleFormat(); case BuiltinType::LongDouble: return Target->getLongDoubleFormat(); + case BuiltinType::Float128: return Target->getFloat128Format(); } } @@ -1480,7 +1477,7 @@ static getConstantArrayInfoInChars(const ASTContext &Context, unsigned Align = EltInfo.second.getQuantity(); if (!Context.getTargetInfo().getCXXABI().isMicrosoft() || Context.getTargetInfo().getPointerWidth(0) == 64) - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); return std::make_pair(CharUnits::fromQuantity(Width), CharUnits::fromQuantity(Align)); } @@ -1564,7 +1561,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Align = EltInfo.Align; if (!getTargetInfo().getCXXABI().isMicrosoft() || getTargetInfo().getPointerWidth(0) == 64) - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); break; } case Type::ExtVector: @@ -1577,7 +1574,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { // This happens for non-power-of-2 length vectors. if (Align & (Align-1)) { Align = llvm::NextPowerOf2(Align); - Width = llvm::RoundUpToAlignment(Width, Align); + Width = llvm::alignTo(Width, Align); } // Adjust the alignment based on the target max. uint64_t TargetVectorAlign = Target->getMaxVectorAlign(); @@ -1660,6 +1657,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getLongDoubleWidth(); Align = Target->getLongDoubleAlign(); break; + case BuiltinType::Float128: + Width = Target->getFloat128Width(); + Align = Target->getFloat128Align(); + break; case BuiltinType::NullPtr: Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t) Align = Target->getPointerAlign(0); // == sizeof(void*) @@ -1680,18 +1681,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case BuiltinType::OCLQueue: case BuiltinType::OCLNDRange: case BuiltinType::OCLReserveID: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" + // Currently these types are pointers to opaque types. Width = Target->getPointerWidth(0); Align = Target->getPointerAlign(0); @@ -1903,8 +1896,8 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { if (T->isMemberPointerType()) return getPreferredTypeAlign(getPointerDiffType().getTypePtr()); - if (Target->getTriple().getArch() == llvm::Triple::xcore) - return ABIAlign; // Never overalign on XCore. + if (!Target->allowsLargerPreferedTypeAlignment()) + return ABIAlign; // Double and long long should be naturally aligned if possible. if (const ComplexType *CT = T->getAs<ComplexType>()) @@ -2991,13 +2984,18 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType, return QualType(New, 0); } +/// \brief Determine whether \p T is canonical as the result type of a function. +static bool isCanonicalResultType(QualType T) { + return T.isCanonical() && + (T.getObjCLifetime() == Qualifiers::OCL_None || + T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); +} + /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const { - const CallingConv CallConv = Info.getCC(); - // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -3009,8 +3007,9 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, return QualType(FT, 0); QualType Canonical; - if (!ResultTy.isCanonical()) { - Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), Info); + if (!isCanonicalResultType(ResultTy)) { + Canonical = + getFunctionNoProtoType(getCanonicalFunctionResultType(ResultTy), Info); // Get the new insert position for the node we care about. FunctionNoProtoType *NewIP = @@ -3018,21 +3017,13 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } - FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv); FunctionNoProtoType *New = new (*this, TypeAlignment) - FunctionNoProtoType(ResultTy, Canonical, newInfo); + FunctionNoProtoType(ResultTy, Canonical, Info); Types.push_back(New); FunctionNoProtoTypes.InsertNode(New, InsertPos); return QualType(New, 0); } -/// \brief Determine whether \p T is canonical as the result type of a function. -static bool isCanonicalResultType(QualType T) { - return T.isCanonical() && - (T.getObjCLifetime() == Qualifiers::OCL_None || - T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); -} - CanQualType ASTContext::getCanonicalFunctionResultType(QualType ResultType) const { CanQualType CanResultType = getCanonicalType(ResultType); @@ -3099,12 +3090,13 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, // them for three variable size arrays at the end: // - parameter types // - exception types - // - consumed-arguments flags + // - extended parameter information // Instead of the exception types, there could be a noexcept // expression, or information used to resolve the exception // specification. size_t Size = sizeof(FunctionProtoType) + NumArgs * sizeof(QualType); + if (EPI.ExceptionSpec.Type == EST_Dynamic) { Size += EPI.ExceptionSpec.Exceptions.size() * sizeof(QualType); } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) { @@ -3114,8 +3106,16 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) { Size += sizeof(FunctionDecl*); } - if (EPI.ConsumedParameters) - Size += NumArgs * sizeof(bool); + + // Put the ExtParameterInfos last. If all were equal, it would make + // more sense to put these before the exception specification, because + // it's much easier to skip past them compared to the elaborate switch + // required to skip the exception specification. However, all is not + // equal; ExtParameterInfos are used to model very uncommon features, + // and it's better not to burden the more common paths. + if (EPI.ExtParameterInfos) { + Size += NumArgs * sizeof(FunctionProtoType::ExtParameterInfo); + } FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment); FunctionProtoType::ExtProtoInfo newEPI = EPI; @@ -3393,23 +3393,19 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, QualType Underlying) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); - - unsigned NumArgs = Args.size(); SmallVector<TemplateArgument, 4> ArgVec; - ArgVec.reserve(NumArgs); - for (unsigned i = 0; i != NumArgs; ++i) - ArgVec.push_back(Args[i].getArgument()); + ArgVec.reserve(Args.size()); + for (const TemplateArgumentLoc &Arg : Args.arguments()) + ArgVec.push_back(Arg.getArgument()); - return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, - Underlying); + return getTemplateSpecializationType(Template, ArgVec, Underlying); } #ifndef NDEBUG -static bool hasAnyPackExpansions(const TemplateArgument *Args, - unsigned NumArgs) { - for (unsigned I = 0; I != NumArgs; ++I) - if (Args[I].isPackExpansion()) +static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) { + for (const TemplateArgument &Arg : Args) + if (Arg.isPackExpansion()) return true; return true; @@ -3418,8 +3414,7 @@ static bool hasAnyPackExpansions(const TemplateArgument *Args, QualType ASTContext::getTemplateSpecializationType(TemplateName Template, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, QualType Underlying) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); @@ -3436,32 +3431,29 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, else { // We can get here with an alias template when the specialization contains // a pack expansion that does not match up with a parameter pack. - assert((!IsTypeAlias || hasAnyPackExpansions(Args, NumArgs)) && + assert((!IsTypeAlias || hasAnyPackExpansions(Args)) && "Caller must compute aliased type"); IsTypeAlias = false; - CanonType = getCanonicalTemplateSpecializationType(Template, Args, - NumArgs); + CanonType = getCanonicalTemplateSpecializationType(Template, Args); } // Allocate the (non-canonical) template specialization type, but don't // try to unique it: these types typically have location information that // we don't unique and don't want to lose. void *Mem = Allocate(sizeof(TemplateSpecializationType) + - sizeof(TemplateArgument) * NumArgs + + sizeof(TemplateArgument) * Args.size() + (IsTypeAlias? sizeof(QualType) : 0), TypeAlignment); TemplateSpecializationType *Spec - = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, CanonType, + = new (Mem) TemplateSpecializationType(Template, Args, CanonType, IsTypeAlias ? Underlying : QualType()); Types.push_back(Spec); return QualType(Spec, 0); } -QualType -ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, - const TemplateArgument *Args, - unsigned NumArgs) const { +QualType ASTContext::getCanonicalTemplateSpecializationType( + TemplateName Template, ArrayRef<TemplateArgument> Args) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); @@ -3472,15 +3464,16 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, // Build the canonical template specialization type. TemplateName CanonTemplate = getCanonicalTemplateName(Template); SmallVector<TemplateArgument, 4> CanonArgs; + unsigned NumArgs = Args.size(); CanonArgs.reserve(NumArgs); - for (unsigned I = 0; I != NumArgs; ++I) - CanonArgs.push_back(getCanonicalTemplateArgument(Args[I])); + for (const TemplateArgument &Arg : Args) + CanonArgs.push_back(getCanonicalTemplateArgument(Arg)); // Determine whether this canonical template specialization type already // exists. llvm::FoldingSetNodeID ID; TemplateSpecializationType::Profile(ID, CanonTemplate, - CanonArgs.data(), NumArgs, *this); + CanonArgs, *this); void *InsertPos = nullptr; TemplateSpecializationType *Spec @@ -3492,7 +3485,7 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, sizeof(TemplateArgument) * NumArgs), TypeAlignment); Spec = new (Mem) TemplateSpecializationType(CanonTemplate, - CanonArgs.data(), NumArgs, + CanonArgs, QualType(), QualType()); Types.push_back(Spec); TemplateSpecializationTypes.InsertNode(Spec, InsertPos); @@ -3592,9 +3585,7 @@ ASTContext::getDependentTemplateSpecializationType( SmallVector<TemplateArgument, 16> ArgCopy; for (unsigned I = 0, E = Args.size(); I != E; ++I) ArgCopy.push_back(Args[I].getArgument()); - return getDependentTemplateSpecializationType(Keyword, NNS, Name, - ArgCopy.size(), - ArgCopy.data()); + return getDependentTemplateSpecializationType(Keyword, NNS, Name, ArgCopy); } QualType @@ -3602,14 +3593,13 @@ ASTContext::getDependentTemplateSpecializationType( ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args) const { + ArrayRef<TemplateArgument> Args) const { assert((!NNS || NNS->isDependent()) && "nested-name-specifier must be dependent"); llvm::FoldingSetNodeID ID; DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS, - Name, NumArgs, Args); + Name, Args); void *InsertPos = nullptr; DependentTemplateSpecializationType *T @@ -3623,6 +3613,7 @@ ASTContext::getDependentTemplateSpecializationType( if (Keyword == ETK_None) CanonKeyword = ETK_Typename; bool AnyNonCanonArgs = false; + unsigned NumArgs = Args.size(); SmallVector<TemplateArgument, 16> CanonArgs(NumArgs); for (unsigned I = 0; I != NumArgs; ++I) { CanonArgs[I] = getCanonicalTemplateArgument(Args[I]); @@ -3633,8 +3624,8 @@ ASTContext::getDependentTemplateSpecializationType( QualType Canon; if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) { Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS, - Name, NumArgs, - CanonArgs.data()); + Name, + CanonArgs); // Find the insert position again. DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -3644,7 +3635,7 @@ ASTContext::getDependentTemplateSpecializationType( sizeof(TemplateArgument) * NumArgs), TypeAlignment); T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS, - Name, NumArgs, Args, Canon); + Name, Args, Canon); Types.push_back(T); DependentTemplateSpecializationTypes.InsertNode(T, InsertPos); return QualType(T, 0); @@ -4012,13 +4003,35 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind Kind) const { - UnaryTransformType *Ty = - new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType, - Kind, - UnderlyingType->isDependentType() ? - QualType() : getCanonicalType(UnderlyingType)); - Types.push_back(Ty); - return QualType(Ty, 0); + UnaryTransformType *ut = nullptr; + + if (BaseType->isDependentType()) { + // Look in the folding set for an existing type. + llvm::FoldingSetNodeID ID; + DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind); + + void *InsertPos = nullptr; + DependentUnaryTransformType *Canon + = DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos); + + if (!Canon) { + // Build a new, canonical __underlying_type(type) type. + Canon = new (*this, TypeAlignment) + DependentUnaryTransformType(*this, getCanonicalType(BaseType), + Kind); + DependentUnaryTransformTypes.InsertNode(Canon, InsertPos); + } + ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, + QualType(), Kind, + QualType(Canon, 0)); + } else { + QualType CanonType = getCanonicalType(UnderlyingType); + ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, + UnderlyingType, Kind, + CanonType); + } + Types.push_back(ut); + return QualType(ut, 0); } /// getAutoType - Return the uniqued reference to the 'auto' type which has been @@ -4623,6 +4636,7 @@ static FloatingRank getFloatingRank(QualType T) { case BuiltinType::Float: return FloatRank; case BuiltinType::Double: return DoubleRank; case BuiltinType::LongDouble: return LongDoubleRank; + case BuiltinType::Float128: return Float128Rank; } } @@ -4639,6 +4653,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, case FloatRank: return FloatComplexTy; case DoubleRank: return DoubleComplexTy; case LongDoubleRank: return LongDoubleComplexTy; + case Float128Rank: return Float128ComplexTy; } } @@ -4648,6 +4663,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, case FloatRank: return FloatTy; case DoubleRank: return DoubleTy; case LongDoubleRank: return LongDoubleTy; + case Float128Rank: return Float128Ty; } llvm_unreachable("getFloatingRank(): illegal value for rank"); } @@ -4868,40 +4884,63 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const { return 1; } -// getCFConstantStringType - Return the type used for constant CFStrings. -QualType ASTContext::getCFConstantStringType() const { +TypedefDecl *ASTContext::getCFConstantStringDecl() const { if (!CFConstantStringTypeDecl) { - CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString"); - CFConstantStringTypeDecl->startDefinition(); + assert(!CFConstantStringTagDecl && + "tag and typedef should be initialized together"); + CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag"); + CFConstantStringTagDecl->startDefinition(); QualType FieldTypes[4]; + const char *FieldNames[4]; // const int *isa; FieldTypes[0] = getPointerType(IntTy.withConst()); + FieldNames[0] = "isa"; // int flags; FieldTypes[1] = IntTy; + FieldNames[1] = "flags"; // const char *str; FieldTypes[2] = getPointerType(CharTy.withConst()); + FieldNames[2] = "str"; // long length; FieldTypes[3] = LongTy; + FieldNames[3] = "length"; // Create fields for (unsigned i = 0; i < 4; ++i) { - FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl, + FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTagDecl, + SourceLocation(), SourceLocation(), - SourceLocation(), nullptr, + &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr, /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); - CFConstantStringTypeDecl->addDecl(Field); + CFConstantStringTagDecl->addDecl(Field); } - CFConstantStringTypeDecl->completeDefinition(); + CFConstantStringTagDecl->completeDefinition(); + // This type is designed to be compatible with NSConstantString, but cannot + // use the same name, since NSConstantString is an interface. + auto tagType = getTagDeclType(CFConstantStringTagDecl); + CFConstantStringTypeDecl = + buildImplicitTypedef(tagType, "__NSConstantString"); } - return getTagDeclType(CFConstantStringTypeDecl); + return CFConstantStringTypeDecl; +} + +RecordDecl *ASTContext::getCFConstantStringTagDecl() const { + if (!CFConstantStringTagDecl) + getCFConstantStringDecl(); // Build the tag and the typedef. + return CFConstantStringTagDecl; +} + +// getCFConstantStringType - Return the type used for constant CFStrings. +QualType ASTContext::getCFConstantStringType() const { + return getTypedefType(getCFConstantStringDecl()); } QualType ASTContext::getObjCSuperType() const { @@ -4914,9 +4953,13 @@ QualType ASTContext::getObjCSuperType() const { } void ASTContext::setCFConstantStringType(QualType T) { - const RecordType *Rec = T->getAs<RecordType>(); - assert(Rec && "Invalid CFConstantStringType"); - CFConstantStringTypeDecl = Rec->getDecl(); + const TypedefType *TD = T->getAs<TypedefType>(); + assert(TD && "Invalid CFConstantStringType"); + CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl()); + auto TagType = + CFConstantStringTypeDecl->getUnderlyingType()->getAs<RecordType>(); + assert(TagType && "Invalid CFConstantStringType"); + CFConstantStringTagDecl = TagType->getDecl(); } QualType ASTContext::getBlockDescriptorType() const { @@ -5096,6 +5139,27 @@ bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); } +ASTContext::InlineVariableDefinitionKind +ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const { + if (!VD->isInline()) + return InlineVariableDefinitionKind::None; + + // In almost all cases, it's a weak definition. + auto *First = VD->getFirstDecl(); + if (!First->isConstexpr() || First->isInlineSpecified() || + !VD->isStaticDataMember()) + return InlineVariableDefinitionKind::Weak; + + // If there's a file-context declaration in this translation unit, it's a + // non-discardable definition. + for (auto *D : VD->redecls()) + if (D->getLexicalDeclContext()->isFileContext()) + return InlineVariableDefinitionKind::Strong; + + // If we've not seen one yet, we don't know. + return InlineVariableDefinitionKind::WeakUnknown; +} + static inline std::string charUnitsToString(const CharUnits &CU) { return llvm::itostr(CU.getQuantity()); @@ -5122,7 +5186,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { SourceLocation Loc; CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); CharUnits ParmOffset = PtrSize; - for (auto PI : Decl->params()) { + for (auto PI : Decl->parameters()) { QualType PType = PI->getType(); CharUnits sz = getObjCEncodingTypeSize(PType); if (sz.isZero()) @@ -5137,7 +5201,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { // Argument types. ParmOffset = PtrSize; - for (auto PVDecl : Decl->params()) { + for (auto PVDecl : Decl->parameters()) { QualType PType = PVDecl->getOriginalType(); if (const ArrayType *AT = dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { @@ -5165,7 +5229,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, getObjCEncodingForType(Decl->getReturnType(), S); CharUnits ParmOffset; // Compute size of all parameters. - for (auto PI : Decl->params()) { + for (auto PI : Decl->parameters()) { QualType PType = PI->getType(); CharUnits sz = getObjCEncodingTypeSize(PType); if (sz.isZero()) @@ -5179,7 +5243,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, ParmOffset = CharUnits::Zero(); // Argument types. - for (auto PVDecl : Decl->params()) { + for (auto PVDecl : Decl->parameters()) { QualType PType = PVDecl->getOriginalType(); if (const ArrayType *AT = dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { @@ -5450,6 +5514,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, case BuiltinType::LongDouble: return 'D'; case BuiltinType::NullPtr: return '*'; // like char* + case BuiltinType::Float128: case BuiltinType::Half: // FIXME: potentially need @encodes for these! return ' '; @@ -5460,18 +5525,9 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, llvm_unreachable("@encoding ObjC primitive type"); // OpenCL and placeholder types don't need @encodings. - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage2dDepth: - case BuiltinType::OCLImage2dArrayDepth: - case BuiltinType::OCLImage2dMSAA: - case BuiltinType::OCLImage2dArrayMSAA: - case BuiltinType::OCLImage2dMSAADepth: - case BuiltinType::OCLImage2dArrayMSAADepth: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: @@ -5691,8 +5747,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); llvm::raw_string_ostream OS(S); TemplateSpecializationType::PrintTemplateArgumentList(OS, - TemplateArgs.data(), - TemplateArgs.size(), + TemplateArgs.asArray(), (*this).getPrintingPolicy()); } } else { @@ -5913,7 +5968,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, QualType *NotEncodedT) const { assert(RDecl && "Expected non-null RecordDecl"); assert(!RDecl->isUnion() && "Should not be called for unions"); - if (!RDecl->getDefinition()) + if (!RDecl->getDefinition() || RDecl->getDefinition()->isInvalidDecl()) return; CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl); @@ -6354,6 +6409,7 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { // }; VaListDecl->completeDefinition(); + Context->VaListTagDecl = VaListDecl; // typedef struct __va_list __builtin_va_list; QualType T = Context->getRecordType(VaListDecl); @@ -7132,6 +7188,11 @@ QualType ASTContext::areCommonBaseCompatible( if (!LDecl || !RDecl) return QualType(); + // When either LHS or RHS is a kindof type, we should return a kindof type. + // For example, for common base of kindof(ASub1) and kindof(ASub2), we return + // kindof(A). + bool anyKindOf = LHS->isKindOfType() || RHS->isKindOfType(); + // Follow the left-hand side up the class hierarchy until we either hit a // root or find the RHS. Record the ancestors in case we don't find it. llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4> @@ -7166,10 +7227,12 @@ QualType ASTContext::areCommonBaseCompatible( anyChanges = true; // If anything in the LHS will have changed, build a new result type. - if (anyChanges) { + // If we need to return a kindof type but LHS is not a kindof type, we + // build a new result type. + if (anyChanges || LHS->isKindOfType() != anyKindOf) { QualType Result = getObjCInterfaceType(LHS->getInterface()); Result = getObjCObjectType(Result, LHSTypeArgs, Protocols, - LHS->isKindOfType()); + anyKindOf || LHS->isKindOfType()); return getObjCObjectPointerType(Result); } @@ -7214,10 +7277,12 @@ QualType ASTContext::areCommonBaseCompatible( if (!Protocols.empty()) anyChanges = true; - if (anyChanges) { + // If we need to return a kindof type but RHS is not a kindof type, we + // build a new result type. + if (anyChanges || RHS->isKindOfType() != anyKindOf) { QualType Result = getObjCInterfaceType(RHS->getInterface()); Result = getObjCObjectType(Result, RHSTypeArgs, Protocols, - RHS->isKindOfType()); + anyKindOf || RHS->isKindOfType()); return getObjCObjectPointerType(Result); } @@ -7461,8 +7526,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (lproto->getTypeQuals() != rproto->getTypeQuals()) return QualType(); - if (LangOpts.ObjCAutoRefCount && - !FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto)) + if (!doFunctionTypesMatchOnExtParameterInfos(rproto, lproto)) return QualType(); // Check parameter type compatibility @@ -7587,6 +7651,15 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, Qualifiers LQuals = LHSCan.getLocalQualifiers(); Qualifiers RQuals = RHSCan.getLocalQualifiers(); if (LQuals != RQuals) { + if (getLangOpts().OpenCL) { + if (LHSCan.getUnqualifiedType() != RHSCan.getUnqualifiedType() || + LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers()) + return QualType(); + if (LQuals.isAddressSpaceSupersetOf(RQuals)) + return LHS; + if (RQuals.isAddressSpaceSupersetOf(LQuals)) + return RHS; + } // If any of these qualifiers are different, we have a type // mismatch. if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() || @@ -7850,21 +7923,26 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, llvm_unreachable("Invalid Type::Class!"); } -bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs( - const FunctionProtoType *FromFunctionType, - const FunctionProtoType *ToFunctionType) { - if (FromFunctionType->hasAnyConsumedParams() != - ToFunctionType->hasAnyConsumedParams()) +bool ASTContext::doFunctionTypesMatchOnExtParameterInfos( + const FunctionProtoType *firstFnType, + const FunctionProtoType *secondFnType) { + // Fast path: if the first type doesn't have ext parameter infos, + // we match if and only if they second type also doesn't have them. + if (!firstFnType->hasExtParameterInfos()) + return !secondFnType->hasExtParameterInfos(); + + // Otherwise, we can only match if the second type has them. + if (!secondFnType->hasExtParameterInfos()) return false; - FunctionProtoType::ExtProtoInfo FromEPI = - FromFunctionType->getExtProtoInfo(); - FunctionProtoType::ExtProtoInfo ToEPI = - ToFunctionType->getExtProtoInfo(); - if (FromEPI.ConsumedParameters && ToEPI.ConsumedParameters) - for (unsigned i = 0, n = FromFunctionType->getNumParams(); i != n; ++i) { - if (FromEPI.ConsumedParameters[i] != ToEPI.ConsumedParameters[i]) - return false; - } + + auto firstEPI = firstFnType->getExtParameterInfos(); + auto secondEPI = secondFnType->getExtParameterInfos(); + assert(firstEPI.size() == secondEPI.size()); + + for (size_t i = 0, n = firstEPI.size(); i != n; ++i) { + if (firstEPI[i] != secondEPI[i]) + return false; + } return true; } @@ -8374,22 +8452,29 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, return GVA_DiscardableODR; } -static GVALinkage adjustGVALinkageForAttributes(GVALinkage L, const Decl *D) { +static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context, + GVALinkage L, const Decl *D) { // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx // dllexport/dllimport on inline functions. if (D->hasAttr<DLLImportAttr>()) { if (L == GVA_DiscardableODR || L == GVA_StrongODR) return GVA_AvailableExternally; - } else if (D->hasAttr<DLLExportAttr>() || D->hasAttr<CUDAGlobalAttr>()) { + } else if (D->hasAttr<DLLExportAttr>()) { if (L == GVA_DiscardableODR) return GVA_StrongODR; + } else if (Context.getLangOpts().CUDA && Context.getLangOpts().CUDAIsDevice && + D->hasAttr<CUDAGlobalAttr>()) { + // Device-side functions with __global__ attribute must always be + // visible externally so they can be launched from host. + if (L == GVA_DiscardableODR || L == GVA_Internal) + return GVA_StrongODR; } return L; } GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { - return adjustGVALinkageForAttributes(basicGVALinkageForFunction(*this, FD), - FD); + return adjustGVALinkageForAttributes( + *this, basicGVALinkageForFunction(*this, FD), FD); } static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, @@ -8422,15 +8507,31 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, if (Context.isMSStaticDataMemberInlineDefinition(VD)) return GVA_DiscardableODR; + // Most non-template variables have strong linkage; inline variables are + // linkonce_odr or (occasionally, for compatibility) weak_odr. + GVALinkage StrongLinkage; + switch (Context.getInlineVariableDefinitionKind(VD)) { + case ASTContext::InlineVariableDefinitionKind::None: + StrongLinkage = GVA_StrongExternal; + break; + case ASTContext::InlineVariableDefinitionKind::Weak: + case ASTContext::InlineVariableDefinitionKind::WeakUnknown: + StrongLinkage = GVA_DiscardableODR; + break; + case ASTContext::InlineVariableDefinitionKind::Strong: + StrongLinkage = GVA_StrongODR; + break; + } + switch (VD->getTemplateSpecializationKind()) { case TSK_Undeclared: - return GVA_StrongExternal; + return StrongLinkage; case TSK_ExplicitSpecialization: return Context.getTargetInfo().getCXXABI().isMicrosoft() && VD->isStaticDataMember() ? GVA_StrongODR - : GVA_StrongExternal; + : StrongLinkage; case TSK_ExplicitInstantiationDefinition: return GVA_StrongODR; @@ -8446,8 +8547,8 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, } GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { - return adjustGVALinkageForAttributes(basicGVALinkageForVariable(*this, VD), - VD); + return adjustGVALinkageForAttributes( + *this, basicGVALinkageForVariable(*this, VD), VD); } bool ASTContext::DeclMustBeEmitted(const Decl *D) { @@ -8464,8 +8565,17 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // We never need to emit an uninstantiated function template. if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) return false; - } else if (isa<OMPThreadPrivateDecl>(D)) + } else if (isa<PragmaCommentDecl>(D)) + return true; + else if (isa<OMPThreadPrivateDecl>(D) || + D->hasAttr<OMPDeclareTargetDeclAttr>()) return true; + else if (isa<PragmaDetectMismatchDecl>(D)) + return true; + else if (isa<OMPThreadPrivateDecl>(D)) + return !D->getDeclContext()->isDependentContext(); + else if (isa<OMPDeclareReductionDecl>(D)) + return !D->getDeclContext()->isDependentContext(); else return false; @@ -8545,8 +8655,25 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, if (IsCXXMethod) return ABI->getDefaultMethodCallConv(IsVariadic); - if (LangOpts.MRTD && !IsVariadic) return CC_X86StdCall; - + switch (LangOpts.getDefaultCallingConv()) { + case LangOptions::DCC_None: + break; + case LangOptions::DCC_CDecl: + return CC_C; + case LangOptions::DCC_FastCall: + if (getTargetInfo().hasFeature("sse2")) + 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; + } return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown); } @@ -8626,6 +8753,8 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const { return DoubleTy; case TargetInfo::LongDouble: return LongDoubleTy; + case TargetInfo::Float128: + return Float128Ty; case TargetInfo::NoFloat: return QualType(); } @@ -8639,8 +8768,7 @@ void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) { } unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const { - llvm::DenseMap<const NamedDecl *, unsigned>::const_iterator I = - MangleNumbers.find(ND); + auto I = MangleNumbers.find(ND); return I != MangleNumbers.end() ? I->second : 1; } @@ -8650,8 +8778,7 @@ void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) { } unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const { - llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I = - StaticLocalNumbers.find(VD); + auto I = StaticLocalNumbers.find(VD); return I != StaticLocalNumbers.end() ? I->second : 1; } |