diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTContext.cpp | 502 |
1 files changed, 341 insertions, 161 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index fb96301..108677a 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -19,6 +19,7 @@ #include "clang/AST/Comment.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" @@ -327,7 +328,7 @@ const Decl *adjustDeclToTemplate(const Decl *D) { // FIXME: Adjust alias templates? return D; } -} // unnamed namespace +} // anonymous namespace const RawComment *ASTContext::getRawCommentForAnyRedecl( const Decl *D, @@ -366,8 +367,10 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl( OriginalDeclForRC = I; RawCommentAndCacheFlags Raw; if (RC) { - Raw.setRaw(RC); + // Call order swapped to work around ICE in VS2015 RTM (Release Win32) + // https://connect.microsoft.com/VisualStudio/feedback/details/1741530 Raw.setKind(RawCommentAndCacheFlags::FromDecl); + Raw.setRaw(RC); } else Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl); Raw.setOriginalDecl(I); @@ -428,7 +431,6 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC, new (*this) comments::FullComment(FC->getBlocks(), ThisDeclInfo); return CFC; - } comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const { @@ -659,8 +661,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( nullptr, TemplateParameterList::Create(*this, SourceLocation(), SourceLocation(), - CanonParams.data(), - CanonParams.size(), + CanonParams, SourceLocation())); // Get the new insert position for the node we care about. @@ -681,9 +682,11 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { case TargetCXXABI::GenericARM: // Same as Itanium at this level case TargetCXXABI::iOS: case TargetCXXABI::iOS64: + case TargetCXXABI::WatchOS: case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericMIPS: case TargetCXXABI::GenericItanium: + case TargetCXXABI::WebAssembly: return CreateItaniumCXXABI(*this); case TargetCXXABI::Microsoft: return CreateMicrosoftCXXABI(*this); @@ -732,19 +735,20 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, SubstTemplateTemplateParmPacks(this_()), GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr), - BuiltinVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), - ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(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), - SourceMgr(SM), LangOpts(LOpts), + MakeIntegerSeqDecl(nullptr), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), - AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts), - Idents(idents), Selectors(sels), BuiltinInfo(builtins), - DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr), - Comments(SM), CommentsLoaded(false), + AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(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); } @@ -757,10 +761,8 @@ ASTContext::~ASTContext() { ReleaseDeclContextMaps(); // 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]); + for (auto &Pair : Deallocations) + (Pair.first)(Pair.second); // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed // because they can contain DenseMaps. @@ -783,23 +785,33 @@ ASTContext::~ASTContext() { A != AEnd; ++A) A->second->~AttrVec(); + for (std::pair<const MaterializeTemporaryExpr *, APValue *> &MTVPair : + MaterializedTemporaryValues) + MTVPair.second->~APValue(); + llvm::DeleteContainerSeconds(MangleNumberingContexts); } void ASTContext::ReleaseParentMapEntries() { - if (!AllParents) return; - for (const auto &Entry : *AllParents) { + if (!PointerParents) return; + for (const auto &Entry : *PointerParents) { if (Entry.second.is<ast_type_traits::DynTypedNode *>()) { delete Entry.second.get<ast_type_traits::DynTypedNode *>(); - } else { - assert(Entry.second.is<ParentVector *>()); + } else if (Entry.second.is<ParentVector *>()) { + delete Entry.second.get<ParentVector *>(); + } + } + for (const auto &Entry : *OtherParents) { + if (Entry.second.is<ast_type_traits::DynTypedNode *>()) { + delete Entry.second.get<ast_type_traits::DynTypedNode *>(); + } else if (Entry.second.is<ParentVector *>()) { delete Entry.second.get<ParentVector *>(); } } } void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { - Deallocations[Callback].push_back(Data); + Deallocations.push_back({Callback, Data}); } void @@ -898,6 +910,24 @@ ExternCContextDecl *ASTContext::getExternCContextDecl() const { return ExternCContext; } +BuiltinTemplateDecl * +ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK, + const IdentifierInfo *II) const { + auto *BuiltinTemplate = BuiltinTemplateDecl::Create(*this, TUDecl, II, BTK); + BuiltinTemplate->setImplicit(); + TUDecl->addDecl(BuiltinTemplate); + + return BuiltinTemplate; +} + +BuiltinTemplateDecl * +ASTContext::getMakeIntegerSeqDecl() const { + if (!MakeIntegerSeqDecl) + MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq, + getMakeIntegerSeqName()); + return MakeIntegerSeqDecl; +} + RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK) const { SourceLocation Loc; @@ -950,13 +980,15 @@ void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) { Types.push_back(Ty); } -void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { +void ASTContext::InitBuiltinTypes(const TargetInfo &Target, + const TargetInfo *AuxTarget) { assert((!this->Target || this->Target == &Target) && "Incorrect target reinitialization"); assert(VoidTy.isNull() && "Context reinitialized?"); this->Target = &Target; - + this->AuxTarget = AuxTarget; + ABI.reset(createCXXABI(Target)); AddrSpaceMap = getAddressSpaceMap(Target, LangOpts); AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts); @@ -1043,6 +1075,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { // Placeholder type for builtin functions. InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn); + // Placeholder type for OMP array sections. + if (LangOpts.OpenMP) + InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); + // C99 6.2.5p11. FloatComplexTy = getComplexType(FloatTy); DoubleComplexTy = getComplexType(DoubleTy); @@ -1059,10 +1095,21 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { 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); InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); + InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent); + InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue); + InitBuiltinType(OCLNDRangeTy, BuiltinType::OCLNDRange); + InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID); } // Builtin type for __objc_yes and __objc_no @@ -1083,7 +1130,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { InitBuiltinType(HalfTy, BuiltinType::Half); // Builtin type used to help define __builtin_va_list. - VaListTagTy = QualType(); + VaListTagDecl = nullptr; } DiagnosticsEngine &ASTContext::getDiagnostics() const { @@ -1629,11 +1676,21 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Align = Target->getIntAlign(); break; case BuiltinType::OCLEvent: + case BuiltinType::OCLClkEvent: + 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: // Currently these types are pointers to opaque types. Width = Target->getPointerWidth(0); @@ -1861,7 +1918,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { /// getTargetDefaultAlignForAttributeAligned - Return the default alignment /// for __attribute__((aligned)) on this target, to be used if no alignment /// value is specified. -unsigned ASTContext::getTargetDefaultAlignForAttributeAligned(void) const { +unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const { return getTargetInfo().getDefaultAlignForAttributeAligned(); } @@ -2006,6 +2063,17 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD, ObjCImpls[CatD] = ImplD; } +const ObjCMethodDecl * +ASTContext::getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const { + return ObjCMethodRedecls.lookup(MD); +} + +void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD, + const ObjCMethodDecl *Redecl) { + assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration"); + ObjCMethodRedecls[MD] = Redecl; +} + const ObjCInterfaceDecl *ASTContext::getObjContainingInterface( const NamedDecl *ND) const { if (const ObjCInterfaceDecl *ID = @@ -2759,9 +2827,10 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType, QualType canon = getQualifiedType(QualType(canonTy,0), canonElementType.Quals); - // If we didn't need extra canonicalization for the element type, - // then just use that as our result. - if (QualType(canonElementType.Ty, 0) == elementType) + // If we didn't need extra canonicalization for the element type or the size + // expression, then just use that as our result. + if (QualType(canonElementType.Ty, 0) == elementType && + canonTy->getSizeExpr() == numElements) return canon; // Otherwise, we need to build a type which follows the spelling @@ -2956,6 +3025,21 @@ static bool isCanonicalResultType(QualType T) { T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); } +CanQualType +ASTContext::getCanonicalFunctionResultType(QualType ResultType) const { + CanQualType CanResultType = getCanonicalType(ResultType); + + // Canonical result types do not have ARC lifetime qualifiers. + if (CanResultType.getQualifiers().hasObjCLifetime()) { + Qualifiers Qs = CanResultType.getQualifiers(); + Qs.removeObjCLifetime(); + return CanQualType::CreateUnsafe( + getQualifiedType(CanResultType.getUnqualifiedType(), Qs)); + } + + return CanResultType; +} + QualType ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, const FunctionProtoType::ExtProtoInfo &EPI) const { @@ -2993,14 +3077,8 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, CanonicalEPI.HasTrailingReturn = false; CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo(); - // Result types do not have ARC lifetime qualifiers. - QualType CanResultTy = getCanonicalType(ResultTy); - if (ResultTy.getQualifiers().hasObjCLifetime()) { - Qualifiers Qs = CanResultTy.getQualifiers(); - Qs.removeObjCLifetime(); - CanResultTy = getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); - } - + // Adjust the canonical function result type. + CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy); Canonical = getFunctionType(CanResultTy, CanonicalArgs, CanonicalEPI); // Get the new insert position for the node we care about. @@ -3164,7 +3242,6 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind, return QualType(type, 0); } - /// \brief Retrieve a substitution-result type. QualType ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, @@ -3595,20 +3672,18 @@ static bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols, return true; } -static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols, - unsigned &NumProtocols) { - ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols; - +static void +SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) { // Sort protocols, keyed by name. - llvm::array_pod_sort(Protocols, ProtocolsEnd, CmpProtocolNames); + llvm::array_pod_sort(Protocols.begin(), Protocols.end(), CmpProtocolNames); // Canonicalize. - for (unsigned I = 0, N = NumProtocols; I != N; ++I) - Protocols[I] = Protocols[I]->getCanonicalDecl(); - + for (ObjCProtocolDecl *&P : Protocols) + P = P->getCanonicalDecl(); + // Remove duplicates. - ProtocolsEnd = std::unique(Protocols, ProtocolsEnd); - NumProtocols = ProtocolsEnd-Protocols; + auto ProtocolsEnd = std::unique(Protocols.begin(), Protocols.end()); + Protocols.erase(ProtocolsEnd, Protocols.end()); } QualType ASTContext::getObjCObjectType(QualType BaseType, @@ -3673,12 +3748,9 @@ QualType ASTContext::getObjCObjectType( ArrayRef<ObjCProtocolDecl *> canonProtocols; SmallVector<ObjCProtocolDecl*, 8> canonProtocolsVec; if (!protocolsSorted) { - canonProtocolsVec.insert(canonProtocolsVec.begin(), - protocols.begin(), - protocols.end()); - unsigned uniqueCount = protocols.size(); - SortAndUniqueProtocols(&canonProtocolsVec[0], uniqueCount); - canonProtocols = llvm::makeArrayRef(&canonProtocolsVec[0], uniqueCount); + canonProtocolsVec.append(protocols.begin(), protocols.end()); + SortAndUniqueProtocols(canonProtocolsVec); + canonProtocols = canonProtocolsVec; } else { canonProtocols = protocols; } @@ -3869,7 +3941,6 @@ QualType ASTContext::getTypeOfType(QualType tofType) const { return QualType(tot, 0); } - /// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType /// nodes. This would never be helpful, since each such type has its own /// expression, and would not give a significant memory saving, since there @@ -3921,20 +3992,20 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType, /// getAutoType - Return the uniqued reference to the 'auto' type which has been /// deduced to the given type, or to the canonical undeduced 'auto' type, or the /// canonical deduced-but-dependent 'auto' type. -QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto, +QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent) const { - if (DeducedType.isNull() && !IsDecltypeAuto && !IsDependent) + if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent) return getAutoDeductType(); // Look in the folding set for an existing type. void *InsertPos = nullptr; llvm::FoldingSetNodeID ID; - AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent); + AutoType::Profile(ID, DeducedType, Keyword, IsDependent); if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(AT, 0); AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType, - IsDecltypeAuto, + Keyword, IsDependent); Types.push_back(AT); if (InsertPos) @@ -3974,7 +4045,7 @@ QualType ASTContext::getAtomicType(QualType T) const { QualType ASTContext::getAutoDeductType() const { if (AutoDeductTy.isNull()) AutoDeductTy = QualType( - new (*this, TypeAlignment) AutoType(QualType(), /*decltype(auto)*/false, + new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto, /*dependent*/false), 0); return AutoDeductTy; @@ -4310,7 +4381,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { A != AEnd; (void)++A, ++Idx) CanonArgs[Idx] = getCanonicalTemplateArgument(*A); - return TemplateArgument(CanonArgs, Arg.pack_size()); + return TemplateArgument(llvm::makeArrayRef(CanonArgs, Arg.pack_size())); } } @@ -4374,7 +4445,6 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); } - const ArrayType *ASTContext::getAsArrayType(QualType T) const { // Handle the non-qualified case efficiently. if (!T.hasLocalQualifiers()) { @@ -4909,8 +4979,6 @@ bool ASTContext::BlockRequiresCopying(QualType Ty, // If we have lifetime, that dominates. if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { - assert(getLangOpts().ObjCAutoRefCount); - switch (lifetime) { case Qualifiers::OCL_None: llvm_unreachable("impossible"); @@ -4944,14 +5012,14 @@ bool ASTContext::getByrefLifetime(QualType Ty, if (Ty->isRecordType()) { HasByrefExtendedLayout = true; LifeTime = Qualifiers::OCL_None; - } - else if (getLangOpts().ObjCAutoRefCount) - LifeTime = Ty.getObjCLifetime(); - // MRR. - else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) + } else if ((LifeTime = Ty.getObjCLifetime())) { + // Honor the ARC qualifiers. + } else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) { + // The MRR rule. LifeTime = Qualifiers::OCL_ExplicitNone; - else + } else { LifeTime = Qualifiers::OCL_None; + } return true; } @@ -4990,9 +5058,10 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const { } bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { - return getLangOpts().MSVCCompat && VD->isStaticDataMember() && + return getTargetInfo().getCXXABI().isMicrosoft() && + VD->isStaticDataMember() && VD->getType()->isIntegralOrEnumerationType() && - VD->isFirstDecl() && !VD->isOutOfLine() && VD->hasInit(); + !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); } static inline @@ -5364,8 +5433,18 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, 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: case BuiltinType::OCLEvent: + case BuiltinType::OCLClkEvent: + case BuiltinType::OCLQueue: + case BuiltinType::OCLNDRange: + case BuiltinType::OCLReserveID: case BuiltinType::OCLSampler: case BuiltinType::Dependent: #define BUILTIN_TYPE(KIND, ID) @@ -5779,7 +5858,6 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, // Just ignore it. case Type::Auto: return; - #define ABSTRACT_TYPE(KIND, BASE) #define TYPE(KIND, BASE) @@ -5998,10 +6076,19 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const { // __builtin_va_list Construction Functions //===----------------------------------------------------------------------===// -static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) { - // typedef char* __builtin_va_list; +static TypedefDecl *CreateCharPtrNamedVaListDecl(const ASTContext *Context, + StringRef Name) { + // typedef char* __builtin[_ms]_va_list; QualType T = Context->getPointerType(Context->CharTy); - return Context->buildImplicitTypedef(T, "__builtin_va_list"); + return Context->buildImplicitTypedef(T, Name); +} + +static TypedefDecl *CreateMSVaListDecl(const ASTContext *Context) { + return CreateCharPtrNamedVaListDecl(Context, "__builtin_ms_va_list"); +} + +static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) { + return CreateCharPtrNamedVaListDecl(Context, "__builtin_va_list"); } static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) { @@ -6067,8 +6154,8 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { VaListTagDecl->addDecl(Field); } VaListTagDecl->completeDefinition(); + Context->VaListTagDecl = VaListTagDecl; QualType VaListTagType = Context->getRecordType(VaListTagDecl); - Context->VaListTagTy = VaListTagType; // } __builtin_va_list; return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list"); @@ -6119,8 +6206,8 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { VaListTagDecl->addDecl(Field); } VaListTagDecl->completeDefinition(); + Context->VaListTagDecl = VaListTagDecl; QualType VaListTagType = Context->getRecordType(VaListTagDecl); - Context->VaListTagTy = VaListTagType; // } __va_list_tag; TypedefDecl *VaListTagTypedefDecl = @@ -6139,7 +6226,7 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { static TypedefDecl * CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { - // typedef struct __va_list_tag { + // struct __va_list_tag { RecordDecl *VaListTagDecl; VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); VaListTagDecl->startDefinition(); @@ -6179,21 +6266,15 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { VaListTagDecl->addDecl(Field); } VaListTagDecl->completeDefinition(); + Context->VaListTagDecl = VaListTagDecl; QualType VaListTagType = Context->getRecordType(VaListTagDecl); - Context->VaListTagTy = VaListTagType; - - // } __va_list_tag; - TypedefDecl *VaListTagTypedefDecl = - Context->buildImplicitTypedef(VaListTagType, "__va_list_tag"); - QualType VaListTagTypedefType = - Context->getTypedefType(VaListTagTypedefDecl); + // }; - // typedef __va_list_tag __builtin_va_list[1]; + // typedef struct __va_list_tag __builtin_va_list[1]; llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); - QualType VaListTagArrayType - = Context->getConstantArrayType(VaListTagTypedefType, - Size, ArrayType::Normal,0); + QualType VaListTagArrayType = + Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0); return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } @@ -6248,7 +6329,7 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { static TypedefDecl * CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { - // typedef struct __va_list_tag { + // struct __va_list_tag { RecordDecl *VaListTagDecl; VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); VaListTagDecl->startDefinition(); @@ -6288,20 +6369,15 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { VaListTagDecl->addDecl(Field); } VaListTagDecl->completeDefinition(); + Context->VaListTagDecl = VaListTagDecl; QualType VaListTagType = Context->getRecordType(VaListTagDecl); - Context->VaListTagTy = VaListTagType; - // } __va_list_tag; - TypedefDecl *VaListTagTypedefDecl = - Context->buildImplicitTypedef(VaListTagType, "__va_list_tag"); - QualType VaListTagTypedefType = - Context->getTypedefType(VaListTagTypedefDecl); + // }; // typedef __va_list_tag __builtin_va_list[1]; llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); - QualType VaListTagArrayType - = Context->getConstantArrayType(VaListTagTypedefType, - Size, ArrayType::Normal,0); + QualType VaListTagArrayType = + Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0); return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } @@ -6339,13 +6415,20 @@ TypedefDecl *ASTContext::getBuiltinVaListDecl() const { return BuiltinVaListDecl; } -QualType ASTContext::getVaListTagType() const { - // Force the creation of VaListTagTy by building the __builtin_va_list +Decl *ASTContext::getVaListTagDecl() const { + // Force the creation of VaListTagDecl by building the __builtin_va_list // declaration. - if (VaListTagTy.isNull()) - (void) getBuiltinVaListDecl(); + if (!VaListTagDecl) + (void)getBuiltinVaListDecl(); + + return VaListTagDecl; +} + +TypedefDecl *ASTContext::getBuiltinMSVaListDecl() const { + if (!BuiltinMSVaListDecl) + BuiltinMSVaListDecl = CreateMSVaListDecl(this); - return VaListTagTy; + return BuiltinMSVaListDecl; } void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { @@ -7734,6 +7817,10 @@ bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs( return true; } +void ASTContext::ResetObjCLayout(const ObjCContainerDecl *CD) { + ObjCLayouts[CD] = nullptr; +} + /// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and /// 'RHS' attributes and returns the merged version; including for function /// return types. @@ -8128,7 +8215,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, QualType ASTContext::GetBuiltinType(unsigned Id, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs) const { - const char *TypeStr = BuiltinInfo.GetTypeString(Id); + const char *TypeStr = BuiltinInfo.getTypeString(Id); SmallVector<QualType, 8> ArgTypes; @@ -8212,7 +8299,8 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, if (!FD->isInlined()) return External; - if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat && + if ((!Context.getLangOpts().CPlusPlus && + !Context.getTargetInfo().getCXXABI().isMicrosoft() && !FD->hasAttr<DLLExportAttr>()) || FD->hasAttr<GNUInlineAttr>()) { // FIXME: This doesn't match gcc's behavior for dllexport inline functions. @@ -8235,13 +8323,13 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, return GVA_DiscardableODR; } -static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) { +static GVALinkage adjustGVALinkageForAttributes(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>()) { + } else if (D->hasAttr<DLLExportAttr>() || D->hasAttr<CUDAGlobalAttr>()) { if (L == GVA_DiscardableODR) return GVA_StrongODR; } @@ -8249,8 +8337,8 @@ static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) { } GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { - return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD), - FD); + return adjustGVALinkageForAttributes(basicGVALinkageForFunction(*this, FD), + FD); } static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, @@ -8285,9 +8373,14 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, switch (VD->getTemplateSpecializationKind()) { case TSK_Undeclared: - case TSK_ExplicitSpecialization: return GVA_StrongExternal; + case TSK_ExplicitSpecialization: + return Context.getTargetInfo().getCXXABI().isMicrosoft() && + VD->isStaticDataMember() + ? GVA_StrongODR + : GVA_StrongExternal; + case TSK_ExplicitInstantiationDefinition: return GVA_StrongODR; @@ -8302,8 +8395,8 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, } GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { - return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD), - VD); + return adjustGVALinkageForAttributes(basicGVALinkageForVariable(*this, VD), + VD); } bool ASTContext::DeclMustBeEmitted(const Decl *D) { @@ -8313,6 +8406,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // Global named register variables (GNU extension) are never emitted. if (VD->getStorageClass() == SC_Register) return false; + if (VD->getDescribedVarTemplate() || + isa<VarTemplatePartialSpecializationDecl>(VD)) + return false; } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { // We never need to emit an uninstantiated function template. if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) @@ -8385,7 +8481,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return true; // Variables that have initialization with side-effects are required. - if (VD->getInit() && VD->getInit()->HasSideEffects(*this)) + if (VD->getInit() && VD->getInit()->HasSideEffects(*this) && + !VD->evaluateValue()) return true; return false; @@ -8425,6 +8522,8 @@ MangleContext *ASTContext::createMangleContext() { case TargetCXXABI::GenericMIPS: case TargetCXXABI::iOS: case TargetCXXABI::iOS64: + case TargetCXXABI::WebAssembly: + case TargetCXXABI::WatchOS: return ItaniumMangleContext::create(*this, getDiagnostics()); case TargetCXXABI::Microsoft: return MicrosoftMangleContext::create(*this, getDiagnostics()); @@ -8543,6 +8642,25 @@ Expr *ASTContext::getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, cast<CXXConstructorDecl>(CD->getFirstDecl()), ParmIdx); } +void ASTContext::addTypedefNameForUnnamedTagDecl(TagDecl *TD, + TypedefNameDecl *DD) { + return ABI->addTypedefNameForUnnamedTagDecl(TD, DD); +} + +TypedefNameDecl * +ASTContext::getTypedefNameForUnnamedTagDecl(const TagDecl *TD) { + return ABI->getTypedefNameForUnnamedTagDecl(TD); +} + +void ASTContext::addDeclaratorForUnnamedTagDecl(TagDecl *TD, + DeclaratorDecl *DD) { + return ABI->addDeclaratorForUnnamedTagDecl(TD, DD); +} + +DeclaratorDecl *ASTContext::getDeclaratorForUnnamedTagDecl(const TagDecl *TD) { + return ABI->getDeclaratorForUnnamedTagDecl(TD); +} + void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) { ParamIndices[D] = index; } @@ -8559,12 +8677,14 @@ 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]; + if (MayCreate) { + APValue *&MTVI = MaterializedTemporaryValues[E]; + if (!MTVI) + MTVI = new (*this) APValue; + return MTVI; + } - llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I = - MaterializedTemporaryValues.find(E); - return I == MaterializedTemporaryValues.end() ? nullptr : &I->second; + return MaterializedTemporaryValues.lookup(E); } bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { @@ -8587,6 +8707,32 @@ bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { namespace { +ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap( + ASTContext::ParentMapPointers::mapped_type U) { + if (const auto *D = U.dyn_cast<const Decl *>()) + return ast_type_traits::DynTypedNode::create(*D); + if (const auto *S = U.dyn_cast<const Stmt *>()) + return ast_type_traits::DynTypedNode::create(*S); + return *U.get<ast_type_traits::DynTypedNode *>(); +} + +/// Template specializations to abstract away from pointers and TypeLocs. +/// @{ +template <typename T> +ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) { + return ast_type_traits::DynTypedNode::create(*Node); +} +template <> +ast_type_traits::DynTypedNode createDynTypedNode(const TypeLoc &Node) { + return ast_type_traits::DynTypedNode::create(Node); +} +template <> +ast_type_traits::DynTypedNode +createDynTypedNode(const NestedNameSpecifierLoc &Node) { + return ast_type_traits::DynTypedNode::create(Node); +} +/// @} + /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their /// parents as defined by the \c RecursiveASTVisitor. /// @@ -8596,22 +8742,25 @@ namespace { /// /// 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); + static std::pair<ASTContext::ParentMapPointers *, + ASTContext::ParentMapOtherNodes *> + buildMap(TranslationUnitDecl &TU) { + ParentMapASTVisitor Visitor(new ASTContext::ParentMapPointers, + new ASTContext::ParentMapOtherNodes); Visitor.TraverseDecl(&TU); - return Visitor.Parents; + return std::make_pair(Visitor.Parents, Visitor.OtherParents); } private: typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase; - ParentMapASTVisitor(ASTContext::ParentMap *Parents) : Parents(Parents) { - } + ParentMapASTVisitor(ASTContext::ParentMapPointers *Parents, + ASTContext::ParentMapOtherNodes *OtherParents) + : Parents(Parents), OtherParents(OtherParents) {} bool shouldVisitTemplateInstantiations() const { return true; @@ -8619,14 +8768,11 @@ namespace { 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 *)) { + template <typename T, typename MapNodeTy, typename BaseTraverseFn, + typename MapTy> + bool TraverseNode(T Node, MapNodeTy MapNode, + BaseTraverseFn BaseTraverse, MapTy *Parents) { if (!Node) return true; if (ParentStack.size() > 0) { @@ -8640,18 +8786,25 @@ namespace { // map. The main problem there is to implement hash functions / // comparison operators for all types that DynTypedNode supports that // do not have pointer identity. - auto &NodeOrVector = (*Parents)[Node]; + auto &NodeOrVector = (*Parents)[MapNode]; if (NodeOrVector.isNull()) { - NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back()); + if (const auto *D = ParentStack.back().get<Decl>()) + NodeOrVector = D; + else if (const auto *S = ParentStack.back().get<Stmt>()) + NodeOrVector = S; + else + NodeOrVector = + new ast_type_traits::DynTypedNode(ParentStack.back()); } else { - if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) { - auto *Node = - NodeOrVector.template get<ast_type_traits::DynTypedNode *>(); - auto *Vector = new ASTContext::ParentVector(1, *Node); + if (!NodeOrVector.template is<ASTContext::ParentVector *>()) { + auto *Vector = new ASTContext::ParentVector( + 1, getSingleDynTypedNodeFromParentMap(NodeOrVector)); + if (auto *Node = + NodeOrVector + .template dyn_cast<ast_type_traits::DynTypedNode *>()) + delete Node; NodeOrVector = Vector; - delete Node; } - assert(NodeOrVector.template is<ASTContext::ParentVector *>()); auto *Vector = NodeOrVector.template get<ASTContext::ParentVector *>(); @@ -8666,47 +8819,74 @@ namespace { Vector->push_back(ParentStack.back()); } } - ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); - bool Result = (this ->* traverse) (Node); + ParentStack.push_back(createDynTypedNode(Node)); + bool Result = BaseTraverse(); ParentStack.pop_back(); return Result; } bool TraverseDecl(Decl *DeclNode) { - return TraverseNode(DeclNode, &VisitorBase::TraverseDecl); + return TraverseNode(DeclNode, DeclNode, + [&] { return VisitorBase::TraverseDecl(DeclNode); }, + Parents); } bool TraverseStmt(Stmt *StmtNode) { - return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); + return TraverseNode(StmtNode, StmtNode, + [&] { return VisitorBase::TraverseStmt(StmtNode); }, + Parents); + } + + bool TraverseTypeLoc(TypeLoc TypeLocNode) { + return TraverseNode( + TypeLocNode, ast_type_traits::DynTypedNode::create(TypeLocNode), + [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); }, + OtherParents); + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) { + return TraverseNode( + NNSLocNode, ast_type_traits::DynTypedNode::create(NNSLocNode), + [&] { + return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); + }, + OtherParents); } - ASTContext::ParentMap *Parents; + ASTContext::ParentMapPointers *Parents; + ASTContext::ParentMapOtherNodes *OtherParents; llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; friend class RecursiveASTVisitor<ParentMapASTVisitor>; }; -} // end namespace +} // anonymous namespace -ArrayRef<ast_type_traits::DynTypedNode> +template <typename NodeTy, typename MapTy> +static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node, + const MapTy &Map) { + auto I = Map.find(Node); + if (I == Map.end()) { + return llvm::ArrayRef<ast_type_traits::DynTypedNode>(); + } + if (auto *V = I->second.template dyn_cast<ASTContext::ParentVector *>()) { + return llvm::makeArrayRef(*V); + } + return getSingleDynTypedNodeFromParentMap(I->second); +} + +ASTContext::DynTypedNodeList 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) { + if (!PointerParents) { // 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 None; - } - if (auto *N = I->second.dyn_cast<ast_type_traits::DynTypedNode *>()) { - return llvm::makeArrayRef(N, 1); + auto Maps = ParentMapASTVisitor::buildMap(*getTranslationUnitDecl()); + PointerParents.reset(Maps.first); + OtherParents.reset(Maps.second); } - return *I->second.get<ParentVector *>(); + if (Node.getNodeKind().hasPointerIdentity()) + return getDynNodeFromMap(Node.getMemoizationData(), *PointerParents); + return getDynNodeFromMap(Node, *OtherParents); } bool |