Path: blob/main/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
35260 views
//===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the ASTContext interface.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/ASTContext.h"13#include "CXXABI.h"14#include "Interp/Context.h"15#include "clang/AST/APValue.h"16#include "clang/AST/ASTConcept.h"17#include "clang/AST/ASTMutationListener.h"18#include "clang/AST/ASTTypeTraits.h"19#include "clang/AST/Attr.h"20#include "clang/AST/AttrIterator.h"21#include "clang/AST/CharUnits.h"22#include "clang/AST/Comment.h"23#include "clang/AST/Decl.h"24#include "clang/AST/DeclBase.h"25#include "clang/AST/DeclCXX.h"26#include "clang/AST/DeclContextInternals.h"27#include "clang/AST/DeclObjC.h"28#include "clang/AST/DeclOpenMP.h"29#include "clang/AST/DeclTemplate.h"30#include "clang/AST/DeclarationName.h"31#include "clang/AST/DependenceFlags.h"32#include "clang/AST/Expr.h"33#include "clang/AST/ExprCXX.h"34#include "clang/AST/ExprConcepts.h"35#include "clang/AST/ExternalASTSource.h"36#include "clang/AST/Mangle.h"37#include "clang/AST/MangleNumberingContext.h"38#include "clang/AST/NestedNameSpecifier.h"39#include "clang/AST/ParentMapContext.h"40#include "clang/AST/RawCommentList.h"41#include "clang/AST/RecordLayout.h"42#include "clang/AST/Stmt.h"43#include "clang/AST/StmtOpenACC.h"44#include "clang/AST/TemplateBase.h"45#include "clang/AST/TemplateName.h"46#include "clang/AST/Type.h"47#include "clang/AST/TypeLoc.h"48#include "clang/AST/UnresolvedSet.h"49#include "clang/AST/VTableBuilder.h"50#include "clang/Basic/AddressSpaces.h"51#include "clang/Basic/Builtins.h"52#include "clang/Basic/CommentOptions.h"53#include "clang/Basic/ExceptionSpecificationType.h"54#include "clang/Basic/IdentifierTable.h"55#include "clang/Basic/LLVM.h"56#include "clang/Basic/LangOptions.h"57#include "clang/Basic/Linkage.h"58#include "clang/Basic/Module.h"59#include "clang/Basic/NoSanitizeList.h"60#include "clang/Basic/ObjCRuntime.h"61#include "clang/Basic/ProfileList.h"62#include "clang/Basic/SourceLocation.h"63#include "clang/Basic/SourceManager.h"64#include "clang/Basic/Specifiers.h"65#include "clang/Basic/TargetCXXABI.h"66#include "clang/Basic/TargetInfo.h"67#include "clang/Basic/XRayLists.h"68#include "llvm/ADT/APFixedPoint.h"69#include "llvm/ADT/APInt.h"70#include "llvm/ADT/APSInt.h"71#include "llvm/ADT/ArrayRef.h"72#include "llvm/ADT/DenseMap.h"73#include "llvm/ADT/DenseSet.h"74#include "llvm/ADT/FoldingSet.h"75#include "llvm/ADT/PointerUnion.h"76#include "llvm/ADT/STLExtras.h"77#include "llvm/ADT/SmallPtrSet.h"78#include "llvm/ADT/SmallVector.h"79#include "llvm/ADT/StringExtras.h"80#include "llvm/ADT/StringRef.h"81#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"82#include "llvm/Support/Capacity.h"83#include "llvm/Support/Casting.h"84#include "llvm/Support/Compiler.h"85#include "llvm/Support/ErrorHandling.h"86#include "llvm/Support/MD5.h"87#include "llvm/Support/MathExtras.h"88#include "llvm/Support/SipHash.h"89#include "llvm/Support/raw_ostream.h"90#include "llvm/TargetParser/AArch64TargetParser.h"91#include "llvm/TargetParser/Triple.h"92#include <algorithm>93#include <cassert>94#include <cstddef>95#include <cstdint>96#include <cstdlib>97#include <map>98#include <memory>99#include <optional>100#include <string>101#include <tuple>102#include <utility>103104using namespace clang;105106enum FloatingRank {107BFloat16Rank,108Float16Rank,109HalfRank,110FloatRank,111DoubleRank,112LongDoubleRank,113Float128Rank,114Ibm128Rank115};116117/// \returns The locations that are relevant when searching for Doc comments118/// related to \p D.119static SmallVector<SourceLocation, 2>120getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) {121assert(D);122123// User can not attach documentation to implicit declarations.124if (D->isImplicit())125return {};126127// User can not attach documentation to implicit instantiations.128if (const auto *FD = dyn_cast<FunctionDecl>(D)) {129if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)130return {};131}132133if (const auto *VD = dyn_cast<VarDecl>(D)) {134if (VD->isStaticDataMember() &&135VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)136return {};137}138139if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) {140if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)141return {};142}143144if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {145TemplateSpecializationKind TSK = CTSD->getSpecializationKind();146if (TSK == TSK_ImplicitInstantiation ||147TSK == TSK_Undeclared)148return {};149}150151if (const auto *ED = dyn_cast<EnumDecl>(D)) {152if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)153return {};154}155if (const auto *TD = dyn_cast<TagDecl>(D)) {156// When tag declaration (but not definition!) is part of the157// decl-specifier-seq of some other declaration, it doesn't get comment158if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())159return {};160}161// TODO: handle comments for function parameters properly.162if (isa<ParmVarDecl>(D))163return {};164165// TODO: we could look up template parameter documentation in the template166// documentation.167if (isa<TemplateTypeParmDecl>(D) ||168isa<NonTypeTemplateParmDecl>(D) ||169isa<TemplateTemplateParmDecl>(D))170return {};171172SmallVector<SourceLocation, 2> Locations;173// Find declaration location.174// For Objective-C declarations we generally don't expect to have multiple175// declarators, thus use declaration starting location as the "declaration176// location".177// For all other declarations multiple declarators are used quite frequently,178// so we use the location of the identifier as the "declaration location".179SourceLocation BaseLocation;180if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) ||181isa<ObjCPropertyDecl>(D) || isa<RedeclarableTemplateDecl>(D) ||182isa<ClassTemplateSpecializationDecl>(D) ||183// Allow association with Y across {} in `typedef struct X {} Y`.184isa<TypedefDecl>(D))185BaseLocation = D->getBeginLoc();186else187BaseLocation = D->getLocation();188189if (!D->getLocation().isMacroID()) {190Locations.emplace_back(BaseLocation);191} else {192const auto *DeclCtx = D->getDeclContext();193194// When encountering definitions generated from a macro (that are not195// contained by another declaration in the macro) we need to try and find196// the comment at the location of the expansion but if there is no comment197// there we should retry to see if there is a comment inside the macro as198// well. To this end we return first BaseLocation to first look at the199// expansion site, the second value is the spelling location of the200// beginning of the declaration defined inside the macro.201if (!(DeclCtx &&202Decl::castFromDeclContext(DeclCtx)->getLocation().isMacroID())) {203Locations.emplace_back(SourceMgr.getExpansionLoc(BaseLocation));204}205206// We use Decl::getBeginLoc() and not just BaseLocation here to ensure that207// we don't refer to the macro argument location at the expansion site (this208// can happen if the name's spelling is provided via macro argument), and209// always to the declaration itself.210Locations.emplace_back(SourceMgr.getSpellingLoc(D->getBeginLoc()));211}212213return Locations;214}215216RawComment *ASTContext::getRawCommentForDeclNoCacheImpl(217const Decl *D, const SourceLocation RepresentativeLocForDecl,218const std::map<unsigned, RawComment *> &CommentsInTheFile) const {219// If the declaration doesn't map directly to a location in a file, we220// can't find the comment.221if (RepresentativeLocForDecl.isInvalid() ||222!RepresentativeLocForDecl.isFileID())223return nullptr;224225// If there are no comments anywhere, we won't find anything.226if (CommentsInTheFile.empty())227return nullptr;228229// Decompose the location for the declaration and find the beginning of the230// file buffer.231const std::pair<FileID, unsigned> DeclLocDecomp =232SourceMgr.getDecomposedLoc(RepresentativeLocForDecl);233234// Slow path.235auto OffsetCommentBehindDecl =236CommentsInTheFile.lower_bound(DeclLocDecomp.second);237238// First check whether we have a trailing comment.239if (OffsetCommentBehindDecl != CommentsInTheFile.end()) {240RawComment *CommentBehindDecl = OffsetCommentBehindDecl->second;241if ((CommentBehindDecl->isDocumentation() ||242LangOpts.CommentOpts.ParseAllComments) &&243CommentBehindDecl->isTrailingComment() &&244(isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) ||245isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) {246247// Check that Doxygen trailing comment comes after the declaration, starts248// on the same line and in the same file as the declaration.249if (SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second) ==250Comments.getCommentBeginLine(CommentBehindDecl, DeclLocDecomp.first,251OffsetCommentBehindDecl->first)) {252return CommentBehindDecl;253}254}255}256257// The comment just after the declaration was not a trailing comment.258// Let's look at the previous comment.259if (OffsetCommentBehindDecl == CommentsInTheFile.begin())260return nullptr;261262auto OffsetCommentBeforeDecl = --OffsetCommentBehindDecl;263RawComment *CommentBeforeDecl = OffsetCommentBeforeDecl->second;264265// Check that we actually have a non-member Doxygen comment.266if (!(CommentBeforeDecl->isDocumentation() ||267LangOpts.CommentOpts.ParseAllComments) ||268CommentBeforeDecl->isTrailingComment())269return nullptr;270271// Decompose the end of the comment.272const unsigned CommentEndOffset =273Comments.getCommentEndOffset(CommentBeforeDecl);274275// Get the corresponding buffer.276bool Invalid = false;277const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first,278&Invalid).data();279if (Invalid)280return nullptr;281282// Extract text between the comment and declaration.283StringRef Text(Buffer + CommentEndOffset,284DeclLocDecomp.second - CommentEndOffset);285286// There should be no other declarations or preprocessor directives between287// comment and declaration.288if (Text.find_last_of(";{}#@") != StringRef::npos)289return nullptr;290291return CommentBeforeDecl;292}293294RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {295const auto DeclLocs = getDeclLocsForCommentSearch(D, SourceMgr);296297for (const auto DeclLoc : DeclLocs) {298// If the declaration doesn't map directly to a location in a file, we299// can't find the comment.300if (DeclLoc.isInvalid() || !DeclLoc.isFileID())301continue;302303if (ExternalSource && !CommentsLoaded) {304ExternalSource->ReadComments();305CommentsLoaded = true;306}307308if (Comments.empty())309continue;310311const FileID File = SourceMgr.getDecomposedLoc(DeclLoc).first;312if (!File.isValid())313continue;314315const auto CommentsInThisFile = Comments.getCommentsInFile(File);316if (!CommentsInThisFile || CommentsInThisFile->empty())317continue;318319if (RawComment *Comment =320getRawCommentForDeclNoCacheImpl(D, DeclLoc, *CommentsInThisFile))321return Comment;322}323324return nullptr;325}326327void ASTContext::addComment(const RawComment &RC) {328assert(LangOpts.RetainCommentsFromSystemHeaders ||329!SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));330Comments.addComment(RC, LangOpts.CommentOpts, BumpAlloc);331}332333/// If we have a 'templated' declaration for a template, adjust 'D' to334/// refer to the actual template.335/// If we have an implicit instantiation, adjust 'D' to refer to template.336static const Decl &adjustDeclToTemplate(const Decl &D) {337if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {338// Is this function declaration part of a function template?339if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())340return *FTD;341342// Nothing to do if function is not an implicit instantiation.343if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)344return D;345346// Function is an implicit instantiation of a function template?347if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())348return *FTD;349350// Function is instantiated from a member definition of a class template?351if (const FunctionDecl *MemberDecl =352FD->getInstantiatedFromMemberFunction())353return *MemberDecl;354355return D;356}357if (const auto *VD = dyn_cast<VarDecl>(&D)) {358// Static data member is instantiated from a member definition of a class359// template?360if (VD->isStaticDataMember())361if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())362return *MemberDecl;363364return D;365}366if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {367// Is this class declaration part of a class template?368if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())369return *CTD;370371// Class is an implicit instantiation of a class template or partial372// specialization?373if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {374if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)375return D;376llvm::PointerUnion<ClassTemplateDecl *,377ClassTemplatePartialSpecializationDecl *>378PU = CTSD->getSpecializedTemplateOrPartial();379return PU.is<ClassTemplateDecl *>()380? *static_cast<const Decl *>(PU.get<ClassTemplateDecl *>())381: *static_cast<const Decl *>(382PU.get<ClassTemplatePartialSpecializationDecl *>());383}384385// Class is instantiated from a member definition of a class template?386if (const MemberSpecializationInfo *Info =387CRD->getMemberSpecializationInfo())388return *Info->getInstantiatedFrom();389390return D;391}392if (const auto *ED = dyn_cast<EnumDecl>(&D)) {393// Enum is instantiated from a member definition of a class template?394if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())395return *MemberDecl;396397return D;398}399// FIXME: Adjust alias templates?400return D;401}402403const RawComment *ASTContext::getRawCommentForAnyRedecl(404const Decl *D,405const Decl **OriginalDecl) const {406if (!D) {407if (OriginalDecl)408OriginalDecl = nullptr;409return nullptr;410}411412D = &adjustDeclToTemplate(*D);413414// Any comment directly attached to D?415{416auto DeclComment = DeclRawComments.find(D);417if (DeclComment != DeclRawComments.end()) {418if (OriginalDecl)419*OriginalDecl = D;420return DeclComment->second;421}422}423424// Any comment attached to any redeclaration of D?425const Decl *CanonicalD = D->getCanonicalDecl();426if (!CanonicalD)427return nullptr;428429{430auto RedeclComment = RedeclChainComments.find(CanonicalD);431if (RedeclComment != RedeclChainComments.end()) {432if (OriginalDecl)433*OriginalDecl = RedeclComment->second;434auto CommentAtRedecl = DeclRawComments.find(RedeclComment->second);435assert(CommentAtRedecl != DeclRawComments.end() &&436"This decl is supposed to have comment attached.");437return CommentAtRedecl->second;438}439}440441// Any redeclarations of D that we haven't checked for comments yet?442// We can't use DenseMap::iterator directly since it'd get invalid.443auto LastCheckedRedecl = [this, CanonicalD]() -> const Decl * {444return CommentlessRedeclChains.lookup(CanonicalD);445}();446447for (const auto Redecl : D->redecls()) {448assert(Redecl);449// Skip all redeclarations that have been checked previously.450if (LastCheckedRedecl) {451if (LastCheckedRedecl == Redecl) {452LastCheckedRedecl = nullptr;453}454continue;455}456const RawComment *RedeclComment = getRawCommentForDeclNoCache(Redecl);457if (RedeclComment) {458cacheRawCommentForDecl(*Redecl, *RedeclComment);459if (OriginalDecl)460*OriginalDecl = Redecl;461return RedeclComment;462}463CommentlessRedeclChains[CanonicalD] = Redecl;464}465466if (OriginalDecl)467*OriginalDecl = nullptr;468return nullptr;469}470471void ASTContext::cacheRawCommentForDecl(const Decl &OriginalD,472const RawComment &Comment) const {473assert(Comment.isDocumentation() || LangOpts.CommentOpts.ParseAllComments);474DeclRawComments.try_emplace(&OriginalD, &Comment);475const Decl *const CanonicalDecl = OriginalD.getCanonicalDecl();476RedeclChainComments.try_emplace(CanonicalDecl, &OriginalD);477CommentlessRedeclChains.erase(CanonicalDecl);478}479480static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,481SmallVectorImpl<const NamedDecl *> &Redeclared) {482const DeclContext *DC = ObjCMethod->getDeclContext();483if (const auto *IMD = dyn_cast<ObjCImplDecl>(DC)) {484const ObjCInterfaceDecl *ID = IMD->getClassInterface();485if (!ID)486return;487// Add redeclared method here.488for (const auto *Ext : ID->known_extensions()) {489if (ObjCMethodDecl *RedeclaredMethod =490Ext->getMethod(ObjCMethod->getSelector(),491ObjCMethod->isInstanceMethod()))492Redeclared.push_back(RedeclaredMethod);493}494}495}496497void ASTContext::attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls,498const Preprocessor *PP) {499if (Comments.empty() || Decls.empty())500return;501502FileID File;503for (const Decl *D : Decls) {504if (D->isInvalidDecl())505continue;506507D = &adjustDeclToTemplate(*D);508SourceLocation Loc = D->getLocation();509if (Loc.isValid()) {510// See if there are any new comments that are not attached to a decl.511// The location doesn't have to be precise - we care only about the file.512File = SourceMgr.getDecomposedLoc(Loc).first;513break;514}515}516517if (File.isInvalid())518return;519520auto CommentsInThisFile = Comments.getCommentsInFile(File);521if (!CommentsInThisFile || CommentsInThisFile->empty() ||522CommentsInThisFile->rbegin()->second->isAttached())523return;524525// There is at least one comment not attached to a decl.526// Maybe it should be attached to one of Decls?527//528// Note that this way we pick up not only comments that precede the529// declaration, but also comments that *follow* the declaration -- thanks to530// the lookahead in the lexer: we've consumed the semicolon and looked531// ahead through comments.532for (const Decl *D : Decls) {533assert(D);534if (D->isInvalidDecl())535continue;536537D = &adjustDeclToTemplate(*D);538539if (DeclRawComments.count(D) > 0)540continue;541542const auto DeclLocs = getDeclLocsForCommentSearch(D, SourceMgr);543544for (const auto DeclLoc : DeclLocs) {545if (DeclLoc.isInvalid() || !DeclLoc.isFileID())546continue;547548if (RawComment *const DocComment = getRawCommentForDeclNoCacheImpl(549D, DeclLoc, *CommentsInThisFile)) {550cacheRawCommentForDecl(*D, *DocComment);551comments::FullComment *FC = DocComment->parse(*this, PP, D);552ParsedComments[D->getCanonicalDecl()] = FC;553break;554}555}556}557}558559comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,560const Decl *D) const {561auto *ThisDeclInfo = new (*this) comments::DeclInfo;562ThisDeclInfo->CommentDecl = D;563ThisDeclInfo->IsFilled = false;564ThisDeclInfo->fill();565ThisDeclInfo->CommentDecl = FC->getDecl();566if (!ThisDeclInfo->TemplateParameters)567ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters;568comments::FullComment *CFC =569new (*this) comments::FullComment(FC->getBlocks(),570ThisDeclInfo);571return CFC;572}573574comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const {575const RawComment *RC = getRawCommentForDeclNoCache(D);576return RC ? RC->parse(*this, nullptr, D) : nullptr;577}578579comments::FullComment *ASTContext::getCommentForDecl(580const Decl *D,581const Preprocessor *PP) const {582if (!D || D->isInvalidDecl())583return nullptr;584D = &adjustDeclToTemplate(*D);585586const Decl *Canonical = D->getCanonicalDecl();587llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =588ParsedComments.find(Canonical);589590if (Pos != ParsedComments.end()) {591if (Canonical != D) {592comments::FullComment *FC = Pos->second;593comments::FullComment *CFC = cloneFullComment(FC, D);594return CFC;595}596return Pos->second;597}598599const Decl *OriginalDecl = nullptr;600601const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl);602if (!RC) {603if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {604SmallVector<const NamedDecl*, 8> Overridden;605const auto *OMD = dyn_cast<ObjCMethodDecl>(D);606if (OMD && OMD->isPropertyAccessor())607if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())608if (comments::FullComment *FC = getCommentForDecl(PDecl, PP))609return cloneFullComment(FC, D);610if (OMD)611addRedeclaredMethods(OMD, Overridden);612getOverriddenMethods(dyn_cast<NamedDecl>(D), Overridden);613for (unsigned i = 0, e = Overridden.size(); i < e; i++)614if (comments::FullComment *FC = getCommentForDecl(Overridden[i], PP))615return cloneFullComment(FC, D);616}617else if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {618// Attach any tag type's documentation to its typedef if latter619// does not have one of its own.620QualType QT = TD->getUnderlyingType();621if (const auto *TT = QT->getAs<TagType>())622if (const Decl *TD = TT->getDecl())623if (comments::FullComment *FC = getCommentForDecl(TD, PP))624return cloneFullComment(FC, D);625}626else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {627while (IC->getSuperClass()) {628IC = IC->getSuperClass();629if (comments::FullComment *FC = getCommentForDecl(IC, PP))630return cloneFullComment(FC, D);631}632}633else if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {634if (const ObjCInterfaceDecl *IC = CD->getClassInterface())635if (comments::FullComment *FC = getCommentForDecl(IC, PP))636return cloneFullComment(FC, D);637}638else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {639if (!(RD = RD->getDefinition()))640return nullptr;641// Check non-virtual bases.642for (const auto &I : RD->bases()) {643if (I.isVirtual() || (I.getAccessSpecifier() != AS_public))644continue;645QualType Ty = I.getType();646if (Ty.isNull())647continue;648if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) {649if (!(NonVirtualBase= NonVirtualBase->getDefinition()))650continue;651652if (comments::FullComment *FC = getCommentForDecl((NonVirtualBase), PP))653return cloneFullComment(FC, D);654}655}656// Check virtual bases.657for (const auto &I : RD->vbases()) {658if (I.getAccessSpecifier() != AS_public)659continue;660QualType Ty = I.getType();661if (Ty.isNull())662continue;663if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) {664if (!(VirtualBase= VirtualBase->getDefinition()))665continue;666if (comments::FullComment *FC = getCommentForDecl((VirtualBase), PP))667return cloneFullComment(FC, D);668}669}670}671return nullptr;672}673674// If the RawComment was attached to other redeclaration of this Decl, we675// should parse the comment in context of that other Decl. This is important676// because comments can contain references to parameter names which can be677// different across redeclarations.678if (D != OriginalDecl && OriginalDecl)679return getCommentForDecl(OriginalDecl, PP);680681comments::FullComment *FC = RC->parse(*this, PP, D);682ParsedComments[Canonical] = FC;683return FC;684}685686void687ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,688const ASTContext &C,689TemplateTemplateParmDecl *Parm) {690ID.AddInteger(Parm->getDepth());691ID.AddInteger(Parm->getPosition());692ID.AddBoolean(Parm->isParameterPack());693694TemplateParameterList *Params = Parm->getTemplateParameters();695ID.AddInteger(Params->size());696for (TemplateParameterList::const_iterator P = Params->begin(),697PEnd = Params->end();698P != PEnd; ++P) {699if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {700ID.AddInteger(0);701ID.AddBoolean(TTP->isParameterPack());702if (TTP->isExpandedParameterPack()) {703ID.AddBoolean(true);704ID.AddInteger(TTP->getNumExpansionParameters());705} else706ID.AddBoolean(false);707continue;708}709710if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {711ID.AddInteger(1);712ID.AddBoolean(NTTP->isParameterPack());713ID.AddPointer(C.getUnconstrainedType(C.getCanonicalType(NTTP->getType()))714.getAsOpaquePtr());715if (NTTP->isExpandedParameterPack()) {716ID.AddBoolean(true);717ID.AddInteger(NTTP->getNumExpansionTypes());718for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) {719QualType T = NTTP->getExpansionType(I);720ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());721}722} else723ID.AddBoolean(false);724continue;725}726727auto *TTP = cast<TemplateTemplateParmDecl>(*P);728ID.AddInteger(2);729Profile(ID, C, TTP);730}731}732733TemplateTemplateParmDecl *734ASTContext::getCanonicalTemplateTemplateParmDecl(735TemplateTemplateParmDecl *TTP) const {736// Check if we already have a canonical template template parameter.737llvm::FoldingSetNodeID ID;738CanonicalTemplateTemplateParm::Profile(ID, *this, TTP);739void *InsertPos = nullptr;740CanonicalTemplateTemplateParm *Canonical741= CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);742if (Canonical)743return Canonical->getParam();744745// Build a canonical template parameter list.746TemplateParameterList *Params = TTP->getTemplateParameters();747SmallVector<NamedDecl *, 4> CanonParams;748CanonParams.reserve(Params->size());749for (TemplateParameterList::const_iterator P = Params->begin(),750PEnd = Params->end();751P != PEnd; ++P) {752// Note that, per C++20 [temp.over.link]/6, when determining whether753// template-parameters are equivalent, constraints are ignored.754if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {755TemplateTypeParmDecl *NewTTP = TemplateTypeParmDecl::Create(756*this, getTranslationUnitDecl(), SourceLocation(), SourceLocation(),757TTP->getDepth(), TTP->getIndex(), nullptr, false,758TTP->isParameterPack(), /*HasTypeConstraint=*/false,759TTP->isExpandedParameterPack()760? std::optional<unsigned>(TTP->getNumExpansionParameters())761: std::nullopt);762CanonParams.push_back(NewTTP);763} else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {764QualType T = getUnconstrainedType(getCanonicalType(NTTP->getType()));765TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);766NonTypeTemplateParmDecl *Param;767if (NTTP->isExpandedParameterPack()) {768SmallVector<QualType, 2> ExpandedTypes;769SmallVector<TypeSourceInfo *, 2> ExpandedTInfos;770for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) {771ExpandedTypes.push_back(getCanonicalType(NTTP->getExpansionType(I)));772ExpandedTInfos.push_back(773getTrivialTypeSourceInfo(ExpandedTypes.back()));774}775776Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(),777SourceLocation(),778SourceLocation(),779NTTP->getDepth(),780NTTP->getPosition(), nullptr,781T,782TInfo,783ExpandedTypes,784ExpandedTInfos);785} else {786Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(),787SourceLocation(),788SourceLocation(),789NTTP->getDepth(),790NTTP->getPosition(), nullptr,791T,792NTTP->isParameterPack(),793TInfo);794}795CanonParams.push_back(Param);796} else797CanonParams.push_back(getCanonicalTemplateTemplateParmDecl(798cast<TemplateTemplateParmDecl>(*P)));799}800801TemplateTemplateParmDecl *CanonTTP = TemplateTemplateParmDecl::Create(802*this, getTranslationUnitDecl(), SourceLocation(), TTP->getDepth(),803TTP->getPosition(), TTP->isParameterPack(), nullptr, /*Typename=*/false,804TemplateParameterList::Create(*this, SourceLocation(), SourceLocation(),805CanonParams, SourceLocation(),806/*RequiresClause=*/nullptr));807808// Get the new insert position for the node we care about.809Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);810assert(!Canonical && "Shouldn't be in the map!");811(void)Canonical;812813// Create the canonical template template parameter entry.814Canonical = new (*this) CanonicalTemplateTemplateParm(CanonTTP);815CanonTemplateTemplateParms.InsertNode(Canonical, InsertPos);816return CanonTTP;817}818819TargetCXXABI::Kind ASTContext::getCXXABIKind() const {820auto Kind = getTargetInfo().getCXXABI().getKind();821return getLangOpts().CXXABI.value_or(Kind);822}823824CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {825if (!LangOpts.CPlusPlus) return nullptr;826827switch (getCXXABIKind()) {828case TargetCXXABI::AppleARM64:829case TargetCXXABI::Fuchsia:830case TargetCXXABI::GenericARM: // Same as Itanium at this level831case TargetCXXABI::iOS:832case TargetCXXABI::WatchOS:833case TargetCXXABI::GenericAArch64:834case TargetCXXABI::GenericMIPS:835case TargetCXXABI::GenericItanium:836case TargetCXXABI::WebAssembly:837case TargetCXXABI::XL:838return CreateItaniumCXXABI(*this);839case TargetCXXABI::Microsoft:840return CreateMicrosoftCXXABI(*this);841}842llvm_unreachable("Invalid CXXABI type!");843}844845interp::Context &ASTContext::getInterpContext() {846if (!InterpContext) {847InterpContext.reset(new interp::Context(*this));848}849return *InterpContext.get();850}851852ParentMapContext &ASTContext::getParentMapContext() {853if (!ParentMapCtx)854ParentMapCtx.reset(new ParentMapContext(*this));855return *ParentMapCtx.get();856}857858static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI,859const LangOptions &LangOpts) {860switch (LangOpts.getAddressSpaceMapMangling()) {861case LangOptions::ASMM_Target:862return TI.useAddressSpaceMapMangling();863case LangOptions::ASMM_On:864return true;865case LangOptions::ASMM_Off:866return false;867}868llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything.");869}870871ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,872IdentifierTable &idents, SelectorTable &sels,873Builtin::Context &builtins, TranslationUnitKind TUKind)874: ConstantArrayTypes(this_(), ConstantArrayTypesLog2InitSize),875DependentSizedArrayTypes(this_()), DependentSizedExtVectorTypes(this_()),876DependentAddressSpaceTypes(this_()), DependentVectorTypes(this_()),877DependentSizedMatrixTypes(this_()),878FunctionProtoTypes(this_(), FunctionProtoTypesLog2InitSize),879DependentTypeOfExprTypes(this_()), DependentDecltypeTypes(this_()),880TemplateSpecializationTypes(this_()),881DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()),882DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()),883ArrayParameterTypes(this_()), CanonTemplateTemplateParms(this_()),884SourceMgr(SM), LangOpts(LOpts),885NoSanitizeL(new NoSanitizeList(LangOpts.NoSanitizeFiles, SM)),886XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,887LangOpts.XRayNeverInstrumentFiles,888LangOpts.XRayAttrListFiles, SM)),889ProfList(new ProfileList(LangOpts.ProfileListFiles, SM)),890PrintingPolicy(LOpts), Idents(idents), Selectors(sels),891BuiltinInfo(builtins), TUKind(TUKind), DeclarationNames(*this),892Comments(SM), CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),893CompCategories(this_()), LastSDM(nullptr, 0) {894addTranslationUnitDecl();895}896897void ASTContext::cleanup() {898// Release the DenseMaps associated with DeclContext objects.899// FIXME: Is this the ideal solution?900ReleaseDeclContextMaps();901902// Call all of the deallocation functions on all of their targets.903for (auto &Pair : Deallocations)904(Pair.first)(Pair.second);905Deallocations.clear();906907// ASTRecordLayout objects in ASTRecordLayouts must always be destroyed908// because they can contain DenseMaps.909for (llvm::DenseMap<const ObjCContainerDecl*,910const ASTRecordLayout*>::iterator911I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; )912// Increment in loop to prevent using deallocated memory.913if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))914R->Destroy(*this);915ObjCLayouts.clear();916917for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator918I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {919// Increment in loop to prevent using deallocated memory.920if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))921R->Destroy(*this);922}923ASTRecordLayouts.clear();924925for (llvm::DenseMap<const Decl*, AttrVec*>::iterator A = DeclAttrs.begin(),926AEnd = DeclAttrs.end();927A != AEnd; ++A)928A->second->~AttrVec();929DeclAttrs.clear();930931for (const auto &Value : ModuleInitializers)932Value.second->~PerModuleInitializers();933ModuleInitializers.clear();934}935936ASTContext::~ASTContext() { cleanup(); }937938void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {939TraversalScope = TopLevelDecls;940getParentMapContext().clear();941}942943void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {944Deallocations.push_back({Callback, Data});945}946947void948ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {949ExternalSource = std::move(Source);950}951952void ASTContext::PrintStats() const {953llvm::errs() << "\n*** AST Context Stats:\n";954llvm::errs() << " " << Types.size() << " types total.\n";955956unsigned counts[] = {957#define TYPE(Name, Parent) 0,958#define ABSTRACT_TYPE(Name, Parent)959#include "clang/AST/TypeNodes.inc"9600 // Extra961};962963for (unsigned i = 0, e = Types.size(); i != e; ++i) {964Type *T = Types[i];965counts[(unsigned)T->getTypeClass()]++;966}967968unsigned Idx = 0;969unsigned TotalBytes = 0;970#define TYPE(Name, Parent) \971if (counts[Idx]) \972llvm::errs() << " " << counts[Idx] << " " << #Name \973<< " types, " << sizeof(Name##Type) << " each " \974<< "(" << counts[Idx] * sizeof(Name##Type) \975<< " bytes)\n"; \976TotalBytes += counts[Idx] * sizeof(Name##Type); \977++Idx;978#define ABSTRACT_TYPE(Name, Parent)979#include "clang/AST/TypeNodes.inc"980981llvm::errs() << "Total bytes = " << TotalBytes << "\n";982983// Implicit special member functions.984llvm::errs() << NumImplicitDefaultConstructorsDeclared << "/"985<< NumImplicitDefaultConstructors986<< " implicit default constructors created\n";987llvm::errs() << NumImplicitCopyConstructorsDeclared << "/"988<< NumImplicitCopyConstructors989<< " implicit copy constructors created\n";990if (getLangOpts().CPlusPlus)991llvm::errs() << NumImplicitMoveConstructorsDeclared << "/"992<< NumImplicitMoveConstructors993<< " implicit move constructors created\n";994llvm::errs() << NumImplicitCopyAssignmentOperatorsDeclared << "/"995<< NumImplicitCopyAssignmentOperators996<< " implicit copy assignment operators created\n";997if (getLangOpts().CPlusPlus)998llvm::errs() << NumImplicitMoveAssignmentOperatorsDeclared << "/"999<< NumImplicitMoveAssignmentOperators1000<< " implicit move assignment operators created\n";1001llvm::errs() << NumImplicitDestructorsDeclared << "/"1002<< NumImplicitDestructors1003<< " implicit destructors created\n";10041005if (ExternalSource) {1006llvm::errs() << "\n";1007ExternalSource->PrintStats();1008}10091010BumpAlloc.PrintStats();1011}10121013void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M,1014bool NotifyListeners) {1015if (NotifyListeners)1016if (auto *Listener = getASTMutationListener())1017Listener->RedefinedHiddenDefinition(ND, M);10181019MergedDefModules[cast<NamedDecl>(ND->getCanonicalDecl())].push_back(M);1020}10211022void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) {1023auto It = MergedDefModules.find(cast<NamedDecl>(ND->getCanonicalDecl()));1024if (It == MergedDefModules.end())1025return;10261027auto &Merged = It->second;1028llvm::DenseSet<Module*> Found;1029for (Module *&M : Merged)1030if (!Found.insert(M).second)1031M = nullptr;1032llvm::erase(Merged, nullptr);1033}10341035ArrayRef<Module *>1036ASTContext::getModulesWithMergedDefinition(const NamedDecl *Def) {1037auto MergedIt =1038MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl()));1039if (MergedIt == MergedDefModules.end())1040return std::nullopt;1041return MergedIt->second;1042}10431044void ASTContext::PerModuleInitializers::resolve(ASTContext &Ctx) {1045if (LazyInitializers.empty())1046return;10471048auto *Source = Ctx.getExternalSource();1049assert(Source && "lazy initializers but no external source");10501051auto LazyInits = std::move(LazyInitializers);1052LazyInitializers.clear();10531054for (auto ID : LazyInits)1055Initializers.push_back(Source->GetExternalDecl(ID));10561057assert(LazyInitializers.empty() &&1058"GetExternalDecl for lazy module initializer added more inits");1059}10601061void ASTContext::addModuleInitializer(Module *M, Decl *D) {1062// One special case: if we add a module initializer that imports another1063// module, and that module's only initializer is an ImportDecl, simplify.1064if (const auto *ID = dyn_cast<ImportDecl>(D)) {1065auto It = ModuleInitializers.find(ID->getImportedModule());10661067// Maybe the ImportDecl does nothing at all. (Common case.)1068if (It == ModuleInitializers.end())1069return;10701071// Maybe the ImportDecl only imports another ImportDecl.1072auto &Imported = *It->second;1073if (Imported.Initializers.size() + Imported.LazyInitializers.size() == 1) {1074Imported.resolve(*this);1075auto *OnlyDecl = Imported.Initializers.front();1076if (isa<ImportDecl>(OnlyDecl))1077D = OnlyDecl;1078}1079}10801081auto *&Inits = ModuleInitializers[M];1082if (!Inits)1083Inits = new (*this) PerModuleInitializers;1084Inits->Initializers.push_back(D);1085}10861087void ASTContext::addLazyModuleInitializers(Module *M,1088ArrayRef<GlobalDeclID> IDs) {1089auto *&Inits = ModuleInitializers[M];1090if (!Inits)1091Inits = new (*this) PerModuleInitializers;1092Inits->LazyInitializers.insert(Inits->LazyInitializers.end(),1093IDs.begin(), IDs.end());1094}10951096ArrayRef<Decl *> ASTContext::getModuleInitializers(Module *M) {1097auto It = ModuleInitializers.find(M);1098if (It == ModuleInitializers.end())1099return std::nullopt;11001101auto *Inits = It->second;1102Inits->resolve(*this);1103return Inits->Initializers;1104}11051106void ASTContext::setCurrentNamedModule(Module *M) {1107assert(M->isNamedModule());1108assert(!CurrentCXXNamedModule &&1109"We should set named module for ASTContext for only once");1110CurrentCXXNamedModule = M;1111}11121113bool ASTContext::isInSameModule(const Module *M1, const Module *M2) {1114if (!M1 != !M2)1115return false;11161117/// Get the representative module for M. The representative module is the1118/// first module unit for a specific primary module name. So that the module1119/// units have the same representative module belongs to the same module.1120///1121/// The process is helpful to reduce the expensive string operations.1122auto GetRepresentativeModule = [this](const Module *M) {1123auto Iter = SameModuleLookupSet.find(M);1124if (Iter != SameModuleLookupSet.end())1125return Iter->second;11261127const Module *RepresentativeModule =1128PrimaryModuleNameMap.try_emplace(M->getPrimaryModuleInterfaceName(), M)1129.first->second;1130SameModuleLookupSet[M] = RepresentativeModule;1131return RepresentativeModule;1132};11331134assert(M1 && "Shouldn't call `isInSameModule` if both M1 and M2 are none.");1135return GetRepresentativeModule(M1) == GetRepresentativeModule(M2);1136}11371138ExternCContextDecl *ASTContext::getExternCContextDecl() const {1139if (!ExternCContext)1140ExternCContext = ExternCContextDecl::Create(*this, getTranslationUnitDecl());11411142return ExternCContext;1143}11441145BuiltinTemplateDecl *1146ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,1147const IdentifierInfo *II) const {1148auto *BuiltinTemplate =1149BuiltinTemplateDecl::Create(*this, getTranslationUnitDecl(), II, BTK);1150BuiltinTemplate->setImplicit();1151getTranslationUnitDecl()->addDecl(BuiltinTemplate);11521153return BuiltinTemplate;1154}11551156BuiltinTemplateDecl *1157ASTContext::getMakeIntegerSeqDecl() const {1158if (!MakeIntegerSeqDecl)1159MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq,1160getMakeIntegerSeqName());1161return MakeIntegerSeqDecl;1162}11631164BuiltinTemplateDecl *1165ASTContext::getTypePackElementDecl() const {1166if (!TypePackElementDecl)1167TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element,1168getTypePackElementName());1169return TypePackElementDecl;1170}11711172RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,1173RecordDecl::TagKind TK) const {1174SourceLocation Loc;1175RecordDecl *NewDecl;1176if (getLangOpts().CPlusPlus)1177NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc,1178Loc, &Idents.get(Name));1179else1180NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc,1181&Idents.get(Name));1182NewDecl->setImplicit();1183NewDecl->addAttr(TypeVisibilityAttr::CreateImplicit(1184const_cast<ASTContext &>(*this), TypeVisibilityAttr::Default));1185return NewDecl;1186}11871188TypedefDecl *ASTContext::buildImplicitTypedef(QualType T,1189StringRef Name) const {1190TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);1191TypedefDecl *NewDecl = TypedefDecl::Create(1192const_cast<ASTContext &>(*this), getTranslationUnitDecl(),1193SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo);1194NewDecl->setImplicit();1195return NewDecl;1196}11971198TypedefDecl *ASTContext::getInt128Decl() const {1199if (!Int128Decl)1200Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t");1201return Int128Decl;1202}12031204TypedefDecl *ASTContext::getUInt128Decl() const {1205if (!UInt128Decl)1206UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t");1207return UInt128Decl;1208}12091210void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {1211auto *Ty = new (*this, alignof(BuiltinType)) BuiltinType(K);1212R = CanQualType::CreateUnsafe(QualType(Ty, 0));1213Types.push_back(Ty);1214}12151216void ASTContext::InitBuiltinTypes(const TargetInfo &Target,1217const TargetInfo *AuxTarget) {1218assert((!this->Target || this->Target == &Target) &&1219"Incorrect target reinitialization");1220assert(VoidTy.isNull() && "Context reinitialized?");12211222this->Target = &Target;1223this->AuxTarget = AuxTarget;12241225ABI.reset(createCXXABI(Target));1226AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);12271228// C99 6.2.5p19.1229InitBuiltinType(VoidTy, BuiltinType::Void);12301231// C99 6.2.5p2.1232InitBuiltinType(BoolTy, BuiltinType::Bool);1233// C99 6.2.5p3.1234if (LangOpts.CharIsSigned)1235InitBuiltinType(CharTy, BuiltinType::Char_S);1236else1237InitBuiltinType(CharTy, BuiltinType::Char_U);1238// C99 6.2.5p4.1239InitBuiltinType(SignedCharTy, BuiltinType::SChar);1240InitBuiltinType(ShortTy, BuiltinType::Short);1241InitBuiltinType(IntTy, BuiltinType::Int);1242InitBuiltinType(LongTy, BuiltinType::Long);1243InitBuiltinType(LongLongTy, BuiltinType::LongLong);12441245// C99 6.2.5p6.1246InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);1247InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);1248InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);1249InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);1250InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);12511252// C99 6.2.5p10.1253InitBuiltinType(FloatTy, BuiltinType::Float);1254InitBuiltinType(DoubleTy, BuiltinType::Double);1255InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);12561257// GNU extension, __float128 for IEEE quadruple precision1258InitBuiltinType(Float128Ty, BuiltinType::Float128);12591260// __ibm128 for IBM extended precision1261InitBuiltinType(Ibm128Ty, BuiltinType::Ibm128);12621263// C11 extension ISO/IEC TS 18661-31264InitBuiltinType(Float16Ty, BuiltinType::Float16);12651266// ISO/IEC JTC1 SC22 WG14 N1169 Extension1267InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum);1268InitBuiltinType(AccumTy, BuiltinType::Accum);1269InitBuiltinType(LongAccumTy, BuiltinType::LongAccum);1270InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);1271InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum);1272InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum);1273InitBuiltinType(ShortFractTy, BuiltinType::ShortFract);1274InitBuiltinType(FractTy, BuiltinType::Fract);1275InitBuiltinType(LongFractTy, BuiltinType::LongFract);1276InitBuiltinType(UnsignedShortFractTy, BuiltinType::UShortFract);1277InitBuiltinType(UnsignedFractTy, BuiltinType::UFract);1278InitBuiltinType(UnsignedLongFractTy, BuiltinType::ULongFract);1279InitBuiltinType(SatShortAccumTy, BuiltinType::SatShortAccum);1280InitBuiltinType(SatAccumTy, BuiltinType::SatAccum);1281InitBuiltinType(SatLongAccumTy, BuiltinType::SatLongAccum);1282InitBuiltinType(SatUnsignedShortAccumTy, BuiltinType::SatUShortAccum);1283InitBuiltinType(SatUnsignedAccumTy, BuiltinType::SatUAccum);1284InitBuiltinType(SatUnsignedLongAccumTy, BuiltinType::SatULongAccum);1285InitBuiltinType(SatShortFractTy, BuiltinType::SatShortFract);1286InitBuiltinType(SatFractTy, BuiltinType::SatFract);1287InitBuiltinType(SatLongFractTy, BuiltinType::SatLongFract);1288InitBuiltinType(SatUnsignedShortFractTy, BuiltinType::SatUShortFract);1289InitBuiltinType(SatUnsignedFractTy, BuiltinType::SatUFract);1290InitBuiltinType(SatUnsignedLongFractTy, BuiltinType::SatULongFract);12911292// GNU extension, 128-bit integers.1293InitBuiltinType(Int128Ty, BuiltinType::Int128);1294InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);12951296// C++ 3.9.1p51297if (TargetInfo::isTypeSigned(Target.getWCharType()))1298InitBuiltinType(WCharTy, BuiltinType::WChar_S);1299else // -fshort-wchar makes wchar_t be unsigned.1300InitBuiltinType(WCharTy, BuiltinType::WChar_U);1301if (LangOpts.CPlusPlus && LangOpts.WChar)1302WideCharTy = WCharTy;1303else {1304// C99 (or C++ using -fno-wchar).1305WideCharTy = getFromTargetType(Target.getWCharType());1306}13071308WIntTy = getFromTargetType(Target.getWIntType());13091310// C++20 (proposed)1311InitBuiltinType(Char8Ty, BuiltinType::Char8);13121313if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++1314InitBuiltinType(Char16Ty, BuiltinType::Char16);1315else // C991316Char16Ty = getFromTargetType(Target.getChar16Type());13171318if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++1319InitBuiltinType(Char32Ty, BuiltinType::Char32);1320else // C991321Char32Ty = getFromTargetType(Target.getChar32Type());13221323// Placeholder type for type-dependent expressions whose type is1324// completely unknown. No code should ever check a type against1325// DependentTy and users should never see it; however, it is here to1326// help diagnose failures to properly check for type-dependent1327// expressions.1328InitBuiltinType(DependentTy, BuiltinType::Dependent);13291330// Placeholder type for functions.1331InitBuiltinType(OverloadTy, BuiltinType::Overload);13321333// Placeholder type for bound members.1334InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember);13351336// Placeholder type for unresolved templates.1337InitBuiltinType(UnresolvedTemplateTy, BuiltinType::UnresolvedTemplate);13381339// Placeholder type for pseudo-objects.1340InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject);13411342// "any" type; useful for debugger-like clients.1343InitBuiltinType(UnknownAnyTy, BuiltinType::UnknownAny);13441345// Placeholder type for unbridged ARC casts.1346InitBuiltinType(ARCUnbridgedCastTy, BuiltinType::ARCUnbridgedCast);13471348// Placeholder type for builtin functions.1349InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn);13501351// Placeholder type for OMP array sections.1352if (LangOpts.OpenMP) {1353InitBuiltinType(ArraySectionTy, BuiltinType::ArraySection);1354InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping);1355InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator);1356}1357// Placeholder type for OpenACC array sections, if we are ALSO in OMP mode,1358// don't bother, as we're just using the same type as OMP.1359if (LangOpts.OpenACC && !LangOpts.OpenMP) {1360InitBuiltinType(ArraySectionTy, BuiltinType::ArraySection);1361}1362if (LangOpts.MatrixTypes)1363InitBuiltinType(IncompleteMatrixIdxTy, BuiltinType::IncompleteMatrixIdx);13641365// Builtin types for 'id', 'Class', and 'SEL'.1366InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);1367InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);1368InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);13691370if (LangOpts.OpenCL) {1371#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \1372InitBuiltinType(SingletonId, BuiltinType::Id);1373#include "clang/Basic/OpenCLImageTypes.def"13741375InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler);1376InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent);1377InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);1378InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);1379InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);13801381#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \1382InitBuiltinType(Id##Ty, BuiltinType::Id);1383#include "clang/Basic/OpenCLExtensionTypes.def"1384}13851386if (Target.hasAArch64SVETypes() ||1387(AuxTarget && AuxTarget->hasAArch64SVETypes())) {1388#define SVE_TYPE(Name, Id, SingletonId) \1389InitBuiltinType(SingletonId, BuiltinType::Id);1390#include "clang/Basic/AArch64SVEACLETypes.def"1391}13921393if (Target.getTriple().isPPC64()) {1394#define PPC_VECTOR_MMA_TYPE(Name, Id, Size) \1395InitBuiltinType(Id##Ty, BuiltinType::Id);1396#include "clang/Basic/PPCTypes.def"1397#define PPC_VECTOR_VSX_TYPE(Name, Id, Size) \1398InitBuiltinType(Id##Ty, BuiltinType::Id);1399#include "clang/Basic/PPCTypes.def"1400}14011402if (Target.hasRISCVVTypes()) {1403#define RVV_TYPE(Name, Id, SingletonId) \1404InitBuiltinType(SingletonId, BuiltinType::Id);1405#include "clang/Basic/RISCVVTypes.def"1406}14071408if (Target.getTriple().isWasm() && Target.hasFeature("reference-types")) {1409#define WASM_TYPE(Name, Id, SingletonId) \1410InitBuiltinType(SingletonId, BuiltinType::Id);1411#include "clang/Basic/WebAssemblyReferenceTypes.def"1412}14131414if (Target.getTriple().isAMDGPU() ||1415(AuxTarget && AuxTarget->getTriple().isAMDGPU())) {1416#define AMDGPU_TYPE(Name, Id, SingletonId) \1417InitBuiltinType(SingletonId, BuiltinType::Id);1418#include "clang/Basic/AMDGPUTypes.def"1419}14201421// Builtin type for __objc_yes and __objc_no1422ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?1423SignedCharTy : BoolTy);14241425ObjCConstantStringType = QualType();14261427ObjCSuperType = QualType();14281429// void * type1430if (LangOpts.OpenCLGenericAddressSpace) {1431auto Q = VoidTy.getQualifiers();1432Q.setAddressSpace(LangAS::opencl_generic);1433VoidPtrTy = getPointerType(getCanonicalType(1434getQualifiedType(VoidTy.getUnqualifiedType(), Q)));1435} else {1436VoidPtrTy = getPointerType(VoidTy);1437}14381439// nullptr type (C++0x 2.14.7)1440InitBuiltinType(NullPtrTy, BuiltinType::NullPtr);14411442// half type (OpenCL 6.1.1.1) / ARM NEON __fp161443InitBuiltinType(HalfTy, BuiltinType::Half);14441445InitBuiltinType(BFloat16Ty, BuiltinType::BFloat16);14461447// Builtin type used to help define __builtin_va_list.1448VaListTagDecl = nullptr;14491450// MSVC predeclares struct _GUID, and we need it to create MSGuidDecls.1451if (LangOpts.MicrosoftExt || LangOpts.Borland) {1452MSGuidTagDecl = buildImplicitRecord("_GUID");1453getTranslationUnitDecl()->addDecl(MSGuidTagDecl);1454}1455}14561457DiagnosticsEngine &ASTContext::getDiagnostics() const {1458return SourceMgr.getDiagnostics();1459}14601461AttrVec& ASTContext::getDeclAttrs(const Decl *D) {1462AttrVec *&Result = DeclAttrs[D];1463if (!Result) {1464void *Mem = Allocate(sizeof(AttrVec));1465Result = new (Mem) AttrVec;1466}14671468return *Result;1469}14701471/// Erase the attributes corresponding to the given declaration.1472void ASTContext::eraseDeclAttrs(const Decl *D) {1473llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D);1474if (Pos != DeclAttrs.end()) {1475Pos->second->~AttrVec();1476DeclAttrs.erase(Pos);1477}1478}14791480// FIXME: Remove ?1481MemberSpecializationInfo *1482ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) {1483assert(Var->isStaticDataMember() && "Not a static data member");1484return getTemplateOrSpecializationInfo(Var)1485.dyn_cast<MemberSpecializationInfo *>();1486}14871488ASTContext::TemplateOrSpecializationInfo1489ASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) {1490llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos =1491TemplateOrInstantiation.find(Var);1492if (Pos == TemplateOrInstantiation.end())1493return {};14941495return Pos->second;1496}14971498void1499ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,1500TemplateSpecializationKind TSK,1501SourceLocation PointOfInstantiation) {1502assert(Inst->isStaticDataMember() && "Not a static data member");1503assert(Tmpl->isStaticDataMember() && "Not a static data member");1504setTemplateOrSpecializationInfo(Inst, new (*this) MemberSpecializationInfo(1505Tmpl, TSK, PointOfInstantiation));1506}15071508void1509ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst,1510TemplateOrSpecializationInfo TSI) {1511assert(!TemplateOrInstantiation[Inst] &&1512"Already noted what the variable was instantiated from");1513TemplateOrInstantiation[Inst] = TSI;1514}15151516NamedDecl *1517ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) {1518return InstantiatedFromUsingDecl.lookup(UUD);1519}15201521void1522ASTContext::setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern) {1523assert((isa<UsingDecl>(Pattern) ||1524isa<UnresolvedUsingValueDecl>(Pattern) ||1525isa<UnresolvedUsingTypenameDecl>(Pattern)) &&1526"pattern decl is not a using decl");1527assert((isa<UsingDecl>(Inst) ||1528isa<UnresolvedUsingValueDecl>(Inst) ||1529isa<UnresolvedUsingTypenameDecl>(Inst)) &&1530"instantiation did not produce a using decl");1531assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists");1532InstantiatedFromUsingDecl[Inst] = Pattern;1533}15341535UsingEnumDecl *1536ASTContext::getInstantiatedFromUsingEnumDecl(UsingEnumDecl *UUD) {1537return InstantiatedFromUsingEnumDecl.lookup(UUD);1538}15391540void ASTContext::setInstantiatedFromUsingEnumDecl(UsingEnumDecl *Inst,1541UsingEnumDecl *Pattern) {1542assert(!InstantiatedFromUsingEnumDecl[Inst] && "pattern already exists");1543InstantiatedFromUsingEnumDecl[Inst] = Pattern;1544}15451546UsingShadowDecl *1547ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {1548return InstantiatedFromUsingShadowDecl.lookup(Inst);1549}15501551void1552ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,1553UsingShadowDecl *Pattern) {1554assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists");1555InstantiatedFromUsingShadowDecl[Inst] = Pattern;1556}15571558FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {1559return InstantiatedFromUnnamedFieldDecl.lookup(Field);1560}15611562void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,1563FieldDecl *Tmpl) {1564assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed");1565assert(!Tmpl->getDeclName() && "Template field decl is not unnamed");1566assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&1567"Already noted what unnamed field was instantiated from");15681569InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;1570}15711572ASTContext::overridden_cxx_method_iterator1573ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {1574return overridden_methods(Method).begin();1575}15761577ASTContext::overridden_cxx_method_iterator1578ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {1579return overridden_methods(Method).end();1580}15811582unsigned1583ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {1584auto Range = overridden_methods(Method);1585return Range.end() - Range.begin();1586}15871588ASTContext::overridden_method_range1589ASTContext::overridden_methods(const CXXMethodDecl *Method) const {1590llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =1591OverriddenMethods.find(Method->getCanonicalDecl());1592if (Pos == OverriddenMethods.end())1593return overridden_method_range(nullptr, nullptr);1594return overridden_method_range(Pos->second.begin(), Pos->second.end());1595}15961597void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,1598const CXXMethodDecl *Overridden) {1599assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl());1600OverriddenMethods[Method].push_back(Overridden);1601}16021603void ASTContext::getOverriddenMethods(1604const NamedDecl *D,1605SmallVectorImpl<const NamedDecl *> &Overridden) const {1606assert(D);16071608if (const auto *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {1609Overridden.append(overridden_methods_begin(CXXMethod),1610overridden_methods_end(CXXMethod));1611return;1612}16131614const auto *Method = dyn_cast<ObjCMethodDecl>(D);1615if (!Method)1616return;16171618SmallVector<const ObjCMethodDecl *, 8> OverDecls;1619Method->getOverriddenMethods(OverDecls);1620Overridden.append(OverDecls.begin(), OverDecls.end());1621}16221623void ASTContext::addedLocalImportDecl(ImportDecl *Import) {1624assert(!Import->getNextLocalImport() &&1625"Import declaration already in the chain");1626assert(!Import->isFromASTFile() && "Non-local import declaration");1627if (!FirstLocalImport) {1628FirstLocalImport = Import;1629LastLocalImport = Import;1630return;1631}16321633LastLocalImport->setNextLocalImport(Import);1634LastLocalImport = Import;1635}16361637//===----------------------------------------------------------------------===//1638// Type Sizing and Analysis1639//===----------------------------------------------------------------------===//16401641/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified1642/// scalar floating point type.1643const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {1644switch (T->castAs<BuiltinType>()->getKind()) {1645default:1646llvm_unreachable("Not a floating point type!");1647case BuiltinType::BFloat16:1648return Target->getBFloat16Format();1649case BuiltinType::Float16:1650return Target->getHalfFormat();1651case BuiltinType::Half:1652return Target->getHalfFormat();1653case BuiltinType::Float: return Target->getFloatFormat();1654case BuiltinType::Double: return Target->getDoubleFormat();1655case BuiltinType::Ibm128:1656return Target->getIbm128Format();1657case BuiltinType::LongDouble:1658if (getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice)1659return AuxTarget->getLongDoubleFormat();1660return Target->getLongDoubleFormat();1661case BuiltinType::Float128:1662if (getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice)1663return AuxTarget->getFloat128Format();1664return Target->getFloat128Format();1665}1666}16671668CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {1669unsigned Align = Target->getCharWidth();16701671const unsigned AlignFromAttr = D->getMaxAlignment();1672if (AlignFromAttr)1673Align = AlignFromAttr;16741675// __attribute__((aligned)) can increase or decrease alignment1676// *except* on a struct or struct member, where it only increases1677// alignment unless 'packed' is also specified.1678//1679// It is an error for alignas to decrease alignment, so we can1680// ignore that possibility; Sema should diagnose it.1681bool UseAlignAttrOnly;1682if (const FieldDecl *FD = dyn_cast<FieldDecl>(D))1683UseAlignAttrOnly =1684FD->hasAttr<PackedAttr>() || FD->getParent()->hasAttr<PackedAttr>();1685else1686UseAlignAttrOnly = AlignFromAttr != 0;1687// If we're using the align attribute only, just ignore everything1688// else about the declaration and its type.1689if (UseAlignAttrOnly) {1690// do nothing1691} else if (const auto *VD = dyn_cast<ValueDecl>(D)) {1692QualType T = VD->getType();1693if (const auto *RT = T->getAs<ReferenceType>()) {1694if (ForAlignof)1695T = RT->getPointeeType();1696else1697T = getPointerType(RT->getPointeeType());1698}1699QualType BaseT = getBaseElementType(T);1700if (T->isFunctionType())1701Align = getTypeInfoImpl(T.getTypePtr()).Align;1702else if (!BaseT->isIncompleteType()) {1703// Adjust alignments of declarations with array type by the1704// large-array alignment on the target.1705if (const ArrayType *arrayType = getAsArrayType(T)) {1706unsigned MinWidth = Target->getLargeArrayMinWidth();1707if (!ForAlignof && MinWidth) {1708if (isa<VariableArrayType>(arrayType))1709Align = std::max(Align, Target->getLargeArrayAlign());1710else if (isa<ConstantArrayType>(arrayType) &&1711MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))1712Align = std::max(Align, Target->getLargeArrayAlign());1713}1714}1715Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));1716if (BaseT.getQualifiers().hasUnaligned())1717Align = Target->getCharWidth();1718}17191720// Ensure miminum alignment for global variables.1721if (const auto *VD = dyn_cast<VarDecl>(D))1722if (VD->hasGlobalStorage() && !ForAlignof) {1723uint64_t TypeSize =1724!BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0;1725Align = std::max(Align, getMinGlobalAlignOfVar(TypeSize, VD));1726}17271728// Fields can be subject to extra alignment constraints, like if1729// the field is packed, the struct is packed, or the struct has a1730// a max-field-alignment constraint (#pragma pack). So calculate1731// the actual alignment of the field within the struct, and then1732// (as we're expected to) constrain that by the alignment of the type.1733if (const auto *Field = dyn_cast<FieldDecl>(VD)) {1734const RecordDecl *Parent = Field->getParent();1735// We can only produce a sensible answer if the record is valid.1736if (!Parent->isInvalidDecl()) {1737const ASTRecordLayout &Layout = getASTRecordLayout(Parent);17381739// Start with the record's overall alignment.1740unsigned FieldAlign = toBits(Layout.getAlignment());17411742// Use the GCD of that and the offset within the record.1743uint64_t Offset = Layout.getFieldOffset(Field->getFieldIndex());1744if (Offset > 0) {1745// Alignment is always a power of 2, so the GCD will be a power of 2,1746// which means we get to do this crazy thing instead of Euclid's.1747uint64_t LowBitOfOffset = Offset & (~Offset + 1);1748if (LowBitOfOffset < FieldAlign)1749FieldAlign = static_cast<unsigned>(LowBitOfOffset);1750}17511752Align = std::min(Align, FieldAlign);1753}1754}1755}17561757// Some targets have hard limitation on the maximum requestable alignment in1758// aligned attribute for static variables.1759const unsigned MaxAlignedAttr = getTargetInfo().getMaxAlignedAttribute();1760const auto *VD = dyn_cast<VarDecl>(D);1761if (MaxAlignedAttr && VD && VD->getStorageClass() == SC_Static)1762Align = std::min(Align, MaxAlignedAttr);17631764return toCharUnitsFromBits(Align);1765}17661767CharUnits ASTContext::getExnObjectAlignment() const {1768return toCharUnitsFromBits(Target->getExnObjectAlignment());1769}17701771// getTypeInfoDataSizeInChars - Return the size of a type, in1772// chars. If the type is a record, its data size is returned. This is1773// the size of the memcpy that's performed when assigning this type1774// using a trivial copy/move assignment operator.1775TypeInfoChars ASTContext::getTypeInfoDataSizeInChars(QualType T) const {1776TypeInfoChars Info = getTypeInfoInChars(T);17771778// In C++, objects can sometimes be allocated into the tail padding1779// of a base-class subobject. We decide whether that's possible1780// during class layout, so here we can just trust the layout results.1781if (getLangOpts().CPlusPlus) {1782if (const auto *RT = T->getAs<RecordType>();1783RT && !RT->getDecl()->isInvalidDecl()) {1784const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl());1785Info.Width = layout.getDataSize();1786}1787}17881789return Info;1790}17911792/// getConstantArrayInfoInChars - Performing the computation in CharUnits1793/// instead of in bits prevents overflowing the uint64_t for some large arrays.1794TypeInfoChars1795static getConstantArrayInfoInChars(const ASTContext &Context,1796const ConstantArrayType *CAT) {1797TypeInfoChars EltInfo = Context.getTypeInfoInChars(CAT->getElementType());1798uint64_t Size = CAT->getZExtSize();1799assert((Size == 0 || static_cast<uint64_t>(EltInfo.Width.getQuantity()) <=1800(uint64_t)(-1)/Size) &&1801"Overflow in array type char size evaluation");1802uint64_t Width = EltInfo.Width.getQuantity() * Size;1803unsigned Align = EltInfo.Align.getQuantity();1804if (!Context.getTargetInfo().getCXXABI().isMicrosoft() ||1805Context.getTargetInfo().getPointerWidth(LangAS::Default) == 64)1806Width = llvm::alignTo(Width, Align);1807return TypeInfoChars(CharUnits::fromQuantity(Width),1808CharUnits::fromQuantity(Align),1809EltInfo.AlignRequirement);1810}18111812TypeInfoChars ASTContext::getTypeInfoInChars(const Type *T) const {1813if (const auto *CAT = dyn_cast<ConstantArrayType>(T))1814return getConstantArrayInfoInChars(*this, CAT);1815TypeInfo Info = getTypeInfo(T);1816return TypeInfoChars(toCharUnitsFromBits(Info.Width),1817toCharUnitsFromBits(Info.Align), Info.AlignRequirement);1818}18191820TypeInfoChars ASTContext::getTypeInfoInChars(QualType T) const {1821return getTypeInfoInChars(T.getTypePtr());1822}18231824bool ASTContext::isPromotableIntegerType(QualType T) const {1825// HLSL doesn't promote all small integer types to int, it1826// just uses the rank-based promotion rules for all types.1827if (getLangOpts().HLSL)1828return false;18291830if (const auto *BT = T->getAs<BuiltinType>())1831switch (BT->getKind()) {1832case BuiltinType::Bool:1833case BuiltinType::Char_S:1834case BuiltinType::Char_U:1835case BuiltinType::SChar:1836case BuiltinType::UChar:1837case BuiltinType::Short:1838case BuiltinType::UShort:1839case BuiltinType::WChar_S:1840case BuiltinType::WChar_U:1841case BuiltinType::Char8:1842case BuiltinType::Char16:1843case BuiltinType::Char32:1844return true;1845default:1846return false;1847}18481849// Enumerated types are promotable to their compatible integer types1850// (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).1851if (const auto *ET = T->getAs<EnumType>()) {1852if (T->isDependentType() || ET->getDecl()->getPromotionType().isNull() ||1853ET->getDecl()->isScoped())1854return false;18551856return true;1857}18581859return false;1860}18611862bool ASTContext::isAlignmentRequired(const Type *T) const {1863return getTypeInfo(T).AlignRequirement != AlignRequirementKind::None;1864}18651866bool ASTContext::isAlignmentRequired(QualType T) const {1867return isAlignmentRequired(T.getTypePtr());1868}18691870unsigned ASTContext::getTypeAlignIfKnown(QualType T,1871bool NeedsPreferredAlignment) const {1872// An alignment on a typedef overrides anything else.1873if (const auto *TT = T->getAs<TypedefType>())1874if (unsigned Align = TT->getDecl()->getMaxAlignment())1875return Align;18761877// If we have an (array of) complete type, we're done.1878T = getBaseElementType(T);1879if (!T->isIncompleteType())1880return NeedsPreferredAlignment ? getPreferredTypeAlign(T) : getTypeAlign(T);18811882// If we had an array type, its element type might be a typedef1883// type with an alignment attribute.1884if (const auto *TT = T->getAs<TypedefType>())1885if (unsigned Align = TT->getDecl()->getMaxAlignment())1886return Align;18871888// Otherwise, see if the declaration of the type had an attribute.1889if (const auto *TT = T->getAs<TagType>())1890return TT->getDecl()->getMaxAlignment();18911892return 0;1893}18941895TypeInfo ASTContext::getTypeInfo(const Type *T) const {1896TypeInfoMap::iterator I = MemoizedTypeInfo.find(T);1897if (I != MemoizedTypeInfo.end())1898return I->second;18991900// This call can invalidate MemoizedTypeInfo[T], so we need a second lookup.1901TypeInfo TI = getTypeInfoImpl(T);1902MemoizedTypeInfo[T] = TI;1903return TI;1904}19051906/// getTypeInfoImpl - Return the size of the specified type, in bits. This1907/// method does not work on incomplete types.1908///1909/// FIXME: Pointers into different addr spaces could have different sizes and1910/// alignment requirements: getPointerInfo should take an AddrSpace, this1911/// should take a QualType, &c.1912TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {1913uint64_t Width = 0;1914unsigned Align = 8;1915AlignRequirementKind AlignRequirement = AlignRequirementKind::None;1916LangAS AS = LangAS::Default;1917switch (T->getTypeClass()) {1918#define TYPE(Class, Base)1919#define ABSTRACT_TYPE(Class, Base)1920#define NON_CANONICAL_TYPE(Class, Base)1921#define DEPENDENT_TYPE(Class, Base) case Type::Class:1922#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) \1923case Type::Class: \1924assert(!T->isDependentType() && "should not see dependent types here"); \1925return getTypeInfo(cast<Class##Type>(T)->desugar().getTypePtr());1926#include "clang/AST/TypeNodes.inc"1927llvm_unreachable("Should not see dependent types");19281929case Type::FunctionNoProto:1930case Type::FunctionProto:1931// GCC extension: alignof(function) = 32 bits1932Width = 0;1933Align = 32;1934break;19351936case Type::IncompleteArray:1937case Type::VariableArray:1938case Type::ConstantArray:1939case Type::ArrayParameter: {1940// Model non-constant sized arrays as size zero, but track the alignment.1941uint64_t Size = 0;1942if (const auto *CAT = dyn_cast<ConstantArrayType>(T))1943Size = CAT->getZExtSize();19441945TypeInfo EltInfo = getTypeInfo(cast<ArrayType>(T)->getElementType());1946assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) &&1947"Overflow in array type bit size evaluation");1948Width = EltInfo.Width * Size;1949Align = EltInfo.Align;1950AlignRequirement = EltInfo.AlignRequirement;1951if (!getTargetInfo().getCXXABI().isMicrosoft() ||1952getTargetInfo().getPointerWidth(LangAS::Default) == 64)1953Width = llvm::alignTo(Width, Align);1954break;1955}19561957case Type::ExtVector:1958case Type::Vector: {1959const auto *VT = cast<VectorType>(T);1960TypeInfo EltInfo = getTypeInfo(VT->getElementType());1961Width = VT->isExtVectorBoolType() ? VT->getNumElements()1962: EltInfo.Width * VT->getNumElements();1963// Enforce at least byte size and alignment.1964Width = std::max<unsigned>(8, Width);1965Align = std::max<unsigned>(8, Width);19661967// If the alignment is not a power of 2, round up to the next power of 2.1968// This happens for non-power-of-2 length vectors.1969if (Align & (Align-1)) {1970Align = llvm::bit_ceil(Align);1971Width = llvm::alignTo(Width, Align);1972}1973// Adjust the alignment based on the target max.1974uint64_t TargetVectorAlign = Target->getMaxVectorAlign();1975if (TargetVectorAlign && TargetVectorAlign < Align)1976Align = TargetVectorAlign;1977if (VT->getVectorKind() == VectorKind::SveFixedLengthData)1978// Adjust the alignment for fixed-length SVE vectors. This is important1979// for non-power-of-2 vector lengths.1980Align = 128;1981else if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)1982// Adjust the alignment for fixed-length SVE predicates.1983Align = 16;1984else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||1985VT->getVectorKind() == VectorKind::RVVFixedLengthMask)1986// Adjust the alignment for fixed-length RVV vectors.1987Align = std::min<unsigned>(64, Width);1988break;1989}19901991case Type::ConstantMatrix: {1992const auto *MT = cast<ConstantMatrixType>(T);1993TypeInfo ElementInfo = getTypeInfo(MT->getElementType());1994// The internal layout of a matrix value is implementation defined.1995// Initially be ABI compatible with arrays with respect to alignment and1996// size.1997Width = ElementInfo.Width * MT->getNumRows() * MT->getNumColumns();1998Align = ElementInfo.Align;1999break;2000}20012002case Type::Builtin:2003switch (cast<BuiltinType>(T)->getKind()) {2004default: llvm_unreachable("Unknown builtin type!");2005case BuiltinType::Void:2006// GCC extension: alignof(void) = 8 bits.2007Width = 0;2008Align = 8;2009break;2010case BuiltinType::Bool:2011Width = Target->getBoolWidth();2012Align = Target->getBoolAlign();2013break;2014case BuiltinType::Char_S:2015case BuiltinType::Char_U:2016case BuiltinType::UChar:2017case BuiltinType::SChar:2018case BuiltinType::Char8:2019Width = Target->getCharWidth();2020Align = Target->getCharAlign();2021break;2022case BuiltinType::WChar_S:2023case BuiltinType::WChar_U:2024Width = Target->getWCharWidth();2025Align = Target->getWCharAlign();2026break;2027case BuiltinType::Char16:2028Width = Target->getChar16Width();2029Align = Target->getChar16Align();2030break;2031case BuiltinType::Char32:2032Width = Target->getChar32Width();2033Align = Target->getChar32Align();2034break;2035case BuiltinType::UShort:2036case BuiltinType::Short:2037Width = Target->getShortWidth();2038Align = Target->getShortAlign();2039break;2040case BuiltinType::UInt:2041case BuiltinType::Int:2042Width = Target->getIntWidth();2043Align = Target->getIntAlign();2044break;2045case BuiltinType::ULong:2046case BuiltinType::Long:2047Width = Target->getLongWidth();2048Align = Target->getLongAlign();2049break;2050case BuiltinType::ULongLong:2051case BuiltinType::LongLong:2052Width = Target->getLongLongWidth();2053Align = Target->getLongLongAlign();2054break;2055case BuiltinType::Int128:2056case BuiltinType::UInt128:2057Width = 128;2058Align = Target->getInt128Align();2059break;2060case BuiltinType::ShortAccum:2061case BuiltinType::UShortAccum:2062case BuiltinType::SatShortAccum:2063case BuiltinType::SatUShortAccum:2064Width = Target->getShortAccumWidth();2065Align = Target->getShortAccumAlign();2066break;2067case BuiltinType::Accum:2068case BuiltinType::UAccum:2069case BuiltinType::SatAccum:2070case BuiltinType::SatUAccum:2071Width = Target->getAccumWidth();2072Align = Target->getAccumAlign();2073break;2074case BuiltinType::LongAccum:2075case BuiltinType::ULongAccum:2076case BuiltinType::SatLongAccum:2077case BuiltinType::SatULongAccum:2078Width = Target->getLongAccumWidth();2079Align = Target->getLongAccumAlign();2080break;2081case BuiltinType::ShortFract:2082case BuiltinType::UShortFract:2083case BuiltinType::SatShortFract:2084case BuiltinType::SatUShortFract:2085Width = Target->getShortFractWidth();2086Align = Target->getShortFractAlign();2087break;2088case BuiltinType::Fract:2089case BuiltinType::UFract:2090case BuiltinType::SatFract:2091case BuiltinType::SatUFract:2092Width = Target->getFractWidth();2093Align = Target->getFractAlign();2094break;2095case BuiltinType::LongFract:2096case BuiltinType::ULongFract:2097case BuiltinType::SatLongFract:2098case BuiltinType::SatULongFract:2099Width = Target->getLongFractWidth();2100Align = Target->getLongFractAlign();2101break;2102case BuiltinType::BFloat16:2103if (Target->hasBFloat16Type()) {2104Width = Target->getBFloat16Width();2105Align = Target->getBFloat16Align();2106} else if ((getLangOpts().SYCLIsDevice ||2107(getLangOpts().OpenMP &&2108getLangOpts().OpenMPIsTargetDevice)) &&2109AuxTarget->hasBFloat16Type()) {2110Width = AuxTarget->getBFloat16Width();2111Align = AuxTarget->getBFloat16Align();2112}2113break;2114case BuiltinType::Float16:2115case BuiltinType::Half:2116if (Target->hasFloat16Type() || !getLangOpts().OpenMP ||2117!getLangOpts().OpenMPIsTargetDevice) {2118Width = Target->getHalfWidth();2119Align = Target->getHalfAlign();2120} else {2121assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice &&2122"Expected OpenMP device compilation.");2123Width = AuxTarget->getHalfWidth();2124Align = AuxTarget->getHalfAlign();2125}2126break;2127case BuiltinType::Float:2128Width = Target->getFloatWidth();2129Align = Target->getFloatAlign();2130break;2131case BuiltinType::Double:2132Width = Target->getDoubleWidth();2133Align = Target->getDoubleAlign();2134break;2135case BuiltinType::Ibm128:2136Width = Target->getIbm128Width();2137Align = Target->getIbm128Align();2138break;2139case BuiltinType::LongDouble:2140if (getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice &&2141(Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() ||2142Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) {2143Width = AuxTarget->getLongDoubleWidth();2144Align = AuxTarget->getLongDoubleAlign();2145} else {2146Width = Target->getLongDoubleWidth();2147Align = Target->getLongDoubleAlign();2148}2149break;2150case BuiltinType::Float128:2151if (Target->hasFloat128Type() || !getLangOpts().OpenMP ||2152!getLangOpts().OpenMPIsTargetDevice) {2153Width = Target->getFloat128Width();2154Align = Target->getFloat128Align();2155} else {2156assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice &&2157"Expected OpenMP device compilation.");2158Width = AuxTarget->getFloat128Width();2159Align = AuxTarget->getFloat128Align();2160}2161break;2162case BuiltinType::NullPtr:2163// C++ 3.9.1p11: sizeof(nullptr_t) == sizeof(void*)2164Width = Target->getPointerWidth(LangAS::Default);2165Align = Target->getPointerAlign(LangAS::Default);2166break;2167case BuiltinType::ObjCId:2168case BuiltinType::ObjCClass:2169case BuiltinType::ObjCSel:2170Width = Target->getPointerWidth(LangAS::Default);2171Align = Target->getPointerAlign(LangAS::Default);2172break;2173case BuiltinType::OCLSampler:2174case BuiltinType::OCLEvent:2175case BuiltinType::OCLClkEvent:2176case BuiltinType::OCLQueue:2177case BuiltinType::OCLReserveID:2178#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \2179case BuiltinType::Id:2180#include "clang/Basic/OpenCLImageTypes.def"2181#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \2182case BuiltinType::Id:2183#include "clang/Basic/OpenCLExtensionTypes.def"2184AS = Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T));2185Width = Target->getPointerWidth(AS);2186Align = Target->getPointerAlign(AS);2187break;2188// The SVE types are effectively target-specific. The length of an2189// SVE_VECTOR_TYPE is only known at runtime, but it is always a multiple2190// of 128 bits. There is one predicate bit for each vector byte, so the2191// length of an SVE_PREDICATE_TYPE is always a multiple of 16 bits.2192//2193// Because the length is only known at runtime, we use a dummy value2194// of 0 for the static length. The alignment values are those defined2195// by the Procedure Call Standard for the Arm Architecture.2196#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId, NumEls, ElBits, \2197IsSigned, IsFP, IsBF) \2198case BuiltinType::Id: \2199Width = 0; \2200Align = 128; \2201break;2202#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId, NumEls) \2203case BuiltinType::Id: \2204Width = 0; \2205Align = 16; \2206break;2207#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \2208case BuiltinType::Id: \2209Width = 0; \2210Align = 16; \2211break;2212#include "clang/Basic/AArch64SVEACLETypes.def"2213#define PPC_VECTOR_TYPE(Name, Id, Size) \2214case BuiltinType::Id: \2215Width = Size; \2216Align = Size; \2217break;2218#include "clang/Basic/PPCTypes.def"2219#define RVV_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, NF, IsSigned, \2220IsFP, IsBF) \2221case BuiltinType::Id: \2222Width = 0; \2223Align = ElBits; \2224break;2225#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) \2226case BuiltinType::Id: \2227Width = 0; \2228Align = 8; \2229break;2230#include "clang/Basic/RISCVVTypes.def"2231#define WASM_TYPE(Name, Id, SingletonId) \2232case BuiltinType::Id: \2233Width = 0; \2234Align = 8; \2235break;2236#include "clang/Basic/WebAssemblyReferenceTypes.def"2237#define AMDGPU_OPAQUE_PTR_TYPE(NAME, MANGLEDNAME, AS, WIDTH, ALIGN, ID, \2238SINGLETONID) \2239case BuiltinType::ID: \2240Width = WIDTH; \2241Align = ALIGN; \2242break;2243#include "clang/Basic/AMDGPUTypes.def"2244}2245break;2246case Type::ObjCObjectPointer:2247Width = Target->getPointerWidth(LangAS::Default);2248Align = Target->getPointerAlign(LangAS::Default);2249break;2250case Type::BlockPointer:2251AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace();2252Width = Target->getPointerWidth(AS);2253Align = Target->getPointerAlign(AS);2254break;2255case Type::LValueReference:2256case Type::RValueReference:2257// alignof and sizeof should never enter this code path here, so we go2258// the pointer route.2259AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace();2260Width = Target->getPointerWidth(AS);2261Align = Target->getPointerAlign(AS);2262break;2263case Type::Pointer:2264AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();2265Width = Target->getPointerWidth(AS);2266Align = Target->getPointerAlign(AS);2267break;2268case Type::MemberPointer: {2269const auto *MPT = cast<MemberPointerType>(T);2270CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT);2271Width = MPI.Width;2272Align = MPI.Align;2273break;2274}2275case Type::Complex: {2276// Complex types have the same alignment as their elements, but twice the2277// size.2278TypeInfo EltInfo = getTypeInfo(cast<ComplexType>(T)->getElementType());2279Width = EltInfo.Width * 2;2280Align = EltInfo.Align;2281break;2282}2283case Type::ObjCObject:2284return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());2285case Type::Adjusted:2286case Type::Decayed:2287return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());2288case Type::ObjCInterface: {2289const auto *ObjCI = cast<ObjCInterfaceType>(T);2290if (ObjCI->getDecl()->isInvalidDecl()) {2291Width = 8;2292Align = 8;2293break;2294}2295const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());2296Width = toBits(Layout.getSize());2297Align = toBits(Layout.getAlignment());2298break;2299}2300case Type::BitInt: {2301const auto *EIT = cast<BitIntType>(T);2302Align = Target->getBitIntAlign(EIT->getNumBits());2303Width = Target->getBitIntWidth(EIT->getNumBits());2304break;2305}2306case Type::Record:2307case Type::Enum: {2308const auto *TT = cast<TagType>(T);23092310if (TT->getDecl()->isInvalidDecl()) {2311Width = 8;2312Align = 8;2313break;2314}23152316if (const auto *ET = dyn_cast<EnumType>(TT)) {2317const EnumDecl *ED = ET->getDecl();2318TypeInfo Info =2319getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType());2320if (unsigned AttrAlign = ED->getMaxAlignment()) {2321Info.Align = AttrAlign;2322Info.AlignRequirement = AlignRequirementKind::RequiredByEnum;2323}2324return Info;2325}23262327const auto *RT = cast<RecordType>(TT);2328const RecordDecl *RD = RT->getDecl();2329const ASTRecordLayout &Layout = getASTRecordLayout(RD);2330Width = toBits(Layout.getSize());2331Align = toBits(Layout.getAlignment());2332AlignRequirement = RD->hasAttr<AlignedAttr>()2333? AlignRequirementKind::RequiredByRecord2334: AlignRequirementKind::None;2335break;2336}23372338case Type::SubstTemplateTypeParm:2339return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->2340getReplacementType().getTypePtr());23412342case Type::Auto:2343case Type::DeducedTemplateSpecialization: {2344const auto *A = cast<DeducedType>(T);2345assert(!A->getDeducedType().isNull() &&2346"cannot request the size of an undeduced or dependent auto type");2347return getTypeInfo(A->getDeducedType().getTypePtr());2348}23492350case Type::Paren:2351return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());23522353case Type::MacroQualified:2354return getTypeInfo(2355cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr());23562357case Type::ObjCTypeParam:2358return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());23592360case Type::Using:2361return getTypeInfo(cast<UsingType>(T)->desugar().getTypePtr());23622363case Type::Typedef: {2364const auto *TT = cast<TypedefType>(T);2365TypeInfo Info = getTypeInfo(TT->desugar().getTypePtr());2366// If the typedef has an aligned attribute on it, it overrides any computed2367// alignment we have. This violates the GCC documentation (which says that2368// attribute(aligned) can only round up) but matches its implementation.2369if (unsigned AttrAlign = TT->getDecl()->getMaxAlignment()) {2370Align = AttrAlign;2371AlignRequirement = AlignRequirementKind::RequiredByTypedef;2372} else {2373Align = Info.Align;2374AlignRequirement = Info.AlignRequirement;2375}2376Width = Info.Width;2377break;2378}23792380case Type::Elaborated:2381return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());23822383case Type::Attributed:2384return getTypeInfo(2385cast<AttributedType>(T)->getEquivalentType().getTypePtr());23862387case Type::CountAttributed:2388return getTypeInfo(cast<CountAttributedType>(T)->desugar().getTypePtr());23892390case Type::BTFTagAttributed:2391return getTypeInfo(2392cast<BTFTagAttributedType>(T)->getWrappedType().getTypePtr());23932394case Type::Atomic: {2395// Start with the base type information.2396TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType());2397Width = Info.Width;2398Align = Info.Align;23992400if (!Width) {2401// An otherwise zero-sized type should still generate an2402// atomic operation.2403Width = Target->getCharWidth();2404assert(Align);2405} else if (Width <= Target->getMaxAtomicPromoteWidth()) {2406// If the size of the type doesn't exceed the platform's max2407// atomic promotion width, make the size and alignment more2408// favorable to atomic operations:24092410// Round the size up to a power of 2.2411Width = llvm::bit_ceil(Width);24122413// Set the alignment equal to the size.2414Align = static_cast<unsigned>(Width);2415}2416}2417break;24182419case Type::Pipe:2420Width = Target->getPointerWidth(LangAS::opencl_global);2421Align = Target->getPointerAlign(LangAS::opencl_global);2422break;2423}24242425assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2");2426return TypeInfo(Width, Align, AlignRequirement);2427}24282429unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {2430UnadjustedAlignMap::iterator I = MemoizedUnadjustedAlign.find(T);2431if (I != MemoizedUnadjustedAlign.end())2432return I->second;24332434unsigned UnadjustedAlign;2435if (const auto *RT = T->getAs<RecordType>()) {2436const RecordDecl *RD = RT->getDecl();2437const ASTRecordLayout &Layout = getASTRecordLayout(RD);2438UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());2439} else if (const auto *ObjCI = T->getAs<ObjCInterfaceType>()) {2440const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());2441UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());2442} else {2443UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType());2444}24452446MemoizedUnadjustedAlign[T] = UnadjustedAlign;2447return UnadjustedAlign;2448}24492450unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const {2451unsigned SimdAlign = llvm::OpenMPIRBuilder::getOpenMPDefaultSimdAlign(2452getTargetInfo().getTriple(), Target->getTargetOpts().FeatureMap);2453return SimdAlign;2454}24552456/// toCharUnitsFromBits - Convert a size in bits to a size in characters.2457CharUnits ASTContext::toCharUnitsFromBits(int64_t BitSize) const {2458return CharUnits::fromQuantity(BitSize / getCharWidth());2459}24602461/// toBits - Convert a size in characters to a size in characters.2462int64_t ASTContext::toBits(CharUnits CharSize) const {2463return CharSize.getQuantity() * getCharWidth();2464}24652466/// getTypeSizeInChars - Return the size of the specified type, in characters.2467/// This method does not work on incomplete types.2468CharUnits ASTContext::getTypeSizeInChars(QualType T) const {2469return getTypeInfoInChars(T).Width;2470}2471CharUnits ASTContext::getTypeSizeInChars(const Type *T) const {2472return getTypeInfoInChars(T).Width;2473}24742475/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in2476/// characters. This method does not work on incomplete types.2477CharUnits ASTContext::getTypeAlignInChars(QualType T) const {2478return toCharUnitsFromBits(getTypeAlign(T));2479}2480CharUnits ASTContext::getTypeAlignInChars(const Type *T) const {2481return toCharUnitsFromBits(getTypeAlign(T));2482}24832484/// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a2485/// type, in characters, before alignment adjustments. This method does2486/// not work on incomplete types.2487CharUnits ASTContext::getTypeUnadjustedAlignInChars(QualType T) const {2488return toCharUnitsFromBits(getTypeUnadjustedAlign(T));2489}2490CharUnits ASTContext::getTypeUnadjustedAlignInChars(const Type *T) const {2491return toCharUnitsFromBits(getTypeUnadjustedAlign(T));2492}24932494/// getPreferredTypeAlign - Return the "preferred" alignment of the specified2495/// type for the current target in bits. This can be different than the ABI2496/// alignment in cases where it is beneficial for performance or backwards2497/// compatibility preserving to overalign a data type. (Note: despite the name,2498/// the preferred alignment is ABI-impacting, and not an optimization.)2499unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {2500TypeInfo TI = getTypeInfo(T);2501unsigned ABIAlign = TI.Align;25022503T = T->getBaseElementTypeUnsafe();25042505// The preferred alignment of member pointers is that of a pointer.2506if (T->isMemberPointerType())2507return getPreferredTypeAlign(getPointerDiffType().getTypePtr());25082509if (!Target->allowsLargerPreferedTypeAlignment())2510return ABIAlign;25112512if (const auto *RT = T->getAs<RecordType>()) {2513const RecordDecl *RD = RT->getDecl();25142515// When used as part of a typedef, or together with a 'packed' attribute,2516// the 'aligned' attribute can be used to decrease alignment. Note that the2517// 'packed' case is already taken into consideration when computing the2518// alignment, we only need to handle the typedef case here.2519if (TI.AlignRequirement == AlignRequirementKind::RequiredByTypedef ||2520RD->isInvalidDecl())2521return ABIAlign;25222523unsigned PreferredAlign = static_cast<unsigned>(2524toBits(getASTRecordLayout(RD).PreferredAlignment));2525assert(PreferredAlign >= ABIAlign &&2526"PreferredAlign should be at least as large as ABIAlign.");2527return PreferredAlign;2528}25292530// Double (and, for targets supporting AIX `power` alignment, long double) and2531// long long should be naturally aligned (despite requiring less alignment) if2532// possible.2533if (const auto *CT = T->getAs<ComplexType>())2534T = CT->getElementType().getTypePtr();2535if (const auto *ET = T->getAs<EnumType>())2536T = ET->getDecl()->getIntegerType().getTypePtr();2537if (T->isSpecificBuiltinType(BuiltinType::Double) ||2538T->isSpecificBuiltinType(BuiltinType::LongLong) ||2539T->isSpecificBuiltinType(BuiltinType::ULongLong) ||2540(T->isSpecificBuiltinType(BuiltinType::LongDouble) &&2541Target->defaultsToAIXPowerAlignment()))2542// Don't increase the alignment if an alignment attribute was specified on a2543// typedef declaration.2544if (!TI.isAlignRequired())2545return std::max(ABIAlign, (unsigned)getTypeSize(T));25462547return ABIAlign;2548}25492550/// getTargetDefaultAlignForAttributeAligned - Return the default alignment2551/// for __attribute__((aligned)) on this target, to be used if no alignment2552/// value is specified.2553unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {2554return getTargetInfo().getDefaultAlignForAttributeAligned();2555}25562557/// getAlignOfGlobalVar - Return the alignment in bits that should be given2558/// to a global variable of the specified type.2559unsigned ASTContext::getAlignOfGlobalVar(QualType T, const VarDecl *VD) const {2560uint64_t TypeSize = getTypeSize(T.getTypePtr());2561return std::max(getPreferredTypeAlign(T),2562getMinGlobalAlignOfVar(TypeSize, VD));2563}25642565/// getAlignOfGlobalVarInChars - Return the alignment in characters that2566/// should be given to a global variable of the specified type.2567CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T,2568const VarDecl *VD) const {2569return toCharUnitsFromBits(getAlignOfGlobalVar(T, VD));2570}25712572unsigned ASTContext::getMinGlobalAlignOfVar(uint64_t Size,2573const VarDecl *VD) const {2574// Make the default handling as that of a non-weak definition in the2575// current translation unit.2576bool HasNonWeakDef = !VD || (VD->hasDefinition() && !VD->isWeak());2577return getTargetInfo().getMinGlobalAlign(Size, HasNonWeakDef);2578}25792580CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const {2581CharUnits Offset = CharUnits::Zero();2582const ASTRecordLayout *Layout = &getASTRecordLayout(RD);2583while (const CXXRecordDecl *Base = Layout->getBaseSharingVBPtr()) {2584Offset += Layout->getBaseClassOffset(Base);2585Layout = &getASTRecordLayout(Base);2586}2587return Offset;2588}25892590CharUnits ASTContext::getMemberPointerPathAdjustment(const APValue &MP) const {2591const ValueDecl *MPD = MP.getMemberPointerDecl();2592CharUnits ThisAdjustment = CharUnits::Zero();2593ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();2594bool DerivedMember = MP.isMemberPointerToDerivedMember();2595const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());2596for (unsigned I = 0, N = Path.size(); I != N; ++I) {2597const CXXRecordDecl *Base = RD;2598const CXXRecordDecl *Derived = Path[I];2599if (DerivedMember)2600std::swap(Base, Derived);2601ThisAdjustment += getASTRecordLayout(Derived).getBaseClassOffset(Base);2602RD = Path[I];2603}2604if (DerivedMember)2605ThisAdjustment = -ThisAdjustment;2606return ThisAdjustment;2607}26082609/// DeepCollectObjCIvars -2610/// This routine first collects all declared, but not synthesized, ivars in2611/// super class and then collects all ivars, including those synthesized for2612/// current class. This routine is used for implementation of current class2613/// when all ivars, declared and synthesized are known.2614void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,2615bool leafClass,2616SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const {2617if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())2618DeepCollectObjCIvars(SuperClass, false, Ivars);2619if (!leafClass) {2620llvm::append_range(Ivars, OI->ivars());2621} else {2622auto *IDecl = const_cast<ObjCInterfaceDecl *>(OI);2623for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;2624Iv= Iv->getNextIvar())2625Ivars.push_back(Iv);2626}2627}26282629/// CollectInheritedProtocols - Collect all protocols in current class and2630/// those inherited by it.2631void ASTContext::CollectInheritedProtocols(const Decl *CDecl,2632llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) {2633if (const auto *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {2634// We can use protocol_iterator here instead of2635// all_referenced_protocol_iterator since we are walking all categories.2636for (auto *Proto : OI->all_referenced_protocols()) {2637CollectInheritedProtocols(Proto, Protocols);2638}26392640// Categories of this Interface.2641for (const auto *Cat : OI->visible_categories())2642CollectInheritedProtocols(Cat, Protocols);26432644if (ObjCInterfaceDecl *SD = OI->getSuperClass())2645while (SD) {2646CollectInheritedProtocols(SD, Protocols);2647SD = SD->getSuperClass();2648}2649} else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {2650for (auto *Proto : OC->protocols()) {2651CollectInheritedProtocols(Proto, Protocols);2652}2653} else if (const auto *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {2654// Insert the protocol.2655if (!Protocols.insert(2656const_cast<ObjCProtocolDecl *>(OP->getCanonicalDecl())).second)2657return;26582659for (auto *Proto : OP->protocols())2660CollectInheritedProtocols(Proto, Protocols);2661}2662}26632664static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,2665const RecordDecl *RD,2666bool CheckIfTriviallyCopyable) {2667assert(RD->isUnion() && "Must be union type");2668CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl());26692670for (const auto *Field : RD->fields()) {2671if (!Context.hasUniqueObjectRepresentations(Field->getType(),2672CheckIfTriviallyCopyable))2673return false;2674CharUnits FieldSize = Context.getTypeSizeInChars(Field->getType());2675if (FieldSize != UnionSize)2676return false;2677}2678return !RD->field_empty();2679}26802681static int64_t getSubobjectOffset(const FieldDecl *Field,2682const ASTContext &Context,2683const clang::ASTRecordLayout & /*Layout*/) {2684return Context.getFieldOffset(Field);2685}26862687static int64_t getSubobjectOffset(const CXXRecordDecl *RD,2688const ASTContext &Context,2689const clang::ASTRecordLayout &Layout) {2690return Context.toBits(Layout.getBaseClassOffset(RD));2691}26922693static std::optional<int64_t>2694structHasUniqueObjectRepresentations(const ASTContext &Context,2695const RecordDecl *RD,2696bool CheckIfTriviallyCopyable);26972698static std::optional<int64_t>2699getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,2700bool CheckIfTriviallyCopyable) {2701if (Field->getType()->isRecordType()) {2702const RecordDecl *RD = Field->getType()->getAsRecordDecl();2703if (!RD->isUnion())2704return structHasUniqueObjectRepresentations(Context, RD,2705CheckIfTriviallyCopyable);2706}27072708// A _BitInt type may not be unique if it has padding bits2709// but if it is a bitfield the padding bits are not used.2710bool IsBitIntType = Field->getType()->isBitIntType();2711if (!Field->getType()->isReferenceType() && !IsBitIntType &&2712!Context.hasUniqueObjectRepresentations(Field->getType(),2713CheckIfTriviallyCopyable))2714return std::nullopt;27152716int64_t FieldSizeInBits =2717Context.toBits(Context.getTypeSizeInChars(Field->getType()));2718if (Field->isBitField()) {2719// If we have explicit padding bits, they don't contribute bits2720// to the actual object representation, so return 0.2721if (Field->isUnnamedBitField())2722return 0;27232724int64_t BitfieldSize = Field->getBitWidthValue(Context);2725if (IsBitIntType) {2726if ((unsigned)BitfieldSize >2727cast<BitIntType>(Field->getType())->getNumBits())2728return std::nullopt;2729} else if (BitfieldSize > FieldSizeInBits) {2730return std::nullopt;2731}2732FieldSizeInBits = BitfieldSize;2733} else if (IsBitIntType && !Context.hasUniqueObjectRepresentations(2734Field->getType(), CheckIfTriviallyCopyable)) {2735return std::nullopt;2736}2737return FieldSizeInBits;2738}27392740static std::optional<int64_t>2741getSubobjectSizeInBits(const CXXRecordDecl *RD, const ASTContext &Context,2742bool CheckIfTriviallyCopyable) {2743return structHasUniqueObjectRepresentations(Context, RD,2744CheckIfTriviallyCopyable);2745}27462747template <typename RangeT>2748static std::optional<int64_t> structSubobjectsHaveUniqueObjectRepresentations(2749const RangeT &Subobjects, int64_t CurOffsetInBits,2750const ASTContext &Context, const clang::ASTRecordLayout &Layout,2751bool CheckIfTriviallyCopyable) {2752for (const auto *Subobject : Subobjects) {2753std::optional<int64_t> SizeInBits =2754getSubobjectSizeInBits(Subobject, Context, CheckIfTriviallyCopyable);2755if (!SizeInBits)2756return std::nullopt;2757if (*SizeInBits != 0) {2758int64_t Offset = getSubobjectOffset(Subobject, Context, Layout);2759if (Offset != CurOffsetInBits)2760return std::nullopt;2761CurOffsetInBits += *SizeInBits;2762}2763}2764return CurOffsetInBits;2765}27662767static std::optional<int64_t>2768structHasUniqueObjectRepresentations(const ASTContext &Context,2769const RecordDecl *RD,2770bool CheckIfTriviallyCopyable) {2771assert(!RD->isUnion() && "Must be struct/class type");2772const auto &Layout = Context.getASTRecordLayout(RD);27732774int64_t CurOffsetInBits = 0;2775if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) {2776if (ClassDecl->isDynamicClass())2777return std::nullopt;27782779SmallVector<CXXRecordDecl *, 4> Bases;2780for (const auto &Base : ClassDecl->bases()) {2781// Empty types can be inherited from, and non-empty types can potentially2782// have tail padding, so just make sure there isn't an error.2783Bases.emplace_back(Base.getType()->getAsCXXRecordDecl());2784}27852786llvm::sort(Bases, [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {2787return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);2788});27892790std::optional<int64_t> OffsetAfterBases =2791structSubobjectsHaveUniqueObjectRepresentations(2792Bases, CurOffsetInBits, Context, Layout, CheckIfTriviallyCopyable);2793if (!OffsetAfterBases)2794return std::nullopt;2795CurOffsetInBits = *OffsetAfterBases;2796}27972798std::optional<int64_t> OffsetAfterFields =2799structSubobjectsHaveUniqueObjectRepresentations(2800RD->fields(), CurOffsetInBits, Context, Layout,2801CheckIfTriviallyCopyable);2802if (!OffsetAfterFields)2803return std::nullopt;2804CurOffsetInBits = *OffsetAfterFields;28052806return CurOffsetInBits;2807}28082809bool ASTContext::hasUniqueObjectRepresentations(2810QualType Ty, bool CheckIfTriviallyCopyable) const {2811// C++17 [meta.unary.prop]:2812// The predicate condition for a template specialization2813// has_unique_object_representations<T> shall be satisfied if and only if:2814// (9.1) - T is trivially copyable, and2815// (9.2) - any two objects of type T with the same value have the same2816// object representation, where:2817// - two objects of array or non-union class type are considered to have2818// the same value if their respective sequences of direct subobjects2819// have the same values, and2820// - two objects of union type are considered to have the same value if2821// they have the same active member and the corresponding members have2822// the same value.2823// The set of scalar types for which this condition holds is2824// implementation-defined. [ Note: If a type has padding bits, the condition2825// does not hold; otherwise, the condition holds true for unsigned integral2826// types. -- end note ]2827assert(!Ty.isNull() && "Null QualType sent to unique object rep check");28282829// Arrays are unique only if their element type is unique.2830if (Ty->isArrayType())2831return hasUniqueObjectRepresentations(getBaseElementType(Ty),2832CheckIfTriviallyCopyable);28332834assert((Ty->isVoidType() || !Ty->isIncompleteType()) &&2835"hasUniqueObjectRepresentations should not be called with an "2836"incomplete type");28372838// (9.1) - T is trivially copyable...2839if (CheckIfTriviallyCopyable && !Ty.isTriviallyCopyableType(*this))2840return false;28412842// All integrals and enums are unique.2843if (Ty->isIntegralOrEnumerationType()) {2844// Except _BitInt types that have padding bits.2845if (const auto *BIT = Ty->getAs<BitIntType>())2846return getTypeSize(BIT) == BIT->getNumBits();28472848return true;2849}28502851// All other pointers are unique.2852if (Ty->isPointerType())2853return true;28542855if (const auto *MPT = Ty->getAs<MemberPointerType>())2856return !ABI->getMemberPointerInfo(MPT).HasPadding;28572858if (Ty->isRecordType()) {2859const RecordDecl *Record = Ty->castAs<RecordType>()->getDecl();28602861if (Record->isInvalidDecl())2862return false;28632864if (Record->isUnion())2865return unionHasUniqueObjectRepresentations(*this, Record,2866CheckIfTriviallyCopyable);28672868std::optional<int64_t> StructSize = structHasUniqueObjectRepresentations(2869*this, Record, CheckIfTriviallyCopyable);28702871return StructSize && *StructSize == static_cast<int64_t>(getTypeSize(Ty));2872}28732874// FIXME: More cases to handle here (list by rsmith):2875// vectors (careful about, eg, vector of 3 foo)2876// _Complex int and friends2877// _Atomic T2878// Obj-C block pointers2879// Obj-C object pointers2880// and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t,2881// clk_event_t, queue_t, reserve_id_t)2882// There're also Obj-C class types and the Obj-C selector type, but I think it2883// makes sense for those to return false here.28842885return false;2886}28872888unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {2889unsigned count = 0;2890// Count ivars declared in class extension.2891for (const auto *Ext : OI->known_extensions())2892count += Ext->ivar_size();28932894// Count ivar defined in this class's implementation. This2895// includes synthesized ivars.2896if (ObjCImplementationDecl *ImplDecl = OI->getImplementation())2897count += ImplDecl->ivar_size();28982899return count;2900}29012902bool ASTContext::isSentinelNullExpr(const Expr *E) {2903if (!E)2904return false;29052906// nullptr_t is always treated as null.2907if (E->getType()->isNullPtrType()) return true;29082909if (E->getType()->isAnyPointerType() &&2910E->IgnoreParenCasts()->isNullPointerConstant(*this,2911Expr::NPC_ValueDependentIsNull))2912return true;29132914// Unfortunately, __null has type 'int'.2915if (isa<GNUNullExpr>(E)) return true;29162917return false;2918}29192920/// Get the implementation of ObjCInterfaceDecl, or nullptr if none2921/// exists.2922ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {2923llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator2924I = ObjCImpls.find(D);2925if (I != ObjCImpls.end())2926return cast<ObjCImplementationDecl>(I->second);2927return nullptr;2928}29292930/// Get the implementation of ObjCCategoryDecl, or nullptr if none2931/// exists.2932ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {2933llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator2934I = ObjCImpls.find(D);2935if (I != ObjCImpls.end())2936return cast<ObjCCategoryImplDecl>(I->second);2937return nullptr;2938}29392940/// Set the implementation of ObjCInterfaceDecl.2941void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,2942ObjCImplementationDecl *ImplD) {2943assert(IFaceD && ImplD && "Passed null params");2944ObjCImpls[IFaceD] = ImplD;2945}29462947/// Set the implementation of ObjCCategoryDecl.2948void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,2949ObjCCategoryImplDecl *ImplD) {2950assert(CatD && ImplD && "Passed null params");2951ObjCImpls[CatD] = ImplD;2952}29532954const ObjCMethodDecl *2955ASTContext::getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const {2956return ObjCMethodRedecls.lookup(MD);2957}29582959void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD,2960const ObjCMethodDecl *Redecl) {2961assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration");2962ObjCMethodRedecls[MD] = Redecl;2963}29642965const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(2966const NamedDecl *ND) const {2967if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext()))2968return ID;2969if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND->getDeclContext()))2970return CD->getClassInterface();2971if (const auto *IMD = dyn_cast<ObjCImplDecl>(ND->getDeclContext()))2972return IMD->getClassInterface();29732974return nullptr;2975}29762977/// Get the copy initialization expression of VarDecl, or nullptr if2978/// none exists.2979BlockVarCopyInit ASTContext::getBlockVarCopyInit(const VarDecl *VD) const {2980assert(VD && "Passed null params");2981assert(VD->hasAttr<BlocksAttr>() &&2982"getBlockVarCopyInits - not __block var");2983auto I = BlockVarCopyInits.find(VD);2984if (I != BlockVarCopyInits.end())2985return I->second;2986return {nullptr, false};2987}29882989/// Set the copy initialization expression of a block var decl.2990void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr,2991bool CanThrow) {2992assert(VD && CopyExpr && "Passed null params");2993assert(VD->hasAttr<BlocksAttr>() &&2994"setBlockVarCopyInits - not __block var");2995BlockVarCopyInits[VD].setExprAndFlag(CopyExpr, CanThrow);2996}29972998TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,2999unsigned DataSize) const {3000if (!DataSize)3001DataSize = TypeLoc::getFullDataSizeForType(T);3002else3003assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&3004"incorrect data size provided to CreateTypeSourceInfo!");30053006auto *TInfo =3007(TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);3008new (TInfo) TypeSourceInfo(T, DataSize);3009return TInfo;3010}30113012TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,3013SourceLocation L) const {3014TypeSourceInfo *DI = CreateTypeSourceInfo(T);3015DI->getTypeLoc().initialize(const_cast<ASTContext &>(*this), L);3016return DI;3017}30183019const ASTRecordLayout &3020ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const {3021return getObjCLayout(D, nullptr);3022}30233024const ASTRecordLayout &3025ASTContext::getASTObjCImplementationLayout(3026const ObjCImplementationDecl *D) const {3027return getObjCLayout(D->getClassInterface(), D);3028}30293030static auto getCanonicalTemplateArguments(const ASTContext &C,3031ArrayRef<TemplateArgument> Args,3032bool &AnyNonCanonArgs) {3033SmallVector<TemplateArgument, 16> CanonArgs(Args);3034for (auto &Arg : CanonArgs) {3035TemplateArgument OrigArg = Arg;3036Arg = C.getCanonicalTemplateArgument(Arg);3037AnyNonCanonArgs |= !Arg.structurallyEquals(OrigArg);3038}3039return CanonArgs;3040}30413042//===----------------------------------------------------------------------===//3043// Type creation/memoization methods3044//===----------------------------------------------------------------------===//30453046QualType3047ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {3048unsigned fastQuals = quals.getFastQualifiers();3049quals.removeFastQualifiers();30503051// Check if we've already instantiated this type.3052llvm::FoldingSetNodeID ID;3053ExtQuals::Profile(ID, baseType, quals);3054void *insertPos = nullptr;3055if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) {3056assert(eq->getQualifiers() == quals);3057return QualType(eq, fastQuals);3058}30593060// If the base type is not canonical, make the appropriate canonical type.3061QualType canon;3062if (!baseType->isCanonicalUnqualified()) {3063SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split();3064canonSplit.Quals.addConsistentQualifiers(quals);3065canon = getExtQualType(canonSplit.Ty, canonSplit.Quals);30663067// Re-find the insert position.3068(void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos);3069}30703071auto *eq = new (*this, alignof(ExtQuals)) ExtQuals(baseType, canon, quals);3072ExtQualNodes.InsertNode(eq, insertPos);3073return QualType(eq, fastQuals);3074}30753076QualType ASTContext::getAddrSpaceQualType(QualType T,3077LangAS AddressSpace) const {3078QualType CanT = getCanonicalType(T);3079if (CanT.getAddressSpace() == AddressSpace)3080return T;30813082// If we are composing extended qualifiers together, merge together3083// into one ExtQuals node.3084QualifierCollector Quals;3085const Type *TypeNode = Quals.strip(T);30863087// If this type already has an address space specified, it cannot get3088// another one.3089assert(!Quals.hasAddressSpace() &&3090"Type cannot be in multiple addr spaces!");3091Quals.addAddressSpace(AddressSpace);30923093return getExtQualType(TypeNode, Quals);3094}30953096QualType ASTContext::removeAddrSpaceQualType(QualType T) const {3097// If the type is not qualified with an address space, just return it3098// immediately.3099if (!T.hasAddressSpace())3100return T;31013102QualifierCollector Quals;3103const Type *TypeNode;3104// For arrays, strip the qualifier off the element type, then reconstruct the3105// array type3106if (T.getTypePtr()->isArrayType()) {3107T = getUnqualifiedArrayType(T, Quals);3108TypeNode = T.getTypePtr();3109} else {3110// If we are composing extended qualifiers together, merge together3111// into one ExtQuals node.3112while (T.hasAddressSpace()) {3113TypeNode = Quals.strip(T);31143115// If the type no longer has an address space after stripping qualifiers,3116// jump out.3117if (!QualType(TypeNode, 0).hasAddressSpace())3118break;31193120// There might be sugar in the way. Strip it and try again.3121T = T.getSingleStepDesugaredType(*this);3122}3123}31243125Quals.removeAddressSpace();31263127// Removal of the address space can mean there are no longer any3128// non-fast qualifiers, so creating an ExtQualType isn't possible (asserts)3129// or required.3130if (Quals.hasNonFastQualifiers())3131return getExtQualType(TypeNode, Quals);3132else3133return QualType(TypeNode, Quals.getFastQualifiers());3134}31353136uint16_t3137ASTContext::getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD) {3138assert(RD->isPolymorphic() &&3139"Attempted to get vtable pointer discriminator on a monomorphic type");3140std::unique_ptr<MangleContext> MC(createMangleContext());3141SmallString<256> Str;3142llvm::raw_svector_ostream Out(Str);3143MC->mangleCXXVTable(RD, Out);3144return llvm::getPointerAuthStableSipHash(Str);3145}31463147/// Encode a function type for use in the discriminator of a function pointer3148/// type. We can't use the itanium scheme for this since C has quite permissive3149/// rules for type compatibility that we need to be compatible with.3150///3151/// Formally, this function associates every function pointer type T with an3152/// encoded string E(T). Let the equivalence relation T1 ~ T2 be defined as3153/// E(T1) == E(T2). E(T) is part of the ABI of values of type T. C type3154/// compatibility requires equivalent treatment under the ABI, so3155/// CCompatible(T1, T2) must imply E(T1) == E(T2), that is, CCompatible must be3156/// a subset of ~. Crucially, however, it must be a proper subset because3157/// CCompatible is not an equivalence relation: for example, int[] is compatible3158/// with both int[1] and int[2], but the latter are not compatible with each3159/// other. Therefore this encoding function must be careful to only distinguish3160/// types if there is no third type with which they are both required to be3161/// compatible.3162static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,3163raw_ostream &OS, QualType QT) {3164// FIXME: Consider address space qualifiers.3165const Type *T = QT.getCanonicalType().getTypePtr();31663167// FIXME: Consider using the C++ type mangling when we encounter a construct3168// that is incompatible with C.31693170switch (T->getTypeClass()) {3171case Type::Atomic:3172return encodeTypeForFunctionPointerAuth(3173Ctx, OS, cast<AtomicType>(T)->getValueType());31743175case Type::LValueReference:3176OS << "R";3177encodeTypeForFunctionPointerAuth(Ctx, OS,3178cast<ReferenceType>(T)->getPointeeType());3179return;3180case Type::RValueReference:3181OS << "O";3182encodeTypeForFunctionPointerAuth(Ctx, OS,3183cast<ReferenceType>(T)->getPointeeType());3184return;31853186case Type::Pointer:3187// C11 6.7.6.1p2:3188// For two pointer types to be compatible, both shall be identically3189// qualified and both shall be pointers to compatible types.3190// FIXME: we should also consider pointee types.3191OS << "P";3192return;31933194case Type::ObjCObjectPointer:3195case Type::BlockPointer:3196OS << "P";3197return;31983199case Type::Complex:3200OS << "C";3201return encodeTypeForFunctionPointerAuth(3202Ctx, OS, cast<ComplexType>(T)->getElementType());32033204case Type::VariableArray:3205case Type::ConstantArray:3206case Type::IncompleteArray:3207case Type::ArrayParameter:3208// C11 6.7.6.2p6:3209// For two array types to be compatible, both shall have compatible3210// element types, and if both size specifiers are present, and are integer3211// constant expressions, then both size specifiers shall have the same3212// constant value [...]3213//3214// So since ElemType[N] has to be compatible ElemType[], we can't encode the3215// width of the array.3216OS << "A";3217return encodeTypeForFunctionPointerAuth(3218Ctx, OS, cast<ArrayType>(T)->getElementType());32193220case Type::ObjCInterface:3221case Type::ObjCObject:3222OS << "<objc_object>";3223return;32243225case Type::Enum: {3226// C11 6.7.2.2p4:3227// Each enumerated type shall be compatible with char, a signed integer3228// type, or an unsigned integer type.3229//3230// So we have to treat enum types as integers.3231QualType UnderlyingType = cast<EnumType>(T)->getDecl()->getIntegerType();3232return encodeTypeForFunctionPointerAuth(3233Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType);3234}32353236case Type::FunctionNoProto:3237case Type::FunctionProto: {3238// C11 6.7.6.3p15:3239// For two function types to be compatible, both shall specify compatible3240// return types. Moreover, the parameter type lists, if both are present,3241// shall agree in the number of parameters and in the use of the ellipsis3242// terminator; corresponding parameters shall have compatible types.3243//3244// That paragraph goes on to describe how unprototyped functions are to be3245// handled, which we ignore here. Unprototyped function pointers are hashed3246// as though they were prototyped nullary functions since thats probably3247// what the user meant. This behavior is non-conforming.3248// FIXME: If we add a "custom discriminator" function type attribute we3249// should encode functions as their discriminators.3250OS << "F";3251const auto *FuncType = cast<FunctionType>(T);3252encodeTypeForFunctionPointerAuth(Ctx, OS, FuncType->getReturnType());3253if (const auto *FPT = dyn_cast<FunctionProtoType>(FuncType)) {3254for (QualType Param : FPT->param_types()) {3255Param = Ctx.getSignatureParameterType(Param);3256encodeTypeForFunctionPointerAuth(Ctx, OS, Param);3257}3258if (FPT->isVariadic())3259OS << "z";3260}3261OS << "E";3262return;3263}32643265case Type::MemberPointer: {3266OS << "M";3267const auto *MPT = T->getAs<MemberPointerType>();3268encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));3269encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());3270return;3271}3272case Type::ExtVector:3273case Type::Vector:3274OS << "Dv" << Ctx.getTypeSizeInChars(T).getQuantity();3275break;32763277// Don't bother discriminating based on these types.3278case Type::Pipe:3279case Type::BitInt:3280case Type::ConstantMatrix:3281OS << "?";3282return;32833284case Type::Builtin: {3285const auto *BTy = T->getAs<BuiltinType>();3286switch (BTy->getKind()) {3287#define SIGNED_TYPE(Id, SingletonId) \3288case BuiltinType::Id: \3289OS << "i"; \3290return;3291#define UNSIGNED_TYPE(Id, SingletonId) \3292case BuiltinType::Id: \3293OS << "i"; \3294return;3295#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:3296#define BUILTIN_TYPE(Id, SingletonId)3297#include "clang/AST/BuiltinTypes.def"3298llvm_unreachable("placeholder types should not appear here.");32993300case BuiltinType::Half:3301OS << "Dh";3302return;3303case BuiltinType::Float:3304OS << "f";3305return;3306case BuiltinType::Double:3307OS << "d";3308return;3309case BuiltinType::LongDouble:3310OS << "e";3311return;3312case BuiltinType::Float16:3313OS << "DF16_";3314return;3315case BuiltinType::Float128:3316OS << "g";3317return;33183319case BuiltinType::Void:3320OS << "v";3321return;33223323case BuiltinType::ObjCId:3324case BuiltinType::ObjCClass:3325case BuiltinType::ObjCSel:3326case BuiltinType::NullPtr:3327OS << "P";3328return;33293330// Don't bother discriminating based on OpenCL types.3331case BuiltinType::OCLSampler:3332case BuiltinType::OCLEvent:3333case BuiltinType::OCLClkEvent:3334case BuiltinType::OCLQueue:3335case BuiltinType::OCLReserveID:3336case BuiltinType::BFloat16:3337case BuiltinType::VectorQuad:3338case BuiltinType::VectorPair:3339OS << "?";3340return;33413342// Don't bother discriminating based on these seldom-used types.3343case BuiltinType::Ibm128:3344return;3345#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \3346case BuiltinType::Id: \3347return;3348#include "clang/Basic/OpenCLImageTypes.def"3349#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \3350case BuiltinType::Id: \3351return;3352#include "clang/Basic/OpenCLExtensionTypes.def"3353#define SVE_TYPE(Name, Id, SingletonId) \3354case BuiltinType::Id: \3355return;3356#include "clang/Basic/AArch64SVEACLETypes.def"3357case BuiltinType::Dependent:3358llvm_unreachable("should never get here");3359case BuiltinType::AMDGPUBufferRsrc:3360case BuiltinType::WasmExternRef:3361#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:3362#include "clang/Basic/RISCVVTypes.def"3363llvm_unreachable("not yet implemented");3364}3365}3366case Type::Record: {3367const RecordDecl *RD = T->getAs<RecordType>()->getDecl();3368const IdentifierInfo *II = RD->getIdentifier();33693370// In C++, an immediate typedef of an anonymous struct or union3371// is considered to name it for ODR purposes, but C's specification3372// of type compatibility does not have a similar rule. Using the typedef3373// name in function type discriminators anyway, as we do here,3374// therefore technically violates the C standard: two function pointer3375// types defined in terms of two typedef'd anonymous structs with3376// different names are formally still compatible, but we are assigning3377// them different discriminators and therefore incompatible ABIs.3378//3379// This is a relatively minor violation that significantly improves3380// discrimination in some cases and has not caused problems in3381// practice. Regardless, it is now part of the ABI in places where3382// function type discrimination is used, and it can no longer be3383// changed except on new platforms.33843385if (!II)3386if (const TypedefNameDecl *Typedef = RD->getTypedefNameForAnonDecl())3387II = Typedef->getDeclName().getAsIdentifierInfo();33883389if (!II) {3390OS << "<anonymous_record>";3391return;3392}3393OS << II->getLength() << II->getName();3394return;3395}3396case Type::DeducedTemplateSpecialization:3397case Type::Auto:3398#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:3399#define DEPENDENT_TYPE(Class, Base) case Type::Class:3400#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:3401#define ABSTRACT_TYPE(Class, Base)3402#define TYPE(Class, Base)3403#include "clang/AST/TypeNodes.inc"3404llvm_unreachable("unexpected non-canonical or dependent type!");3405return;3406}3407}34083409uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {3410assert(!T->isDependentType() &&3411"cannot compute type discriminator of a dependent type");34123413SmallString<256> Str;3414llvm::raw_svector_ostream Out(Str);34153416if (T->isFunctionPointerType() || T->isFunctionReferenceType())3417T = T->getPointeeType();34183419if (T->isFunctionType()) {3420encodeTypeForFunctionPointerAuth(*this, Out, T);3421} else {3422T = T.getUnqualifiedType();3423std::unique_ptr<MangleContext> MC(createMangleContext());3424MC->mangleCanonicalTypeName(T, Out);3425}34263427return llvm::getPointerAuthStableSipHash(Str);3428}34293430QualType ASTContext::getObjCGCQualType(QualType T,3431Qualifiers::GC GCAttr) const {3432QualType CanT = getCanonicalType(T);3433if (CanT.getObjCGCAttr() == GCAttr)3434return T;34353436if (const auto *ptr = T->getAs<PointerType>()) {3437QualType Pointee = ptr->getPointeeType();3438if (Pointee->isAnyPointerType()) {3439QualType ResultType = getObjCGCQualType(Pointee, GCAttr);3440return getPointerType(ResultType);3441}3442}34433444// If we are composing extended qualifiers together, merge together3445// into one ExtQuals node.3446QualifierCollector Quals;3447const Type *TypeNode = Quals.strip(T);34483449// If this type already has an ObjCGC specified, it cannot get3450// another one.3451assert(!Quals.hasObjCGCAttr() &&3452"Type cannot have multiple ObjCGCs!");3453Quals.addObjCGCAttr(GCAttr);34543455return getExtQualType(TypeNode, Quals);3456}34573458QualType ASTContext::removePtrSizeAddrSpace(QualType T) const {3459if (const PointerType *Ptr = T->getAs<PointerType>()) {3460QualType Pointee = Ptr->getPointeeType();3461if (isPtrSizeAddressSpace(Pointee.getAddressSpace())) {3462return getPointerType(removeAddrSpaceQualType(Pointee));3463}3464}3465return T;3466}34673468QualType ASTContext::getCountAttributedType(3469QualType WrappedTy, Expr *CountExpr, bool CountInBytes, bool OrNull,3470ArrayRef<TypeCoupledDeclRefInfo> DependentDecls) const {3471assert(WrappedTy->isPointerType() || WrappedTy->isArrayType());34723473llvm::FoldingSetNodeID ID;3474CountAttributedType::Profile(ID, WrappedTy, CountExpr, CountInBytes, OrNull);34753476void *InsertPos = nullptr;3477CountAttributedType *CATy =3478CountAttributedTypes.FindNodeOrInsertPos(ID, InsertPos);3479if (CATy)3480return QualType(CATy, 0);34813482QualType CanonTy = getCanonicalType(WrappedTy);3483size_t Size = CountAttributedType::totalSizeToAlloc<TypeCoupledDeclRefInfo>(3484DependentDecls.size());3485CATy = (CountAttributedType *)Allocate(Size, TypeAlignment);3486new (CATy) CountAttributedType(WrappedTy, CanonTy, CountExpr, CountInBytes,3487OrNull, DependentDecls);3488Types.push_back(CATy);3489CountAttributedTypes.InsertNode(CATy, InsertPos);34903491return QualType(CATy, 0);3492}34933494const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,3495FunctionType::ExtInfo Info) {3496if (T->getExtInfo() == Info)3497return T;34983499QualType Result;3500if (const auto *FNPT = dyn_cast<FunctionNoProtoType>(T)) {3501Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);3502} else {3503const auto *FPT = cast<FunctionProtoType>(T);3504FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();3505EPI.ExtInfo = Info;3506Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);3507}35083509return cast<FunctionType>(Result.getTypePtr());3510}35113512void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,3513QualType ResultType) {3514FD = FD->getMostRecentDecl();3515while (true) {3516const auto *FPT = FD->getType()->castAs<FunctionProtoType>();3517FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();3518FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));3519if (FunctionDecl *Next = FD->getPreviousDecl())3520FD = Next;3521else3522break;3523}3524if (ASTMutationListener *L = getASTMutationListener())3525L->DeducedReturnType(FD, ResultType);3526}35273528/// Get a function type and produce the equivalent function type with the3529/// specified exception specification. Type sugar that can be present on a3530/// declaration of a function with an exception specification is permitted3531/// and preserved. Other type sugar (for instance, typedefs) is not.3532QualType ASTContext::getFunctionTypeWithExceptionSpec(3533QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const {3534// Might have some parens.3535if (const auto *PT = dyn_cast<ParenType>(Orig))3536return getParenType(3537getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));35383539// Might be wrapped in a macro qualified type.3540if (const auto *MQT = dyn_cast<MacroQualifiedType>(Orig))3541return getMacroQualifiedType(3542getFunctionTypeWithExceptionSpec(MQT->getUnderlyingType(), ESI),3543MQT->getMacroIdentifier());35443545// Might have a calling-convention attribute.3546if (const auto *AT = dyn_cast<AttributedType>(Orig))3547return getAttributedType(3548AT->getAttrKind(),3549getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),3550getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));35513552// Anything else must be a function type. Rebuild it with the new exception3553// specification.3554const auto *Proto = Orig->castAs<FunctionProtoType>();3555return getFunctionType(3556Proto->getReturnType(), Proto->getParamTypes(),3557Proto->getExtProtoInfo().withExceptionSpec(ESI));3558}35593560bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,3561QualType U) const {3562return hasSameType(T, U) ||3563(getLangOpts().CPlusPlus17 &&3564hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None),3565getFunctionTypeWithExceptionSpec(U, EST_None)));3566}35673568QualType ASTContext::getFunctionTypeWithoutPtrSizes(QualType T) {3569if (const auto *Proto = T->getAs<FunctionProtoType>()) {3570QualType RetTy = removePtrSizeAddrSpace(Proto->getReturnType());3571SmallVector<QualType, 16> Args(Proto->param_types().size());3572for (unsigned i = 0, n = Args.size(); i != n; ++i)3573Args[i] = removePtrSizeAddrSpace(Proto->param_types()[i]);3574return getFunctionType(RetTy, Args, Proto->getExtProtoInfo());3575}35763577if (const FunctionNoProtoType *Proto = T->getAs<FunctionNoProtoType>()) {3578QualType RetTy = removePtrSizeAddrSpace(Proto->getReturnType());3579return getFunctionNoProtoType(RetTy, Proto->getExtInfo());3580}35813582return T;3583}35843585bool ASTContext::hasSameFunctionTypeIgnoringPtrSizes(QualType T, QualType U) {3586return hasSameType(T, U) ||3587hasSameType(getFunctionTypeWithoutPtrSizes(T),3588getFunctionTypeWithoutPtrSizes(U));3589}35903591void ASTContext::adjustExceptionSpec(3592FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI,3593bool AsWritten) {3594// Update the type.3595QualType Updated =3596getFunctionTypeWithExceptionSpec(FD->getType(), ESI);3597FD->setType(Updated);35983599if (!AsWritten)3600return;36013602// Update the type in the type source information too.3603if (TypeSourceInfo *TSInfo = FD->getTypeSourceInfo()) {3604// If the type and the type-as-written differ, we may need to update3605// the type-as-written too.3606if (TSInfo->getType() != FD->getType())3607Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI);36083609// FIXME: When we get proper type location information for exceptions,3610// we'll also have to rebuild the TypeSourceInfo. For now, we just patch3611// up the TypeSourceInfo;3612assert(TypeLoc::getFullDataSizeForType(Updated) ==3613TypeLoc::getFullDataSizeForType(TSInfo->getType()) &&3614"TypeLoc size mismatch from updating exception specification");3615TSInfo->overrideType(Updated);3616}3617}36183619/// getComplexType - Return the uniqued reference to the type for a complex3620/// number with the specified element type.3621QualType ASTContext::getComplexType(QualType T) const {3622// Unique pointers, to guarantee there is only one pointer of a particular3623// structure.3624llvm::FoldingSetNodeID ID;3625ComplexType::Profile(ID, T);36263627void *InsertPos = nullptr;3628if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))3629return QualType(CT, 0);36303631// If the pointee type isn't canonical, this won't be a canonical type either,3632// so fill in the canonical type field.3633QualType Canonical;3634if (!T.isCanonical()) {3635Canonical = getComplexType(getCanonicalType(T));36363637// Get the new insert position for the node we care about.3638ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);3639assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3640}3641auto *New = new (*this, alignof(ComplexType)) ComplexType(T, Canonical);3642Types.push_back(New);3643ComplexTypes.InsertNode(New, InsertPos);3644return QualType(New, 0);3645}36463647/// getPointerType - Return the uniqued reference to the type for a pointer to3648/// the specified type.3649QualType ASTContext::getPointerType(QualType T) const {3650// Unique pointers, to guarantee there is only one pointer of a particular3651// structure.3652llvm::FoldingSetNodeID ID;3653PointerType::Profile(ID, T);36543655void *InsertPos = nullptr;3656if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))3657return QualType(PT, 0);36583659// If the pointee type isn't canonical, this won't be a canonical type either,3660// so fill in the canonical type field.3661QualType Canonical;3662if (!T.isCanonical()) {3663Canonical = getPointerType(getCanonicalType(T));36643665// Get the new insert position for the node we care about.3666PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);3667assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3668}3669auto *New = new (*this, alignof(PointerType)) PointerType(T, Canonical);3670Types.push_back(New);3671PointerTypes.InsertNode(New, InsertPos);3672return QualType(New, 0);3673}36743675QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {3676llvm::FoldingSetNodeID ID;3677AdjustedType::Profile(ID, Orig, New);3678void *InsertPos = nullptr;3679AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);3680if (AT)3681return QualType(AT, 0);36823683QualType Canonical = getCanonicalType(New);36843685// Get the new insert position for the node we care about.3686AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);3687assert(!AT && "Shouldn't be in the map!");36883689AT = new (*this, alignof(AdjustedType))3690AdjustedType(Type::Adjusted, Orig, New, Canonical);3691Types.push_back(AT);3692AdjustedTypes.InsertNode(AT, InsertPos);3693return QualType(AT, 0);3694}36953696QualType ASTContext::getDecayedType(QualType Orig, QualType Decayed) const {3697llvm::FoldingSetNodeID ID;3698AdjustedType::Profile(ID, Orig, Decayed);3699void *InsertPos = nullptr;3700AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);3701if (AT)3702return QualType(AT, 0);37033704QualType Canonical = getCanonicalType(Decayed);37053706// Get the new insert position for the node we care about.3707AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);3708assert(!AT && "Shouldn't be in the map!");37093710AT = new (*this, alignof(DecayedType)) DecayedType(Orig, Decayed, Canonical);3711Types.push_back(AT);3712AdjustedTypes.InsertNode(AT, InsertPos);3713return QualType(AT, 0);3714}37153716QualType ASTContext::getDecayedType(QualType T) const {3717assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");37183719QualType Decayed;37203721// C99 6.7.5.3p7:3722// A declaration of a parameter as "array of type" shall be3723// adjusted to "qualified pointer to type", where the type3724// qualifiers (if any) are those specified within the [ and ] of3725// the array type derivation.3726if (T->isArrayType())3727Decayed = getArrayDecayedType(T);37283729// C99 6.7.5.3p8:3730// A declaration of a parameter as "function returning type"3731// shall be adjusted to "pointer to function returning type", as3732// in 6.3.2.1.3733if (T->isFunctionType())3734Decayed = getPointerType(T);37353736return getDecayedType(T, Decayed);3737}37383739QualType ASTContext::getArrayParameterType(QualType Ty) const {3740if (Ty->isArrayParameterType())3741return Ty;3742assert(Ty->isConstantArrayType() && "Ty must be an array type.");3743const auto *ATy = cast<ConstantArrayType>(Ty);3744llvm::FoldingSetNodeID ID;3745ATy->Profile(ID, *this, ATy->getElementType(), ATy->getZExtSize(),3746ATy->getSizeExpr(), ATy->getSizeModifier(),3747ATy->getIndexTypeQualifiers().getAsOpaqueValue());3748void *InsertPos = nullptr;3749ArrayParameterType *AT =3750ArrayParameterTypes.FindNodeOrInsertPos(ID, InsertPos);3751if (AT)3752return QualType(AT, 0);37533754QualType Canonical;3755if (!Ty.isCanonical()) {3756Canonical = getArrayParameterType(getCanonicalType(Ty));37573758// Get the new insert position for the node we care about.3759AT = ArrayParameterTypes.FindNodeOrInsertPos(ID, InsertPos);3760assert(!AT && "Shouldn't be in the map!");3761}37623763AT = new (*this, alignof(ArrayParameterType))3764ArrayParameterType(ATy, Canonical);3765Types.push_back(AT);3766ArrayParameterTypes.InsertNode(AT, InsertPos);3767return QualType(AT, 0);3768}37693770/// getBlockPointerType - Return the uniqued reference to the type for3771/// a pointer to the specified block.3772QualType ASTContext::getBlockPointerType(QualType T) const {3773assert(T->isFunctionType() && "block of function types only");3774// Unique pointers, to guarantee there is only one block of a particular3775// structure.3776llvm::FoldingSetNodeID ID;3777BlockPointerType::Profile(ID, T);37783779void *InsertPos = nullptr;3780if (BlockPointerType *PT =3781BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))3782return QualType(PT, 0);37833784// If the block pointee type isn't canonical, this won't be a canonical3785// type either so fill in the canonical type field.3786QualType Canonical;3787if (!T.isCanonical()) {3788Canonical = getBlockPointerType(getCanonicalType(T));37893790// Get the new insert position for the node we care about.3791BlockPointerType *NewIP =3792BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);3793assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3794}3795auto *New =3796new (*this, alignof(BlockPointerType)) BlockPointerType(T, Canonical);3797Types.push_back(New);3798BlockPointerTypes.InsertNode(New, InsertPos);3799return QualType(New, 0);3800}38013802/// getLValueReferenceType - Return the uniqued reference to the type for an3803/// lvalue reference to the specified type.3804QualType3805ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {3806assert((!T->isPlaceholderType() ||3807T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&3808"Unresolved placeholder type");38093810// Unique pointers, to guarantee there is only one pointer of a particular3811// structure.3812llvm::FoldingSetNodeID ID;3813ReferenceType::Profile(ID, T, SpelledAsLValue);38143815void *InsertPos = nullptr;3816if (LValueReferenceType *RT =3817LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))3818return QualType(RT, 0);38193820const auto *InnerRef = T->getAs<ReferenceType>();38213822// If the referencee type isn't canonical, this won't be a canonical type3823// either, so fill in the canonical type field.3824QualType Canonical;3825if (!SpelledAsLValue || InnerRef || !T.isCanonical()) {3826QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);3827Canonical = getLValueReferenceType(getCanonicalType(PointeeType));38283829// Get the new insert position for the node we care about.3830LValueReferenceType *NewIP =3831LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);3832assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3833}38343835auto *New = new (*this, alignof(LValueReferenceType))3836LValueReferenceType(T, Canonical, SpelledAsLValue);3837Types.push_back(New);3838LValueReferenceTypes.InsertNode(New, InsertPos);38393840return QualType(New, 0);3841}38423843/// getRValueReferenceType - Return the uniqued reference to the type for an3844/// rvalue reference to the specified type.3845QualType ASTContext::getRValueReferenceType(QualType T) const {3846assert((!T->isPlaceholderType() ||3847T->isSpecificPlaceholderType(BuiltinType::UnknownAny)) &&3848"Unresolved placeholder type");38493850// Unique pointers, to guarantee there is only one pointer of a particular3851// structure.3852llvm::FoldingSetNodeID ID;3853ReferenceType::Profile(ID, T, false);38543855void *InsertPos = nullptr;3856if (RValueReferenceType *RT =3857RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))3858return QualType(RT, 0);38593860const auto *InnerRef = T->getAs<ReferenceType>();38613862// If the referencee type isn't canonical, this won't be a canonical type3863// either, so fill in the canonical type field.3864QualType Canonical;3865if (InnerRef || !T.isCanonical()) {3866QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);3867Canonical = getRValueReferenceType(getCanonicalType(PointeeType));38683869// Get the new insert position for the node we care about.3870RValueReferenceType *NewIP =3871RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);3872assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3873}38743875auto *New = new (*this, alignof(RValueReferenceType))3876RValueReferenceType(T, Canonical);3877Types.push_back(New);3878RValueReferenceTypes.InsertNode(New, InsertPos);3879return QualType(New, 0);3880}38813882/// getMemberPointerType - Return the uniqued reference to the type for a3883/// member pointer to the specified type, in the specified class.3884QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {3885// Unique pointers, to guarantee there is only one pointer of a particular3886// structure.3887llvm::FoldingSetNodeID ID;3888MemberPointerType::Profile(ID, T, Cls);38893890void *InsertPos = nullptr;3891if (MemberPointerType *PT =3892MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))3893return QualType(PT, 0);38943895// If the pointee or class type isn't canonical, this won't be a canonical3896// type either, so fill in the canonical type field.3897QualType Canonical;3898if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {3899Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));39003901// Get the new insert position for the node we care about.3902MemberPointerType *NewIP =3903MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);3904assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3905}3906auto *New = new (*this, alignof(MemberPointerType))3907MemberPointerType(T, Cls, Canonical);3908Types.push_back(New);3909MemberPointerTypes.InsertNode(New, InsertPos);3910return QualType(New, 0);3911}39123913/// getConstantArrayType - Return the unique reference to the type for an3914/// array of the specified element type.3915QualType ASTContext::getConstantArrayType(QualType EltTy,3916const llvm::APInt &ArySizeIn,3917const Expr *SizeExpr,3918ArraySizeModifier ASM,3919unsigned IndexTypeQuals) const {3920assert((EltTy->isDependentType() ||3921EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&3922"Constant array of VLAs is illegal!");39233924// We only need the size as part of the type if it's instantiation-dependent.3925if (SizeExpr && !SizeExpr->isInstantiationDependent())3926SizeExpr = nullptr;39273928// Convert the array size into a canonical width matching the pointer size for3929// the target.3930llvm::APInt ArySize(ArySizeIn);3931ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth());39323933llvm::FoldingSetNodeID ID;3934ConstantArrayType::Profile(ID, *this, EltTy, ArySize.getZExtValue(), SizeExpr,3935ASM, IndexTypeQuals);39363937void *InsertPos = nullptr;3938if (ConstantArrayType *ATP =3939ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))3940return QualType(ATP, 0);39413942// If the element type isn't canonical or has qualifiers, or the array bound3943// is instantiation-dependent, this won't be a canonical type either, so fill3944// in the canonical type field.3945QualType Canon;3946// FIXME: Check below should look for qualifiers behind sugar.3947if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers() || SizeExpr) {3948SplitQualType canonSplit = getCanonicalType(EltTy).split();3949Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, nullptr,3950ASM, IndexTypeQuals);3951Canon = getQualifiedType(Canon, canonSplit.Quals);39523953// Get the new insert position for the node we care about.3954ConstantArrayType *NewIP =3955ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);3956assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;3957}39583959auto *New = ConstantArrayType::Create(*this, EltTy, Canon, ArySize, SizeExpr,3960ASM, IndexTypeQuals);3961ConstantArrayTypes.InsertNode(New, InsertPos);3962Types.push_back(New);3963return QualType(New, 0);3964}39653966/// getVariableArrayDecayedType - Turns the given type, which may be3967/// variably-modified, into the corresponding type with all the known3968/// sizes replaced with [*].3969QualType ASTContext::getVariableArrayDecayedType(QualType type) const {3970// Vastly most common case.3971if (!type->isVariablyModifiedType()) return type;39723973QualType result;39743975SplitQualType split = type.getSplitDesugaredType();3976const Type *ty = split.Ty;3977switch (ty->getTypeClass()) {3978#define TYPE(Class, Base)3979#define ABSTRACT_TYPE(Class, Base)3980#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:3981#include "clang/AST/TypeNodes.inc"3982llvm_unreachable("didn't desugar past all non-canonical types?");39833984// These types should never be variably-modified.3985case Type::Builtin:3986case Type::Complex:3987case Type::Vector:3988case Type::DependentVector:3989case Type::ExtVector:3990case Type::DependentSizedExtVector:3991case Type::ConstantMatrix:3992case Type::DependentSizedMatrix:3993case Type::DependentAddressSpace:3994case Type::ObjCObject:3995case Type::ObjCInterface:3996case Type::ObjCObjectPointer:3997case Type::Record:3998case Type::Enum:3999case Type::UnresolvedUsing:4000case Type::TypeOfExpr:4001case Type::TypeOf:4002case Type::Decltype:4003case Type::UnaryTransform:4004case Type::DependentName:4005case Type::InjectedClassName:4006case Type::TemplateSpecialization:4007case Type::DependentTemplateSpecialization:4008case Type::TemplateTypeParm:4009case Type::SubstTemplateTypeParmPack:4010case Type::Auto:4011case Type::DeducedTemplateSpecialization:4012case Type::PackExpansion:4013case Type::PackIndexing:4014case Type::BitInt:4015case Type::DependentBitInt:4016case Type::ArrayParameter:4017llvm_unreachable("type should never be variably-modified");40184019// These types can be variably-modified but should never need to4020// further decay.4021case Type::FunctionNoProto:4022case Type::FunctionProto:4023case Type::BlockPointer:4024case Type::MemberPointer:4025case Type::Pipe:4026return type;40274028// These types can be variably-modified. All these modifications4029// preserve structure except as noted by comments.4030// TODO: if we ever care about optimizing VLAs, there are no-op4031// optimizations available here.4032case Type::Pointer:4033result = getPointerType(getVariableArrayDecayedType(4034cast<PointerType>(ty)->getPointeeType()));4035break;40364037case Type::LValueReference: {4038const auto *lv = cast<LValueReferenceType>(ty);4039result = getLValueReferenceType(4040getVariableArrayDecayedType(lv->getPointeeType()),4041lv->isSpelledAsLValue());4042break;4043}40444045case Type::RValueReference: {4046const auto *lv = cast<RValueReferenceType>(ty);4047result = getRValueReferenceType(4048getVariableArrayDecayedType(lv->getPointeeType()));4049break;4050}40514052case Type::Atomic: {4053const auto *at = cast<AtomicType>(ty);4054result = getAtomicType(getVariableArrayDecayedType(at->getValueType()));4055break;4056}40574058case Type::ConstantArray: {4059const auto *cat = cast<ConstantArrayType>(ty);4060result = getConstantArrayType(4061getVariableArrayDecayedType(cat->getElementType()),4062cat->getSize(),4063cat->getSizeExpr(),4064cat->getSizeModifier(),4065cat->getIndexTypeCVRQualifiers());4066break;4067}40684069case Type::DependentSizedArray: {4070const auto *dat = cast<DependentSizedArrayType>(ty);4071result = getDependentSizedArrayType(4072getVariableArrayDecayedType(dat->getElementType()),4073dat->getSizeExpr(),4074dat->getSizeModifier(),4075dat->getIndexTypeCVRQualifiers(),4076dat->getBracketsRange());4077break;4078}40794080// Turn incomplete types into [*] types.4081case Type::IncompleteArray: {4082const auto *iat = cast<IncompleteArrayType>(ty);4083result =4084getVariableArrayType(getVariableArrayDecayedType(iat->getElementType()),4085/*size*/ nullptr, ArraySizeModifier::Normal,4086iat->getIndexTypeCVRQualifiers(), SourceRange());4087break;4088}40894090// Turn VLA types into [*] types.4091case Type::VariableArray: {4092const auto *vat = cast<VariableArrayType>(ty);4093result = getVariableArrayType(4094getVariableArrayDecayedType(vat->getElementType()),4095/*size*/ nullptr, ArraySizeModifier::Star,4096vat->getIndexTypeCVRQualifiers(), vat->getBracketsRange());4097break;4098}4099}41004101// Apply the top-level qualifiers from the original.4102return getQualifiedType(result, split.Quals);4103}41044105/// getVariableArrayType - Returns a non-unique reference to the type for a4106/// variable array of the specified element type.4107QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,4108ArraySizeModifier ASM,4109unsigned IndexTypeQuals,4110SourceRange Brackets) const {4111// Since we don't unique expressions, it isn't possible to unique VLA's4112// that have an expression provided for their size.4113QualType Canon;41144115// Be sure to pull qualifiers off the element type.4116// FIXME: Check below should look for qualifiers behind sugar.4117if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {4118SplitQualType canonSplit = getCanonicalType(EltTy).split();4119Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM,4120IndexTypeQuals, Brackets);4121Canon = getQualifiedType(Canon, canonSplit.Quals);4122}41234124auto *New = new (*this, alignof(VariableArrayType))4125VariableArrayType(EltTy, Canon, NumElts, ASM, IndexTypeQuals, Brackets);41264127VariableArrayTypes.push_back(New);4128Types.push_back(New);4129return QualType(New, 0);4130}41314132/// getDependentSizedArrayType - Returns a non-unique reference to4133/// the type for a dependently-sized array of the specified element4134/// type.4135QualType ASTContext::getDependentSizedArrayType(QualType elementType,4136Expr *numElements,4137ArraySizeModifier ASM,4138unsigned elementTypeQuals,4139SourceRange brackets) const {4140assert((!numElements || numElements->isTypeDependent() ||4141numElements->isValueDependent()) &&4142"Size must be type- or value-dependent!");41434144SplitQualType canonElementType = getCanonicalType(elementType).split();41454146void *insertPos = nullptr;4147llvm::FoldingSetNodeID ID;4148DependentSizedArrayType::Profile(4149ID, *this, numElements ? QualType(canonElementType.Ty, 0) : elementType,4150ASM, elementTypeQuals, numElements);41514152// Look for an existing type with these properties.4153DependentSizedArrayType *canonTy =4154DependentSizedArrayTypes.FindNodeOrInsertPos(ID, insertPos);41554156// Dependently-sized array types that do not have a specified number4157// of elements will have their sizes deduced from a dependent4158// initializer.4159if (!numElements) {4160if (canonTy)4161return QualType(canonTy, 0);41624163auto *newType = new (*this, alignof(DependentSizedArrayType))4164DependentSizedArrayType(elementType, QualType(), numElements, ASM,4165elementTypeQuals, brackets);4166DependentSizedArrayTypes.InsertNode(newType, insertPos);4167Types.push_back(newType);4168return QualType(newType, 0);4169}41704171// If we don't have one, build one.4172if (!canonTy) {4173canonTy = new (*this, alignof(DependentSizedArrayType))4174DependentSizedArrayType(QualType(canonElementType.Ty, 0), QualType(),4175numElements, ASM, elementTypeQuals, brackets);4176DependentSizedArrayTypes.InsertNode(canonTy, insertPos);4177Types.push_back(canonTy);4178}41794180// Apply qualifiers from the element type to the array.4181QualType canon = getQualifiedType(QualType(canonTy,0),4182canonElementType.Quals);41834184// If we didn't need extra canonicalization for the element type or the size4185// expression, then just use that as our result.4186if (QualType(canonElementType.Ty, 0) == elementType &&4187canonTy->getSizeExpr() == numElements)4188return canon;41894190// Otherwise, we need to build a type which follows the spelling4191// of the element type.4192auto *sugaredType = new (*this, alignof(DependentSizedArrayType))4193DependentSizedArrayType(elementType, canon, numElements, ASM,4194elementTypeQuals, brackets);4195Types.push_back(sugaredType);4196return QualType(sugaredType, 0);4197}41984199QualType ASTContext::getIncompleteArrayType(QualType elementType,4200ArraySizeModifier ASM,4201unsigned elementTypeQuals) const {4202llvm::FoldingSetNodeID ID;4203IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals);42044205void *insertPos = nullptr;4206if (IncompleteArrayType *iat =4207IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos))4208return QualType(iat, 0);42094210// If the element type isn't canonical, this won't be a canonical type4211// either, so fill in the canonical type field. We also have to pull4212// qualifiers off the element type.4213QualType canon;42144215// FIXME: Check below should look for qualifiers behind sugar.4216if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) {4217SplitQualType canonSplit = getCanonicalType(elementType).split();4218canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0),4219ASM, elementTypeQuals);4220canon = getQualifiedType(canon, canonSplit.Quals);42214222// Get the new insert position for the node we care about.4223IncompleteArrayType *existing =4224IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos);4225assert(!existing && "Shouldn't be in the map!"); (void) existing;4226}42274228auto *newType = new (*this, alignof(IncompleteArrayType))4229IncompleteArrayType(elementType, canon, ASM, elementTypeQuals);42304231IncompleteArrayTypes.InsertNode(newType, insertPos);4232Types.push_back(newType);4233return QualType(newType, 0);4234}42354236ASTContext::BuiltinVectorTypeInfo4237ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const {4238#define SVE_INT_ELTTY(BITS, ELTS, SIGNED, NUMVECTORS) \4239{getIntTypeForBitwidth(BITS, SIGNED), llvm::ElementCount::getScalable(ELTS), \4240NUMVECTORS};42414242#define SVE_ELTTY(ELTTY, ELTS, NUMVECTORS) \4243{ELTTY, llvm::ElementCount::getScalable(ELTS), NUMVECTORS};42444245switch (Ty->getKind()) {4246default:4247llvm_unreachable("Unsupported builtin vector type");4248case BuiltinType::SveInt8:4249return SVE_INT_ELTTY(8, 16, true, 1);4250case BuiltinType::SveUint8:4251return SVE_INT_ELTTY(8, 16, false, 1);4252case BuiltinType::SveInt8x2:4253return SVE_INT_ELTTY(8, 16, true, 2);4254case BuiltinType::SveUint8x2:4255return SVE_INT_ELTTY(8, 16, false, 2);4256case BuiltinType::SveInt8x3:4257return SVE_INT_ELTTY(8, 16, true, 3);4258case BuiltinType::SveUint8x3:4259return SVE_INT_ELTTY(8, 16, false, 3);4260case BuiltinType::SveInt8x4:4261return SVE_INT_ELTTY(8, 16, true, 4);4262case BuiltinType::SveUint8x4:4263return SVE_INT_ELTTY(8, 16, false, 4);4264case BuiltinType::SveInt16:4265return SVE_INT_ELTTY(16, 8, true, 1);4266case BuiltinType::SveUint16:4267return SVE_INT_ELTTY(16, 8, false, 1);4268case BuiltinType::SveInt16x2:4269return SVE_INT_ELTTY(16, 8, true, 2);4270case BuiltinType::SveUint16x2:4271return SVE_INT_ELTTY(16, 8, false, 2);4272case BuiltinType::SveInt16x3:4273return SVE_INT_ELTTY(16, 8, true, 3);4274case BuiltinType::SveUint16x3:4275return SVE_INT_ELTTY(16, 8, false, 3);4276case BuiltinType::SveInt16x4:4277return SVE_INT_ELTTY(16, 8, true, 4);4278case BuiltinType::SveUint16x4:4279return SVE_INT_ELTTY(16, 8, false, 4);4280case BuiltinType::SveInt32:4281return SVE_INT_ELTTY(32, 4, true, 1);4282case BuiltinType::SveUint32:4283return SVE_INT_ELTTY(32, 4, false, 1);4284case BuiltinType::SveInt32x2:4285return SVE_INT_ELTTY(32, 4, true, 2);4286case BuiltinType::SveUint32x2:4287return SVE_INT_ELTTY(32, 4, false, 2);4288case BuiltinType::SveInt32x3:4289return SVE_INT_ELTTY(32, 4, true, 3);4290case BuiltinType::SveUint32x3:4291return SVE_INT_ELTTY(32, 4, false, 3);4292case BuiltinType::SveInt32x4:4293return SVE_INT_ELTTY(32, 4, true, 4);4294case BuiltinType::SveUint32x4:4295return SVE_INT_ELTTY(32, 4, false, 4);4296case BuiltinType::SveInt64:4297return SVE_INT_ELTTY(64, 2, true, 1);4298case BuiltinType::SveUint64:4299return SVE_INT_ELTTY(64, 2, false, 1);4300case BuiltinType::SveInt64x2:4301return SVE_INT_ELTTY(64, 2, true, 2);4302case BuiltinType::SveUint64x2:4303return SVE_INT_ELTTY(64, 2, false, 2);4304case BuiltinType::SveInt64x3:4305return SVE_INT_ELTTY(64, 2, true, 3);4306case BuiltinType::SveUint64x3:4307return SVE_INT_ELTTY(64, 2, false, 3);4308case BuiltinType::SveInt64x4:4309return SVE_INT_ELTTY(64, 2, true, 4);4310case BuiltinType::SveUint64x4:4311return SVE_INT_ELTTY(64, 2, false, 4);4312case BuiltinType::SveBool:4313return SVE_ELTTY(BoolTy, 16, 1);4314case BuiltinType::SveBoolx2:4315return SVE_ELTTY(BoolTy, 16, 2);4316case BuiltinType::SveBoolx4:4317return SVE_ELTTY(BoolTy, 16, 4);4318case BuiltinType::SveFloat16:4319return SVE_ELTTY(HalfTy, 8, 1);4320case BuiltinType::SveFloat16x2:4321return SVE_ELTTY(HalfTy, 8, 2);4322case BuiltinType::SveFloat16x3:4323return SVE_ELTTY(HalfTy, 8, 3);4324case BuiltinType::SveFloat16x4:4325return SVE_ELTTY(HalfTy, 8, 4);4326case BuiltinType::SveFloat32:4327return SVE_ELTTY(FloatTy, 4, 1);4328case BuiltinType::SveFloat32x2:4329return SVE_ELTTY(FloatTy, 4, 2);4330case BuiltinType::SveFloat32x3:4331return SVE_ELTTY(FloatTy, 4, 3);4332case BuiltinType::SveFloat32x4:4333return SVE_ELTTY(FloatTy, 4, 4);4334case BuiltinType::SveFloat64:4335return SVE_ELTTY(DoubleTy, 2, 1);4336case BuiltinType::SveFloat64x2:4337return SVE_ELTTY(DoubleTy, 2, 2);4338case BuiltinType::SveFloat64x3:4339return SVE_ELTTY(DoubleTy, 2, 3);4340case BuiltinType::SveFloat64x4:4341return SVE_ELTTY(DoubleTy, 2, 4);4342case BuiltinType::SveBFloat16:4343return SVE_ELTTY(BFloat16Ty, 8, 1);4344case BuiltinType::SveBFloat16x2:4345return SVE_ELTTY(BFloat16Ty, 8, 2);4346case BuiltinType::SveBFloat16x3:4347return SVE_ELTTY(BFloat16Ty, 8, 3);4348case BuiltinType::SveBFloat16x4:4349return SVE_ELTTY(BFloat16Ty, 8, 4);4350#define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, \4351IsSigned) \4352case BuiltinType::Id: \4353return {getIntTypeForBitwidth(ElBits, IsSigned), \4354llvm::ElementCount::getScalable(NumEls), NF};4355#define RVV_VECTOR_TYPE_FLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \4356case BuiltinType::Id: \4357return {ElBits == 16 ? Float16Ty : (ElBits == 32 ? FloatTy : DoubleTy), \4358llvm::ElementCount::getScalable(NumEls), NF};4359#define RVV_VECTOR_TYPE_BFLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \4360case BuiltinType::Id: \4361return {BFloat16Ty, llvm::ElementCount::getScalable(NumEls), NF};4362#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \4363case BuiltinType::Id: \4364return {BoolTy, llvm::ElementCount::getScalable(NumEls), 1};4365#include "clang/Basic/RISCVVTypes.def"4366}4367}43684369/// getExternrefType - Return a WebAssembly externref type, which represents an4370/// opaque reference to a host value.4371QualType ASTContext::getWebAssemblyExternrefType() const {4372if (Target->getTriple().isWasm() && Target->hasFeature("reference-types")) {4373#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \4374if (BuiltinType::Id == BuiltinType::WasmExternRef) \4375return SingletonId;4376#include "clang/Basic/WebAssemblyReferenceTypes.def"4377}4378llvm_unreachable(4379"shouldn't try to generate type externref outside WebAssembly target");4380}43814382/// getScalableVectorType - Return the unique reference to a scalable vector4383/// type of the specified element type and size. VectorType must be a built-in4384/// type.4385QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts,4386unsigned NumFields) const {4387if (Target->hasAArch64SVETypes()) {4388uint64_t EltTySize = getTypeSize(EltTy);4389#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId, NumEls, ElBits, \4390IsSigned, IsFP, IsBF) \4391if (!EltTy->isBooleanType() && \4392((EltTy->hasIntegerRepresentation() && \4393EltTy->hasSignedIntegerRepresentation() == IsSigned) || \4394(EltTy->hasFloatingRepresentation() && !EltTy->isBFloat16Type() && \4395IsFP && !IsBF) || \4396(EltTy->hasFloatingRepresentation() && EltTy->isBFloat16Type() && \4397IsBF && !IsFP)) && \4398EltTySize == ElBits && NumElts == NumEls) { \4399return SingletonId; \4400}4401#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId, NumEls) \4402if (EltTy->isBooleanType() && NumElts == NumEls) \4403return SingletonId;4404#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingleTonId)4405#include "clang/Basic/AArch64SVEACLETypes.def"4406} else if (Target->hasRISCVVTypes()) {4407uint64_t EltTySize = getTypeSize(EltTy);4408#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \4409IsFP, IsBF) \4410if (!EltTy->isBooleanType() && \4411((EltTy->hasIntegerRepresentation() && \4412EltTy->hasSignedIntegerRepresentation() == IsSigned) || \4413(EltTy->hasFloatingRepresentation() && !EltTy->isBFloat16Type() && \4414IsFP && !IsBF) || \4415(EltTy->hasFloatingRepresentation() && EltTy->isBFloat16Type() && \4416IsBF && !IsFP)) && \4417EltTySize == ElBits && NumElts == NumEls && NumFields == NF) \4418return SingletonId;4419#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \4420if (EltTy->isBooleanType() && NumElts == NumEls) \4421return SingletonId;4422#include "clang/Basic/RISCVVTypes.def"4423}4424return QualType();4425}44264427/// getVectorType - Return the unique reference to a vector type of4428/// the specified element type and size. VectorType must be a built-in type.4429QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,4430VectorKind VecKind) const {4431assert(vecType->isBuiltinType() ||4432(vecType->isBitIntType() &&4433// Only support _BitInt elements with byte-sized power of 2 NumBits.4434llvm::isPowerOf2_32(vecType->castAs<BitIntType>()->getNumBits()) &&4435vecType->castAs<BitIntType>()->getNumBits() >= 8));44364437// Check if we've already instantiated a vector of this type.4438llvm::FoldingSetNodeID ID;4439VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind);44404441void *InsertPos = nullptr;4442if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))4443return QualType(VTP, 0);44444445// If the element type isn't canonical, this won't be a canonical type either,4446// so fill in the canonical type field.4447QualType Canonical;4448if (!vecType.isCanonical()) {4449Canonical = getVectorType(getCanonicalType(vecType), NumElts, VecKind);44504451// Get the new insert position for the node we care about.4452VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);4453assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;4454}4455auto *New = new (*this, alignof(VectorType))4456VectorType(vecType, NumElts, Canonical, VecKind);4457VectorTypes.InsertNode(New, InsertPos);4458Types.push_back(New);4459return QualType(New, 0);4460}44614462QualType ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr,4463SourceLocation AttrLoc,4464VectorKind VecKind) const {4465llvm::FoldingSetNodeID ID;4466DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr,4467VecKind);4468void *InsertPos = nullptr;4469DependentVectorType *Canon =4470DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);4471DependentVectorType *New;44724473if (Canon) {4474New = new (*this, alignof(DependentVectorType)) DependentVectorType(4475VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind);4476} else {4477QualType CanonVecTy = getCanonicalType(VecType);4478if (CanonVecTy == VecType) {4479New = new (*this, alignof(DependentVectorType))4480DependentVectorType(VecType, QualType(), SizeExpr, AttrLoc, VecKind);44814482DependentVectorType *CanonCheck =4483DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);4484assert(!CanonCheck &&4485"Dependent-sized vector_size canonical type broken");4486(void)CanonCheck;4487DependentVectorTypes.InsertNode(New, InsertPos);4488} else {4489QualType CanonTy = getDependentVectorType(CanonVecTy, SizeExpr,4490SourceLocation(), VecKind);4491New = new (*this, alignof(DependentVectorType))4492DependentVectorType(VecType, CanonTy, SizeExpr, AttrLoc, VecKind);4493}4494}44954496Types.push_back(New);4497return QualType(New, 0);4498}44994500/// getExtVectorType - Return the unique reference to an extended vector type of4501/// the specified element type and size. VectorType must be a built-in type.4502QualType ASTContext::getExtVectorType(QualType vecType,4503unsigned NumElts) const {4504assert(vecType->isBuiltinType() || vecType->isDependentType() ||4505(vecType->isBitIntType() &&4506// Only support _BitInt elements with byte-sized power of 2 NumBits.4507llvm::isPowerOf2_32(vecType->castAs<BitIntType>()->getNumBits()) &&4508vecType->castAs<BitIntType>()->getNumBits() >= 8));45094510// Check if we've already instantiated a vector of this type.4511llvm::FoldingSetNodeID ID;4512VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,4513VectorKind::Generic);4514void *InsertPos = nullptr;4515if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))4516return QualType(VTP, 0);45174518// If the element type isn't canonical, this won't be a canonical type either,4519// so fill in the canonical type field.4520QualType Canonical;4521if (!vecType.isCanonical()) {4522Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);45234524// Get the new insert position for the node we care about.4525VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);4526assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;4527}4528auto *New = new (*this, alignof(ExtVectorType))4529ExtVectorType(vecType, NumElts, Canonical);4530VectorTypes.InsertNode(New, InsertPos);4531Types.push_back(New);4532return QualType(New, 0);4533}45344535QualType4536ASTContext::getDependentSizedExtVectorType(QualType vecType,4537Expr *SizeExpr,4538SourceLocation AttrLoc) const {4539llvm::FoldingSetNodeID ID;4540DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),4541SizeExpr);45424543void *InsertPos = nullptr;4544DependentSizedExtVectorType *Canon4545= DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);4546DependentSizedExtVectorType *New;4547if (Canon) {4548// We already have a canonical version of this array type; use it as4549// the canonical type for a newly-built type.4550New = new (*this, alignof(DependentSizedExtVectorType))4551DependentSizedExtVectorType(vecType, QualType(Canon, 0), SizeExpr,4552AttrLoc);4553} else {4554QualType CanonVecTy = getCanonicalType(vecType);4555if (CanonVecTy == vecType) {4556New = new (*this, alignof(DependentSizedExtVectorType))4557DependentSizedExtVectorType(vecType, QualType(), SizeExpr, AttrLoc);45584559DependentSizedExtVectorType *CanonCheck4560= DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);4561assert(!CanonCheck && "Dependent-sized ext_vector canonical type broken");4562(void)CanonCheck;4563DependentSizedExtVectorTypes.InsertNode(New, InsertPos);4564} else {4565QualType CanonExtTy = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,4566SourceLocation());4567New = new (*this, alignof(DependentSizedExtVectorType))4568DependentSizedExtVectorType(vecType, CanonExtTy, SizeExpr, AttrLoc);4569}4570}45714572Types.push_back(New);4573return QualType(New, 0);4574}45754576QualType ASTContext::getConstantMatrixType(QualType ElementTy, unsigned NumRows,4577unsigned NumColumns) const {4578llvm::FoldingSetNodeID ID;4579ConstantMatrixType::Profile(ID, ElementTy, NumRows, NumColumns,4580Type::ConstantMatrix);45814582assert(MatrixType::isValidElementType(ElementTy) &&4583"need a valid element type");4584assert(ConstantMatrixType::isDimensionValid(NumRows) &&4585ConstantMatrixType::isDimensionValid(NumColumns) &&4586"need valid matrix dimensions");4587void *InsertPos = nullptr;4588if (ConstantMatrixType *MTP = MatrixTypes.FindNodeOrInsertPos(ID, InsertPos))4589return QualType(MTP, 0);45904591QualType Canonical;4592if (!ElementTy.isCanonical()) {4593Canonical =4594getConstantMatrixType(getCanonicalType(ElementTy), NumRows, NumColumns);45954596ConstantMatrixType *NewIP = MatrixTypes.FindNodeOrInsertPos(ID, InsertPos);4597assert(!NewIP && "Matrix type shouldn't already exist in the map");4598(void)NewIP;4599}46004601auto *New = new (*this, alignof(ConstantMatrixType))4602ConstantMatrixType(ElementTy, NumRows, NumColumns, Canonical);4603MatrixTypes.InsertNode(New, InsertPos);4604Types.push_back(New);4605return QualType(New, 0);4606}46074608QualType ASTContext::getDependentSizedMatrixType(QualType ElementTy,4609Expr *RowExpr,4610Expr *ColumnExpr,4611SourceLocation AttrLoc) const {4612QualType CanonElementTy = getCanonicalType(ElementTy);4613llvm::FoldingSetNodeID ID;4614DependentSizedMatrixType::Profile(ID, *this, CanonElementTy, RowExpr,4615ColumnExpr);46164617void *InsertPos = nullptr;4618DependentSizedMatrixType *Canon =4619DependentSizedMatrixTypes.FindNodeOrInsertPos(ID, InsertPos);46204621if (!Canon) {4622Canon = new (*this, alignof(DependentSizedMatrixType))4623DependentSizedMatrixType(CanonElementTy, QualType(), RowExpr,4624ColumnExpr, AttrLoc);4625#ifndef NDEBUG4626DependentSizedMatrixType *CanonCheck =4627DependentSizedMatrixTypes.FindNodeOrInsertPos(ID, InsertPos);4628assert(!CanonCheck && "Dependent-sized matrix canonical type broken");4629#endif4630DependentSizedMatrixTypes.InsertNode(Canon, InsertPos);4631Types.push_back(Canon);4632}46334634// Already have a canonical version of the matrix type4635//4636// If it exactly matches the requested type, use it directly.4637if (Canon->getElementType() == ElementTy && Canon->getRowExpr() == RowExpr &&4638Canon->getRowExpr() == ColumnExpr)4639return QualType(Canon, 0);46404641// Use Canon as the canonical type for newly-built type.4642DependentSizedMatrixType *New = new (*this, alignof(DependentSizedMatrixType))4643DependentSizedMatrixType(ElementTy, QualType(Canon, 0), RowExpr,4644ColumnExpr, AttrLoc);4645Types.push_back(New);4646return QualType(New, 0);4647}46484649QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,4650Expr *AddrSpaceExpr,4651SourceLocation AttrLoc) const {4652assert(AddrSpaceExpr->isInstantiationDependent());46534654QualType canonPointeeType = getCanonicalType(PointeeType);46554656void *insertPos = nullptr;4657llvm::FoldingSetNodeID ID;4658DependentAddressSpaceType::Profile(ID, *this, canonPointeeType,4659AddrSpaceExpr);46604661DependentAddressSpaceType *canonTy =4662DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos);46634664if (!canonTy) {4665canonTy = new (*this, alignof(DependentAddressSpaceType))4666DependentAddressSpaceType(canonPointeeType, QualType(), AddrSpaceExpr,4667AttrLoc);4668DependentAddressSpaceTypes.InsertNode(canonTy, insertPos);4669Types.push_back(canonTy);4670}46714672if (canonPointeeType == PointeeType &&4673canonTy->getAddrSpaceExpr() == AddrSpaceExpr)4674return QualType(canonTy, 0);46754676auto *sugaredType = new (*this, alignof(DependentAddressSpaceType))4677DependentAddressSpaceType(PointeeType, QualType(canonTy, 0),4678AddrSpaceExpr, AttrLoc);4679Types.push_back(sugaredType);4680return QualType(sugaredType, 0);4681}46824683/// Determine whether \p T is canonical as the result type of a function.4684static bool isCanonicalResultType(QualType T) {4685return T.isCanonical() &&4686(T.getObjCLifetime() == Qualifiers::OCL_None ||4687T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);4688}46894690/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.4691QualType4692ASTContext::getFunctionNoProtoType(QualType ResultTy,4693const FunctionType::ExtInfo &Info) const {4694// FIXME: This assertion cannot be enabled (yet) because the ObjC rewriter4695// functionality creates a function without a prototype regardless of4696// language mode (so it makes them even in C++). Once the rewriter has been4697// fixed, this assertion can be enabled again.4698//assert(!LangOpts.requiresStrictPrototypes() &&4699// "strict prototypes are disabled");47004701// Unique functions, to guarantee there is only one function of a particular4702// structure.4703llvm::FoldingSetNodeID ID;4704FunctionNoProtoType::Profile(ID, ResultTy, Info);47054706void *InsertPos = nullptr;4707if (FunctionNoProtoType *FT =4708FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))4709return QualType(FT, 0);47104711QualType Canonical;4712if (!isCanonicalResultType(ResultTy)) {4713Canonical =4714getFunctionNoProtoType(getCanonicalFunctionResultType(ResultTy), Info);47154716// Get the new insert position for the node we care about.4717FunctionNoProtoType *NewIP =4718FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);4719assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;4720}47214722auto *New = new (*this, alignof(FunctionNoProtoType))4723FunctionNoProtoType(ResultTy, Canonical, Info);4724Types.push_back(New);4725FunctionNoProtoTypes.InsertNode(New, InsertPos);4726return QualType(New, 0);4727}47284729CanQualType4730ASTContext::getCanonicalFunctionResultType(QualType ResultType) const {4731CanQualType CanResultType = getCanonicalType(ResultType);47324733// Canonical result types do not have ARC lifetime qualifiers.4734if (CanResultType.getQualifiers().hasObjCLifetime()) {4735Qualifiers Qs = CanResultType.getQualifiers();4736Qs.removeObjCLifetime();4737return CanQualType::CreateUnsafe(4738getQualifiedType(CanResultType.getUnqualifiedType(), Qs));4739}47404741return CanResultType;4742}47434744static bool isCanonicalExceptionSpecification(4745const FunctionProtoType::ExceptionSpecInfo &ESI, bool NoexceptInType) {4746if (ESI.Type == EST_None)4747return true;4748if (!NoexceptInType)4749return false;47504751// C++17 onwards: exception specification is part of the type, as a simple4752// boolean "can this function type throw".4753if (ESI.Type == EST_BasicNoexcept)4754return true;47554756// A noexcept(expr) specification is (possibly) canonical if expr is4757// value-dependent.4758if (ESI.Type == EST_DependentNoexcept)4759return true;47604761// A dynamic exception specification is canonical if it only contains pack4762// expansions (so we can't tell whether it's non-throwing) and all its4763// contained types are canonical.4764if (ESI.Type == EST_Dynamic) {4765bool AnyPackExpansions = false;4766for (QualType ET : ESI.Exceptions) {4767if (!ET.isCanonical())4768return false;4769if (ET->getAs<PackExpansionType>())4770AnyPackExpansions = true;4771}4772return AnyPackExpansions;4773}47744775return false;4776}47774778QualType ASTContext::getFunctionTypeInternal(4779QualType ResultTy, ArrayRef<QualType> ArgArray,4780const FunctionProtoType::ExtProtoInfo &EPI, bool OnlyWantCanonical) const {4781size_t NumArgs = ArgArray.size();47824783// Unique functions, to guarantee there is only one function of a particular4784// structure.4785llvm::FoldingSetNodeID ID;4786FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI,4787*this, true);47884789QualType Canonical;4790bool Unique = false;47914792void *InsertPos = nullptr;4793if (FunctionProtoType *FPT =4794FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) {4795QualType Existing = QualType(FPT, 0);47964797// If we find a pre-existing equivalent FunctionProtoType, we can just reuse4798// it so long as our exception specification doesn't contain a dependent4799// noexcept expression, or we're just looking for a canonical type.4800// Otherwise, we're going to need to create a type4801// sugar node to hold the concrete expression.4802if (OnlyWantCanonical || !isComputedNoexcept(EPI.ExceptionSpec.Type) ||4803EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr())4804return Existing;48054806// We need a new type sugar node for this one, to hold the new noexcept4807// expression. We do no canonicalization here, but that's OK since we don't4808// expect to see the same noexcept expression much more than once.4809Canonical = getCanonicalType(Existing);4810Unique = true;4811}48124813bool NoexceptInType = getLangOpts().CPlusPlus17;4814bool IsCanonicalExceptionSpec =4815isCanonicalExceptionSpecification(EPI.ExceptionSpec, NoexceptInType);48164817// Determine whether the type being created is already canonical or not.4818bool isCanonical = !Unique && IsCanonicalExceptionSpec &&4819isCanonicalResultType(ResultTy) && !EPI.HasTrailingReturn;4820for (unsigned i = 0; i != NumArgs && isCanonical; ++i)4821if (!ArgArray[i].isCanonicalAsParam())4822isCanonical = false;48234824if (OnlyWantCanonical)4825assert(isCanonical &&4826"given non-canonical parameters constructing canonical type");48274828// If this type isn't canonical, get the canonical version of it if we don't4829// already have it. The exception spec is only partially part of the4830// canonical type, and only in C++17 onwards.4831if (!isCanonical && Canonical.isNull()) {4832SmallVector<QualType, 16> CanonicalArgs;4833CanonicalArgs.reserve(NumArgs);4834for (unsigned i = 0; i != NumArgs; ++i)4835CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i]));48364837llvm::SmallVector<QualType, 8> ExceptionTypeStorage;4838FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI;4839CanonicalEPI.HasTrailingReturn = false;48404841if (IsCanonicalExceptionSpec) {4842// Exception spec is already OK.4843} else if (NoexceptInType) {4844switch (EPI.ExceptionSpec.Type) {4845case EST_Unparsed: case EST_Unevaluated: case EST_Uninstantiated:4846// We don't know yet. It shouldn't matter what we pick here; no-one4847// should ever look at this.4848[[fallthrough]];4849case EST_None: case EST_MSAny: case EST_NoexceptFalse:4850CanonicalEPI.ExceptionSpec.Type = EST_None;4851break;48524853// A dynamic exception specification is almost always "not noexcept",4854// with the exception that a pack expansion might expand to no types.4855case EST_Dynamic: {4856bool AnyPacks = false;4857for (QualType ET : EPI.ExceptionSpec.Exceptions) {4858if (ET->getAs<PackExpansionType>())4859AnyPacks = true;4860ExceptionTypeStorage.push_back(getCanonicalType(ET));4861}4862if (!AnyPacks)4863CanonicalEPI.ExceptionSpec.Type = EST_None;4864else {4865CanonicalEPI.ExceptionSpec.Type = EST_Dynamic;4866CanonicalEPI.ExceptionSpec.Exceptions = ExceptionTypeStorage;4867}4868break;4869}48704871case EST_DynamicNone:4872case EST_BasicNoexcept:4873case EST_NoexceptTrue:4874case EST_NoThrow:4875CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;4876break;48774878case EST_DependentNoexcept:4879llvm_unreachable("dependent noexcept is already canonical");4880}4881} else {4882CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();4883}48844885// Adjust the canonical function result type.4886CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy);4887Canonical =4888getFunctionTypeInternal(CanResultTy, CanonicalArgs, CanonicalEPI, true);48894890// Get the new insert position for the node we care about.4891FunctionProtoType *NewIP =4892FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);4893assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;4894}48954896// Compute the needed size to hold this FunctionProtoType and the4897// various trailing objects.4898auto ESH = FunctionProtoType::getExceptionSpecSize(4899EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size());4900size_t Size = FunctionProtoType::totalSizeToAlloc<4901QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields,4902FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType,4903Expr *, FunctionDecl *, FunctionProtoType::ExtParameterInfo, Qualifiers,4904FunctionEffect, EffectConditionExpr>(4905NumArgs, EPI.Variadic, EPI.requiresFunctionProtoTypeExtraBitfields(),4906EPI.requiresFunctionProtoTypeArmAttributes(), ESH.NumExceptionType,4907ESH.NumExprPtr, ESH.NumFunctionDeclPtr,4908EPI.ExtParameterInfos ? NumArgs : 0,4909EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0, EPI.FunctionEffects.size(),4910EPI.FunctionEffects.conditions().size());49114912auto *FTP = (FunctionProtoType *)Allocate(Size, alignof(FunctionProtoType));4913FunctionProtoType::ExtProtoInfo newEPI = EPI;4914new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI);4915Types.push_back(FTP);4916if (!Unique)4917FunctionProtoTypes.InsertNode(FTP, InsertPos);4918if (!EPI.FunctionEffects.empty())4919AnyFunctionEffects = true;4920return QualType(FTP, 0);4921}49224923QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {4924llvm::FoldingSetNodeID ID;4925PipeType::Profile(ID, T, ReadOnly);49264927void *InsertPos = nullptr;4928if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos))4929return QualType(PT, 0);49304931// If the pipe element type isn't canonical, this won't be a canonical type4932// either, so fill in the canonical type field.4933QualType Canonical;4934if (!T.isCanonical()) {4935Canonical = getPipeType(getCanonicalType(T), ReadOnly);49364937// Get the new insert position for the node we care about.4938PipeType *NewIP = PipeTypes.FindNodeOrInsertPos(ID, InsertPos);4939assert(!NewIP && "Shouldn't be in the map!");4940(void)NewIP;4941}4942auto *New = new (*this, alignof(PipeType)) PipeType(T, Canonical, ReadOnly);4943Types.push_back(New);4944PipeTypes.InsertNode(New, InsertPos);4945return QualType(New, 0);4946}49474948QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const {4949// OpenCL v1.1 s6.5.3: a string literal is in the constant address space.4950return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant)4951: Ty;4952}49534954QualType ASTContext::getReadPipeType(QualType T) const {4955return getPipeType(T, true);4956}49574958QualType ASTContext::getWritePipeType(QualType T) const {4959return getPipeType(T, false);4960}49614962QualType ASTContext::getBitIntType(bool IsUnsigned, unsigned NumBits) const {4963llvm::FoldingSetNodeID ID;4964BitIntType::Profile(ID, IsUnsigned, NumBits);49654966void *InsertPos = nullptr;4967if (BitIntType *EIT = BitIntTypes.FindNodeOrInsertPos(ID, InsertPos))4968return QualType(EIT, 0);49694970auto *New = new (*this, alignof(BitIntType)) BitIntType(IsUnsigned, NumBits);4971BitIntTypes.InsertNode(New, InsertPos);4972Types.push_back(New);4973return QualType(New, 0);4974}49754976QualType ASTContext::getDependentBitIntType(bool IsUnsigned,4977Expr *NumBitsExpr) const {4978assert(NumBitsExpr->isInstantiationDependent() && "Only good for dependent");4979llvm::FoldingSetNodeID ID;4980DependentBitIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr);49814982void *InsertPos = nullptr;4983if (DependentBitIntType *Existing =4984DependentBitIntTypes.FindNodeOrInsertPos(ID, InsertPos))4985return QualType(Existing, 0);49864987auto *New = new (*this, alignof(DependentBitIntType))4988DependentBitIntType(IsUnsigned, NumBitsExpr);4989DependentBitIntTypes.InsertNode(New, InsertPos);49904991Types.push_back(New);4992return QualType(New, 0);4993}49944995#ifndef NDEBUG4996static bool NeedsInjectedClassNameType(const RecordDecl *D) {4997if (!isa<CXXRecordDecl>(D)) return false;4998const auto *RD = cast<CXXRecordDecl>(D);4999if (isa<ClassTemplatePartialSpecializationDecl>(RD))5000return true;5001if (RD->getDescribedClassTemplate() &&5002!isa<ClassTemplateSpecializationDecl>(RD))5003return true;5004return false;5005}5006#endif50075008/// getInjectedClassNameType - Return the unique reference to the5009/// injected class name type for the specified templated declaration.5010QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl,5011QualType TST) const {5012assert(NeedsInjectedClassNameType(Decl));5013if (Decl->TypeForDecl) {5014assert(isa<InjectedClassNameType>(Decl->TypeForDecl));5015} else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDecl()) {5016assert(PrevDecl->TypeForDecl && "previous declaration has no type");5017Decl->TypeForDecl = PrevDecl->TypeForDecl;5018assert(isa<InjectedClassNameType>(Decl->TypeForDecl));5019} else {5020Type *newType = new (*this, alignof(InjectedClassNameType))5021InjectedClassNameType(Decl, TST);5022Decl->TypeForDecl = newType;5023Types.push_back(newType);5024}5025return QualType(Decl->TypeForDecl, 0);5026}50275028/// getTypeDeclType - Return the unique reference to the type for the5029/// specified type declaration.5030QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {5031assert(Decl && "Passed null for Decl param");5032assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");50335034if (const auto *Typedef = dyn_cast<TypedefNameDecl>(Decl))5035return getTypedefType(Typedef);50365037assert(!isa<TemplateTypeParmDecl>(Decl) &&5038"Template type parameter types are always available.");50395040if (const auto *Record = dyn_cast<RecordDecl>(Decl)) {5041assert(Record->isFirstDecl() && "struct/union has previous declaration");5042assert(!NeedsInjectedClassNameType(Record));5043return getRecordType(Record);5044} else if (const auto *Enum = dyn_cast<EnumDecl>(Decl)) {5045assert(Enum->isFirstDecl() && "enum has previous declaration");5046return getEnumType(Enum);5047} else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {5048return getUnresolvedUsingType(Using);5049} else5050llvm_unreachable("TypeDecl without a type?");50515052return QualType(Decl->TypeForDecl, 0);5053}50545055/// getTypedefType - Return the unique reference to the type for the5056/// specified typedef name decl.5057QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl,5058QualType Underlying) const {5059if (!Decl->TypeForDecl) {5060if (Underlying.isNull())5061Underlying = Decl->getUnderlyingType();5062auto *NewType = new (*this, alignof(TypedefType)) TypedefType(5063Type::Typedef, Decl, QualType(), getCanonicalType(Underlying));5064Decl->TypeForDecl = NewType;5065Types.push_back(NewType);5066return QualType(NewType, 0);5067}5068if (Underlying.isNull() || Decl->getUnderlyingType() == Underlying)5069return QualType(Decl->TypeForDecl, 0);5070assert(hasSameType(Decl->getUnderlyingType(), Underlying));50715072llvm::FoldingSetNodeID ID;5073TypedefType::Profile(ID, Decl, Underlying);50745075void *InsertPos = nullptr;5076if (TypedefType *T = TypedefTypes.FindNodeOrInsertPos(ID, InsertPos)) {5077assert(!T->typeMatchesDecl() &&5078"non-divergent case should be handled with TypeDecl");5079return QualType(T, 0);5080}50815082void *Mem = Allocate(TypedefType::totalSizeToAlloc<QualType>(true),5083alignof(TypedefType));5084auto *NewType = new (Mem) TypedefType(Type::Typedef, Decl, Underlying,5085getCanonicalType(Underlying));5086TypedefTypes.InsertNode(NewType, InsertPos);5087Types.push_back(NewType);5088return QualType(NewType, 0);5089}50905091QualType ASTContext::getUsingType(const UsingShadowDecl *Found,5092QualType Underlying) const {5093llvm::FoldingSetNodeID ID;5094UsingType::Profile(ID, Found, Underlying);50955096void *InsertPos = nullptr;5097if (UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos))5098return QualType(T, 0);50995100const Type *TypeForDecl =5101cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl();51025103assert(!Underlying.hasLocalQualifiers());5104QualType Canon = Underlying->getCanonicalTypeInternal();5105assert(TypeForDecl->getCanonicalTypeInternal() == Canon);51065107if (Underlying.getTypePtr() == TypeForDecl)5108Underlying = QualType();5109void *Mem =5110Allocate(UsingType::totalSizeToAlloc<QualType>(!Underlying.isNull()),5111alignof(UsingType));5112UsingType *NewType = new (Mem) UsingType(Found, Underlying, Canon);5113Types.push_back(NewType);5114UsingTypes.InsertNode(NewType, InsertPos);5115return QualType(NewType, 0);5116}51175118QualType ASTContext::getRecordType(const RecordDecl *Decl) const {5119if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);51205121if (const RecordDecl *PrevDecl = Decl->getPreviousDecl())5122if (PrevDecl->TypeForDecl)5123return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);51245125auto *newType = new (*this, alignof(RecordType)) RecordType(Decl);5126Decl->TypeForDecl = newType;5127Types.push_back(newType);5128return QualType(newType, 0);5129}51305131QualType ASTContext::getEnumType(const EnumDecl *Decl) const {5132if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);51335134if (const EnumDecl *PrevDecl = Decl->getPreviousDecl())5135if (PrevDecl->TypeForDecl)5136return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);51375138auto *newType = new (*this, alignof(EnumType)) EnumType(Decl);5139Decl->TypeForDecl = newType;5140Types.push_back(newType);5141return QualType(newType, 0);5142}51435144QualType ASTContext::getUnresolvedUsingType(5145const UnresolvedUsingTypenameDecl *Decl) const {5146if (Decl->TypeForDecl)5147return QualType(Decl->TypeForDecl, 0);51485149if (const UnresolvedUsingTypenameDecl *CanonicalDecl =5150Decl->getCanonicalDecl())5151if (CanonicalDecl->TypeForDecl)5152return QualType(Decl->TypeForDecl = CanonicalDecl->TypeForDecl, 0);51535154Type *newType =5155new (*this, alignof(UnresolvedUsingType)) UnresolvedUsingType(Decl);5156Decl->TypeForDecl = newType;5157Types.push_back(newType);5158return QualType(newType, 0);5159}51605161QualType ASTContext::getAttributedType(attr::Kind attrKind,5162QualType modifiedType,5163QualType equivalentType) const {5164llvm::FoldingSetNodeID id;5165AttributedType::Profile(id, attrKind, modifiedType, equivalentType);51665167void *insertPos = nullptr;5168AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);5169if (type) return QualType(type, 0);51705171QualType canon = getCanonicalType(equivalentType);5172type = new (*this, alignof(AttributedType))5173AttributedType(canon, attrKind, modifiedType, equivalentType);51745175Types.push_back(type);5176AttributedTypes.InsertNode(type, insertPos);51775178return QualType(type, 0);5179}51805181QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,5182QualType Wrapped) {5183llvm::FoldingSetNodeID ID;5184BTFTagAttributedType::Profile(ID, Wrapped, BTFAttr);51855186void *InsertPos = nullptr;5187BTFTagAttributedType *Ty =5188BTFTagAttributedTypes.FindNodeOrInsertPos(ID, InsertPos);5189if (Ty)5190return QualType(Ty, 0);51915192QualType Canon = getCanonicalType(Wrapped);5193Ty = new (*this, alignof(BTFTagAttributedType))5194BTFTagAttributedType(Canon, Wrapped, BTFAttr);51955196Types.push_back(Ty);5197BTFTagAttributedTypes.InsertNode(Ty, InsertPos);51985199return QualType(Ty, 0);5200}52015202/// Retrieve a substitution-result type.5203QualType ASTContext::getSubstTemplateTypeParmType(5204QualType Replacement, Decl *AssociatedDecl, unsigned Index,5205std::optional<unsigned> PackIndex) const {5206llvm::FoldingSetNodeID ID;5207SubstTemplateTypeParmType::Profile(ID, Replacement, AssociatedDecl, Index,5208PackIndex);5209void *InsertPos = nullptr;5210SubstTemplateTypeParmType *SubstParm =5211SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);52125213if (!SubstParm) {5214void *Mem = Allocate(SubstTemplateTypeParmType::totalSizeToAlloc<QualType>(5215!Replacement.isCanonical()),5216alignof(SubstTemplateTypeParmType));5217SubstParm = new (Mem) SubstTemplateTypeParmType(Replacement, AssociatedDecl,5218Index, PackIndex);5219Types.push_back(SubstParm);5220SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);5221}52225223return QualType(SubstParm, 0);5224}52255226/// Retrieve a5227QualType5228ASTContext::getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,5229unsigned Index, bool Final,5230const TemplateArgument &ArgPack) {5231#ifndef NDEBUG5232for (const auto &P : ArgPack.pack_elements())5233assert(P.getKind() == TemplateArgument::Type && "Pack contains a non-type");5234#endif52355236llvm::FoldingSetNodeID ID;5237SubstTemplateTypeParmPackType::Profile(ID, AssociatedDecl, Index, Final,5238ArgPack);5239void *InsertPos = nullptr;5240if (SubstTemplateTypeParmPackType *SubstParm =5241SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))5242return QualType(SubstParm, 0);52435244QualType Canon;5245{5246TemplateArgument CanonArgPack = getCanonicalTemplateArgument(ArgPack);5247if (!AssociatedDecl->isCanonicalDecl() ||5248!CanonArgPack.structurallyEquals(ArgPack)) {5249Canon = getSubstTemplateTypeParmPackType(5250AssociatedDecl->getCanonicalDecl(), Index, Final, CanonArgPack);5251[[maybe_unused]] const auto *Nothing =5252SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos);5253assert(!Nothing);5254}5255}52565257auto *SubstParm = new (*this, alignof(SubstTemplateTypeParmPackType))5258SubstTemplateTypeParmPackType(Canon, AssociatedDecl, Index, Final,5259ArgPack);5260Types.push_back(SubstParm);5261SubstTemplateTypeParmPackTypes.InsertNode(SubstParm, InsertPos);5262return QualType(SubstParm, 0);5263}52645265/// Retrieve the template type parameter type for a template5266/// parameter or parameter pack with the given depth, index, and (optionally)5267/// name.5268QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,5269bool ParameterPack,5270TemplateTypeParmDecl *TTPDecl) const {5271llvm::FoldingSetNodeID ID;5272TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);5273void *InsertPos = nullptr;5274TemplateTypeParmType *TypeParm5275= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);52765277if (TypeParm)5278return QualType(TypeParm, 0);52795280if (TTPDecl) {5281QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);5282TypeParm = new (*this, alignof(TemplateTypeParmType))5283TemplateTypeParmType(TTPDecl, Canon);52845285TemplateTypeParmType *TypeCheck5286= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);5287assert(!TypeCheck && "Template type parameter canonical type broken");5288(void)TypeCheck;5289} else5290TypeParm = new (*this, alignof(TemplateTypeParmType))5291TemplateTypeParmType(Depth, Index, ParameterPack);52925293Types.push_back(TypeParm);5294TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);52955296return QualType(TypeParm, 0);5297}52985299TypeSourceInfo *5300ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,5301SourceLocation NameLoc,5302const TemplateArgumentListInfo &Args,5303QualType Underlying) const {5304assert(!Name.getAsDependentTemplateName() &&5305"No dependent template names here!");5306QualType TST =5307getTemplateSpecializationType(Name, Args.arguments(), Underlying);53085309TypeSourceInfo *DI = CreateTypeSourceInfo(TST);5310TemplateSpecializationTypeLoc TL =5311DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>();5312TL.setTemplateKeywordLoc(SourceLocation());5313TL.setTemplateNameLoc(NameLoc);5314TL.setLAngleLoc(Args.getLAngleLoc());5315TL.setRAngleLoc(Args.getRAngleLoc());5316for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)5317TL.setArgLocInfo(i, Args[i].getLocInfo());5318return DI;5319}53205321QualType5322ASTContext::getTemplateSpecializationType(TemplateName Template,5323ArrayRef<TemplateArgumentLoc> Args,5324QualType Underlying) const {5325assert(!Template.getAsDependentTemplateName() &&5326"No dependent template names here!");53275328SmallVector<TemplateArgument, 4> ArgVec;5329ArgVec.reserve(Args.size());5330for (const TemplateArgumentLoc &Arg : Args)5331ArgVec.push_back(Arg.getArgument());53325333return getTemplateSpecializationType(Template, ArgVec, Underlying);5334}53355336#ifndef NDEBUG5337static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) {5338for (const TemplateArgument &Arg : Args)5339if (Arg.isPackExpansion())5340return true;53415342return true;5343}5344#endif53455346QualType5347ASTContext::getTemplateSpecializationType(TemplateName Template,5348ArrayRef<TemplateArgument> Args,5349QualType Underlying) const {5350assert(!Template.getAsDependentTemplateName() &&5351"No dependent template names here!");53525353const auto *TD = Template.getAsTemplateDecl();5354bool IsTypeAlias = TD && TD->isTypeAlias();5355QualType CanonType;5356if (!Underlying.isNull())5357CanonType = getCanonicalType(Underlying);5358else {5359// We can get here with an alias template when the specialization contains5360// a pack expansion that does not match up with a parameter pack.5361assert((!IsTypeAlias || hasAnyPackExpansions(Args)) &&5362"Caller must compute aliased type");5363IsTypeAlias = false;5364CanonType = getCanonicalTemplateSpecializationType(Template, Args);5365}53665367// Allocate the (non-canonical) template specialization type, but don't5368// try to unique it: these types typically have location information that5369// we don't unique and don't want to lose.5370void *Mem = Allocate(sizeof(TemplateSpecializationType) +5371sizeof(TemplateArgument) * Args.size() +5372(IsTypeAlias ? sizeof(QualType) : 0),5373alignof(TemplateSpecializationType));5374auto *Spec5375= new (Mem) TemplateSpecializationType(Template, Args, CanonType,5376IsTypeAlias ? Underlying : QualType());53775378Types.push_back(Spec);5379return QualType(Spec, 0);5380}53815382QualType ASTContext::getCanonicalTemplateSpecializationType(5383TemplateName Template, ArrayRef<TemplateArgument> Args) const {5384assert(!Template.getAsDependentTemplateName() &&5385"No dependent template names here!");53865387// Build the canonical template specialization type.5388TemplateName CanonTemplate = getCanonicalTemplateName(Template);5389bool AnyNonCanonArgs = false;5390auto CanonArgs =5391::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);53925393// Determine whether this canonical template specialization type already5394// exists.5395llvm::FoldingSetNodeID ID;5396TemplateSpecializationType::Profile(ID, CanonTemplate,5397CanonArgs, *this);53985399void *InsertPos = nullptr;5400TemplateSpecializationType *Spec5401= TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);54025403if (!Spec) {5404// Allocate a new canonical template specialization type.5405void *Mem = Allocate((sizeof(TemplateSpecializationType) +5406sizeof(TemplateArgument) * CanonArgs.size()),5407alignof(TemplateSpecializationType));5408Spec = new (Mem) TemplateSpecializationType(CanonTemplate,5409CanonArgs,5410QualType(), QualType());5411Types.push_back(Spec);5412TemplateSpecializationTypes.InsertNode(Spec, InsertPos);5413}54145415assert(Spec->isDependentType() &&5416"Non-dependent template-id type must have a canonical type");5417return QualType(Spec, 0);5418}54195420QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,5421NestedNameSpecifier *NNS,5422QualType NamedType,5423TagDecl *OwnedTagDecl) const {5424llvm::FoldingSetNodeID ID;5425ElaboratedType::Profile(ID, Keyword, NNS, NamedType, OwnedTagDecl);54265427void *InsertPos = nullptr;5428ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);5429if (T)5430return QualType(T, 0);54315432QualType Canon = NamedType;5433if (!Canon.isCanonical()) {5434Canon = getCanonicalType(NamedType);5435ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);5436assert(!CheckT && "Elaborated canonical type broken");5437(void)CheckT;5438}54395440void *Mem =5441Allocate(ElaboratedType::totalSizeToAlloc<TagDecl *>(!!OwnedTagDecl),5442alignof(ElaboratedType));5443T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);54445445Types.push_back(T);5446ElaboratedTypes.InsertNode(T, InsertPos);5447return QualType(T, 0);5448}54495450QualType5451ASTContext::getParenType(QualType InnerType) const {5452llvm::FoldingSetNodeID ID;5453ParenType::Profile(ID, InnerType);54545455void *InsertPos = nullptr;5456ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);5457if (T)5458return QualType(T, 0);54595460QualType Canon = InnerType;5461if (!Canon.isCanonical()) {5462Canon = getCanonicalType(InnerType);5463ParenType *CheckT = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);5464assert(!CheckT && "Paren canonical type broken");5465(void)CheckT;5466}54675468T = new (*this, alignof(ParenType)) ParenType(InnerType, Canon);5469Types.push_back(T);5470ParenTypes.InsertNode(T, InsertPos);5471return QualType(T, 0);5472}54735474QualType5475ASTContext::getMacroQualifiedType(QualType UnderlyingTy,5476const IdentifierInfo *MacroII) const {5477QualType Canon = UnderlyingTy;5478if (!Canon.isCanonical())5479Canon = getCanonicalType(UnderlyingTy);54805481auto *newType = new (*this, alignof(MacroQualifiedType))5482MacroQualifiedType(UnderlyingTy, Canon, MacroII);5483Types.push_back(newType);5484return QualType(newType, 0);5485}54865487QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,5488NestedNameSpecifier *NNS,5489const IdentifierInfo *Name,5490QualType Canon) const {5491if (Canon.isNull()) {5492NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);5493if (CanonNNS != NNS)5494Canon = getDependentNameType(Keyword, CanonNNS, Name);5495}54965497llvm::FoldingSetNodeID ID;5498DependentNameType::Profile(ID, Keyword, NNS, Name);54995500void *InsertPos = nullptr;5501DependentNameType *T5502= DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);5503if (T)5504return QualType(T, 0);55055506T = new (*this, alignof(DependentNameType))5507DependentNameType(Keyword, NNS, Name, Canon);5508Types.push_back(T);5509DependentNameTypes.InsertNode(T, InsertPos);5510return QualType(T, 0);5511}55125513QualType ASTContext::getDependentTemplateSpecializationType(5514ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,5515const IdentifierInfo *Name, ArrayRef<TemplateArgumentLoc> Args) const {5516// TODO: avoid this copy5517SmallVector<TemplateArgument, 16> ArgCopy;5518for (unsigned I = 0, E = Args.size(); I != E; ++I)5519ArgCopy.push_back(Args[I].getArgument());5520return getDependentTemplateSpecializationType(Keyword, NNS, Name, ArgCopy);5521}55225523QualType5524ASTContext::getDependentTemplateSpecializationType(5525ElaboratedTypeKeyword Keyword,5526NestedNameSpecifier *NNS,5527const IdentifierInfo *Name,5528ArrayRef<TemplateArgument> Args) const {5529assert((!NNS || NNS->isDependent()) &&5530"nested-name-specifier must be dependent");55315532llvm::FoldingSetNodeID ID;5533DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,5534Name, Args);55355536void *InsertPos = nullptr;5537DependentTemplateSpecializationType *T5538= DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);5539if (T)5540return QualType(T, 0);55415542NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);55435544ElaboratedTypeKeyword CanonKeyword = Keyword;5545if (Keyword == ElaboratedTypeKeyword::None)5546CanonKeyword = ElaboratedTypeKeyword::Typename;55475548bool AnyNonCanonArgs = false;5549auto CanonArgs =5550::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);55515552QualType Canon;5553if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) {5554Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS,5555Name,5556CanonArgs);55575558// Find the insert position again.5559[[maybe_unused]] auto *Nothing =5560DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);5561assert(!Nothing && "canonical type broken");5562}55635564void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) +5565sizeof(TemplateArgument) * Args.size()),5566alignof(DependentTemplateSpecializationType));5567T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS,5568Name, Args, Canon);5569Types.push_back(T);5570DependentTemplateSpecializationTypes.InsertNode(T, InsertPos);5571return QualType(T, 0);5572}55735574TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {5575TemplateArgument Arg;5576if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {5577QualType ArgType = getTypeDeclType(TTP);5578if (TTP->isParameterPack())5579ArgType = getPackExpansionType(ArgType, std::nullopt);55805581Arg = TemplateArgument(ArgType);5582} else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {5583QualType T =5584NTTP->getType().getNonPackExpansionType().getNonLValueExprType(*this);5585// For class NTTPs, ensure we include the 'const' so the type matches that5586// of a real template argument.5587// FIXME: It would be more faithful to model this as something like an5588// lvalue-to-rvalue conversion applied to a const-qualified lvalue.5589if (T->isRecordType())5590T.addConst();5591Expr *E = new (*this) DeclRefExpr(5592*this, NTTP, /*RefersToEnclosingVariableOrCapture*/ false, T,5593Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation());55945595if (NTTP->isParameterPack())5596E = new (*this)5597PackExpansionExpr(DependentTy, E, NTTP->getLocation(), std::nullopt);5598Arg = TemplateArgument(E);5599} else {5600auto *TTP = cast<TemplateTemplateParmDecl>(Param);5601TemplateName Name = getQualifiedTemplateName(5602nullptr, /*TemplateKeyword=*/false, TemplateName(TTP));5603if (TTP->isParameterPack())5604Arg = TemplateArgument(Name, std::optional<unsigned>());5605else5606Arg = TemplateArgument(Name);5607}56085609if (Param->isTemplateParameterPack())5610Arg = TemplateArgument::CreatePackCopy(*this, Arg);56115612return Arg;5613}56145615void5616ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params,5617SmallVectorImpl<TemplateArgument> &Args) {5618Args.reserve(Args.size() + Params->size());56195620for (NamedDecl *Param : *Params)5621Args.push_back(getInjectedTemplateArg(Param));5622}56235624QualType ASTContext::getPackExpansionType(QualType Pattern,5625std::optional<unsigned> NumExpansions,5626bool ExpectPackInType) {5627assert((!ExpectPackInType || Pattern->containsUnexpandedParameterPack()) &&5628"Pack expansions must expand one or more parameter packs");56295630llvm::FoldingSetNodeID ID;5631PackExpansionType::Profile(ID, Pattern, NumExpansions);56325633void *InsertPos = nullptr;5634PackExpansionType *T = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);5635if (T)5636return QualType(T, 0);56375638QualType Canon;5639if (!Pattern.isCanonical()) {5640Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions,5641/*ExpectPackInType=*/false);56425643// Find the insert position again, in case we inserted an element into5644// PackExpansionTypes and invalidated our insert position.5645PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);5646}56475648T = new (*this, alignof(PackExpansionType))5649PackExpansionType(Pattern, Canon, NumExpansions);5650Types.push_back(T);5651PackExpansionTypes.InsertNode(T, InsertPos);5652return QualType(T, 0);5653}56545655/// CmpProtocolNames - Comparison predicate for sorting protocols5656/// alphabetically.5657static int CmpProtocolNames(ObjCProtocolDecl *const *LHS,5658ObjCProtocolDecl *const *RHS) {5659return DeclarationName::compare((*LHS)->getDeclName(), (*RHS)->getDeclName());5660}56615662static bool areSortedAndUniqued(ArrayRef<ObjCProtocolDecl *> Protocols) {5663if (Protocols.empty()) return true;56645665if (Protocols[0]->getCanonicalDecl() != Protocols[0])5666return false;56675668for (unsigned i = 1; i != Protocols.size(); ++i)5669if (CmpProtocolNames(&Protocols[i - 1], &Protocols[i]) >= 0 ||5670Protocols[i]->getCanonicalDecl() != Protocols[i])5671return false;5672return true;5673}56745675static void5676SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) {5677// Sort protocols, keyed by name.5678llvm::array_pod_sort(Protocols.begin(), Protocols.end(), CmpProtocolNames);56795680// Canonicalize.5681for (ObjCProtocolDecl *&P : Protocols)5682P = P->getCanonicalDecl();56835684// Remove duplicates.5685auto ProtocolsEnd = std::unique(Protocols.begin(), Protocols.end());5686Protocols.erase(ProtocolsEnd, Protocols.end());5687}56885689QualType ASTContext::getObjCObjectType(QualType BaseType,5690ObjCProtocolDecl * const *Protocols,5691unsigned NumProtocols) const {5692return getObjCObjectType(BaseType, {},5693llvm::ArrayRef(Protocols, NumProtocols),5694/*isKindOf=*/false);5695}56965697QualType ASTContext::getObjCObjectType(5698QualType baseType,5699ArrayRef<QualType> typeArgs,5700ArrayRef<ObjCProtocolDecl *> protocols,5701bool isKindOf) const {5702// If the base type is an interface and there aren't any protocols or5703// type arguments to add, then the interface type will do just fine.5704if (typeArgs.empty() && protocols.empty() && !isKindOf &&5705isa<ObjCInterfaceType>(baseType))5706return baseType;57075708// Look in the folding set for an existing type.5709llvm::FoldingSetNodeID ID;5710ObjCObjectTypeImpl::Profile(ID, baseType, typeArgs, protocols, isKindOf);5711void *InsertPos = nullptr;5712if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))5713return QualType(QT, 0);57145715// Determine the type arguments to be used for canonicalization,5716// which may be explicitly specified here or written on the base5717// type.5718ArrayRef<QualType> effectiveTypeArgs = typeArgs;5719if (effectiveTypeArgs.empty()) {5720if (const auto *baseObject = baseType->getAs<ObjCObjectType>())5721effectiveTypeArgs = baseObject->getTypeArgs();5722}57235724// Build the canonical type, which has the canonical base type and a5725// sorted-and-uniqued list of protocols and the type arguments5726// canonicalized.5727QualType canonical;5728bool typeArgsAreCanonical = llvm::all_of(5729effectiveTypeArgs, [&](QualType type) { return type.isCanonical(); });5730bool protocolsSorted = areSortedAndUniqued(protocols);5731if (!typeArgsAreCanonical || !protocolsSorted || !baseType.isCanonical()) {5732// Determine the canonical type arguments.5733ArrayRef<QualType> canonTypeArgs;5734SmallVector<QualType, 4> canonTypeArgsVec;5735if (!typeArgsAreCanonical) {5736canonTypeArgsVec.reserve(effectiveTypeArgs.size());5737for (auto typeArg : effectiveTypeArgs)5738canonTypeArgsVec.push_back(getCanonicalType(typeArg));5739canonTypeArgs = canonTypeArgsVec;5740} else {5741canonTypeArgs = effectiveTypeArgs;5742}57435744ArrayRef<ObjCProtocolDecl *> canonProtocols;5745SmallVector<ObjCProtocolDecl*, 8> canonProtocolsVec;5746if (!protocolsSorted) {5747canonProtocolsVec.append(protocols.begin(), protocols.end());5748SortAndUniqueProtocols(canonProtocolsVec);5749canonProtocols = canonProtocolsVec;5750} else {5751canonProtocols = protocols;5752}57535754canonical = getObjCObjectType(getCanonicalType(baseType), canonTypeArgs,5755canonProtocols, isKindOf);57565757// Regenerate InsertPos.5758ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos);5759}57605761unsigned size = sizeof(ObjCObjectTypeImpl);5762size += typeArgs.size() * sizeof(QualType);5763size += protocols.size() * sizeof(ObjCProtocolDecl *);5764void *mem = Allocate(size, alignof(ObjCObjectTypeImpl));5765auto *T =5766new (mem) ObjCObjectTypeImpl(canonical, baseType, typeArgs, protocols,5767isKindOf);57685769Types.push_back(T);5770ObjCObjectTypes.InsertNode(T, InsertPos);5771return QualType(T, 0);5772}57735774/// Apply Objective-C protocol qualifiers to the given type.5775/// If this is for the canonical type of a type parameter, we can apply5776/// protocol qualifiers on the ObjCObjectPointerType.5777QualType5778ASTContext::applyObjCProtocolQualifiers(QualType type,5779ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,5780bool allowOnPointerType) const {5781hasError = false;57825783if (const auto *objT = dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {5784return getObjCTypeParamType(objT->getDecl(), protocols);5785}57865787// Apply protocol qualifiers to ObjCObjectPointerType.5788if (allowOnPointerType) {5789if (const auto *objPtr =5790dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {5791const ObjCObjectType *objT = objPtr->getObjectType();5792// Merge protocol lists and construct ObjCObjectType.5793SmallVector<ObjCProtocolDecl*, 8> protocolsVec;5794protocolsVec.append(objT->qual_begin(),5795objT->qual_end());5796protocolsVec.append(protocols.begin(), protocols.end());5797ArrayRef<ObjCProtocolDecl *> protocols = protocolsVec;5798type = getObjCObjectType(5799objT->getBaseType(),5800objT->getTypeArgsAsWritten(),5801protocols,5802objT->isKindOfTypeAsWritten());5803return getObjCObjectPointerType(type);5804}5805}58065807// Apply protocol qualifiers to ObjCObjectType.5808if (const auto *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){5809// FIXME: Check for protocols to which the class type is already5810// known to conform.58115812return getObjCObjectType(objT->getBaseType(),5813objT->getTypeArgsAsWritten(),5814protocols,5815objT->isKindOfTypeAsWritten());5816}58175818// If the canonical type is ObjCObjectType, ...5819if (type->isObjCObjectType()) {5820// Silently overwrite any existing protocol qualifiers.5821// TODO: determine whether that's the right thing to do.58225823// FIXME: Check for protocols to which the class type is already5824// known to conform.5825return getObjCObjectType(type, {}, protocols, false);5826}58275828// id<protocol-list>5829if (type->isObjCIdType()) {5830const auto *objPtr = type->castAs<ObjCObjectPointerType>();5831type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols,5832objPtr->isKindOfType());5833return getObjCObjectPointerType(type);5834}58355836// Class<protocol-list>5837if (type->isObjCClassType()) {5838const auto *objPtr = type->castAs<ObjCObjectPointerType>();5839type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols,5840objPtr->isKindOfType());5841return getObjCObjectPointerType(type);5842}58435844hasError = true;5845return type;5846}58475848QualType5849ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,5850ArrayRef<ObjCProtocolDecl *> protocols) const {5851// Look in the folding set for an existing type.5852llvm::FoldingSetNodeID ID;5853ObjCTypeParamType::Profile(ID, Decl, Decl->getUnderlyingType(), protocols);5854void *InsertPos = nullptr;5855if (ObjCTypeParamType *TypeParam =5856ObjCTypeParamTypes.FindNodeOrInsertPos(ID, InsertPos))5857return QualType(TypeParam, 0);58585859// We canonicalize to the underlying type.5860QualType Canonical = getCanonicalType(Decl->getUnderlyingType());5861if (!protocols.empty()) {5862// Apply the protocol qualifers.5863bool hasError;5864Canonical = getCanonicalType(applyObjCProtocolQualifiers(5865Canonical, protocols, hasError, true /*allowOnPointerType*/));5866assert(!hasError && "Error when apply protocol qualifier to bound type");5867}58685869unsigned size = sizeof(ObjCTypeParamType);5870size += protocols.size() * sizeof(ObjCProtocolDecl *);5871void *mem = Allocate(size, alignof(ObjCTypeParamType));5872auto *newType = new (mem) ObjCTypeParamType(Decl, Canonical, protocols);58735874Types.push_back(newType);5875ObjCTypeParamTypes.InsertNode(newType, InsertPos);5876return QualType(newType, 0);5877}58785879void ASTContext::adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,5880ObjCTypeParamDecl *New) const {5881New->setTypeSourceInfo(getTrivialTypeSourceInfo(Orig->getUnderlyingType()));5882// Update TypeForDecl after updating TypeSourceInfo.5883auto NewTypeParamTy = cast<ObjCTypeParamType>(New->getTypeForDecl());5884SmallVector<ObjCProtocolDecl *, 8> protocols;5885protocols.append(NewTypeParamTy->qual_begin(), NewTypeParamTy->qual_end());5886QualType UpdatedTy = getObjCTypeParamType(New, protocols);5887New->setTypeForDecl(UpdatedTy.getTypePtr());5888}58895890/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's5891/// protocol list adopt all protocols in QT's qualified-id protocol5892/// list.5893bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT,5894ObjCInterfaceDecl *IC) {5895if (!QT->isObjCQualifiedIdType())5896return false;58975898if (const auto *OPT = QT->getAs<ObjCObjectPointerType>()) {5899// If both the right and left sides have qualifiers.5900for (auto *Proto : OPT->quals()) {5901if (!IC->ClassImplementsProtocol(Proto, false))5902return false;5903}5904return true;5905}5906return false;5907}59085909/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in5910/// QT's qualified-id protocol list adopt all protocols in IDecl's list5911/// of protocols.5912bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,5913ObjCInterfaceDecl *IDecl) {5914if (!QT->isObjCQualifiedIdType())5915return false;5916const auto *OPT = QT->getAs<ObjCObjectPointerType>();5917if (!OPT)5918return false;5919if (!IDecl->hasDefinition())5920return false;5921llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols;5922CollectInheritedProtocols(IDecl, InheritedProtocols);5923if (InheritedProtocols.empty())5924return false;5925// Check that if every protocol in list of id<plist> conforms to a protocol5926// of IDecl's, then bridge casting is ok.5927bool Conforms = false;5928for (auto *Proto : OPT->quals()) {5929Conforms = false;5930for (auto *PI : InheritedProtocols) {5931if (ProtocolCompatibleWithProtocol(Proto, PI)) {5932Conforms = true;5933break;5934}5935}5936if (!Conforms)5937break;5938}5939if (Conforms)5940return true;59415942for (auto *PI : InheritedProtocols) {5943// If both the right and left sides have qualifiers.5944bool Adopts = false;5945for (auto *Proto : OPT->quals()) {5946// return 'true' if 'PI' is in the inheritance hierarchy of Proto5947if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto)))5948break;5949}5950if (!Adopts)5951return false;5952}5953return true;5954}59555956/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for5957/// the given object type.5958QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {5959llvm::FoldingSetNodeID ID;5960ObjCObjectPointerType::Profile(ID, ObjectT);59615962void *InsertPos = nullptr;5963if (ObjCObjectPointerType *QT =5964ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))5965return QualType(QT, 0);59665967// Find the canonical object type.5968QualType Canonical;5969if (!ObjectT.isCanonical()) {5970Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT));59715972// Regenerate InsertPos.5973ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos);5974}59755976// No match.5977void *Mem =5978Allocate(sizeof(ObjCObjectPointerType), alignof(ObjCObjectPointerType));5979auto *QType =5980new (Mem) ObjCObjectPointerType(Canonical, ObjectT);59815982Types.push_back(QType);5983ObjCObjectPointerTypes.InsertNode(QType, InsertPos);5984return QualType(QType, 0);5985}59865987/// getObjCInterfaceType - Return the unique reference to the type for the5988/// specified ObjC interface decl. The list of protocols is optional.5989QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,5990ObjCInterfaceDecl *PrevDecl) const {5991if (Decl->TypeForDecl)5992return QualType(Decl->TypeForDecl, 0);59935994if (PrevDecl) {5995assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");5996Decl->TypeForDecl = PrevDecl->TypeForDecl;5997return QualType(PrevDecl->TypeForDecl, 0);5998}59996000// Prefer the definition, if there is one.6001if (const ObjCInterfaceDecl *Def = Decl->getDefinition())6002Decl = Def;60036004void *Mem = Allocate(sizeof(ObjCInterfaceType), alignof(ObjCInterfaceType));6005auto *T = new (Mem) ObjCInterfaceType(Decl);6006Decl->TypeForDecl = T;6007Types.push_back(T);6008return QualType(T, 0);6009}60106011/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique6012/// TypeOfExprType AST's (since expression's are never shared). For example,6013/// multiple declarations that refer to "typeof(x)" all contain different6014/// DeclRefExpr's. This doesn't effect the type checker, since it operates6015/// on canonical type's (which are always unique).6016QualType ASTContext::getTypeOfExprType(Expr *tofExpr, TypeOfKind Kind) const {6017TypeOfExprType *toe;6018if (tofExpr->isTypeDependent()) {6019llvm::FoldingSetNodeID ID;6020DependentTypeOfExprType::Profile(ID, *this, tofExpr,6021Kind == TypeOfKind::Unqualified);60226023void *InsertPos = nullptr;6024DependentTypeOfExprType *Canon =6025DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);6026if (Canon) {6027// We already have a "canonical" version of an identical, dependent6028// typeof(expr) type. Use that as our canonical type.6029toe = new (*this, alignof(TypeOfExprType)) TypeOfExprType(6030*this, tofExpr, Kind, QualType((TypeOfExprType *)Canon, 0));6031} else {6032// Build a new, canonical typeof(expr) type.6033Canon = new (*this, alignof(DependentTypeOfExprType))6034DependentTypeOfExprType(*this, tofExpr, Kind);6035DependentTypeOfExprTypes.InsertNode(Canon, InsertPos);6036toe = Canon;6037}6038} else {6039QualType Canonical = getCanonicalType(tofExpr->getType());6040toe = new (*this, alignof(TypeOfExprType))6041TypeOfExprType(*this, tofExpr, Kind, Canonical);6042}6043Types.push_back(toe);6044return QualType(toe, 0);6045}60466047/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique6048/// TypeOfType nodes. The only motivation to unique these nodes would be6049/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be6050/// an issue. This doesn't affect the type checker, since it operates6051/// on canonical types (which are always unique).6052QualType ASTContext::getTypeOfType(QualType tofType, TypeOfKind Kind) const {6053QualType Canonical = getCanonicalType(tofType);6054auto *tot = new (*this, alignof(TypeOfType))6055TypeOfType(*this, tofType, Canonical, Kind);6056Types.push_back(tot);6057return QualType(tot, 0);6058}60596060/// getReferenceQualifiedType - Given an expr, will return the type for6061/// that expression, as in [dcl.type.simple]p4 but without taking id-expressions6062/// and class member access into account.6063QualType ASTContext::getReferenceQualifiedType(const Expr *E) const {6064// C++11 [dcl.type.simple]p4:6065// [...]6066QualType T = E->getType();6067switch (E->getValueKind()) {6068// - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the6069// type of e;6070case VK_XValue:6071return getRValueReferenceType(T);6072// - otherwise, if e is an lvalue, decltype(e) is T&, where T is the6073// type of e;6074case VK_LValue:6075return getLValueReferenceType(T);6076// - otherwise, decltype(e) is the type of e.6077case VK_PRValue:6078return T;6079}6080llvm_unreachable("Unknown value kind");6081}60826083/// Unlike many "get<Type>" functions, we don't unique DecltypeType6084/// nodes. This would never be helpful, since each such type has its own6085/// expression, and would not give a significant memory saving, since there6086/// is an Expr tree under each such type.6087QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {6088DecltypeType *dt;60896090// C++11 [temp.type]p2:6091// If an expression e involves a template parameter, decltype(e) denotes a6092// unique dependent type. Two such decltype-specifiers refer to the same6093// type only if their expressions are equivalent (14.5.6.1).6094if (e->isInstantiationDependent()) {6095llvm::FoldingSetNodeID ID;6096DependentDecltypeType::Profile(ID, *this, e);60976098void *InsertPos = nullptr;6099DependentDecltypeType *Canon6100= DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);6101if (!Canon) {6102// Build a new, canonical decltype(expr) type.6103Canon = new (*this, alignof(DependentDecltypeType))6104DependentDecltypeType(e, DependentTy);6105DependentDecltypeTypes.InsertNode(Canon, InsertPos);6106}6107dt = new (*this, alignof(DecltypeType))6108DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));6109} else {6110dt = new (*this, alignof(DecltypeType))6111DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));6112}6113Types.push_back(dt);6114return QualType(dt, 0);6115}61166117QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,6118bool FullySubstituted,6119ArrayRef<QualType> Expansions,6120int Index) const {6121QualType Canonical;6122if (FullySubstituted && Index != -1) {6123Canonical = getCanonicalType(Expansions[Index]);6124} else {6125llvm::FoldingSetNodeID ID;6126PackIndexingType::Profile(ID, *this, Pattern, IndexExpr);6127void *InsertPos = nullptr;6128PackIndexingType *Canon =6129DependentPackIndexingTypes.FindNodeOrInsertPos(ID, InsertPos);6130if (!Canon) {6131void *Mem = Allocate(6132PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),6133TypeAlignment);6134Canon = new (Mem)6135PackIndexingType(*this, QualType(), Pattern, IndexExpr, Expansions);6136DependentPackIndexingTypes.InsertNode(Canon, InsertPos);6137}6138Canonical = QualType(Canon, 0);6139}61406141void *Mem =6142Allocate(PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),6143TypeAlignment);6144auto *T = new (Mem)6145PackIndexingType(*this, Canonical, Pattern, IndexExpr, Expansions);6146Types.push_back(T);6147return QualType(T, 0);6148}61496150/// getUnaryTransformationType - We don't unique these, since the memory6151/// savings are minimal and these are rare.6152QualType ASTContext::getUnaryTransformType(QualType BaseType,6153QualType UnderlyingType,6154UnaryTransformType::UTTKind Kind)6155const {6156UnaryTransformType *ut = nullptr;61576158if (BaseType->isDependentType()) {6159// Look in the folding set for an existing type.6160llvm::FoldingSetNodeID ID;6161DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind);61626163void *InsertPos = nullptr;6164DependentUnaryTransformType *Canon6165= DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos);61666167if (!Canon) {6168// Build a new, canonical __underlying_type(type) type.6169Canon = new (*this, alignof(DependentUnaryTransformType))6170DependentUnaryTransformType(*this, getCanonicalType(BaseType), Kind);6171DependentUnaryTransformTypes.InsertNode(Canon, InsertPos);6172}6173ut = new (*this, alignof(UnaryTransformType))6174UnaryTransformType(BaseType, QualType(), Kind, QualType(Canon, 0));6175} else {6176QualType CanonType = getCanonicalType(UnderlyingType);6177ut = new (*this, alignof(UnaryTransformType))6178UnaryTransformType(BaseType, UnderlyingType, Kind, CanonType);6179}6180Types.push_back(ut);6181return QualType(ut, 0);6182}61836184QualType ASTContext::getAutoTypeInternal(6185QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent,6186bool IsPack, ConceptDecl *TypeConstraintConcept,6187ArrayRef<TemplateArgument> TypeConstraintArgs, bool IsCanon) const {6188if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto &&6189!TypeConstraintConcept && !IsDependent)6190return getAutoDeductType();61916192// Look in the folding set for an existing type.6193void *InsertPos = nullptr;6194llvm::FoldingSetNodeID ID;6195AutoType::Profile(ID, *this, DeducedType, Keyword, IsDependent,6196TypeConstraintConcept, TypeConstraintArgs);6197if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))6198return QualType(AT, 0);61996200QualType Canon;6201if (!IsCanon) {6202if (!DeducedType.isNull()) {6203Canon = DeducedType.getCanonicalType();6204} else if (TypeConstraintConcept) {6205bool AnyNonCanonArgs = false;6206ConceptDecl *CanonicalConcept = TypeConstraintConcept->getCanonicalDecl();6207auto CanonicalConceptArgs = ::getCanonicalTemplateArguments(6208*this, TypeConstraintArgs, AnyNonCanonArgs);6209if (CanonicalConcept != TypeConstraintConcept || AnyNonCanonArgs) {6210Canon =6211getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,6212CanonicalConcept, CanonicalConceptArgs, true);6213// Find the insert position again.6214[[maybe_unused]] auto *Nothing =6215AutoTypes.FindNodeOrInsertPos(ID, InsertPos);6216assert(!Nothing && "canonical type broken");6217}6218}6219}62206221void *Mem = Allocate(sizeof(AutoType) +6222sizeof(TemplateArgument) * TypeConstraintArgs.size(),6223alignof(AutoType));6224auto *AT = new (Mem) AutoType(6225DeducedType, Keyword,6226(IsDependent ? TypeDependence::DependentInstantiation6227: TypeDependence::None) |6228(IsPack ? TypeDependence::UnexpandedPack : TypeDependence::None),6229Canon, TypeConstraintConcept, TypeConstraintArgs);6230Types.push_back(AT);6231AutoTypes.InsertNode(AT, InsertPos);6232return QualType(AT, 0);6233}62346235/// getAutoType - Return the uniqued reference to the 'auto' type which has been6236/// deduced to the given type, or to the canonical undeduced 'auto' type, or the6237/// canonical deduced-but-dependent 'auto' type.6238QualType6239ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,6240bool IsDependent, bool IsPack,6241ConceptDecl *TypeConstraintConcept,6242ArrayRef<TemplateArgument> TypeConstraintArgs) const {6243assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack");6244assert((!IsDependent || DeducedType.isNull()) &&6245"A dependent auto should be undeduced");6246return getAutoTypeInternal(DeducedType, Keyword, IsDependent, IsPack,6247TypeConstraintConcept, TypeConstraintArgs);6248}62496250QualType ASTContext::getUnconstrainedType(QualType T) const {6251QualType CanonT = T.getCanonicalType();62526253// Remove a type-constraint from a top-level auto or decltype(auto).6254if (auto *AT = CanonT->getAs<AutoType>()) {6255if (!AT->isConstrained())6256return T;6257return getQualifiedType(getAutoType(QualType(), AT->getKeyword(),6258AT->isDependentType(),6259AT->containsUnexpandedParameterPack()),6260T.getQualifiers());6261}62626263// FIXME: We only support constrained auto at the top level in the type of a6264// non-type template parameter at the moment. Once we lift that restriction,6265// we'll need to recursively build types containing auto here.6266assert(!CanonT->getContainedAutoType() ||6267!CanonT->getContainedAutoType()->isConstrained());6268return T;6269}62706271/// Return the uniqued reference to the deduced template specialization type6272/// which has been deduced to the given type, or to the canonical undeduced6273/// such type, or the canonical deduced-but-dependent such type.6274QualType ASTContext::getDeducedTemplateSpecializationType(6275TemplateName Template, QualType DeducedType, bool IsDependent) const {6276// Look in the folding set for an existing type.6277void *InsertPos = nullptr;6278llvm::FoldingSetNodeID ID;6279DeducedTemplateSpecializationType::Profile(ID, Template, DeducedType,6280IsDependent);6281if (DeducedTemplateSpecializationType *DTST =6282DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos))6283return QualType(DTST, 0);62846285auto *DTST = new (*this, alignof(DeducedTemplateSpecializationType))6286DeducedTemplateSpecializationType(Template, DeducedType, IsDependent);6287llvm::FoldingSetNodeID TempID;6288DTST->Profile(TempID);6289assert(ID == TempID && "ID does not match");6290Types.push_back(DTST);6291DeducedTemplateSpecializationTypes.InsertNode(DTST, InsertPos);6292return QualType(DTST, 0);6293}62946295/// getAtomicType - Return the uniqued reference to the atomic type for6296/// the given value type.6297QualType ASTContext::getAtomicType(QualType T) const {6298// Unique pointers, to guarantee there is only one pointer of a particular6299// structure.6300llvm::FoldingSetNodeID ID;6301AtomicType::Profile(ID, T);63026303void *InsertPos = nullptr;6304if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos))6305return QualType(AT, 0);63066307// If the atomic value type isn't canonical, this won't be a canonical type6308// either, so fill in the canonical type field.6309QualType Canonical;6310if (!T.isCanonical()) {6311Canonical = getAtomicType(getCanonicalType(T));63126313// Get the new insert position for the node we care about.6314AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);6315assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;6316}6317auto *New = new (*this, alignof(AtomicType)) AtomicType(T, Canonical);6318Types.push_back(New);6319AtomicTypes.InsertNode(New, InsertPos);6320return QualType(New, 0);6321}63226323/// getAutoDeductType - Get type pattern for deducing against 'auto'.6324QualType ASTContext::getAutoDeductType() const {6325if (AutoDeductTy.isNull())6326AutoDeductTy = QualType(new (*this, alignof(AutoType))6327AutoType(QualType(), AutoTypeKeyword::Auto,6328TypeDependence::None, QualType(),6329/*concept*/ nullptr, /*args*/ {}),63300);6331return AutoDeductTy;6332}63336334/// getAutoRRefDeductType - Get type pattern for deducing against 'auto &&'.6335QualType ASTContext::getAutoRRefDeductType() const {6336if (AutoRRefDeductTy.isNull())6337AutoRRefDeductTy = getRValueReferenceType(getAutoDeductType());6338assert(!AutoRRefDeductTy.isNull() && "can't build 'auto &&' pattern");6339return AutoRRefDeductTy;6340}63416342/// getTagDeclType - Return the unique reference to the type for the6343/// specified TagDecl (struct/union/class/enum) decl.6344QualType ASTContext::getTagDeclType(const TagDecl *Decl) const {6345assert(Decl);6346// FIXME: What is the design on getTagDeclType when it requires casting6347// away const? mutable?6348return getTypeDeclType(const_cast<TagDecl*>(Decl));6349}63506351/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result6352/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and6353/// needs to agree with the definition in <stddef.h>.6354CanQualType ASTContext::getSizeType() const {6355return getFromTargetType(Target->getSizeType());6356}63576358/// Return the unique signed counterpart of the integer type6359/// corresponding to size_t.6360CanQualType ASTContext::getSignedSizeType() const {6361return getFromTargetType(Target->getSignedSizeType());6362}63636364/// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5).6365CanQualType ASTContext::getIntMaxType() const {6366return getFromTargetType(Target->getIntMaxType());6367}63686369/// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5).6370CanQualType ASTContext::getUIntMaxType() const {6371return getFromTargetType(Target->getUIntMaxType());6372}63736374/// getSignedWCharType - Return the type of "signed wchar_t".6375/// Used when in C++, as a GCC extension.6376QualType ASTContext::getSignedWCharType() const {6377// FIXME: derive from "Target" ?6378return WCharTy;6379}63806381/// getUnsignedWCharType - Return the type of "unsigned wchar_t".6382/// Used when in C++, as a GCC extension.6383QualType ASTContext::getUnsignedWCharType() const {6384// FIXME: derive from "Target" ?6385return UnsignedIntTy;6386}63876388QualType ASTContext::getIntPtrType() const {6389return getFromTargetType(Target->getIntPtrType());6390}63916392QualType ASTContext::getUIntPtrType() const {6393return getCorrespondingUnsignedType(getIntPtrType());6394}63956396/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)6397/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).6398QualType ASTContext::getPointerDiffType() const {6399return getFromTargetType(Target->getPtrDiffType(LangAS::Default));6400}64016402/// Return the unique unsigned counterpart of "ptrdiff_t"6403/// integer type. The standard (C11 7.21.6.1p7) refers to this type6404/// in the definition of %tu format specifier.6405QualType ASTContext::getUnsignedPointerDiffType() const {6406return getFromTargetType(Target->getUnsignedPtrDiffType(LangAS::Default));6407}64086409/// Return the unique type for "pid_t" defined in6410/// <sys/types.h>. We need this to compute the correct type for vfork().6411QualType ASTContext::getProcessIDType() const {6412return getFromTargetType(Target->getProcessIDType());6413}64146415//===----------------------------------------------------------------------===//6416// Type Operators6417//===----------------------------------------------------------------------===//64186419CanQualType ASTContext::getCanonicalParamType(QualType T) const {6420// Push qualifiers into arrays, and then discard any remaining6421// qualifiers.6422T = getCanonicalType(T);6423T = getVariableArrayDecayedType(T);6424const Type *Ty = T.getTypePtr();6425QualType Result;6426if (getLangOpts().HLSL && isa<ConstantArrayType>(Ty)) {6427Result = getArrayParameterType(QualType(Ty, 0));6428} else if (isa<ArrayType>(Ty)) {6429Result = getArrayDecayedType(QualType(Ty,0));6430} else if (isa<FunctionType>(Ty)) {6431Result = getPointerType(QualType(Ty, 0));6432} else {6433Result = QualType(Ty, 0);6434}64356436return CanQualType::CreateUnsafe(Result);6437}64386439QualType ASTContext::getUnqualifiedArrayType(QualType type,6440Qualifiers &quals) const {6441SplitQualType splitType = type.getSplitUnqualifiedType();64426443// FIXME: getSplitUnqualifiedType() actually walks all the way to6444// the unqualified desugared type and then drops it on the floor.6445// We then have to strip that sugar back off with6446// getUnqualifiedDesugaredType(), which is silly.6447const auto *AT =6448dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());64496450// If we don't have an array, just use the results in splitType.6451if (!AT) {6452quals = splitType.Quals;6453return QualType(splitType.Ty, 0);6454}64556456// Otherwise, recurse on the array's element type.6457QualType elementType = AT->getElementType();6458QualType unqualElementType = getUnqualifiedArrayType(elementType, quals);64596460// If that didn't change the element type, AT has no qualifiers, so we6461// can just use the results in splitType.6462if (elementType == unqualElementType) {6463assert(quals.empty()); // from the recursive call6464quals = splitType.Quals;6465return QualType(splitType.Ty, 0);6466}64676468// Otherwise, add in the qualifiers from the outermost type, then6469// build the type back up.6470quals.addConsistentQualifiers(splitType.Quals);64716472if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {6473return getConstantArrayType(unqualElementType, CAT->getSize(),6474CAT->getSizeExpr(), CAT->getSizeModifier(), 0);6475}64766477if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) {6478return getIncompleteArrayType(unqualElementType, IAT->getSizeModifier(), 0);6479}64806481if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) {6482return getVariableArrayType(unqualElementType,6483VAT->getSizeExpr(),6484VAT->getSizeModifier(),6485VAT->getIndexTypeCVRQualifiers(),6486VAT->getBracketsRange());6487}64886489const auto *DSAT = cast<DependentSizedArrayType>(AT);6490return getDependentSizedArrayType(unqualElementType, DSAT->getSizeExpr(),6491DSAT->getSizeModifier(), 0,6492SourceRange());6493}64946495/// Attempt to unwrap two types that may both be array types with the same bound6496/// (or both be array types of unknown bound) for the purpose of comparing the6497/// cv-decomposition of two types per C++ [conv.qual].6498///6499/// \param AllowPiMismatch Allow the Pi1 and Pi2 to differ as described in6500/// C++20 [conv.qual], if permitted by the current language mode.6501void ASTContext::UnwrapSimilarArrayTypes(QualType &T1, QualType &T2,6502bool AllowPiMismatch) {6503while (true) {6504auto *AT1 = getAsArrayType(T1);6505if (!AT1)6506return;65076508auto *AT2 = getAsArrayType(T2);6509if (!AT2)6510return;65116512// If we don't have two array types with the same constant bound nor two6513// incomplete array types, we've unwrapped everything we can.6514// C++20 also permits one type to be a constant array type and the other6515// to be an incomplete array type.6516// FIXME: Consider also unwrapping array of unknown bound and VLA.6517if (auto *CAT1 = dyn_cast<ConstantArrayType>(AT1)) {6518auto *CAT2 = dyn_cast<ConstantArrayType>(AT2);6519if (!((CAT2 && CAT1->getSize() == CAT2->getSize()) ||6520(AllowPiMismatch && getLangOpts().CPlusPlus20 &&6521isa<IncompleteArrayType>(AT2))))6522return;6523} else if (isa<IncompleteArrayType>(AT1)) {6524if (!(isa<IncompleteArrayType>(AT2) ||6525(AllowPiMismatch && getLangOpts().CPlusPlus20 &&6526isa<ConstantArrayType>(AT2))))6527return;6528} else {6529return;6530}65316532T1 = AT1->getElementType();6533T2 = AT2->getElementType();6534}6535}65366537/// Attempt to unwrap two types that may be similar (C++ [conv.qual]).6538///6539/// If T1 and T2 are both pointer types of the same kind, or both array types6540/// with the same bound, unwraps layers from T1 and T2 until a pointer type is6541/// unwrapped. Top-level qualifiers on T1 and T2 are ignored.6542///6543/// This function will typically be called in a loop that successively6544/// "unwraps" pointer and pointer-to-member types to compare them at each6545/// level.6546///6547/// \param AllowPiMismatch Allow the Pi1 and Pi2 to differ as described in6548/// C++20 [conv.qual], if permitted by the current language mode.6549///6550/// \return \c true if a pointer type was unwrapped, \c false if we reached a6551/// pair of types that can't be unwrapped further.6552bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,6553bool AllowPiMismatch) {6554UnwrapSimilarArrayTypes(T1, T2, AllowPiMismatch);65556556const auto *T1PtrType = T1->getAs<PointerType>();6557const auto *T2PtrType = T2->getAs<PointerType>();6558if (T1PtrType && T2PtrType) {6559T1 = T1PtrType->getPointeeType();6560T2 = T2PtrType->getPointeeType();6561return true;6562}65636564const auto *T1MPType = T1->getAs<MemberPointerType>();6565const auto *T2MPType = T2->getAs<MemberPointerType>();6566if (T1MPType && T2MPType &&6567hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),6568QualType(T2MPType->getClass(), 0))) {6569T1 = T1MPType->getPointeeType();6570T2 = T2MPType->getPointeeType();6571return true;6572}65736574if (getLangOpts().ObjC) {6575const auto *T1OPType = T1->getAs<ObjCObjectPointerType>();6576const auto *T2OPType = T2->getAs<ObjCObjectPointerType>();6577if (T1OPType && T2OPType) {6578T1 = T1OPType->getPointeeType();6579T2 = T2OPType->getPointeeType();6580return true;6581}6582}65836584// FIXME: Block pointers, too?65856586return false;6587}65886589bool ASTContext::hasSimilarType(QualType T1, QualType T2) {6590while (true) {6591Qualifiers Quals;6592T1 = getUnqualifiedArrayType(T1, Quals);6593T2 = getUnqualifiedArrayType(T2, Quals);6594if (hasSameType(T1, T2))6595return true;6596if (!UnwrapSimilarTypes(T1, T2))6597return false;6598}6599}66006601bool ASTContext::hasCvrSimilarType(QualType T1, QualType T2) {6602while (true) {6603Qualifiers Quals1, Quals2;6604T1 = getUnqualifiedArrayType(T1, Quals1);6605T2 = getUnqualifiedArrayType(T2, Quals2);66066607Quals1.removeCVRQualifiers();6608Quals2.removeCVRQualifiers();6609if (Quals1 != Quals2)6610return false;66116612if (hasSameType(T1, T2))6613return true;66146615if (!UnwrapSimilarTypes(T1, T2, /*AllowPiMismatch*/ false))6616return false;6617}6618}66196620DeclarationNameInfo6621ASTContext::getNameForTemplate(TemplateName Name,6622SourceLocation NameLoc) const {6623switch (Name.getKind()) {6624case TemplateName::QualifiedTemplate:6625case TemplateName::Template:6626// DNInfo work in progress: CHECKME: what about DNLoc?6627return DeclarationNameInfo(Name.getAsTemplateDecl()->getDeclName(),6628NameLoc);66296630case TemplateName::OverloadedTemplate: {6631OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();6632// DNInfo work in progress: CHECKME: what about DNLoc?6633return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);6634}66356636case TemplateName::AssumedTemplate: {6637AssumedTemplateStorage *Storage = Name.getAsAssumedTemplateName();6638return DeclarationNameInfo(Storage->getDeclName(), NameLoc);6639}66406641case TemplateName::DependentTemplate: {6642DependentTemplateName *DTN = Name.getAsDependentTemplateName();6643DeclarationName DName;6644if (DTN->isIdentifier()) {6645DName = DeclarationNames.getIdentifier(DTN->getIdentifier());6646return DeclarationNameInfo(DName, NameLoc);6647} else {6648DName = DeclarationNames.getCXXOperatorName(DTN->getOperator());6649// DNInfo work in progress: FIXME: source locations?6650DeclarationNameLoc DNLoc =6651DeclarationNameLoc::makeCXXOperatorNameLoc(SourceRange());6652return DeclarationNameInfo(DName, NameLoc, DNLoc);6653}6654}66556656case TemplateName::SubstTemplateTemplateParm: {6657SubstTemplateTemplateParmStorage *subst6658= Name.getAsSubstTemplateTemplateParm();6659return DeclarationNameInfo(subst->getParameter()->getDeclName(),6660NameLoc);6661}66626663case TemplateName::SubstTemplateTemplateParmPack: {6664SubstTemplateTemplateParmPackStorage *subst6665= Name.getAsSubstTemplateTemplateParmPack();6666return DeclarationNameInfo(subst->getParameterPack()->getDeclName(),6667NameLoc);6668}6669case TemplateName::UsingTemplate:6670return DeclarationNameInfo(Name.getAsUsingShadowDecl()->getDeclName(),6671NameLoc);6672}66736674llvm_unreachable("bad template name kind!");6675}66766677TemplateName6678ASTContext::getCanonicalTemplateName(const TemplateName &Name) const {6679switch (Name.getKind()) {6680case TemplateName::UsingTemplate:6681case TemplateName::QualifiedTemplate:6682case TemplateName::Template: {6683TemplateDecl *Template = Name.getAsTemplateDecl();6684if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template))6685Template = getCanonicalTemplateTemplateParmDecl(TTP);66866687// The canonical template name is the canonical template declaration.6688return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));6689}66906691case TemplateName::OverloadedTemplate:6692case TemplateName::AssumedTemplate:6693llvm_unreachable("cannot canonicalize unresolved template");66946695case TemplateName::DependentTemplate: {6696DependentTemplateName *DTN = Name.getAsDependentTemplateName();6697assert(DTN && "Non-dependent template names must refer to template decls.");6698return DTN->CanonicalTemplateName;6699}67006701case TemplateName::SubstTemplateTemplateParm: {6702SubstTemplateTemplateParmStorage *subst6703= Name.getAsSubstTemplateTemplateParm();6704return getCanonicalTemplateName(subst->getReplacement());6705}67066707case TemplateName::SubstTemplateTemplateParmPack: {6708SubstTemplateTemplateParmPackStorage *subst =6709Name.getAsSubstTemplateTemplateParmPack();6710TemplateArgument canonArgPack =6711getCanonicalTemplateArgument(subst->getArgumentPack());6712return getSubstTemplateTemplateParmPack(6713canonArgPack, subst->getAssociatedDecl()->getCanonicalDecl(),6714subst->getFinal(), subst->getIndex());6715}6716}67176718llvm_unreachable("bad template name!");6719}67206721bool ASTContext::hasSameTemplateName(const TemplateName &X,6722const TemplateName &Y) const {6723return getCanonicalTemplateName(X).getAsVoidPointer() ==6724getCanonicalTemplateName(Y).getAsVoidPointer();6725}67266727bool ASTContext::isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const {6728if (!XCE != !YCE)6729return false;67306731if (!XCE)6732return true;67336734llvm::FoldingSetNodeID XCEID, YCEID;6735XCE->Profile(XCEID, *this, /*Canonical=*/true, /*ProfileLambdaExpr=*/true);6736YCE->Profile(YCEID, *this, /*Canonical=*/true, /*ProfileLambdaExpr=*/true);6737return XCEID == YCEID;6738}67396740bool ASTContext::isSameTypeConstraint(const TypeConstraint *XTC,6741const TypeConstraint *YTC) const {6742if (!XTC != !YTC)6743return false;67446745if (!XTC)6746return true;67476748auto *NCX = XTC->getNamedConcept();6749auto *NCY = YTC->getNamedConcept();6750if (!NCX || !NCY || !isSameEntity(NCX, NCY))6751return false;6752if (XTC->getConceptReference()->hasExplicitTemplateArgs() !=6753YTC->getConceptReference()->hasExplicitTemplateArgs())6754return false;6755if (XTC->getConceptReference()->hasExplicitTemplateArgs())6756if (XTC->getConceptReference()6757->getTemplateArgsAsWritten()6758->NumTemplateArgs !=6759YTC->getConceptReference()->getTemplateArgsAsWritten()->NumTemplateArgs)6760return false;67616762// Compare slowly by profiling.6763//6764// We couldn't compare the profiling result for the template6765// args here. Consider the following example in different modules:6766//6767// template <__integer_like _Tp, C<_Tp> Sentinel>6768// constexpr _Tp operator()(_Tp &&__t, Sentinel &&last) const {6769// return __t;6770// }6771//6772// When we compare the profiling result for `C<_Tp>` in different6773// modules, it will compare the type of `_Tp` in different modules.6774// However, the type of `_Tp` in different modules refer to different6775// types here naturally. So we couldn't compare the profiling result6776// for the template args directly.6777return isSameConstraintExpr(XTC->getImmediatelyDeclaredConstraint(),6778YTC->getImmediatelyDeclaredConstraint());6779}67806781bool ASTContext::isSameTemplateParameter(const NamedDecl *X,6782const NamedDecl *Y) const {6783if (X->getKind() != Y->getKind())6784return false;67856786if (auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) {6787auto *TY = cast<TemplateTypeParmDecl>(Y);6788if (TX->isParameterPack() != TY->isParameterPack())6789return false;6790if (TX->hasTypeConstraint() != TY->hasTypeConstraint())6791return false;6792return isSameTypeConstraint(TX->getTypeConstraint(),6793TY->getTypeConstraint());6794}67956796if (auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) {6797auto *TY = cast<NonTypeTemplateParmDecl>(Y);6798return TX->isParameterPack() == TY->isParameterPack() &&6799TX->getASTContext().hasSameType(TX->getType(), TY->getType()) &&6800isSameConstraintExpr(TX->getPlaceholderTypeConstraint(),6801TY->getPlaceholderTypeConstraint());6802}68036804auto *TX = cast<TemplateTemplateParmDecl>(X);6805auto *TY = cast<TemplateTemplateParmDecl>(Y);6806return TX->isParameterPack() == TY->isParameterPack() &&6807isSameTemplateParameterList(TX->getTemplateParameters(),6808TY->getTemplateParameters());6809}68106811bool ASTContext::isSameTemplateParameterList(6812const TemplateParameterList *X, const TemplateParameterList *Y) const {6813if (X->size() != Y->size())6814return false;68156816for (unsigned I = 0, N = X->size(); I != N; ++I)6817if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I)))6818return false;68196820return isSameConstraintExpr(X->getRequiresClause(), Y->getRequiresClause());6821}68226823bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X,6824const NamedDecl *Y) const {6825// If the type parameter isn't the same already, we don't need to check the6826// default argument further.6827if (!isSameTemplateParameter(X, Y))6828return false;68296830if (auto *TTPX = dyn_cast<TemplateTypeParmDecl>(X)) {6831auto *TTPY = cast<TemplateTypeParmDecl>(Y);6832if (!TTPX->hasDefaultArgument() || !TTPY->hasDefaultArgument())6833return false;68346835return hasSameType(TTPX->getDefaultArgument().getArgument().getAsType(),6836TTPY->getDefaultArgument().getArgument().getAsType());6837}68386839if (auto *NTTPX = dyn_cast<NonTypeTemplateParmDecl>(X)) {6840auto *NTTPY = cast<NonTypeTemplateParmDecl>(Y);6841if (!NTTPX->hasDefaultArgument() || !NTTPY->hasDefaultArgument())6842return false;68436844Expr *DefaultArgumentX =6845NTTPX->getDefaultArgument().getArgument().getAsExpr()->IgnoreImpCasts();6846Expr *DefaultArgumentY =6847NTTPY->getDefaultArgument().getArgument().getAsExpr()->IgnoreImpCasts();6848llvm::FoldingSetNodeID XID, YID;6849DefaultArgumentX->Profile(XID, *this, /*Canonical=*/true);6850DefaultArgumentY->Profile(YID, *this, /*Canonical=*/true);6851return XID == YID;6852}68536854auto *TTPX = cast<TemplateTemplateParmDecl>(X);6855auto *TTPY = cast<TemplateTemplateParmDecl>(Y);68566857if (!TTPX->hasDefaultArgument() || !TTPY->hasDefaultArgument())6858return false;68596860const TemplateArgument &TAX = TTPX->getDefaultArgument().getArgument();6861const TemplateArgument &TAY = TTPY->getDefaultArgument().getArgument();6862return hasSameTemplateName(TAX.getAsTemplate(), TAY.getAsTemplate());6863}68646865static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) {6866if (auto *NS = X->getAsNamespace())6867return NS;6868if (auto *NAS = X->getAsNamespaceAlias())6869return NAS->getNamespace();6870return nullptr;6871}68726873static bool isSameQualifier(const NestedNameSpecifier *X,6874const NestedNameSpecifier *Y) {6875if (auto *NSX = getNamespace(X)) {6876auto *NSY = getNamespace(Y);6877if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl())6878return false;6879} else if (X->getKind() != Y->getKind())6880return false;68816882// FIXME: For namespaces and types, we're permitted to check that the entity6883// is named via the same tokens. We should probably do so.6884switch (X->getKind()) {6885case NestedNameSpecifier::Identifier:6886if (X->getAsIdentifier() != Y->getAsIdentifier())6887return false;6888break;6889case NestedNameSpecifier::Namespace:6890case NestedNameSpecifier::NamespaceAlias:6891// We've already checked that we named the same namespace.6892break;6893case NestedNameSpecifier::TypeSpec:6894case NestedNameSpecifier::TypeSpecWithTemplate:6895if (X->getAsType()->getCanonicalTypeInternal() !=6896Y->getAsType()->getCanonicalTypeInternal())6897return false;6898break;6899case NestedNameSpecifier::Global:6900case NestedNameSpecifier::Super:6901return true;6902}69036904// Recurse into earlier portion of NNS, if any.6905auto *PX = X->getPrefix();6906auto *PY = Y->getPrefix();6907if (PX && PY)6908return isSameQualifier(PX, PY);6909return !PX && !PY;6910}69116912/// Determine whether the attributes we can overload on are identical for A and6913/// B. Will ignore any overloadable attrs represented in the type of A and B.6914static bool hasSameOverloadableAttrs(const FunctionDecl *A,6915const FunctionDecl *B) {6916// Note that pass_object_size attributes are represented in the function's6917// ExtParameterInfo, so we don't need to check them here.69186919llvm::FoldingSetNodeID Cand1ID, Cand2ID;6920auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>();6921auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>();69226923for (auto Pair : zip_longest(AEnableIfAttrs, BEnableIfAttrs)) {6924std::optional<EnableIfAttr *> Cand1A = std::get<0>(Pair);6925std::optional<EnableIfAttr *> Cand2A = std::get<1>(Pair);69266927// Return false if the number of enable_if attributes is different.6928if (!Cand1A || !Cand2A)6929return false;69306931Cand1ID.clear();6932Cand2ID.clear();69336934(*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true);6935(*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true);69366937// Return false if any of the enable_if expressions of A and B are6938// different.6939if (Cand1ID != Cand2ID)6940return false;6941}6942return true;6943}69446945bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) const {6946// Caution: this function is called by the AST reader during deserialization,6947// so it cannot rely on AST invariants being met. Non-trivial accessors6948// should be avoided, along with any traversal of redeclaration chains.69496950if (X == Y)6951return true;69526953if (X->getDeclName() != Y->getDeclName())6954return false;69556956// Must be in the same context.6957//6958// Note that we can't use DeclContext::Equals here, because the DeclContexts6959// could be two different declarations of the same function. (We will fix the6960// semantic DC to refer to the primary definition after merging.)6961if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()),6962cast<Decl>(Y->getDeclContext()->getRedeclContext())))6963return false;69646965// Two typedefs refer to the same entity if they have the same underlying6966// type.6967if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X))6968if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y))6969return hasSameType(TypedefX->getUnderlyingType(),6970TypedefY->getUnderlyingType());69716972// Must have the same kind.6973if (X->getKind() != Y->getKind())6974return false;69756976// Objective-C classes and protocols with the same name always match.6977if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))6978return true;69796980if (isa<ClassTemplateSpecializationDecl>(X)) {6981// No need to handle these here: we merge them when adding them to the6982// template.6983return false;6984}69856986// Compatible tags match.6987if (const auto *TagX = dyn_cast<TagDecl>(X)) {6988const auto *TagY = cast<TagDecl>(Y);6989return (TagX->getTagKind() == TagY->getTagKind()) ||6990((TagX->getTagKind() == TagTypeKind::Struct ||6991TagX->getTagKind() == TagTypeKind::Class ||6992TagX->getTagKind() == TagTypeKind::Interface) &&6993(TagY->getTagKind() == TagTypeKind::Struct ||6994TagY->getTagKind() == TagTypeKind::Class ||6995TagY->getTagKind() == TagTypeKind::Interface));6996}69976998// Functions with the same type and linkage match.6999// FIXME: This needs to cope with merging of prototyped/non-prototyped7000// functions, etc.7001if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) {7002const auto *FuncY = cast<FunctionDecl>(Y);7003if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) {7004const auto *CtorY = cast<CXXConstructorDecl>(Y);7005if (CtorX->getInheritedConstructor() &&7006!isSameEntity(CtorX->getInheritedConstructor().getConstructor(),7007CtorY->getInheritedConstructor().getConstructor()))7008return false;7009}70107011if (FuncX->isMultiVersion() != FuncY->isMultiVersion())7012return false;70137014// Multiversioned functions with different feature strings are represented7015// as separate declarations.7016if (FuncX->isMultiVersion()) {7017const auto *TAX = FuncX->getAttr<TargetAttr>();7018const auto *TAY = FuncY->getAttr<TargetAttr>();7019assert(TAX && TAY && "Multiversion Function without target attribute");70207021if (TAX->getFeaturesStr() != TAY->getFeaturesStr())7022return false;7023}70247025// Per C++20 [temp.over.link]/4, friends in different classes are sometimes7026// not the same entity if they are constrained.7027if ((FuncX->isMemberLikeConstrainedFriend() ||7028FuncY->isMemberLikeConstrainedFriend()) &&7029!FuncX->getLexicalDeclContext()->Equals(7030FuncY->getLexicalDeclContext())) {7031return false;7032}70337034if (!isSameConstraintExpr(FuncX->getTrailingRequiresClause(),7035FuncY->getTrailingRequiresClause()))7036return false;70377038auto GetTypeAsWritten = [](const FunctionDecl *FD) {7039// Map to the first declaration that we've already merged into this one.7040// The TSI of redeclarations might not match (due to calling conventions7041// being inherited onto the type but not the TSI), but the TSI type of7042// the first declaration of the function should match across modules.7043FD = FD->getCanonicalDecl();7044return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType()7045: FD->getType();7046};7047QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY);7048if (!hasSameType(XT, YT)) {7049// We can get functions with different types on the redecl chain in C++177050// if they have differing exception specifications and at least one of7051// the excpetion specs is unresolved.7052auto *XFPT = XT->getAs<FunctionProtoType>();7053auto *YFPT = YT->getAs<FunctionProtoType>();7054if (getLangOpts().CPlusPlus17 && XFPT && YFPT &&7055(isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||7056isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&7057hasSameFunctionTypeIgnoringExceptionSpec(XT, YT))7058return true;7059return false;7060}70617062return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&7063hasSameOverloadableAttrs(FuncX, FuncY);7064}70657066// Variables with the same type and linkage match.7067if (const auto *VarX = dyn_cast<VarDecl>(X)) {7068const auto *VarY = cast<VarDecl>(Y);7069if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) {7070// During deserialization, we might compare variables before we load7071// their types. Assume the types will end up being the same.7072if (VarX->getType().isNull() || VarY->getType().isNull())7073return true;70747075if (hasSameType(VarX->getType(), VarY->getType()))7076return true;70777078// We can get decls with different types on the redecl chain. Eg.7079// template <typename T> struct S { static T Var[]; }; // #17080// template <typename T> T S<T>::Var[sizeof(T)]; // #27081// Only? happens when completing an incomplete array type. In this case7082// when comparing #1 and #2 we should go through their element type.7083const ArrayType *VarXTy = getAsArrayType(VarX->getType());7084const ArrayType *VarYTy = getAsArrayType(VarY->getType());7085if (!VarXTy || !VarYTy)7086return false;7087if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType())7088return hasSameType(VarXTy->getElementType(), VarYTy->getElementType());7089}7090return false;7091}70927093// Namespaces with the same name and inlinedness match.7094if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) {7095const auto *NamespaceY = cast<NamespaceDecl>(Y);7096return NamespaceX->isInline() == NamespaceY->isInline();7097}70987099// Identical template names and kinds match if their template parameter lists7100// and patterns match.7101if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) {7102const auto *TemplateY = cast<TemplateDecl>(Y);71037104// ConceptDecl wouldn't be the same if their constraint expression differs.7105if (const auto *ConceptX = dyn_cast<ConceptDecl>(X)) {7106const auto *ConceptY = cast<ConceptDecl>(Y);7107if (!isSameConstraintExpr(ConceptX->getConstraintExpr(),7108ConceptY->getConstraintExpr()))7109return false;7110}71117112return isSameEntity(TemplateX->getTemplatedDecl(),7113TemplateY->getTemplatedDecl()) &&7114isSameTemplateParameterList(TemplateX->getTemplateParameters(),7115TemplateY->getTemplateParameters());7116}71177118// Fields with the same name and the same type match.7119if (const auto *FDX = dyn_cast<FieldDecl>(X)) {7120const auto *FDY = cast<FieldDecl>(Y);7121// FIXME: Also check the bitwidth is odr-equivalent, if any.7122return hasSameType(FDX->getType(), FDY->getType());7123}71247125// Indirect fields with the same target field match.7126if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) {7127const auto *IFDY = cast<IndirectFieldDecl>(Y);7128return IFDX->getAnonField()->getCanonicalDecl() ==7129IFDY->getAnonField()->getCanonicalDecl();7130}71317132// Enumerators with the same name match.7133if (isa<EnumConstantDecl>(X))7134// FIXME: Also check the value is odr-equivalent.7135return true;71367137// Using shadow declarations with the same target match.7138if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) {7139const auto *USY = cast<UsingShadowDecl>(Y);7140return declaresSameEntity(USX->getTargetDecl(), USY->getTargetDecl());7141}71427143// Using declarations with the same qualifier match. (We already know that7144// the name matches.)7145if (const auto *UX = dyn_cast<UsingDecl>(X)) {7146const auto *UY = cast<UsingDecl>(Y);7147return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&7148UX->hasTypename() == UY->hasTypename() &&7149UX->isAccessDeclaration() == UY->isAccessDeclaration();7150}7151if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) {7152const auto *UY = cast<UnresolvedUsingValueDecl>(Y);7153return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&7154UX->isAccessDeclaration() == UY->isAccessDeclaration();7155}7156if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) {7157return isSameQualifier(7158UX->getQualifier(),7159cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier());7160}71617162// Using-pack declarations are only created by instantiation, and match if7163// they're instantiated from matching UnresolvedUsing...Decls.7164if (const auto *UX = dyn_cast<UsingPackDecl>(X)) {7165return declaresSameEntity(7166UX->getInstantiatedFromUsingDecl(),7167cast<UsingPackDecl>(Y)->getInstantiatedFromUsingDecl());7168}71697170// Namespace alias definitions with the same target match.7171if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) {7172const auto *NAY = cast<NamespaceAliasDecl>(Y);7173return NAX->getNamespace()->Equals(NAY->getNamespace());7174}71757176return false;7177}71787179TemplateArgument7180ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {7181switch (Arg.getKind()) {7182case TemplateArgument::Null:7183return Arg;71847185case TemplateArgument::Expression:7186return Arg;71877188case TemplateArgument::Declaration: {7189auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());7190return TemplateArgument(D, getCanonicalType(Arg.getParamTypeForDecl()),7191Arg.getIsDefaulted());7192}71937194case TemplateArgument::NullPtr:7195return TemplateArgument(getCanonicalType(Arg.getNullPtrType()),7196/*isNullPtr*/ true, Arg.getIsDefaulted());71977198case TemplateArgument::Template:7199return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()),7200Arg.getIsDefaulted());72017202case TemplateArgument::TemplateExpansion:7203return TemplateArgument(7204getCanonicalTemplateName(Arg.getAsTemplateOrTemplatePattern()),7205Arg.getNumTemplateExpansions(), Arg.getIsDefaulted());72067207case TemplateArgument::Integral:7208return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType()));72097210case TemplateArgument::StructuralValue:7211return TemplateArgument(*this,7212getCanonicalType(Arg.getStructuralValueType()),7213Arg.getAsStructuralValue());72147215case TemplateArgument::Type:7216return TemplateArgument(getCanonicalType(Arg.getAsType()),7217/*isNullPtr*/ false, Arg.getIsDefaulted());72187219case TemplateArgument::Pack: {7220bool AnyNonCanonArgs = false;7221auto CanonArgs = ::getCanonicalTemplateArguments(7222*this, Arg.pack_elements(), AnyNonCanonArgs);7223if (!AnyNonCanonArgs)7224return Arg;7225return TemplateArgument::CreatePackCopy(const_cast<ASTContext &>(*this),7226CanonArgs);7227}7228}72297230// Silence GCC warning7231llvm_unreachable("Unhandled template argument kind");7232}72337234NestedNameSpecifier *7235ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {7236if (!NNS)7237return nullptr;72387239switch (NNS->getKind()) {7240case NestedNameSpecifier::Identifier:7241// Canonicalize the prefix but keep the identifier the same.7242return NestedNameSpecifier::Create(*this,7243getCanonicalNestedNameSpecifier(NNS->getPrefix()),7244NNS->getAsIdentifier());72457246case NestedNameSpecifier::Namespace:7247// A namespace is canonical; build a nested-name-specifier with7248// this namespace and no prefix.7249return NestedNameSpecifier::Create(*this, nullptr,7250NNS->getAsNamespace()->getFirstDecl());72517252case NestedNameSpecifier::NamespaceAlias:7253// A namespace is canonical; build a nested-name-specifier with7254// this namespace and no prefix.7255return NestedNameSpecifier::Create(7256*this, nullptr,7257NNS->getAsNamespaceAlias()->getNamespace()->getFirstDecl());72587259// The difference between TypeSpec and TypeSpecWithTemplate is that the7260// latter will have the 'template' keyword when printed.7261case NestedNameSpecifier::TypeSpec:7262case NestedNameSpecifier::TypeSpecWithTemplate: {7263const Type *T = getCanonicalType(NNS->getAsType());72647265// If we have some kind of dependent-named type (e.g., "typename T::type"),7266// break it apart into its prefix and identifier, then reconsititute those7267// as the canonical nested-name-specifier. This is required to canonicalize7268// a dependent nested-name-specifier involving typedefs of dependent-name7269// types, e.g.,7270// typedef typename T::type T1;7271// typedef typename T1::type T2;7272if (const auto *DNT = T->getAs<DependentNameType>())7273return NestedNameSpecifier::Create(*this, DNT->getQualifier(),7274DNT->getIdentifier());7275if (const auto *DTST = T->getAs<DependentTemplateSpecializationType>())7276return NestedNameSpecifier::Create(*this, DTST->getQualifier(), true, T);72777278// TODO: Set 'Template' parameter to true for other template types.7279return NestedNameSpecifier::Create(*this, nullptr, false, T);7280}72817282case NestedNameSpecifier::Global:7283case NestedNameSpecifier::Super:7284// The global specifier and __super specifer are canonical and unique.7285return NNS;7286}72877288llvm_unreachable("Invalid NestedNameSpecifier::Kind!");7289}72907291const ArrayType *ASTContext::getAsArrayType(QualType T) const {7292// Handle the non-qualified case efficiently.7293if (!T.hasLocalQualifiers()) {7294// Handle the common positive case fast.7295if (const auto *AT = dyn_cast<ArrayType>(T))7296return AT;7297}72987299// Handle the common negative case fast.7300if (!isa<ArrayType>(T.getCanonicalType()))7301return nullptr;73027303// Apply any qualifiers from the array type to the element type. This7304// implements C99 6.7.3p8: "If the specification of an array type includes7305// any type qualifiers, the element type is so qualified, not the array type."73067307// If we get here, we either have type qualifiers on the type, or we have7308// sugar such as a typedef in the way. If we have type qualifiers on the type7309// we must propagate them down into the element type.73107311SplitQualType split = T.getSplitDesugaredType();7312Qualifiers qs = split.Quals;73137314// If we have a simple case, just return now.7315const auto *ATy = dyn_cast<ArrayType>(split.Ty);7316if (!ATy || qs.empty())7317return ATy;73187319// Otherwise, we have an array and we have qualifiers on it. Push the7320// qualifiers into the array element type and return a new array type.7321QualType NewEltTy = getQualifiedType(ATy->getElementType(), qs);73227323if (const auto *CAT = dyn_cast<ConstantArrayType>(ATy))7324return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),7325CAT->getSizeExpr(),7326CAT->getSizeModifier(),7327CAT->getIndexTypeCVRQualifiers()));7328if (const auto *IAT = dyn_cast<IncompleteArrayType>(ATy))7329return cast<ArrayType>(getIncompleteArrayType(NewEltTy,7330IAT->getSizeModifier(),7331IAT->getIndexTypeCVRQualifiers()));73327333if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(ATy))7334return cast<ArrayType>(7335getDependentSizedArrayType(NewEltTy,7336DSAT->getSizeExpr(),7337DSAT->getSizeModifier(),7338DSAT->getIndexTypeCVRQualifiers(),7339DSAT->getBracketsRange()));73407341const auto *VAT = cast<VariableArrayType>(ATy);7342return cast<ArrayType>(getVariableArrayType(NewEltTy,7343VAT->getSizeExpr(),7344VAT->getSizeModifier(),7345VAT->getIndexTypeCVRQualifiers(),7346VAT->getBracketsRange()));7347}73487349QualType ASTContext::getAdjustedParameterType(QualType T) const {7350if (getLangOpts().HLSL && T->isConstantArrayType())7351return getArrayParameterType(T);7352if (T->isArrayType() || T->isFunctionType())7353return getDecayedType(T);7354return T;7355}73567357QualType ASTContext::getSignatureParameterType(QualType T) const {7358T = getVariableArrayDecayedType(T);7359T = getAdjustedParameterType(T);7360return T.getUnqualifiedType();7361}73627363QualType ASTContext::getExceptionObjectType(QualType T) const {7364// C++ [except.throw]p3:7365// A throw-expression initializes a temporary object, called the exception7366// object, the type of which is determined by removing any top-level7367// cv-qualifiers from the static type of the operand of throw and adjusting7368// the type from "array of T" or "function returning T" to "pointer to T"7369// or "pointer to function returning T", [...]7370T = getVariableArrayDecayedType(T);7371if (T->isArrayType() || T->isFunctionType())7372T = getDecayedType(T);7373return T.getUnqualifiedType();7374}73757376/// getArrayDecayedType - Return the properly qualified result of decaying the7377/// specified array type to a pointer. This operation is non-trivial when7378/// handling typedefs etc. The canonical type of "T" must be an array type,7379/// this returns a pointer to a properly qualified element of the array.7380///7381/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.7382QualType ASTContext::getArrayDecayedType(QualType Ty) const {7383// Get the element type with 'getAsArrayType' so that we don't lose any7384// typedefs in the element type of the array. This also handles propagation7385// of type qualifiers from the array type into the element type if present7386// (C99 6.7.3p8).7387const ArrayType *PrettyArrayType = getAsArrayType(Ty);7388assert(PrettyArrayType && "Not an array type!");73897390QualType PtrTy = getPointerType(PrettyArrayType->getElementType());73917392// int x[restrict 4] -> int *restrict7393QualType Result = getQualifiedType(PtrTy,7394PrettyArrayType->getIndexTypeQualifiers());73957396// int x[_Nullable] -> int * _Nullable7397if (auto Nullability = Ty->getNullability()) {7398Result = const_cast<ASTContext *>(this)->getAttributedType(7399AttributedType::getNullabilityAttrKind(*Nullability), Result, Result);7400}7401return Result;7402}74037404QualType ASTContext::getBaseElementType(const ArrayType *array) const {7405return getBaseElementType(array->getElementType());7406}74077408QualType ASTContext::getBaseElementType(QualType type) const {7409Qualifiers qs;7410while (true) {7411SplitQualType split = type.getSplitDesugaredType();7412const ArrayType *array = split.Ty->getAsArrayTypeUnsafe();7413if (!array) break;74147415type = array->getElementType();7416qs.addConsistentQualifiers(split.Quals);7417}74187419return getQualifiedType(type, qs);7420}74217422/// getConstantArrayElementCount - Returns number of constant array elements.7423uint64_t7424ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const {7425uint64_t ElementCount = 1;7426do {7427ElementCount *= CA->getZExtSize();7428CA = dyn_cast_or_null<ConstantArrayType>(7429CA->getElementType()->getAsArrayTypeUnsafe());7430} while (CA);7431return ElementCount;7432}74337434uint64_t ASTContext::getArrayInitLoopExprElementCount(7435const ArrayInitLoopExpr *AILE) const {7436if (!AILE)7437return 0;74387439uint64_t ElementCount = 1;74407441do {7442ElementCount *= AILE->getArraySize().getZExtValue();7443AILE = dyn_cast<ArrayInitLoopExpr>(AILE->getSubExpr());7444} while (AILE);74457446return ElementCount;7447}74487449/// getFloatingRank - Return a relative rank for floating point types.7450/// This routine will assert if passed a built-in type that isn't a float.7451static FloatingRank getFloatingRank(QualType T) {7452if (const auto *CT = T->getAs<ComplexType>())7453return getFloatingRank(CT->getElementType());74547455switch (T->castAs<BuiltinType>()->getKind()) {7456default: llvm_unreachable("getFloatingRank(): not a floating type");7457case BuiltinType::Float16: return Float16Rank;7458case BuiltinType::Half: return HalfRank;7459case BuiltinType::Float: return FloatRank;7460case BuiltinType::Double: return DoubleRank;7461case BuiltinType::LongDouble: return LongDoubleRank;7462case BuiltinType::Float128: return Float128Rank;7463case BuiltinType::BFloat16: return BFloat16Rank;7464case BuiltinType::Ibm128: return Ibm128Rank;7465}7466}74677468/// getFloatingTypeOrder - Compare the rank of the two specified floating7469/// point types, ignoring the domain of the type (i.e. 'double' ==7470/// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If7471/// LHS < RHS, return -1.7472int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const {7473FloatingRank LHSR = getFloatingRank(LHS);7474FloatingRank RHSR = getFloatingRank(RHS);74757476if (LHSR == RHSR)7477return 0;7478if (LHSR > RHSR)7479return 1;7480return -1;7481}74827483int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const {7484if (&getFloatTypeSemantics(LHS) == &getFloatTypeSemantics(RHS))7485return 0;7486return getFloatingTypeOrder(LHS, RHS);7487}74887489/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This7490/// routine will assert if passed a built-in type that isn't an integer or enum,7491/// or if it is not canonicalized.7492unsigned ASTContext::getIntegerRank(const Type *T) const {7493assert(T->isCanonicalUnqualified() && "T should be canonicalized");74947495// Results in this 'losing' to any type of the same size, but winning if7496// larger.7497if (const auto *EIT = dyn_cast<BitIntType>(T))7498return 0 + (EIT->getNumBits() << 3);74997500switch (cast<BuiltinType>(T)->getKind()) {7501default: llvm_unreachable("getIntegerRank(): not a built-in integer");7502case BuiltinType::Bool:7503return 1 + (getIntWidth(BoolTy) << 3);7504case BuiltinType::Char_S:7505case BuiltinType::Char_U:7506case BuiltinType::SChar:7507case BuiltinType::UChar:7508return 2 + (getIntWidth(CharTy) << 3);7509case BuiltinType::Short:7510case BuiltinType::UShort:7511return 3 + (getIntWidth(ShortTy) << 3);7512case BuiltinType::Int:7513case BuiltinType::UInt:7514return 4 + (getIntWidth(IntTy) << 3);7515case BuiltinType::Long:7516case BuiltinType::ULong:7517return 5 + (getIntWidth(LongTy) << 3);7518case BuiltinType::LongLong:7519case BuiltinType::ULongLong:7520return 6 + (getIntWidth(LongLongTy) << 3);7521case BuiltinType::Int128:7522case BuiltinType::UInt128:7523return 7 + (getIntWidth(Int128Ty) << 3);75247525// "The ranks of char8_t, char16_t, char32_t, and wchar_t equal the ranks of7526// their underlying types" [c++20 conv.rank]7527case BuiltinType::Char8:7528return getIntegerRank(UnsignedCharTy.getTypePtr());7529case BuiltinType::Char16:7530return getIntegerRank(7531getFromTargetType(Target->getChar16Type()).getTypePtr());7532case BuiltinType::Char32:7533return getIntegerRank(7534getFromTargetType(Target->getChar32Type()).getTypePtr());7535case BuiltinType::WChar_S:7536case BuiltinType::WChar_U:7537return getIntegerRank(7538getFromTargetType(Target->getWCharType()).getTypePtr());7539}7540}75417542/// Whether this is a promotable bitfield reference according7543/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).7544///7545/// \returns the type this bit-field will promote to, or NULL if no7546/// promotion occurs.7547QualType ASTContext::isPromotableBitField(Expr *E) const {7548if (E->isTypeDependent() || E->isValueDependent())7549return {};75507551// C++ [conv.prom]p5:7552// If the bit-field has an enumerated type, it is treated as any other7553// value of that type for promotion purposes.7554if (getLangOpts().CPlusPlus && E->getType()->isEnumeralType())7555return {};75567557// FIXME: We should not do this unless E->refersToBitField() is true. This7558// matters in C where getSourceBitField() will find bit-fields for various7559// cases where the source expression is not a bit-field designator.75607561FieldDecl *Field = E->getSourceBitField(); // FIXME: conditional bit-fields?7562if (!Field)7563return {};75647565QualType FT = Field->getType();75667567uint64_t BitWidth = Field->getBitWidthValue(*this);7568uint64_t IntSize = getTypeSize(IntTy);7569// C++ [conv.prom]p5:7570// A prvalue for an integral bit-field can be converted to a prvalue of type7571// int if int can represent all the values of the bit-field; otherwise, it7572// can be converted to unsigned int if unsigned int can represent all the7573// values of the bit-field. If the bit-field is larger yet, no integral7574// promotion applies to it.7575// C11 6.3.1.1/2:7576// [For a bit-field of type _Bool, int, signed int, or unsigned int:]7577// If an int can represent all values of the original type (as restricted by7578// the width, for a bit-field), the value is converted to an int; otherwise,7579// it is converted to an unsigned int.7580//7581// FIXME: C does not permit promotion of a 'long : 3' bitfield to int.7582// We perform that promotion here to match GCC and C++.7583// FIXME: C does not permit promotion of an enum bit-field whose rank is7584// greater than that of 'int'. We perform that promotion to match GCC.7585//7586// C23 6.3.1.1p2:7587// The value from a bit-field of a bit-precise integer type is converted to7588// the corresponding bit-precise integer type. (The rest is the same as in7589// C11.)7590if (QualType QT = Field->getType(); QT->isBitIntType())7591return QT;75927593if (BitWidth < IntSize)7594return IntTy;75957596if (BitWidth == IntSize)7597return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;75987599// Bit-fields wider than int are not subject to promotions, and therefore act7600// like the base type. GCC has some weird bugs in this area that we7601// deliberately do not follow (GCC follows a pre-standard resolution to7602// C's DR315 which treats bit-width as being part of the type, and this leaks7603// into their semantics in some cases).7604return {};7605}76067607/// getPromotedIntegerType - Returns the type that Promotable will7608/// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable7609/// integer type.7610QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {7611assert(!Promotable.isNull());7612assert(isPromotableIntegerType(Promotable));7613if (const auto *ET = Promotable->getAs<EnumType>())7614return ET->getDecl()->getPromotionType();76157616if (const auto *BT = Promotable->getAs<BuiltinType>()) {7617// C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t7618// (3.9.1) can be converted to a prvalue of the first of the following7619// types that can represent all the values of its underlying type:7620// int, unsigned int, long int, unsigned long int, long long int, or7621// unsigned long long int [...]7622// FIXME: Is there some better way to compute this?7623if (BT->getKind() == BuiltinType::WChar_S ||7624BT->getKind() == BuiltinType::WChar_U ||7625BT->getKind() == BuiltinType::Char8 ||7626BT->getKind() == BuiltinType::Char16 ||7627BT->getKind() == BuiltinType::Char32) {7628bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S;7629uint64_t FromSize = getTypeSize(BT);7630QualType PromoteTypes[] = { IntTy, UnsignedIntTy, LongTy, UnsignedLongTy,7631LongLongTy, UnsignedLongLongTy };7632for (const auto &PT : PromoteTypes) {7633uint64_t ToSize = getTypeSize(PT);7634if (FromSize < ToSize ||7635(FromSize == ToSize && FromIsSigned == PT->isSignedIntegerType()))7636return PT;7637}7638llvm_unreachable("char type should fit into long long");7639}7640}76417642// At this point, we should have a signed or unsigned integer type.7643if (Promotable->isSignedIntegerType())7644return IntTy;7645uint64_t PromotableSize = getIntWidth(Promotable);7646uint64_t IntSize = getIntWidth(IntTy);7647assert(Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize);7648return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy;7649}76507651/// Recurses in pointer/array types until it finds an objc retainable7652/// type and returns its ownership.7653Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {7654while (!T.isNull()) {7655if (T.getObjCLifetime() != Qualifiers::OCL_None)7656return T.getObjCLifetime();7657if (T->isArrayType())7658T = getBaseElementType(T);7659else if (const auto *PT = T->getAs<PointerType>())7660T = PT->getPointeeType();7661else if (const auto *RT = T->getAs<ReferenceType>())7662T = RT->getPointeeType();7663else7664break;7665}76667667return Qualifiers::OCL_None;7668}76697670static const Type *getIntegerTypeForEnum(const EnumType *ET) {7671// Incomplete enum types are not treated as integer types.7672// FIXME: In C++, enum types are never integer types.7673if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())7674return ET->getDecl()->getIntegerType().getTypePtr();7675return nullptr;7676}76777678/// getIntegerTypeOrder - Returns the highest ranked integer type:7679/// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If7680/// LHS < RHS, return -1.7681int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {7682const Type *LHSC = getCanonicalType(LHS).getTypePtr();7683const Type *RHSC = getCanonicalType(RHS).getTypePtr();76847685// Unwrap enums to their underlying type.7686if (const auto *ET = dyn_cast<EnumType>(LHSC))7687LHSC = getIntegerTypeForEnum(ET);7688if (const auto *ET = dyn_cast<EnumType>(RHSC))7689RHSC = getIntegerTypeForEnum(ET);76907691if (LHSC == RHSC) return 0;76927693bool LHSUnsigned = LHSC->isUnsignedIntegerType();7694bool RHSUnsigned = RHSC->isUnsignedIntegerType();76957696unsigned LHSRank = getIntegerRank(LHSC);7697unsigned RHSRank = getIntegerRank(RHSC);76987699if (LHSUnsigned == RHSUnsigned) { // Both signed or both unsigned.7700if (LHSRank == RHSRank) return 0;7701return LHSRank > RHSRank ? 1 : -1;7702}77037704// Otherwise, the LHS is signed and the RHS is unsigned or visa versa.7705if (LHSUnsigned) {7706// If the unsigned [LHS] type is larger, return it.7707if (LHSRank >= RHSRank)7708return 1;77097710// If the signed type can represent all values of the unsigned type, it7711// wins. Because we are dealing with 2's complement and types that are7712// powers of two larger than each other, this is always safe.7713return -1;7714}77157716// If the unsigned [RHS] type is larger, return it.7717if (RHSRank >= LHSRank)7718return -1;77197720// If the signed type can represent all values of the unsigned type, it7721// wins. Because we are dealing with 2's complement and types that are7722// powers of two larger than each other, this is always safe.7723return 1;7724}77257726TypedefDecl *ASTContext::getCFConstantStringDecl() const {7727if (CFConstantStringTypeDecl)7728return CFConstantStringTypeDecl;77297730assert(!CFConstantStringTagDecl &&7731"tag and typedef should be initialized together");7732CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag");7733CFConstantStringTagDecl->startDefinition();77347735struct {7736QualType Type;7737const char *Name;7738} Fields[5];7739unsigned Count = 0;77407741/// Objective-C ABI7742///7743/// typedef struct __NSConstantString_tag {7744/// const int *isa;7745/// int flags;7746/// const char *str;7747/// long length;7748/// } __NSConstantString;7749///7750/// Swift ABI (4.1, 4.2)7751///7752/// typedef struct __NSConstantString_tag {7753/// uintptr_t _cfisa;7754/// uintptr_t _swift_rc;7755/// _Atomic(uint64_t) _cfinfoa;7756/// const char *_ptr;7757/// uint32_t _length;7758/// } __NSConstantString;7759///7760/// Swift ABI (5.0)7761///7762/// typedef struct __NSConstantString_tag {7763/// uintptr_t _cfisa;7764/// uintptr_t _swift_rc;7765/// _Atomic(uint64_t) _cfinfoa;7766/// const char *_ptr;7767/// uintptr_t _length;7768/// } __NSConstantString;77697770const auto CFRuntime = getLangOpts().CFRuntime;7771if (static_cast<unsigned>(CFRuntime) <7772static_cast<unsigned>(LangOptions::CoreFoundationABI::Swift)) {7773Fields[Count++] = { getPointerType(IntTy.withConst()), "isa" };7774Fields[Count++] = { IntTy, "flags" };7775Fields[Count++] = { getPointerType(CharTy.withConst()), "str" };7776Fields[Count++] = { LongTy, "length" };7777} else {7778Fields[Count++] = { getUIntPtrType(), "_cfisa" };7779Fields[Count++] = { getUIntPtrType(), "_swift_rc" };7780Fields[Count++] = { getFromTargetType(Target->getUInt64Type()), "_swift_rc" };7781Fields[Count++] = { getPointerType(CharTy.withConst()), "_ptr" };7782if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 ||7783CFRuntime == LangOptions::CoreFoundationABI::Swift4_2)7784Fields[Count++] = { IntTy, "_ptr" };7785else7786Fields[Count++] = { getUIntPtrType(), "_ptr" };7787}77887789// Create fields7790for (unsigned i = 0; i < Count; ++i) {7791FieldDecl *Field =7792FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(),7793SourceLocation(), &Idents.get(Fields[i].Name),7794Fields[i].Type, /*TInfo=*/nullptr,7795/*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);7796Field->setAccess(AS_public);7797CFConstantStringTagDecl->addDecl(Field);7798}77997800CFConstantStringTagDecl->completeDefinition();7801// This type is designed to be compatible with NSConstantString, but cannot7802// use the same name, since NSConstantString is an interface.7803auto tagType = getTagDeclType(CFConstantStringTagDecl);7804CFConstantStringTypeDecl =7805buildImplicitTypedef(tagType, "__NSConstantString");78067807return CFConstantStringTypeDecl;7808}78097810RecordDecl *ASTContext::getCFConstantStringTagDecl() const {7811if (!CFConstantStringTagDecl)7812getCFConstantStringDecl(); // Build the tag and the typedef.7813return CFConstantStringTagDecl;7814}78157816// getCFConstantStringType - Return the type used for constant CFStrings.7817QualType ASTContext::getCFConstantStringType() const {7818return getTypedefType(getCFConstantStringDecl());7819}78207821QualType ASTContext::getObjCSuperType() const {7822if (ObjCSuperType.isNull()) {7823RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super");7824getTranslationUnitDecl()->addDecl(ObjCSuperTypeDecl);7825ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl);7826}7827return ObjCSuperType;7828}78297830void ASTContext::setCFConstantStringType(QualType T) {7831const auto *TD = T->castAs<TypedefType>();7832CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl());7833const auto *TagType =7834CFConstantStringTypeDecl->getUnderlyingType()->castAs<RecordType>();7835CFConstantStringTagDecl = TagType->getDecl();7836}78377838QualType ASTContext::getBlockDescriptorType() const {7839if (BlockDescriptorType)7840return getTagDeclType(BlockDescriptorType);78417842RecordDecl *RD;7843// FIXME: Needs the FlagAppleBlock bit.7844RD = buildImplicitRecord("__block_descriptor");7845RD->startDefinition();78467847QualType FieldTypes[] = {7848UnsignedLongTy,7849UnsignedLongTy,7850};78517852static const char *const FieldNames[] = {7853"reserved",7854"Size"7855};78567857for (size_t i = 0; i < 2; ++i) {7858FieldDecl *Field = FieldDecl::Create(7859*this, RD, SourceLocation(), SourceLocation(),7860&Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,7861/*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);7862Field->setAccess(AS_public);7863RD->addDecl(Field);7864}78657866RD->completeDefinition();78677868BlockDescriptorType = RD;78697870return getTagDeclType(BlockDescriptorType);7871}78727873QualType ASTContext::getBlockDescriptorExtendedType() const {7874if (BlockDescriptorExtendedType)7875return getTagDeclType(BlockDescriptorExtendedType);78767877RecordDecl *RD;7878// FIXME: Needs the FlagAppleBlock bit.7879RD = buildImplicitRecord("__block_descriptor_withcopydispose");7880RD->startDefinition();78817882QualType FieldTypes[] = {7883UnsignedLongTy,7884UnsignedLongTy,7885getPointerType(VoidPtrTy),7886getPointerType(VoidPtrTy)7887};78887889static const char *const FieldNames[] = {7890"reserved",7891"Size",7892"CopyFuncPtr",7893"DestroyFuncPtr"7894};78957896for (size_t i = 0; i < 4; ++i) {7897FieldDecl *Field = FieldDecl::Create(7898*this, RD, SourceLocation(), SourceLocation(),7899&Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,7900/*BitWidth=*/nullptr,7901/*Mutable=*/false, ICIS_NoInit);7902Field->setAccess(AS_public);7903RD->addDecl(Field);7904}79057906RD->completeDefinition();79077908BlockDescriptorExtendedType = RD;7909return getTagDeclType(BlockDescriptorExtendedType);7910}79117912OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const {7913const auto *BT = dyn_cast<BuiltinType>(T);79147915if (!BT) {7916if (isa<PipeType>(T))7917return OCLTK_Pipe;79187919return OCLTK_Default;7920}79217922switch (BT->getKind()) {7923#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \7924case BuiltinType::Id: \7925return OCLTK_Image;7926#include "clang/Basic/OpenCLImageTypes.def"79277928case BuiltinType::OCLClkEvent:7929return OCLTK_ClkEvent;79307931case BuiltinType::OCLEvent:7932return OCLTK_Event;79337934case BuiltinType::OCLQueue:7935return OCLTK_Queue;79367937case BuiltinType::OCLReserveID:7938return OCLTK_ReserveID;79397940case BuiltinType::OCLSampler:7941return OCLTK_Sampler;79427943default:7944return OCLTK_Default;7945}7946}79477948LangAS ASTContext::getOpenCLTypeAddrSpace(const Type *T) const {7949return Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T));7950}79517952/// BlockRequiresCopying - Returns true if byref variable "D" of type "Ty"7953/// requires copy/dispose. Note that this must match the logic7954/// in buildByrefHelpers.7955bool ASTContext::BlockRequiresCopying(QualType Ty,7956const VarDecl *D) {7957if (const CXXRecordDecl *record = Ty->getAsCXXRecordDecl()) {7958const Expr *copyExpr = getBlockVarCopyInit(D).getCopyExpr();7959if (!copyExpr && record->hasTrivialDestructor()) return false;79607961return true;7962}79637964// The block needs copy/destroy helpers if Ty is non-trivial to destructively7965// move or destroy.7966if (Ty.isNonTrivialToPrimitiveDestructiveMove() || Ty.isDestructedType())7967return true;79687969if (!Ty->isObjCRetainableType()) return false;79707971Qualifiers qs = Ty.getQualifiers();79727973// If we have lifetime, that dominates.7974if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {7975switch (lifetime) {7976case Qualifiers::OCL_None: llvm_unreachable("impossible");79777978// These are just bits as far as the runtime is concerned.7979case Qualifiers::OCL_ExplicitNone:7980case Qualifiers::OCL_Autoreleasing:7981return false;79827983// These cases should have been taken care of when checking the type's7984// non-triviality.7985case Qualifiers::OCL_Weak:7986case Qualifiers::OCL_Strong:7987llvm_unreachable("impossible");7988}7989llvm_unreachable("fell out of lifetime switch!");7990}7991return (Ty->isBlockPointerType() || isObjCNSObjectType(Ty) ||7992Ty->isObjCObjectPointerType());7993}79947995bool ASTContext::getByrefLifetime(QualType Ty,7996Qualifiers::ObjCLifetime &LifeTime,7997bool &HasByrefExtendedLayout) const {7998if (!getLangOpts().ObjC ||7999getLangOpts().getGC() != LangOptions::NonGC)8000return false;80018002HasByrefExtendedLayout = false;8003if (Ty->isRecordType()) {8004HasByrefExtendedLayout = true;8005LifeTime = Qualifiers::OCL_None;8006} else if ((LifeTime = Ty.getObjCLifetime())) {8007// Honor the ARC qualifiers.8008} else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) {8009// The MRR rule.8010LifeTime = Qualifiers::OCL_ExplicitNone;8011} else {8012LifeTime = Qualifiers::OCL_None;8013}8014return true;8015}80168017CanQualType ASTContext::getNSUIntegerType() const {8018assert(Target && "Expected target to be initialized");8019const llvm::Triple &T = Target->getTriple();8020// Windows is LLP64 rather than LP648021if (T.isOSWindows() && T.isArch64Bit())8022return UnsignedLongLongTy;8023return UnsignedLongTy;8024}80258026CanQualType ASTContext::getNSIntegerType() const {8027assert(Target && "Expected target to be initialized");8028const llvm::Triple &T = Target->getTriple();8029// Windows is LLP64 rather than LP648030if (T.isOSWindows() && T.isArch64Bit())8031return LongLongTy;8032return LongTy;8033}80348035TypedefDecl *ASTContext::getObjCInstanceTypeDecl() {8036if (!ObjCInstanceTypeDecl)8037ObjCInstanceTypeDecl =8038buildImplicitTypedef(getObjCIdType(), "instancetype");8039return ObjCInstanceTypeDecl;8040}80418042// This returns true if a type has been typedefed to BOOL:8043// typedef <type> BOOL;8044static bool isTypeTypedefedAsBOOL(QualType T) {8045if (const auto *TT = dyn_cast<TypedefType>(T))8046if (IdentifierInfo *II = TT->getDecl()->getIdentifier())8047return II->isStr("BOOL");80488049return false;8050}80518052/// getObjCEncodingTypeSize returns size of type for objective-c encoding8053/// purpose.8054CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const {8055if (!type->isIncompleteArrayType() && type->isIncompleteType())8056return CharUnits::Zero();80578058CharUnits sz = getTypeSizeInChars(type);80598060// Make all integer and enum types at least as large as an int8061if (sz.isPositive() && type->isIntegralOrEnumerationType())8062sz = std::max(sz, getTypeSizeInChars(IntTy));8063// Treat arrays as pointers, since that's how they're passed in.8064else if (type->isArrayType())8065sz = getTypeSizeInChars(VoidPtrTy);8066return sz;8067}80688069bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {8070return getTargetInfo().getCXXABI().isMicrosoft() &&8071VD->isStaticDataMember() &&8072VD->getType()->isIntegralOrEnumerationType() &&8073!VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();8074}80758076ASTContext::InlineVariableDefinitionKind8077ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {8078if (!VD->isInline())8079return InlineVariableDefinitionKind::None;80808081// In almost all cases, it's a weak definition.8082auto *First = VD->getFirstDecl();8083if (First->isInlineSpecified() || !First->isStaticDataMember())8084return InlineVariableDefinitionKind::Weak;80858086// If there's a file-context declaration in this translation unit, it's a8087// non-discardable definition.8088for (auto *D : VD->redecls())8089if (D->getLexicalDeclContext()->isFileContext() &&8090!D->isInlineSpecified() && (D->isConstexpr() || First->isConstexpr()))8091return InlineVariableDefinitionKind::Strong;80928093// If we've not seen one yet, we don't know.8094return InlineVariableDefinitionKind::WeakUnknown;8095}80968097static std::string charUnitsToString(const CharUnits &CU) {8098return llvm::itostr(CU.getQuantity());8099}81008101/// getObjCEncodingForBlock - Return the encoded type for this block8102/// declaration.8103std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {8104std::string S;81058106const BlockDecl *Decl = Expr->getBlockDecl();8107QualType BlockTy =8108Expr->getType()->castAs<BlockPointerType>()->getPointeeType();8109QualType BlockReturnTy = BlockTy->castAs<FunctionType>()->getReturnType();8110// Encode result type.8111if (getLangOpts().EncodeExtendedBlockSig)8112getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, BlockReturnTy, S,8113true /*Extended*/);8114else8115getObjCEncodingForType(BlockReturnTy, S);8116// Compute size of all parameters.8117// Start with computing size of a pointer in number of bytes.8118// FIXME: There might(should) be a better way of doing this computation!8119CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);8120CharUnits ParmOffset = PtrSize;8121for (auto *PI : Decl->parameters()) {8122QualType PType = PI->getType();8123CharUnits sz = getObjCEncodingTypeSize(PType);8124if (sz.isZero())8125continue;8126assert(sz.isPositive() && "BlockExpr - Incomplete param type");8127ParmOffset += sz;8128}8129// Size of the argument frame8130S += charUnitsToString(ParmOffset);8131// Block pointer and offset.8132S += "@?0";81338134// Argument types.8135ParmOffset = PtrSize;8136for (auto *PVDecl : Decl->parameters()) {8137QualType PType = PVDecl->getOriginalType();8138if (const auto *AT =8139dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {8140// Use array's original type only if it has known number of8141// elements.8142if (!isa<ConstantArrayType>(AT))8143PType = PVDecl->getType();8144} else if (PType->isFunctionType())8145PType = PVDecl->getType();8146if (getLangOpts().EncodeExtendedBlockSig)8147getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, PType,8148S, true /*Extended*/);8149else8150getObjCEncodingForType(PType, S);8151S += charUnitsToString(ParmOffset);8152ParmOffset += getObjCEncodingTypeSize(PType);8153}81548155return S;8156}81578158std::string8159ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const {8160std::string S;8161// Encode result type.8162getObjCEncodingForType(Decl->getReturnType(), S);8163CharUnits ParmOffset;8164// Compute size of all parameters.8165for (auto *PI : Decl->parameters()) {8166QualType PType = PI->getType();8167CharUnits sz = getObjCEncodingTypeSize(PType);8168if (sz.isZero())8169continue;81708171assert(sz.isPositive() &&8172"getObjCEncodingForFunctionDecl - Incomplete param type");8173ParmOffset += sz;8174}8175S += charUnitsToString(ParmOffset);8176ParmOffset = CharUnits::Zero();81778178// Argument types.8179for (auto *PVDecl : Decl->parameters()) {8180QualType PType = PVDecl->getOriginalType();8181if (const auto *AT =8182dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {8183// Use array's original type only if it has known number of8184// elements.8185if (!isa<ConstantArrayType>(AT))8186PType = PVDecl->getType();8187} else if (PType->isFunctionType())8188PType = PVDecl->getType();8189getObjCEncodingForType(PType, S);8190S += charUnitsToString(ParmOffset);8191ParmOffset += getObjCEncodingTypeSize(PType);8192}81938194return S;8195}81968197/// getObjCEncodingForMethodParameter - Return the encoded type for a single8198/// method parameter or return type. If Extended, include class names and8199/// block object types.8200void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,8201QualType T, std::string& S,8202bool Extended) const {8203// Encode type qualifier, 'in', 'inout', etc. for the parameter.8204getObjCEncodingForTypeQualifier(QT, S);8205// Encode parameter type.8206ObjCEncOptions Options = ObjCEncOptions()8207.setExpandPointedToStructures()8208.setExpandStructures()8209.setIsOutermostType();8210if (Extended)8211Options.setEncodeBlockParameters().setEncodeClassNames();8212getObjCEncodingForTypeImpl(T, S, Options, /*Field=*/nullptr);8213}82148215/// getObjCEncodingForMethodDecl - Return the encoded type for this method8216/// declaration.8217std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,8218bool Extended) const {8219// FIXME: This is not very efficient.8220// Encode return type.8221std::string S;8222getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(),8223Decl->getReturnType(), S, Extended);8224// Compute size of all parameters.8225// Start with computing size of a pointer in number of bytes.8226// FIXME: There might(should) be a better way of doing this computation!8227CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);8228// The first two arguments (self and _cmd) are pointers; account for8229// their size.8230CharUnits ParmOffset = 2 * PtrSize;8231for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(),8232E = Decl->sel_param_end(); PI != E; ++PI) {8233QualType PType = (*PI)->getType();8234CharUnits sz = getObjCEncodingTypeSize(PType);8235if (sz.isZero())8236continue;82378238assert(sz.isPositive() &&8239"getObjCEncodingForMethodDecl - Incomplete param type");8240ParmOffset += sz;8241}8242S += charUnitsToString(ParmOffset);8243S += "@0:";8244S += charUnitsToString(PtrSize);82458246// Argument types.8247ParmOffset = 2 * PtrSize;8248for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(),8249E = Decl->sel_param_end(); PI != E; ++PI) {8250const ParmVarDecl *PVDecl = *PI;8251QualType PType = PVDecl->getOriginalType();8252if (const auto *AT =8253dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {8254// Use array's original type only if it has known number of8255// elements.8256if (!isa<ConstantArrayType>(AT))8257PType = PVDecl->getType();8258} else if (PType->isFunctionType())8259PType = PVDecl->getType();8260getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(),8261PType, S, Extended);8262S += charUnitsToString(ParmOffset);8263ParmOffset += getObjCEncodingTypeSize(PType);8264}82658266return S;8267}82688269ObjCPropertyImplDecl *8270ASTContext::getObjCPropertyImplDeclForPropertyDecl(8271const ObjCPropertyDecl *PD,8272const Decl *Container) const {8273if (!Container)8274return nullptr;8275if (const auto *CID = dyn_cast<ObjCCategoryImplDecl>(Container)) {8276for (auto *PID : CID->property_impls())8277if (PID->getPropertyDecl() == PD)8278return PID;8279} else {8280const auto *OID = cast<ObjCImplementationDecl>(Container);8281for (auto *PID : OID->property_impls())8282if (PID->getPropertyDecl() == PD)8283return PID;8284}8285return nullptr;8286}82878288/// getObjCEncodingForPropertyDecl - Return the encoded type for this8289/// property declaration. If non-NULL, Container must be either an8290/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be8291/// NULL when getting encodings for protocol properties.8292/// Property attributes are stored as a comma-delimited C string. The simple8293/// attributes readonly and bycopy are encoded as single characters. The8294/// parametrized attributes, getter=name, setter=name, and ivar=name, are8295/// encoded as single characters, followed by an identifier. Property types8296/// are also encoded as a parametrized attribute. The characters used to encode8297/// these attributes are defined by the following enumeration:8298/// @code8299/// enum PropertyAttributes {8300/// kPropertyReadOnly = 'R', // property is read-only.8301/// kPropertyBycopy = 'C', // property is a copy of the value last assigned8302/// kPropertyByref = '&', // property is a reference to the value last assigned8303/// kPropertyDynamic = 'D', // property is dynamic8304/// kPropertyGetter = 'G', // followed by getter selector name8305/// kPropertySetter = 'S', // followed by setter selector name8306/// kPropertyInstanceVariable = 'V' // followed by instance variable name8307/// kPropertyType = 'T' // followed by old-style type encoding.8308/// kPropertyWeak = 'W' // 'weak' property8309/// kPropertyStrong = 'P' // property GC'able8310/// kPropertyNonAtomic = 'N' // property non-atomic8311/// kPropertyOptional = '?' // property optional8312/// };8313/// @endcode8314std::string8315ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,8316const Decl *Container) const {8317// Collect information from the property implementation decl(s).8318bool Dynamic = false;8319ObjCPropertyImplDecl *SynthesizePID = nullptr;83208321if (ObjCPropertyImplDecl *PropertyImpDecl =8322getObjCPropertyImplDeclForPropertyDecl(PD, Container)) {8323if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)8324Dynamic = true;8325else8326SynthesizePID = PropertyImpDecl;8327}83288329// FIXME: This is not very efficient.8330std::string S = "T";83318332// Encode result type.8333// GCC has some special rules regarding encoding of properties which8334// closely resembles encoding of ivars.8335getObjCEncodingForPropertyType(PD->getType(), S);83368337if (PD->isOptional())8338S += ",?";83398340if (PD->isReadOnly()) {8341S += ",R";8342if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_copy)8343S += ",C";8344if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_retain)8345S += ",&";8346if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak)8347S += ",W";8348} else {8349switch (PD->getSetterKind()) {8350case ObjCPropertyDecl::Assign: break;8351case ObjCPropertyDecl::Copy: S += ",C"; break;8352case ObjCPropertyDecl::Retain: S += ",&"; break;8353case ObjCPropertyDecl::Weak: S += ",W"; break;8354}8355}83568357// It really isn't clear at all what this means, since properties8358// are "dynamic by default".8359if (Dynamic)8360S += ",D";83618362if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_nonatomic)8363S += ",N";83648365if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_getter) {8366S += ",G";8367S += PD->getGetterName().getAsString();8368}83698370if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_setter) {8371S += ",S";8372S += PD->getSetterName().getAsString();8373}83748375if (SynthesizePID) {8376const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl();8377S += ",V";8378S += OID->getNameAsString();8379}83808381// FIXME: OBJCGC: weak & strong8382return S;8383}83848385/// getLegacyIntegralTypeEncoding -8386/// Another legacy compatibility encoding: 32-bit longs are encoded as8387/// 'l' or 'L' , but not always. For typedefs, we need to use8388/// 'i' or 'I' instead if encoding a struct field, or a pointer!8389void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const {8390if (PointeeTy->getAs<TypedefType>()) {8391if (const auto *BT = PointeeTy->getAs<BuiltinType>()) {8392if (BT->getKind() == BuiltinType::ULong && getIntWidth(PointeeTy) == 32)8393PointeeTy = UnsignedIntTy;8394else8395if (BT->getKind() == BuiltinType::Long && getIntWidth(PointeeTy) == 32)8396PointeeTy = IntTy;8397}8398}8399}84008401void ASTContext::getObjCEncodingForType(QualType T, std::string& S,8402const FieldDecl *Field,8403QualType *NotEncodedT) const {8404// We follow the behavior of gcc, expanding structures which are8405// directly pointed to, and expanding embedded structures. Note that8406// these rules are sufficient to prevent recursive encoding of the8407// same type.8408getObjCEncodingForTypeImpl(T, S,8409ObjCEncOptions()8410.setExpandPointedToStructures()8411.setExpandStructures()8412.setIsOutermostType(),8413Field, NotEncodedT);8414}84158416void ASTContext::getObjCEncodingForPropertyType(QualType T,8417std::string& S) const {8418// Encode result type.8419// GCC has some special rules regarding encoding of properties which8420// closely resembles encoding of ivars.8421getObjCEncodingForTypeImpl(T, S,8422ObjCEncOptions()8423.setExpandPointedToStructures()8424.setExpandStructures()8425.setIsOutermostType()8426.setEncodingProperty(),8427/*Field=*/nullptr);8428}84298430static char getObjCEncodingForPrimitiveType(const ASTContext *C,8431const BuiltinType *BT) {8432BuiltinType::Kind kind = BT->getKind();8433switch (kind) {8434case BuiltinType::Void: return 'v';8435case BuiltinType::Bool: return 'B';8436case BuiltinType::Char8:8437case BuiltinType::Char_U:8438case BuiltinType::UChar: return 'C';8439case BuiltinType::Char16:8440case BuiltinType::UShort: return 'S';8441case BuiltinType::Char32:8442case BuiltinType::UInt: return 'I';8443case BuiltinType::ULong:8444return C->getTargetInfo().getLongWidth() == 32 ? 'L' : 'Q';8445case BuiltinType::UInt128: return 'T';8446case BuiltinType::ULongLong: return 'Q';8447case BuiltinType::Char_S:8448case BuiltinType::SChar: return 'c';8449case BuiltinType::Short: return 's';8450case BuiltinType::WChar_S:8451case BuiltinType::WChar_U:8452case BuiltinType::Int: return 'i';8453case BuiltinType::Long:8454return C->getTargetInfo().getLongWidth() == 32 ? 'l' : 'q';8455case BuiltinType::LongLong: return 'q';8456case BuiltinType::Int128: return 't';8457case BuiltinType::Float: return 'f';8458case BuiltinType::Double: return 'd';8459case BuiltinType::LongDouble: return 'D';8460case BuiltinType::NullPtr: return '*'; // like char*84618462case BuiltinType::BFloat16:8463case BuiltinType::Float16:8464case BuiltinType::Float128:8465case BuiltinType::Ibm128:8466case BuiltinType::Half:8467case BuiltinType::ShortAccum:8468case BuiltinType::Accum:8469case BuiltinType::LongAccum:8470case BuiltinType::UShortAccum:8471case BuiltinType::UAccum:8472case BuiltinType::ULongAccum:8473case BuiltinType::ShortFract:8474case BuiltinType::Fract:8475case BuiltinType::LongFract:8476case BuiltinType::UShortFract:8477case BuiltinType::UFract:8478case BuiltinType::ULongFract:8479case BuiltinType::SatShortAccum:8480case BuiltinType::SatAccum:8481case BuiltinType::SatLongAccum:8482case BuiltinType::SatUShortAccum:8483case BuiltinType::SatUAccum:8484case BuiltinType::SatULongAccum:8485case BuiltinType::SatShortFract:8486case BuiltinType::SatFract:8487case BuiltinType::SatLongFract:8488case BuiltinType::SatUShortFract:8489case BuiltinType::SatUFract:8490case BuiltinType::SatULongFract:8491// FIXME: potentially need @encodes for these!8492return ' ';84938494#define SVE_TYPE(Name, Id, SingletonId) \8495case BuiltinType::Id:8496#include "clang/Basic/AArch64SVEACLETypes.def"8497#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:8498#include "clang/Basic/RISCVVTypes.def"8499#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:8500#include "clang/Basic/WebAssemblyReferenceTypes.def"8501#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:8502#include "clang/Basic/AMDGPUTypes.def"8503{8504DiagnosticsEngine &Diags = C->getDiagnostics();8505unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,8506"cannot yet @encode type %0");8507Diags.Report(DiagID) << BT->getName(C->getPrintingPolicy());8508return ' ';8509}85108511case BuiltinType::ObjCId:8512case BuiltinType::ObjCClass:8513case BuiltinType::ObjCSel:8514llvm_unreachable("@encoding ObjC primitive type");85158516// OpenCL and placeholder types don't need @encodings.8517#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \8518case BuiltinType::Id:8519#include "clang/Basic/OpenCLImageTypes.def"8520#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \8521case BuiltinType::Id:8522#include "clang/Basic/OpenCLExtensionTypes.def"8523case BuiltinType::OCLEvent:8524case BuiltinType::OCLClkEvent:8525case BuiltinType::OCLQueue:8526case BuiltinType::OCLReserveID:8527case BuiltinType::OCLSampler:8528case BuiltinType::Dependent:8529#define PPC_VECTOR_TYPE(Name, Id, Size) \8530case BuiltinType::Id:8531#include "clang/Basic/PPCTypes.def"8532#define BUILTIN_TYPE(KIND, ID)8533#define PLACEHOLDER_TYPE(KIND, ID) \8534case BuiltinType::KIND:8535#include "clang/AST/BuiltinTypes.def"8536llvm_unreachable("invalid builtin type for @encode");8537}8538llvm_unreachable("invalid BuiltinType::Kind value");8539}85408541static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) {8542EnumDecl *Enum = ET->getDecl();85438544// The encoding of an non-fixed enum type is always 'i', regardless of size.8545if (!Enum->isFixed())8546return 'i';85478548// The encoding of a fixed enum type matches its fixed underlying type.8549const auto *BT = Enum->getIntegerType()->castAs<BuiltinType>();8550return getObjCEncodingForPrimitiveType(C, BT);8551}85528553static void EncodeBitField(const ASTContext *Ctx, std::string& S,8554QualType T, const FieldDecl *FD) {8555assert(FD->isBitField() && "not a bitfield - getObjCEncodingForTypeImpl");8556S += 'b';8557// The NeXT runtime encodes bit fields as b followed by the number of bits.8558// The GNU runtime requires more information; bitfields are encoded as b,8559// then the offset (in bits) of the first element, then the type of the8560// bitfield, then the size in bits. For example, in this structure:8561//8562// struct8563// {8564// int integer;8565// int flags:2;8566// };8567// On a 32-bit system, the encoding for flags would be b2 for the NeXT8568// runtime, but b32i2 for the GNU runtime. The reason for this extra8569// information is not especially sensible, but we're stuck with it for8570// compatibility with GCC, although providing it breaks anything that8571// actually uses runtime introspection and wants to work on both runtimes...8572if (Ctx->getLangOpts().ObjCRuntime.isGNUFamily()) {8573uint64_t Offset;85748575if (const auto *IVD = dyn_cast<ObjCIvarDecl>(FD)) {8576Offset = Ctx->lookupFieldBitOffset(IVD->getContainingInterface(), nullptr,8577IVD);8578} else {8579const RecordDecl *RD = FD->getParent();8580const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD);8581Offset = RL.getFieldOffset(FD->getFieldIndex());8582}85838584S += llvm::utostr(Offset);85858586if (const auto *ET = T->getAs<EnumType>())8587S += ObjCEncodingForEnumType(Ctx, ET);8588else {8589const auto *BT = T->castAs<BuiltinType>();8590S += getObjCEncodingForPrimitiveType(Ctx, BT);8591}8592}8593S += llvm::utostr(FD->getBitWidthValue(*Ctx));8594}85958596// Helper function for determining whether the encoded type string would include8597// a template specialization type.8598static bool hasTemplateSpecializationInEncodedString(const Type *T,8599bool VisitBasesAndFields) {8600T = T->getBaseElementTypeUnsafe();86018602if (auto *PT = T->getAs<PointerType>())8603return hasTemplateSpecializationInEncodedString(8604PT->getPointeeType().getTypePtr(), false);86058606auto *CXXRD = T->getAsCXXRecordDecl();86078608if (!CXXRD)8609return false;86108611if (isa<ClassTemplateSpecializationDecl>(CXXRD))8612return true;86138614if (!CXXRD->hasDefinition() || !VisitBasesAndFields)8615return false;86168617for (const auto &B : CXXRD->bases())8618if (hasTemplateSpecializationInEncodedString(B.getType().getTypePtr(),8619true))8620return true;86218622for (auto *FD : CXXRD->fields())8623if (hasTemplateSpecializationInEncodedString(FD->getType().getTypePtr(),8624true))8625return true;86268627return false;8628}86298630// FIXME: Use SmallString for accumulating string.8631void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,8632const ObjCEncOptions Options,8633const FieldDecl *FD,8634QualType *NotEncodedT) const {8635CanQualType CT = getCanonicalType(T);8636switch (CT->getTypeClass()) {8637case Type::Builtin:8638case Type::Enum:8639if (FD && FD->isBitField())8640return EncodeBitField(this, S, T, FD);8641if (const auto *BT = dyn_cast<BuiltinType>(CT))8642S += getObjCEncodingForPrimitiveType(this, BT);8643else8644S += ObjCEncodingForEnumType(this, cast<EnumType>(CT));8645return;86468647case Type::Complex:8648S += 'j';8649getObjCEncodingForTypeImpl(T->castAs<ComplexType>()->getElementType(), S,8650ObjCEncOptions(),8651/*Field=*/nullptr);8652return;86538654case Type::Atomic:8655S += 'A';8656getObjCEncodingForTypeImpl(T->castAs<AtomicType>()->getValueType(), S,8657ObjCEncOptions(),8658/*Field=*/nullptr);8659return;86608661// encoding for pointer or reference types.8662case Type::Pointer:8663case Type::LValueReference:8664case Type::RValueReference: {8665QualType PointeeTy;8666if (isa<PointerType>(CT)) {8667const auto *PT = T->castAs<PointerType>();8668if (PT->isObjCSelType()) {8669S += ':';8670return;8671}8672PointeeTy = PT->getPointeeType();8673} else {8674PointeeTy = T->castAs<ReferenceType>()->getPointeeType();8675}86768677bool isReadOnly = false;8678// For historical/compatibility reasons, the read-only qualifier of the8679// pointee gets emitted _before_ the '^'. The read-only qualifier of8680// the pointer itself gets ignored, _unless_ we are looking at a typedef!8681// Also, do not emit the 'r' for anything but the outermost type!8682if (T->getAs<TypedefType>()) {8683if (Options.IsOutermostType() && T.isConstQualified()) {8684isReadOnly = true;8685S += 'r';8686}8687} else if (Options.IsOutermostType()) {8688QualType P = PointeeTy;8689while (auto PT = P->getAs<PointerType>())8690P = PT->getPointeeType();8691if (P.isConstQualified()) {8692isReadOnly = true;8693S += 'r';8694}8695}8696if (isReadOnly) {8697// Another legacy compatibility encoding. Some ObjC qualifier and type8698// combinations need to be rearranged.8699// Rewrite "in const" from "nr" to "rn"8700if (StringRef(S).ends_with("nr"))8701S.replace(S.end()-2, S.end(), "rn");8702}87038704if (PointeeTy->isCharType()) {8705// char pointer types should be encoded as '*' unless it is a8706// type that has been typedef'd to 'BOOL'.8707if (!isTypeTypedefedAsBOOL(PointeeTy)) {8708S += '*';8709return;8710}8711} else if (const auto *RTy = PointeeTy->getAs<RecordType>()) {8712// GCC binary compat: Need to convert "struct objc_class *" to "#".8713if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) {8714S += '#';8715return;8716}8717// GCC binary compat: Need to convert "struct objc_object *" to "@".8718if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_object")) {8719S += '@';8720return;8721}8722// If the encoded string for the class includes template names, just emit8723// "^v" for pointers to the class.8724if (getLangOpts().CPlusPlus &&8725(!getLangOpts().EncodeCXXClassTemplateSpec &&8726hasTemplateSpecializationInEncodedString(8727RTy, Options.ExpandPointedToStructures()))) {8728S += "^v";8729return;8730}8731// fall through...8732}8733S += '^';8734getLegacyIntegralTypeEncoding(PointeeTy);87358736ObjCEncOptions NewOptions;8737if (Options.ExpandPointedToStructures())8738NewOptions.setExpandStructures();8739getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions,8740/*Field=*/nullptr, NotEncodedT);8741return;8742}87438744case Type::ConstantArray:8745case Type::IncompleteArray:8746case Type::VariableArray: {8747const auto *AT = cast<ArrayType>(CT);87488749if (isa<IncompleteArrayType>(AT) && !Options.IsStructField()) {8750// Incomplete arrays are encoded as a pointer to the array element.8751S += '^';87528753getObjCEncodingForTypeImpl(8754AT->getElementType(), S,8755Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD);8756} else {8757S += '[';87588759if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))8760S += llvm::utostr(CAT->getZExtSize());8761else {8762//Variable length arrays are encoded as a regular array with 0 elements.8763assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&8764"Unknown array type!");8765S += '0';8766}87678768getObjCEncodingForTypeImpl(8769AT->getElementType(), S,8770Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD,8771NotEncodedT);8772S += ']';8773}8774return;8775}87768777case Type::FunctionNoProto:8778case Type::FunctionProto:8779S += '?';8780return;87818782case Type::Record: {8783RecordDecl *RDecl = cast<RecordType>(CT)->getDecl();8784S += RDecl->isUnion() ? '(' : '{';8785// Anonymous structures print as '?'8786if (const IdentifierInfo *II = RDecl->getIdentifier()) {8787S += II->getName();8788if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {8789const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();8790llvm::raw_string_ostream OS(S);8791printTemplateArgumentList(OS, TemplateArgs.asArray(),8792getPrintingPolicy());8793}8794} else {8795S += '?';8796}8797if (Options.ExpandStructures()) {8798S += '=';8799if (!RDecl->isUnion()) {8800getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT);8801} else {8802for (const auto *Field : RDecl->fields()) {8803if (FD) {8804S += '"';8805S += Field->getNameAsString();8806S += '"';8807}88088809// Special case bit-fields.8810if (Field->isBitField()) {8811getObjCEncodingForTypeImpl(Field->getType(), S,8812ObjCEncOptions().setExpandStructures(),8813Field);8814} else {8815QualType qt = Field->getType();8816getLegacyIntegralTypeEncoding(qt);8817getObjCEncodingForTypeImpl(8818qt, S,8819ObjCEncOptions().setExpandStructures().setIsStructField(), FD,8820NotEncodedT);8821}8822}8823}8824}8825S += RDecl->isUnion() ? ')' : '}';8826return;8827}88288829case Type::BlockPointer: {8830const auto *BT = T->castAs<BlockPointerType>();8831S += "@?"; // Unlike a pointer-to-function, which is "^?".8832if (Options.EncodeBlockParameters()) {8833const auto *FT = BT->getPointeeType()->castAs<FunctionType>();88348835S += '<';8836// Block return type8837getObjCEncodingForTypeImpl(FT->getReturnType(), S,8838Options.forComponentType(), FD, NotEncodedT);8839// Block self8840S += "@?";8841// Block parameters8842if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {8843for (const auto &I : FPT->param_types())8844getObjCEncodingForTypeImpl(I, S, Options.forComponentType(), FD,8845NotEncodedT);8846}8847S += '>';8848}8849return;8850}88518852case Type::ObjCObject: {8853// hack to match legacy encoding of *id and *Class8854QualType Ty = getObjCObjectPointerType(CT);8855if (Ty->isObjCIdType()) {8856S += "{objc_object=}";8857return;8858}8859else if (Ty->isObjCClassType()) {8860S += "{objc_class=}";8861return;8862}8863// TODO: Double check to make sure this intentionally falls through.8864[[fallthrough]];8865}88668867case Type::ObjCInterface: {8868// Ignore protocol qualifiers when mangling at this level.8869// @encode(class_name)8870ObjCInterfaceDecl *OI = T->castAs<ObjCObjectType>()->getInterface();8871S += '{';8872S += OI->getObjCRuntimeNameAsString();8873if (Options.ExpandStructures()) {8874S += '=';8875SmallVector<const ObjCIvarDecl*, 32> Ivars;8876DeepCollectObjCIvars(OI, true, Ivars);8877for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {8878const FieldDecl *Field = Ivars[i];8879if (Field->isBitField())8880getObjCEncodingForTypeImpl(Field->getType(), S,8881ObjCEncOptions().setExpandStructures(),8882Field);8883else8884getObjCEncodingForTypeImpl(Field->getType(), S,8885ObjCEncOptions().setExpandStructures(), FD,8886NotEncodedT);8887}8888}8889S += '}';8890return;8891}88928893case Type::ObjCObjectPointer: {8894const auto *OPT = T->castAs<ObjCObjectPointerType>();8895if (OPT->isObjCIdType()) {8896S += '@';8897return;8898}88998900if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {8901// FIXME: Consider if we need to output qualifiers for 'Class<p>'.8902// Since this is a binary compatibility issue, need to consult with8903// runtime folks. Fortunately, this is a *very* obscure construct.8904S += '#';8905return;8906}89078908if (OPT->isObjCQualifiedIdType()) {8909getObjCEncodingForTypeImpl(8910getObjCIdType(), S,8911Options.keepingOnly(ObjCEncOptions()8912.setExpandPointedToStructures()8913.setExpandStructures()),8914FD);8915if (FD || Options.EncodingProperty() || Options.EncodeClassNames()) {8916// Note that we do extended encoding of protocol qualifier list8917// Only when doing ivar or property encoding.8918S += '"';8919for (const auto *I : OPT->quals()) {8920S += '<';8921S += I->getObjCRuntimeNameAsString();8922S += '>';8923}8924S += '"';8925}8926return;8927}89288929S += '@';8930if (OPT->getInterfaceDecl() &&8931(FD || Options.EncodingProperty() || Options.EncodeClassNames())) {8932S += '"';8933S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();8934for (const auto *I : OPT->quals()) {8935S += '<';8936S += I->getObjCRuntimeNameAsString();8937S += '>';8938}8939S += '"';8940}8941return;8942}89438944// gcc just blithely ignores member pointers.8945// FIXME: we should do better than that. 'M' is available.8946case Type::MemberPointer:8947// This matches gcc's encoding, even though technically it is insufficient.8948//FIXME. We should do a better job than gcc.8949case Type::Vector:8950case Type::ExtVector:8951// Until we have a coherent encoding of these three types, issue warning.8952if (NotEncodedT)8953*NotEncodedT = T;8954return;89558956case Type::ConstantMatrix:8957if (NotEncodedT)8958*NotEncodedT = T;8959return;89608961case Type::BitInt:8962if (NotEncodedT)8963*NotEncodedT = T;8964return;89658966// We could see an undeduced auto type here during error recovery.8967// Just ignore it.8968case Type::Auto:8969case Type::DeducedTemplateSpecialization:8970return;89718972case Type::ArrayParameter:8973case Type::Pipe:8974#define ABSTRACT_TYPE(KIND, BASE)8975#define TYPE(KIND, BASE)8976#define DEPENDENT_TYPE(KIND, BASE) \8977case Type::KIND:8978#define NON_CANONICAL_TYPE(KIND, BASE) \8979case Type::KIND:8980#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(KIND, BASE) \8981case Type::KIND:8982#include "clang/AST/TypeNodes.inc"8983llvm_unreachable("@encode for dependent type!");8984}8985llvm_unreachable("bad type kind!");8986}89878988void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,8989std::string &S,8990const FieldDecl *FD,8991bool includeVBases,8992QualType *NotEncodedT) const {8993assert(RDecl && "Expected non-null RecordDecl");8994assert(!RDecl->isUnion() && "Should not be called for unions");8995if (!RDecl->getDefinition() || RDecl->getDefinition()->isInvalidDecl())8996return;89978998const auto *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);8999std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets;9000const ASTRecordLayout &layout = getASTRecordLayout(RDecl);90019002if (CXXRec) {9003for (const auto &BI : CXXRec->bases()) {9004if (!BI.isVirtual()) {9005CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();9006if (base->isEmpty())9007continue;9008uint64_t offs = toBits(layout.getBaseClassOffset(base));9009FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),9010std::make_pair(offs, base));9011}9012}9013}90149015for (FieldDecl *Field : RDecl->fields()) {9016if (!Field->isZeroLengthBitField(*this) && Field->isZeroSize(*this))9017continue;9018uint64_t offs = layout.getFieldOffset(Field->getFieldIndex());9019FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),9020std::make_pair(offs, Field));9021}90229023if (CXXRec && includeVBases) {9024for (const auto &BI : CXXRec->vbases()) {9025CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();9026if (base->isEmpty())9027continue;9028uint64_t offs = toBits(layout.getVBaseClassOffset(base));9029if (offs >= uint64_t(toBits(layout.getNonVirtualSize())) &&9030FieldOrBaseOffsets.find(offs) == FieldOrBaseOffsets.end())9031FieldOrBaseOffsets.insert(FieldOrBaseOffsets.end(),9032std::make_pair(offs, base));9033}9034}90359036CharUnits size;9037if (CXXRec) {9038size = includeVBases ? layout.getSize() : layout.getNonVirtualSize();9039} else {9040size = layout.getSize();9041}90429043#ifndef NDEBUG9044uint64_t CurOffs = 0;9045#endif9046std::multimap<uint64_t, NamedDecl *>::iterator9047CurLayObj = FieldOrBaseOffsets.begin();90489049if (CXXRec && CXXRec->isDynamicClass() &&9050(CurLayObj == FieldOrBaseOffsets.end() || CurLayObj->first != 0)) {9051if (FD) {9052S += "\"_vptr$";9053std::string recname = CXXRec->getNameAsString();9054if (recname.empty()) recname = "?";9055S += recname;9056S += '"';9057}9058S += "^^?";9059#ifndef NDEBUG9060CurOffs += getTypeSize(VoidPtrTy);9061#endif9062}90639064if (!RDecl->hasFlexibleArrayMember()) {9065// Mark the end of the structure.9066uint64_t offs = toBits(size);9067FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),9068std::make_pair(offs, nullptr));9069}90709071for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {9072#ifndef NDEBUG9073assert(CurOffs <= CurLayObj->first);9074if (CurOffs < CurLayObj->first) {9075uint64_t padding = CurLayObj->first - CurOffs;9076// FIXME: There doesn't seem to be a way to indicate in the encoding that9077// packing/alignment of members is different that normal, in which case9078// the encoding will be out-of-sync with the real layout.9079// If the runtime switches to just consider the size of types without9080// taking into account alignment, we could make padding explicit in the9081// encoding (e.g. using arrays of chars). The encoding strings would be9082// longer then though.9083CurOffs += padding;9084}9085#endif90869087NamedDecl *dcl = CurLayObj->second;9088if (!dcl)9089break; // reached end of structure.90909091if (auto *base = dyn_cast<CXXRecordDecl>(dcl)) {9092// We expand the bases without their virtual bases since those are going9093// in the initial structure. Note that this differs from gcc which9094// expands virtual bases each time one is encountered in the hierarchy,9095// making the encoding type bigger than it really is.9096getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false,9097NotEncodedT);9098assert(!base->isEmpty());9099#ifndef NDEBUG9100CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());9101#endif9102} else {9103const auto *field = cast<FieldDecl>(dcl);9104if (FD) {9105S += '"';9106S += field->getNameAsString();9107S += '"';9108}91099110if (field->isBitField()) {9111EncodeBitField(this, S, field->getType(), field);9112#ifndef NDEBUG9113CurOffs += field->getBitWidthValue(*this);9114#endif9115} else {9116QualType qt = field->getType();9117getLegacyIntegralTypeEncoding(qt);9118getObjCEncodingForTypeImpl(9119qt, S, ObjCEncOptions().setExpandStructures().setIsStructField(),9120FD, NotEncodedT);9121#ifndef NDEBUG9122CurOffs += getTypeSize(field->getType());9123#endif9124}9125}9126}9127}91289129void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,9130std::string& S) const {9131if (QT & Decl::OBJC_TQ_In)9132S += 'n';9133if (QT & Decl::OBJC_TQ_Inout)9134S += 'N';9135if (QT & Decl::OBJC_TQ_Out)9136S += 'o';9137if (QT & Decl::OBJC_TQ_Bycopy)9138S += 'O';9139if (QT & Decl::OBJC_TQ_Byref)9140S += 'R';9141if (QT & Decl::OBJC_TQ_Oneway)9142S += 'V';9143}91449145TypedefDecl *ASTContext::getObjCIdDecl() const {9146if (!ObjCIdDecl) {9147QualType T = getObjCObjectType(ObjCBuiltinIdTy, {}, {});9148T = getObjCObjectPointerType(T);9149ObjCIdDecl = buildImplicitTypedef(T, "id");9150}9151return ObjCIdDecl;9152}91539154TypedefDecl *ASTContext::getObjCSelDecl() const {9155if (!ObjCSelDecl) {9156QualType T = getPointerType(ObjCBuiltinSelTy);9157ObjCSelDecl = buildImplicitTypedef(T, "SEL");9158}9159return ObjCSelDecl;9160}91619162TypedefDecl *ASTContext::getObjCClassDecl() const {9163if (!ObjCClassDecl) {9164QualType T = getObjCObjectType(ObjCBuiltinClassTy, {}, {});9165T = getObjCObjectPointerType(T);9166ObjCClassDecl = buildImplicitTypedef(T, "Class");9167}9168return ObjCClassDecl;9169}91709171ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {9172if (!ObjCProtocolClassDecl) {9173ObjCProtocolClassDecl9174= ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(),9175SourceLocation(),9176&Idents.get("Protocol"),9177/*typeParamList=*/nullptr,9178/*PrevDecl=*/nullptr,9179SourceLocation(), true);9180}91819182return ObjCProtocolClassDecl;9183}91849185//===----------------------------------------------------------------------===//9186// __builtin_va_list Construction Functions9187//===----------------------------------------------------------------------===//91889189static TypedefDecl *CreateCharPtrNamedVaListDecl(const ASTContext *Context,9190StringRef Name) {9191// typedef char* __builtin[_ms]_va_list;9192QualType T = Context->getPointerType(Context->CharTy);9193return Context->buildImplicitTypedef(T, Name);9194}91959196static TypedefDecl *CreateMSVaListDecl(const ASTContext *Context) {9197return CreateCharPtrNamedVaListDecl(Context, "__builtin_ms_va_list");9198}91999200static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {9201return CreateCharPtrNamedVaListDecl(Context, "__builtin_va_list");9202}92039204static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {9205// typedef void* __builtin_va_list;9206QualType T = Context->getPointerType(Context->VoidTy);9207return Context->buildImplicitTypedef(T, "__builtin_va_list");9208}92099210static TypedefDecl *9211CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {9212// struct __va_list9213RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list");9214if (Context->getLangOpts().CPlusPlus) {9215// namespace std { struct __va_list {9216auto *NS = NamespaceDecl::Create(9217const_cast<ASTContext &>(*Context), Context->getTranslationUnitDecl(),9218/*Inline=*/false, SourceLocation(), SourceLocation(),9219&Context->Idents.get("std"),9220/*PrevDecl=*/nullptr, /*Nested=*/false);9221NS->setImplicit();9222VaListTagDecl->setDeclContext(NS);9223}92249225VaListTagDecl->startDefinition();92269227const size_t NumFields = 5;9228QualType FieldTypes[NumFields];9229const char *FieldNames[NumFields];92309231// void *__stack;9232FieldTypes[0] = Context->getPointerType(Context->VoidTy);9233FieldNames[0] = "__stack";92349235// void *__gr_top;9236FieldTypes[1] = Context->getPointerType(Context->VoidTy);9237FieldNames[1] = "__gr_top";92389239// void *__vr_top;9240FieldTypes[2] = Context->getPointerType(Context->VoidTy);9241FieldNames[2] = "__vr_top";92429243// int __gr_offs;9244FieldTypes[3] = Context->IntTy;9245FieldNames[3] = "__gr_offs";92469247// int __vr_offs;9248FieldTypes[4] = Context->IntTy;9249FieldNames[4] = "__vr_offs";92509251// Create fields9252for (unsigned i = 0; i < NumFields; ++i) {9253FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),9254VaListTagDecl,9255SourceLocation(),9256SourceLocation(),9257&Context->Idents.get(FieldNames[i]),9258FieldTypes[i], /*TInfo=*/nullptr,9259/*BitWidth=*/nullptr,9260/*Mutable=*/false,9261ICIS_NoInit);9262Field->setAccess(AS_public);9263VaListTagDecl->addDecl(Field);9264}9265VaListTagDecl->completeDefinition();9266Context->VaListTagDecl = VaListTagDecl;9267QualType VaListTagType = Context->getRecordType(VaListTagDecl);92689269// } __builtin_va_list;9270return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");9271}92729273static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {9274// typedef struct __va_list_tag {9275RecordDecl *VaListTagDecl;92769277VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");9278VaListTagDecl->startDefinition();92799280const size_t NumFields = 5;9281QualType FieldTypes[NumFields];9282const char *FieldNames[NumFields];92839284// unsigned char gpr;9285FieldTypes[0] = Context->UnsignedCharTy;9286FieldNames[0] = "gpr";92879288// unsigned char fpr;9289FieldTypes[1] = Context->UnsignedCharTy;9290FieldNames[1] = "fpr";92919292// unsigned short reserved;9293FieldTypes[2] = Context->UnsignedShortTy;9294FieldNames[2] = "reserved";92959296// void* overflow_arg_area;9297FieldTypes[3] = Context->getPointerType(Context->VoidTy);9298FieldNames[3] = "overflow_arg_area";92999300// void* reg_save_area;9301FieldTypes[4] = Context->getPointerType(Context->VoidTy);9302FieldNames[4] = "reg_save_area";93039304// Create fields9305for (unsigned i = 0; i < NumFields; ++i) {9306FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl,9307SourceLocation(),9308SourceLocation(),9309&Context->Idents.get(FieldNames[i]),9310FieldTypes[i], /*TInfo=*/nullptr,9311/*BitWidth=*/nullptr,9312/*Mutable=*/false,9313ICIS_NoInit);9314Field->setAccess(AS_public);9315VaListTagDecl->addDecl(Field);9316}9317VaListTagDecl->completeDefinition();9318Context->VaListTagDecl = VaListTagDecl;9319QualType VaListTagType = Context->getRecordType(VaListTagDecl);93209321// } __va_list_tag;9322TypedefDecl *VaListTagTypedefDecl =9323Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");93249325QualType VaListTagTypedefType =9326Context->getTypedefType(VaListTagTypedefDecl);93279328// typedef __va_list_tag __builtin_va_list[1];9329llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);9330QualType VaListTagArrayType = Context->getConstantArrayType(9331VaListTagTypedefType, Size, nullptr, ArraySizeModifier::Normal, 0);9332return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");9333}93349335static TypedefDecl *9336CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {9337// struct __va_list_tag {9338RecordDecl *VaListTagDecl;9339VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");9340VaListTagDecl->startDefinition();93419342const size_t NumFields = 4;9343QualType FieldTypes[NumFields];9344const char *FieldNames[NumFields];93459346// unsigned gp_offset;9347FieldTypes[0] = Context->UnsignedIntTy;9348FieldNames[0] = "gp_offset";93499350// unsigned fp_offset;9351FieldTypes[1] = Context->UnsignedIntTy;9352FieldNames[1] = "fp_offset";93539354// void* overflow_arg_area;9355FieldTypes[2] = Context->getPointerType(Context->VoidTy);9356FieldNames[2] = "overflow_arg_area";93579358// void* reg_save_area;9359FieldTypes[3] = Context->getPointerType(Context->VoidTy);9360FieldNames[3] = "reg_save_area";93619362// Create fields9363for (unsigned i = 0; i < NumFields; ++i) {9364FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),9365VaListTagDecl,9366SourceLocation(),9367SourceLocation(),9368&Context->Idents.get(FieldNames[i]),9369FieldTypes[i], /*TInfo=*/nullptr,9370/*BitWidth=*/nullptr,9371/*Mutable=*/false,9372ICIS_NoInit);9373Field->setAccess(AS_public);9374VaListTagDecl->addDecl(Field);9375}9376VaListTagDecl->completeDefinition();9377Context->VaListTagDecl = VaListTagDecl;9378QualType VaListTagType = Context->getRecordType(VaListTagDecl);93799380// };93819382// typedef struct __va_list_tag __builtin_va_list[1];9383llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);9384QualType VaListTagArrayType = Context->getConstantArrayType(9385VaListTagType, Size, nullptr, ArraySizeModifier::Normal, 0);9386return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");9387}93889389static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {9390// typedef int __builtin_va_list[4];9391llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 4);9392QualType IntArrayType = Context->getConstantArrayType(9393Context->IntTy, Size, nullptr, ArraySizeModifier::Normal, 0);9394return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list");9395}93969397static TypedefDecl *9398CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {9399// struct __va_list9400RecordDecl *VaListDecl = Context->buildImplicitRecord("__va_list");9401if (Context->getLangOpts().CPlusPlus) {9402// namespace std { struct __va_list {9403NamespaceDecl *NS;9404NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context),9405Context->getTranslationUnitDecl(),9406/*Inline=*/false, SourceLocation(),9407SourceLocation(), &Context->Idents.get("std"),9408/*PrevDecl=*/nullptr, /*Nested=*/false);9409NS->setImplicit();9410VaListDecl->setDeclContext(NS);9411}94129413VaListDecl->startDefinition();94149415// void * __ap;9416FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),9417VaListDecl,9418SourceLocation(),9419SourceLocation(),9420&Context->Idents.get("__ap"),9421Context->getPointerType(Context->VoidTy),9422/*TInfo=*/nullptr,9423/*BitWidth=*/nullptr,9424/*Mutable=*/false,9425ICIS_NoInit);9426Field->setAccess(AS_public);9427VaListDecl->addDecl(Field);94289429// };9430VaListDecl->completeDefinition();9431Context->VaListTagDecl = VaListDecl;94329433// typedef struct __va_list __builtin_va_list;9434QualType T = Context->getRecordType(VaListDecl);9435return Context->buildImplicitTypedef(T, "__builtin_va_list");9436}94379438static TypedefDecl *9439CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {9440// struct __va_list_tag {9441RecordDecl *VaListTagDecl;9442VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");9443VaListTagDecl->startDefinition();94449445const size_t NumFields = 4;9446QualType FieldTypes[NumFields];9447const char *FieldNames[NumFields];94489449// long __gpr;9450FieldTypes[0] = Context->LongTy;9451FieldNames[0] = "__gpr";94529453// long __fpr;9454FieldTypes[1] = Context->LongTy;9455FieldNames[1] = "__fpr";94569457// void *__overflow_arg_area;9458FieldTypes[2] = Context->getPointerType(Context->VoidTy);9459FieldNames[2] = "__overflow_arg_area";94609461// void *__reg_save_area;9462FieldTypes[3] = Context->getPointerType(Context->VoidTy);9463FieldNames[3] = "__reg_save_area";94649465// Create fields9466for (unsigned i = 0; i < NumFields; ++i) {9467FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),9468VaListTagDecl,9469SourceLocation(),9470SourceLocation(),9471&Context->Idents.get(FieldNames[i]),9472FieldTypes[i], /*TInfo=*/nullptr,9473/*BitWidth=*/nullptr,9474/*Mutable=*/false,9475ICIS_NoInit);9476Field->setAccess(AS_public);9477VaListTagDecl->addDecl(Field);9478}9479VaListTagDecl->completeDefinition();9480Context->VaListTagDecl = VaListTagDecl;9481QualType VaListTagType = Context->getRecordType(VaListTagDecl);94829483// };94849485// typedef __va_list_tag __builtin_va_list[1];9486llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);9487QualType VaListTagArrayType = Context->getConstantArrayType(9488VaListTagType, Size, nullptr, ArraySizeModifier::Normal, 0);94899490return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");9491}94929493static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {9494// typedef struct __va_list_tag {9495RecordDecl *VaListTagDecl;9496VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");9497VaListTagDecl->startDefinition();94989499const size_t NumFields = 3;9500QualType FieldTypes[NumFields];9501const char *FieldNames[NumFields];95029503// void *CurrentSavedRegisterArea;9504FieldTypes[0] = Context->getPointerType(Context->VoidTy);9505FieldNames[0] = "__current_saved_reg_area_pointer";95069507// void *SavedRegAreaEnd;9508FieldTypes[1] = Context->getPointerType(Context->VoidTy);9509FieldNames[1] = "__saved_reg_area_end_pointer";95109511// void *OverflowArea;9512FieldTypes[2] = Context->getPointerType(Context->VoidTy);9513FieldNames[2] = "__overflow_area_pointer";95149515// Create fields9516for (unsigned i = 0; i < NumFields; ++i) {9517FieldDecl *Field = FieldDecl::Create(9518const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),9519SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],9520/*TInfo=*/nullptr,9521/*BitWidth=*/nullptr,9522/*Mutable=*/false, ICIS_NoInit);9523Field->setAccess(AS_public);9524VaListTagDecl->addDecl(Field);9525}9526VaListTagDecl->completeDefinition();9527Context->VaListTagDecl = VaListTagDecl;9528QualType VaListTagType = Context->getRecordType(VaListTagDecl);95299530// } __va_list_tag;9531TypedefDecl *VaListTagTypedefDecl =9532Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");95339534QualType VaListTagTypedefType = Context->getTypedefType(VaListTagTypedefDecl);95359536// typedef __va_list_tag __builtin_va_list[1];9537llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);9538QualType VaListTagArrayType = Context->getConstantArrayType(9539VaListTagTypedefType, Size, nullptr, ArraySizeModifier::Normal, 0);95409541return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");9542}95439544static TypedefDecl *CreateVaListDecl(const ASTContext *Context,9545TargetInfo::BuiltinVaListKind Kind) {9546switch (Kind) {9547case TargetInfo::CharPtrBuiltinVaList:9548return CreateCharPtrBuiltinVaListDecl(Context);9549case TargetInfo::VoidPtrBuiltinVaList:9550return CreateVoidPtrBuiltinVaListDecl(Context);9551case TargetInfo::AArch64ABIBuiltinVaList:9552return CreateAArch64ABIBuiltinVaListDecl(Context);9553case TargetInfo::PowerABIBuiltinVaList:9554return CreatePowerABIBuiltinVaListDecl(Context);9555case TargetInfo::X86_64ABIBuiltinVaList:9556return CreateX86_64ABIBuiltinVaListDecl(Context);9557case TargetInfo::PNaClABIBuiltinVaList:9558return CreatePNaClABIBuiltinVaListDecl(Context);9559case TargetInfo::AAPCSABIBuiltinVaList:9560return CreateAAPCSABIBuiltinVaListDecl(Context);9561case TargetInfo::SystemZBuiltinVaList:9562return CreateSystemZBuiltinVaListDecl(Context);9563case TargetInfo::HexagonBuiltinVaList:9564return CreateHexagonBuiltinVaListDecl(Context);9565}95669567llvm_unreachable("Unhandled __builtin_va_list type kind");9568}95699570TypedefDecl *ASTContext::getBuiltinVaListDecl() const {9571if (!BuiltinVaListDecl) {9572BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind());9573assert(BuiltinVaListDecl->isImplicit());9574}95759576return BuiltinVaListDecl;9577}95789579Decl *ASTContext::getVaListTagDecl() const {9580// Force the creation of VaListTagDecl by building the __builtin_va_list9581// declaration.9582if (!VaListTagDecl)9583(void)getBuiltinVaListDecl();95849585return VaListTagDecl;9586}95879588TypedefDecl *ASTContext::getBuiltinMSVaListDecl() const {9589if (!BuiltinMSVaListDecl)9590BuiltinMSVaListDecl = CreateMSVaListDecl(this);95919592return BuiltinMSVaListDecl;9593}95949595bool ASTContext::canBuiltinBeRedeclared(const FunctionDecl *FD) const {9596// Allow redecl custom type checking builtin for HLSL.9597if (LangOpts.HLSL && FD->getBuiltinID() != Builtin::NotBuiltin &&9598BuiltinInfo.hasCustomTypechecking(FD->getBuiltinID()))9599return true;9600return BuiltinInfo.canBeRedeclared(FD->getBuiltinID());9601}96029603void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {9604assert(ObjCConstantStringType.isNull() &&9605"'NSConstantString' type already set!");96069607ObjCConstantStringType = getObjCInterfaceType(Decl);9608}96099610/// Retrieve the template name that corresponds to a non-empty9611/// lookup.9612TemplateName9613ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,9614UnresolvedSetIterator End) const {9615unsigned size = End - Begin;9616assert(size > 1 && "set is not overloaded!");96179618void *memory = Allocate(sizeof(OverloadedTemplateStorage) +9619size * sizeof(FunctionTemplateDecl*));9620auto *OT = new (memory) OverloadedTemplateStorage(size);96219622NamedDecl **Storage = OT->getStorage();9623for (UnresolvedSetIterator I = Begin; I != End; ++I) {9624NamedDecl *D = *I;9625assert(isa<FunctionTemplateDecl>(D) ||9626isa<UnresolvedUsingValueDecl>(D) ||9627(isa<UsingShadowDecl>(D) &&9628isa<FunctionTemplateDecl>(D->getUnderlyingDecl())));9629*Storage++ = D;9630}96319632return TemplateName(OT);9633}96349635/// Retrieve a template name representing an unqualified-id that has been9636/// assumed to name a template for ADL purposes.9637TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const {9638auto *OT = new (*this) AssumedTemplateStorage(Name);9639return TemplateName(OT);9640}96419642/// Retrieve the template name that represents a qualified9643/// template name such as \c std::vector.9644TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,9645bool TemplateKeyword,9646TemplateName Template) const {9647assert(Template.getKind() == TemplateName::Template ||9648Template.getKind() == TemplateName::UsingTemplate);96499650// FIXME: Canonicalization?9651llvm::FoldingSetNodeID ID;9652QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);96539654void *InsertPos = nullptr;9655QualifiedTemplateName *QTN =9656QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);9657if (!QTN) {9658QTN = new (*this, alignof(QualifiedTemplateName))9659QualifiedTemplateName(NNS, TemplateKeyword, Template);9660QualifiedTemplateNames.InsertNode(QTN, InsertPos);9661}96629663return TemplateName(QTN);9664}96659666/// Retrieve the template name that represents a dependent9667/// template name such as \c MetaFun::template apply.9668TemplateName9669ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,9670const IdentifierInfo *Name) const {9671assert((!NNS || NNS->isDependent()) &&9672"Nested name specifier must be dependent");96739674llvm::FoldingSetNodeID ID;9675DependentTemplateName::Profile(ID, NNS, Name);96769677void *InsertPos = nullptr;9678DependentTemplateName *QTN =9679DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);96809681if (QTN)9682return TemplateName(QTN);96839684NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);9685if (CanonNNS == NNS) {9686QTN = new (*this, alignof(DependentTemplateName))9687DependentTemplateName(NNS, Name);9688} else {9689TemplateName Canon = getDependentTemplateName(CanonNNS, Name);9690QTN = new (*this, alignof(DependentTemplateName))9691DependentTemplateName(NNS, Name, Canon);9692DependentTemplateName *CheckQTN =9693DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);9694assert(!CheckQTN && "Dependent type name canonicalization broken");9695(void)CheckQTN;9696}96979698DependentTemplateNames.InsertNode(QTN, InsertPos);9699return TemplateName(QTN);9700}97019702/// Retrieve the template name that represents a dependent9703/// template name such as \c MetaFun::template operator+.9704TemplateName9705ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,9706OverloadedOperatorKind Operator) const {9707assert((!NNS || NNS->isDependent()) &&9708"Nested name specifier must be dependent");97099710llvm::FoldingSetNodeID ID;9711DependentTemplateName::Profile(ID, NNS, Operator);97129713void *InsertPos = nullptr;9714DependentTemplateName *QTN9715= DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);97169717if (QTN)9718return TemplateName(QTN);97199720NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);9721if (CanonNNS == NNS) {9722QTN = new (*this, alignof(DependentTemplateName))9723DependentTemplateName(NNS, Operator);9724} else {9725TemplateName Canon = getDependentTemplateName(CanonNNS, Operator);9726QTN = new (*this, alignof(DependentTemplateName))9727DependentTemplateName(NNS, Operator, Canon);97289729DependentTemplateName *CheckQTN9730= DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);9731assert(!CheckQTN && "Dependent template name canonicalization broken");9732(void)CheckQTN;9733}97349735DependentTemplateNames.InsertNode(QTN, InsertPos);9736return TemplateName(QTN);9737}97389739TemplateName ASTContext::getSubstTemplateTemplateParm(9740TemplateName Replacement, Decl *AssociatedDecl, unsigned Index,9741std::optional<unsigned> PackIndex) const {9742llvm::FoldingSetNodeID ID;9743SubstTemplateTemplateParmStorage::Profile(ID, Replacement, AssociatedDecl,9744Index, PackIndex);97459746void *insertPos = nullptr;9747SubstTemplateTemplateParmStorage *subst9748= SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);97499750if (!subst) {9751subst = new (*this) SubstTemplateTemplateParmStorage(9752Replacement, AssociatedDecl, Index, PackIndex);9753SubstTemplateTemplateParms.InsertNode(subst, insertPos);9754}97559756return TemplateName(subst);9757}97589759TemplateName9760ASTContext::getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack,9761Decl *AssociatedDecl,9762unsigned Index, bool Final) const {9763auto &Self = const_cast<ASTContext &>(*this);9764llvm::FoldingSetNodeID ID;9765SubstTemplateTemplateParmPackStorage::Profile(ID, Self, ArgPack,9766AssociatedDecl, Index, Final);97679768void *InsertPos = nullptr;9769SubstTemplateTemplateParmPackStorage *Subst9770= SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);97719772if (!Subst) {9773Subst = new (*this) SubstTemplateTemplateParmPackStorage(9774ArgPack.pack_elements(), AssociatedDecl, Index, Final);9775SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos);9776}97779778return TemplateName(Subst);9779}97809781/// getFromTargetType - Given one of the integer types provided by9782/// TargetInfo, produce the corresponding type. The unsigned @p Type9783/// is actually a value of type @c TargetInfo::IntType.9784CanQualType ASTContext::getFromTargetType(unsigned Type) const {9785switch (Type) {9786case TargetInfo::NoInt: return {};9787case TargetInfo::SignedChar: return SignedCharTy;9788case TargetInfo::UnsignedChar: return UnsignedCharTy;9789case TargetInfo::SignedShort: return ShortTy;9790case TargetInfo::UnsignedShort: return UnsignedShortTy;9791case TargetInfo::SignedInt: return IntTy;9792case TargetInfo::UnsignedInt: return UnsignedIntTy;9793case TargetInfo::SignedLong: return LongTy;9794case TargetInfo::UnsignedLong: return UnsignedLongTy;9795case TargetInfo::SignedLongLong: return LongLongTy;9796case TargetInfo::UnsignedLongLong: return UnsignedLongLongTy;9797}97989799llvm_unreachable("Unhandled TargetInfo::IntType value");9800}98019802//===----------------------------------------------------------------------===//9803// Type Predicates.9804//===----------------------------------------------------------------------===//98059806/// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's9807/// garbage collection attribute.9808///9809Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const {9810if (getLangOpts().getGC() == LangOptions::NonGC)9811return Qualifiers::GCNone;98129813assert(getLangOpts().ObjC);9814Qualifiers::GC GCAttrs = Ty.getObjCGCAttr();98159816// Default behaviour under objective-C's gc is for ObjC pointers9817// (or pointers to them) be treated as though they were declared9818// as __strong.9819if (GCAttrs == Qualifiers::GCNone) {9820if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType())9821return Qualifiers::Strong;9822else if (Ty->isPointerType())9823return getObjCGCAttrKind(Ty->castAs<PointerType>()->getPointeeType());9824} else {9825// It's not valid to set GC attributes on anything that isn't a9826// pointer.9827#ifndef NDEBUG9828QualType CT = Ty->getCanonicalTypeInternal();9829while (const auto *AT = dyn_cast<ArrayType>(CT))9830CT = AT->getElementType();9831assert(CT->isAnyPointerType() || CT->isBlockPointerType());9832#endif9833}9834return GCAttrs;9835}98369837//===----------------------------------------------------------------------===//9838// Type Compatibility Testing9839//===----------------------------------------------------------------------===//98409841/// areCompatVectorTypes - Return true if the two specified vector types are9842/// compatible.9843static bool areCompatVectorTypes(const VectorType *LHS,9844const VectorType *RHS) {9845assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified());9846return LHS->getElementType() == RHS->getElementType() &&9847LHS->getNumElements() == RHS->getNumElements();9848}98499850/// areCompatMatrixTypes - Return true if the two specified matrix types are9851/// compatible.9852static bool areCompatMatrixTypes(const ConstantMatrixType *LHS,9853const ConstantMatrixType *RHS) {9854assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified());9855return LHS->getElementType() == RHS->getElementType() &&9856LHS->getNumRows() == RHS->getNumRows() &&9857LHS->getNumColumns() == RHS->getNumColumns();9858}98599860bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,9861QualType SecondVec) {9862assert(FirstVec->isVectorType() && "FirstVec should be a vector type");9863assert(SecondVec->isVectorType() && "SecondVec should be a vector type");98649865if (hasSameUnqualifiedType(FirstVec, SecondVec))9866return true;98679868// Treat Neon vector types and most AltiVec vector types as if they are the9869// equivalent GCC vector types.9870const auto *First = FirstVec->castAs<VectorType>();9871const auto *Second = SecondVec->castAs<VectorType>();9872if (First->getNumElements() == Second->getNumElements() &&9873hasSameType(First->getElementType(), Second->getElementType()) &&9874First->getVectorKind() != VectorKind::AltiVecPixel &&9875First->getVectorKind() != VectorKind::AltiVecBool &&9876Second->getVectorKind() != VectorKind::AltiVecPixel &&9877Second->getVectorKind() != VectorKind::AltiVecBool &&9878First->getVectorKind() != VectorKind::SveFixedLengthData &&9879First->getVectorKind() != VectorKind::SveFixedLengthPredicate &&9880Second->getVectorKind() != VectorKind::SveFixedLengthData &&9881Second->getVectorKind() != VectorKind::SveFixedLengthPredicate &&9882First->getVectorKind() != VectorKind::RVVFixedLengthData &&9883Second->getVectorKind() != VectorKind::RVVFixedLengthData &&9884First->getVectorKind() != VectorKind::RVVFixedLengthMask &&9885Second->getVectorKind() != VectorKind::RVVFixedLengthMask)9886return true;98879888return false;9889}98909891/// getSVETypeSize - Return SVE vector or predicate register size.9892static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty) {9893assert(Ty->isSveVLSBuiltinType() && "Invalid SVE Type");9894if (Ty->getKind() == BuiltinType::SveBool ||9895Ty->getKind() == BuiltinType::SveCount)9896return (Context.getLangOpts().VScaleMin * 128) / Context.getCharWidth();9897return Context.getLangOpts().VScaleMin * 128;9898}98999900bool ASTContext::areCompatibleSveTypes(QualType FirstType,9901QualType SecondType) {9902auto IsValidCast = [this](QualType FirstType, QualType SecondType) {9903if (const auto *BT = FirstType->getAs<BuiltinType>()) {9904if (const auto *VT = SecondType->getAs<VectorType>()) {9905// Predicates have the same representation as uint8 so we also have to9906// check the kind to make these types incompatible.9907if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)9908return BT->getKind() == BuiltinType::SveBool;9909else if (VT->getVectorKind() == VectorKind::SveFixedLengthData)9910return VT->getElementType().getCanonicalType() ==9911FirstType->getSveEltType(*this);9912else if (VT->getVectorKind() == VectorKind::Generic)9913return getTypeSize(SecondType) == getSVETypeSize(*this, BT) &&9914hasSameType(VT->getElementType(),9915getBuiltinVectorTypeInfo(BT).ElementType);9916}9917}9918return false;9919};99209921return IsValidCast(FirstType, SecondType) ||9922IsValidCast(SecondType, FirstType);9923}99249925bool ASTContext::areLaxCompatibleSveTypes(QualType FirstType,9926QualType SecondType) {9927auto IsLaxCompatible = [this](QualType FirstType, QualType SecondType) {9928const auto *BT = FirstType->getAs<BuiltinType>();9929if (!BT)9930return false;99319932const auto *VecTy = SecondType->getAs<VectorType>();9933if (VecTy && (VecTy->getVectorKind() == VectorKind::SveFixedLengthData ||9934VecTy->getVectorKind() == VectorKind::Generic)) {9935const LangOptions::LaxVectorConversionKind LVCKind =9936getLangOpts().getLaxVectorConversions();99379938// Can not convert between sve predicates and sve vectors because of9939// different size.9940if (BT->getKind() == BuiltinType::SveBool &&9941VecTy->getVectorKind() == VectorKind::SveFixedLengthData)9942return false;99439944// If __ARM_FEATURE_SVE_BITS != N do not allow GNU vector lax conversion.9945// "Whenever __ARM_FEATURE_SVE_BITS==N, GNUT implicitly9946// converts to VLAT and VLAT implicitly converts to GNUT."9947// ACLE Spec Version 00bet6, 3.7.3.2. Behavior common to vectors and9948// predicates.9949if (VecTy->getVectorKind() == VectorKind::Generic &&9950getTypeSize(SecondType) != getSVETypeSize(*this, BT))9951return false;99529953// If -flax-vector-conversions=all is specified, the types are9954// certainly compatible.9955if (LVCKind == LangOptions::LaxVectorConversionKind::All)9956return true;99579958// If -flax-vector-conversions=integer is specified, the types are9959// compatible if the elements are integer types.9960if (LVCKind == LangOptions::LaxVectorConversionKind::Integer)9961return VecTy->getElementType().getCanonicalType()->isIntegerType() &&9962FirstType->getSveEltType(*this)->isIntegerType();9963}99649965return false;9966};99679968return IsLaxCompatible(FirstType, SecondType) ||9969IsLaxCompatible(SecondType, FirstType);9970}99719972/// getRVVTypeSize - Return RVV vector register size.9973static uint64_t getRVVTypeSize(ASTContext &Context, const BuiltinType *Ty) {9974assert(Ty->isRVVVLSBuiltinType() && "Invalid RVV Type");9975auto VScale = Context.getTargetInfo().getVScaleRange(Context.getLangOpts());9976if (!VScale)9977return 0;99789979ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo(Ty);99809981uint64_t EltSize = Context.getTypeSize(Info.ElementType);9982if (Info.ElementType == Context.BoolTy)9983EltSize = 1;99849985uint64_t MinElts = Info.EC.getKnownMinValue();9986return VScale->first * MinElts * EltSize;9987}99889989bool ASTContext::areCompatibleRVVTypes(QualType FirstType,9990QualType SecondType) {9991assert(9992((FirstType->isRVVSizelessBuiltinType() && SecondType->isVectorType()) ||9993(FirstType->isVectorType() && SecondType->isRVVSizelessBuiltinType())) &&9994"Expected RVV builtin type and vector type!");99959996auto IsValidCast = [this](QualType FirstType, QualType SecondType) {9997if (const auto *BT = FirstType->getAs<BuiltinType>()) {9998if (const auto *VT = SecondType->getAs<VectorType>()) {9999if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) {10000BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);10001return FirstType->isRVVVLSBuiltinType() &&10002Info.ElementType == BoolTy &&10003getTypeSize(SecondType) == getRVVTypeSize(*this, BT);10004}10005if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||10006VT->getVectorKind() == VectorKind::Generic)10007return FirstType->isRVVVLSBuiltinType() &&10008getTypeSize(SecondType) == getRVVTypeSize(*this, BT) &&10009hasSameType(VT->getElementType(),10010getBuiltinVectorTypeInfo(BT).ElementType);10011}10012}10013return false;10014};1001510016return IsValidCast(FirstType, SecondType) ||10017IsValidCast(SecondType, FirstType);10018}1001910020bool ASTContext::areLaxCompatibleRVVTypes(QualType FirstType,10021QualType SecondType) {10022assert(10023((FirstType->isRVVSizelessBuiltinType() && SecondType->isVectorType()) ||10024(FirstType->isVectorType() && SecondType->isRVVSizelessBuiltinType())) &&10025"Expected RVV builtin type and vector type!");1002610027auto IsLaxCompatible = [this](QualType FirstType, QualType SecondType) {10028const auto *BT = FirstType->getAs<BuiltinType>();10029if (!BT)10030return false;1003110032if (!BT->isRVVVLSBuiltinType())10033return false;1003410035const auto *VecTy = SecondType->getAs<VectorType>();10036if (VecTy && VecTy->getVectorKind() == VectorKind::Generic) {10037const LangOptions::LaxVectorConversionKind LVCKind =10038getLangOpts().getLaxVectorConversions();1003910040// If __riscv_v_fixed_vlen != N do not allow vector lax conversion.10041if (getTypeSize(SecondType) != getRVVTypeSize(*this, BT))10042return false;1004310044// If -flax-vector-conversions=all is specified, the types are10045// certainly compatible.10046if (LVCKind == LangOptions::LaxVectorConversionKind::All)10047return true;1004810049// If -flax-vector-conversions=integer is specified, the types are10050// compatible if the elements are integer types.10051if (LVCKind == LangOptions::LaxVectorConversionKind::Integer)10052return VecTy->getElementType().getCanonicalType()->isIntegerType() &&10053FirstType->getRVVEltType(*this)->isIntegerType();10054}1005510056return false;10057};1005810059return IsLaxCompatible(FirstType, SecondType) ||10060IsLaxCompatible(SecondType, FirstType);10061}1006210063bool ASTContext::hasDirectOwnershipQualifier(QualType Ty) const {10064while (true) {10065// __strong id10066if (const AttributedType *Attr = dyn_cast<AttributedType>(Ty)) {10067if (Attr->getAttrKind() == attr::ObjCOwnership)10068return true;1006910070Ty = Attr->getModifiedType();1007110072// X *__strong (...)10073} else if (const ParenType *Paren = dyn_cast<ParenType>(Ty)) {10074Ty = Paren->getInnerType();1007510076// We do not want to look through typedefs, typeof(expr),10077// typeof(type), or any other way that the type is somehow10078// abstracted.10079} else {10080return false;10081}10082}10083}1008410085//===----------------------------------------------------------------------===//10086// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.10087//===----------------------------------------------------------------------===//1008810089/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the10090/// inheritance hierarchy of 'rProto'.10091bool10092ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,10093ObjCProtocolDecl *rProto) const {10094if (declaresSameEntity(lProto, rProto))10095return true;10096for (auto *PI : rProto->protocols())10097if (ProtocolCompatibleWithProtocol(lProto, PI))10098return true;10099return false;10100}1010110102/// ObjCQualifiedClassTypesAreCompatible - compare Class<pr,...> and10103/// Class<pr1, ...>.10104bool ASTContext::ObjCQualifiedClassTypesAreCompatible(10105const ObjCObjectPointerType *lhs, const ObjCObjectPointerType *rhs) {10106for (auto *lhsProto : lhs->quals()) {10107bool match = false;10108for (auto *rhsProto : rhs->quals()) {10109if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) {10110match = true;10111break;10112}10113}10114if (!match)10115return false;10116}10117return true;10118}1011910120/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an10121/// ObjCQualifiedIDType.10122bool ASTContext::ObjCQualifiedIdTypesAreCompatible(10123const ObjCObjectPointerType *lhs, const ObjCObjectPointerType *rhs,10124bool compare) {10125// Allow id<P..> and an 'id' in all cases.10126if (lhs->isObjCIdType() || rhs->isObjCIdType())10127return true;1012810129// Don't allow id<P..> to convert to Class or Class<P..> in either direction.10130if (lhs->isObjCClassType() || lhs->isObjCQualifiedClassType() ||10131rhs->isObjCClassType() || rhs->isObjCQualifiedClassType())10132return false;1013310134if (lhs->isObjCQualifiedIdType()) {10135if (rhs->qual_empty()) {10136// If the RHS is a unqualified interface pointer "NSString*",10137// make sure we check the class hierarchy.10138if (ObjCInterfaceDecl *rhsID = rhs->getInterfaceDecl()) {10139for (auto *I : lhs->quals()) {10140// when comparing an id<P> on lhs with a static type on rhs,10141// see if static class implements all of id's protocols, directly or10142// through its super class and categories.10143if (!rhsID->ClassImplementsProtocol(I, true))10144return false;10145}10146}10147// If there are no qualifiers and no interface, we have an 'id'.10148return true;10149}10150// Both the right and left sides have qualifiers.10151for (auto *lhsProto : lhs->quals()) {10152bool match = false;1015310154// when comparing an id<P> on lhs with a static type on rhs,10155// see if static class implements all of id's protocols, directly or10156// through its super class and categories.10157for (auto *rhsProto : rhs->quals()) {10158if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||10159(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {10160match = true;10161break;10162}10163}10164// If the RHS is a qualified interface pointer "NSString<P>*",10165// make sure we check the class hierarchy.10166if (ObjCInterfaceDecl *rhsID = rhs->getInterfaceDecl()) {10167for (auto *I : lhs->quals()) {10168// when comparing an id<P> on lhs with a static type on rhs,10169// see if static class implements all of id's protocols, directly or10170// through its super class and categories.10171if (rhsID->ClassImplementsProtocol(I, true)) {10172match = true;10173break;10174}10175}10176}10177if (!match)10178return false;10179}1018010181return true;10182}1018310184assert(rhs->isObjCQualifiedIdType() && "One of the LHS/RHS should be id<x>");1018510186if (lhs->getInterfaceType()) {10187// If both the right and left sides have qualifiers.10188for (auto *lhsProto : lhs->quals()) {10189bool match = false;1019010191// when comparing an id<P> on rhs with a static type on lhs,10192// see if static class implements all of id's protocols, directly or10193// through its super class and categories.10194// First, lhs protocols in the qualifier list must be found, direct10195// or indirect in rhs's qualifier list or it is a mismatch.10196for (auto *rhsProto : rhs->quals()) {10197if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||10198(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {10199match = true;10200break;10201}10202}10203if (!match)10204return false;10205}1020610207// Static class's protocols, or its super class or category protocols10208// must be found, direct or indirect in rhs's qualifier list or it is a mismatch.10209if (ObjCInterfaceDecl *lhsID = lhs->getInterfaceDecl()) {10210llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols;10211CollectInheritedProtocols(lhsID, LHSInheritedProtocols);10212// This is rather dubious but matches gcc's behavior. If lhs has10213// no type qualifier and its class has no static protocol(s)10214// assume that it is mismatch.10215if (LHSInheritedProtocols.empty() && lhs->qual_empty())10216return false;10217for (auto *lhsProto : LHSInheritedProtocols) {10218bool match = false;10219for (auto *rhsProto : rhs->quals()) {10220if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||10221(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {10222match = true;10223break;10224}10225}10226if (!match)10227return false;10228}10229}10230return true;10231}10232return false;10233}1023410235/// canAssignObjCInterfaces - Return true if the two interface types are10236/// compatible for assignment from RHS to LHS. This handles validation of any10237/// protocol qualifiers on the LHS or RHS.10238bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,10239const ObjCObjectPointerType *RHSOPT) {10240const ObjCObjectType* LHS = LHSOPT->getObjectType();10241const ObjCObjectType* RHS = RHSOPT->getObjectType();1024210243// If either type represents the built-in 'id' type, return true.10244if (LHS->isObjCUnqualifiedId() || RHS->isObjCUnqualifiedId())10245return true;1024610247// Function object that propagates a successful result or handles10248// __kindof types.10249auto finish = [&](bool succeeded) -> bool {10250if (succeeded)10251return true;1025210253if (!RHS->isKindOfType())10254return false;1025510256// Strip off __kindof and protocol qualifiers, then check whether10257// we can assign the other way.10258return canAssignObjCInterfaces(RHSOPT->stripObjCKindOfTypeAndQuals(*this),10259LHSOPT->stripObjCKindOfTypeAndQuals(*this));10260};1026110262// Casts from or to id<P> are allowed when the other side has compatible10263// protocols.10264if (LHS->isObjCQualifiedId() || RHS->isObjCQualifiedId()) {10265return finish(ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT, false));10266}1026710268// Verify protocol compatibility for casts from Class<P1> to Class<P2>.10269if (LHS->isObjCQualifiedClass() && RHS->isObjCQualifiedClass()) {10270return finish(ObjCQualifiedClassTypesAreCompatible(LHSOPT, RHSOPT));10271}1027210273// Casts from Class to Class<Foo>, or vice-versa, are allowed.10274if (LHS->isObjCClass() && RHS->isObjCClass()) {10275return true;10276}1027710278// If we have 2 user-defined types, fall into that path.10279if (LHS->getInterface() && RHS->getInterface()) {10280return finish(canAssignObjCInterfaces(LHS, RHS));10281}1028210283return false;10284}1028510286/// canAssignObjCInterfacesInBlockPointer - This routine is specifically written10287/// for providing type-safety for objective-c pointers used to pass/return10288/// arguments in block literals. When passed as arguments, passing 'A*' where10289/// 'id' is expected is not OK. Passing 'Sub *" where 'Super *" is expected is10290/// not OK. For the return type, the opposite is not OK.10291bool ASTContext::canAssignObjCInterfacesInBlockPointer(10292const ObjCObjectPointerType *LHSOPT,10293const ObjCObjectPointerType *RHSOPT,10294bool BlockReturnType) {1029510296// Function object that propagates a successful result or handles10297// __kindof types.10298auto finish = [&](bool succeeded) -> bool {10299if (succeeded)10300return true;1030110302const ObjCObjectPointerType *Expected = BlockReturnType ? RHSOPT : LHSOPT;10303if (!Expected->isKindOfType())10304return false;1030510306// Strip off __kindof and protocol qualifiers, then check whether10307// we can assign the other way.10308return canAssignObjCInterfacesInBlockPointer(10309RHSOPT->stripObjCKindOfTypeAndQuals(*this),10310LHSOPT->stripObjCKindOfTypeAndQuals(*this),10311BlockReturnType);10312};1031310314if (RHSOPT->isObjCBuiltinType() || LHSOPT->isObjCIdType())10315return true;1031610317if (LHSOPT->isObjCBuiltinType()) {10318return finish(RHSOPT->isObjCBuiltinType() ||10319RHSOPT->isObjCQualifiedIdType());10320}1032110322if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType()) {10323if (getLangOpts().CompatibilityQualifiedIdBlockParamTypeChecking)10324// Use for block parameters previous type checking for compatibility.10325return finish(ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT, false) ||10326// Or corrected type checking as in non-compat mode.10327(!BlockReturnType &&10328ObjCQualifiedIdTypesAreCompatible(RHSOPT, LHSOPT, false)));10329else10330return finish(ObjCQualifiedIdTypesAreCompatible(10331(BlockReturnType ? LHSOPT : RHSOPT),10332(BlockReturnType ? RHSOPT : LHSOPT), false));10333}1033410335const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();10336const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();10337if (LHS && RHS) { // We have 2 user-defined types.10338if (LHS != RHS) {10339if (LHS->getDecl()->isSuperClassOf(RHS->getDecl()))10340return finish(BlockReturnType);10341if (RHS->getDecl()->isSuperClassOf(LHS->getDecl()))10342return finish(!BlockReturnType);10343}10344else10345return true;10346}10347return false;10348}1034910350/// Comparison routine for Objective-C protocols to be used with10351/// llvm::array_pod_sort.10352static int compareObjCProtocolsByName(ObjCProtocolDecl * const *lhs,10353ObjCProtocolDecl * const *rhs) {10354return (*lhs)->getName().compare((*rhs)->getName());10355}1035610357/// getIntersectionOfProtocols - This routine finds the intersection of set10358/// of protocols inherited from two distinct objective-c pointer objects with10359/// the given common base.10360/// It is used to build composite qualifier list of the composite type of10361/// the conditional expression involving two objective-c pointer objects.10362static10363void getIntersectionOfProtocols(ASTContext &Context,10364const ObjCInterfaceDecl *CommonBase,10365const ObjCObjectPointerType *LHSOPT,10366const ObjCObjectPointerType *RHSOPT,10367SmallVectorImpl<ObjCProtocolDecl *> &IntersectionSet) {1036810369const ObjCObjectType* LHS = LHSOPT->getObjectType();10370const ObjCObjectType* RHS = RHSOPT->getObjectType();10371assert(LHS->getInterface() && "LHS must have an interface base");10372assert(RHS->getInterface() && "RHS must have an interface base");1037310374// Add all of the protocols for the LHS.10375llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSProtocolSet;1037610377// Start with the protocol qualifiers.10378for (auto *proto : LHS->quals()) {10379Context.CollectInheritedProtocols(proto, LHSProtocolSet);10380}1038110382// Also add the protocols associated with the LHS interface.10383Context.CollectInheritedProtocols(LHS->getInterface(), LHSProtocolSet);1038410385// Add all of the protocols for the RHS.10386llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSProtocolSet;1038710388// Start with the protocol qualifiers.10389for (auto *proto : RHS->quals()) {10390Context.CollectInheritedProtocols(proto, RHSProtocolSet);10391}1039210393// Also add the protocols associated with the RHS interface.10394Context.CollectInheritedProtocols(RHS->getInterface(), RHSProtocolSet);1039510396// Compute the intersection of the collected protocol sets.10397for (auto *proto : LHSProtocolSet) {10398if (RHSProtocolSet.count(proto))10399IntersectionSet.push_back(proto);10400}1040110402// Compute the set of protocols that is implied by either the common type or10403// the protocols within the intersection.10404llvm::SmallPtrSet<ObjCProtocolDecl *, 8> ImpliedProtocols;10405Context.CollectInheritedProtocols(CommonBase, ImpliedProtocols);1040610407// Remove any implied protocols from the list of inherited protocols.10408if (!ImpliedProtocols.empty()) {10409llvm::erase_if(IntersectionSet, [&](ObjCProtocolDecl *proto) -> bool {10410return ImpliedProtocols.contains(proto);10411});10412}1041310414// Sort the remaining protocols by name.10415llvm::array_pod_sort(IntersectionSet.begin(), IntersectionSet.end(),10416compareObjCProtocolsByName);10417}1041810419/// Determine whether the first type is a subtype of the second.10420static bool canAssignObjCObjectTypes(ASTContext &ctx, QualType lhs,10421QualType rhs) {10422// Common case: two object pointers.10423const auto *lhsOPT = lhs->getAs<ObjCObjectPointerType>();10424const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();10425if (lhsOPT && rhsOPT)10426return ctx.canAssignObjCInterfaces(lhsOPT, rhsOPT);1042710428// Two block pointers.10429const auto *lhsBlock = lhs->getAs<BlockPointerType>();10430const auto *rhsBlock = rhs->getAs<BlockPointerType>();10431if (lhsBlock && rhsBlock)10432return ctx.typesAreBlockPointerCompatible(lhs, rhs);1043310434// If either is an unqualified 'id' and the other is a block, it's10435// acceptable.10436if ((lhsOPT && lhsOPT->isObjCIdType() && rhsBlock) ||10437(rhsOPT && rhsOPT->isObjCIdType() && lhsBlock))10438return true;1043910440return false;10441}1044210443// Check that the given Objective-C type argument lists are equivalent.10444static bool sameObjCTypeArgs(ASTContext &ctx,10445const ObjCInterfaceDecl *iface,10446ArrayRef<QualType> lhsArgs,10447ArrayRef<QualType> rhsArgs,10448bool stripKindOf) {10449if (lhsArgs.size() != rhsArgs.size())10450return false;1045110452ObjCTypeParamList *typeParams = iface->getTypeParamList();10453if (!typeParams)10454return false;1045510456for (unsigned i = 0, n = lhsArgs.size(); i != n; ++i) {10457if (ctx.hasSameType(lhsArgs[i], rhsArgs[i]))10458continue;1045910460switch (typeParams->begin()[i]->getVariance()) {10461case ObjCTypeParamVariance::Invariant:10462if (!stripKindOf ||10463!ctx.hasSameType(lhsArgs[i].stripObjCKindOfType(ctx),10464rhsArgs[i].stripObjCKindOfType(ctx))) {10465return false;10466}10467break;1046810469case ObjCTypeParamVariance::Covariant:10470if (!canAssignObjCObjectTypes(ctx, lhsArgs[i], rhsArgs[i]))10471return false;10472break;1047310474case ObjCTypeParamVariance::Contravariant:10475if (!canAssignObjCObjectTypes(ctx, rhsArgs[i], lhsArgs[i]))10476return false;10477break;10478}10479}1048010481return true;10482}1048310484QualType ASTContext::areCommonBaseCompatible(10485const ObjCObjectPointerType *Lptr,10486const ObjCObjectPointerType *Rptr) {10487const ObjCObjectType *LHS = Lptr->getObjectType();10488const ObjCObjectType *RHS = Rptr->getObjectType();10489const ObjCInterfaceDecl* LDecl = LHS->getInterface();10490const ObjCInterfaceDecl* RDecl = RHS->getInterface();1049110492if (!LDecl || !RDecl)10493return {};1049410495// When either LHS or RHS is a kindof type, we should return a kindof type.10496// For example, for common base of kindof(ASub1) and kindof(ASub2), we return10497// kindof(A).10498bool anyKindOf = LHS->isKindOfType() || RHS->isKindOfType();1049910500// Follow the left-hand side up the class hierarchy until we either hit a10501// root or find the RHS. Record the ancestors in case we don't find it.10502llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4>10503LHSAncestors;10504while (true) {10505// Record this ancestor. We'll need this if the common type isn't in the10506// path from the LHS to the root.10507LHSAncestors[LHS->getInterface()->getCanonicalDecl()] = LHS;1050810509if (declaresSameEntity(LHS->getInterface(), RDecl)) {10510// Get the type arguments.10511ArrayRef<QualType> LHSTypeArgs = LHS->getTypeArgsAsWritten();10512bool anyChanges = false;10513if (LHS->isSpecialized() && RHS->isSpecialized()) {10514// Both have type arguments, compare them.10515if (!sameObjCTypeArgs(*this, LHS->getInterface(),10516LHS->getTypeArgs(), RHS->getTypeArgs(),10517/*stripKindOf=*/true))10518return {};10519} else if (LHS->isSpecialized() != RHS->isSpecialized()) {10520// If only one has type arguments, the result will not have type10521// arguments.10522LHSTypeArgs = {};10523anyChanges = true;10524}1052510526// Compute the intersection of protocols.10527SmallVector<ObjCProtocolDecl *, 8> Protocols;10528getIntersectionOfProtocols(*this, LHS->getInterface(), Lptr, Rptr,10529Protocols);10530if (!Protocols.empty())10531anyChanges = true;1053210533// If anything in the LHS will have changed, build a new result type.10534// If we need to return a kindof type but LHS is not a kindof type, we10535// build a new result type.10536if (anyChanges || LHS->isKindOfType() != anyKindOf) {10537QualType Result = getObjCInterfaceType(LHS->getInterface());10538Result = getObjCObjectType(Result, LHSTypeArgs, Protocols,10539anyKindOf || LHS->isKindOfType());10540return getObjCObjectPointerType(Result);10541}1054210543return getObjCObjectPointerType(QualType(LHS, 0));10544}1054510546// Find the superclass.10547QualType LHSSuperType = LHS->getSuperClassType();10548if (LHSSuperType.isNull())10549break;1055010551LHS = LHSSuperType->castAs<ObjCObjectType>();10552}1055310554// We didn't find anything by following the LHS to its root; now check10555// the RHS against the cached set of ancestors.10556while (true) {10557auto KnownLHS = LHSAncestors.find(RHS->getInterface()->getCanonicalDecl());10558if (KnownLHS != LHSAncestors.end()) {10559LHS = KnownLHS->second;1056010561// Get the type arguments.10562ArrayRef<QualType> RHSTypeArgs = RHS->getTypeArgsAsWritten();10563bool anyChanges = false;10564if (LHS->isSpecialized() && RHS->isSpecialized()) {10565// Both have type arguments, compare them.10566if (!sameObjCTypeArgs(*this, LHS->getInterface(),10567LHS->getTypeArgs(), RHS->getTypeArgs(),10568/*stripKindOf=*/true))10569return {};10570} else if (LHS->isSpecialized() != RHS->isSpecialized()) {10571// If only one has type arguments, the result will not have type10572// arguments.10573RHSTypeArgs = {};10574anyChanges = true;10575}1057610577// Compute the intersection of protocols.10578SmallVector<ObjCProtocolDecl *, 8> Protocols;10579getIntersectionOfProtocols(*this, RHS->getInterface(), Lptr, Rptr,10580Protocols);10581if (!Protocols.empty())10582anyChanges = true;1058310584// If we need to return a kindof type but RHS is not a kindof type, we10585// build a new result type.10586if (anyChanges || RHS->isKindOfType() != anyKindOf) {10587QualType Result = getObjCInterfaceType(RHS->getInterface());10588Result = getObjCObjectType(Result, RHSTypeArgs, Protocols,10589anyKindOf || RHS->isKindOfType());10590return getObjCObjectPointerType(Result);10591}1059210593return getObjCObjectPointerType(QualType(RHS, 0));10594}1059510596// Find the superclass of the RHS.10597QualType RHSSuperType = RHS->getSuperClassType();10598if (RHSSuperType.isNull())10599break;1060010601RHS = RHSSuperType->castAs<ObjCObjectType>();10602}1060310604return {};10605}1060610607bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,10608const ObjCObjectType *RHS) {10609assert(LHS->getInterface() && "LHS is not an interface type");10610assert(RHS->getInterface() && "RHS is not an interface type");1061110612// Verify that the base decls are compatible: the RHS must be a subclass of10613// the LHS.10614ObjCInterfaceDecl *LHSInterface = LHS->getInterface();10615bool IsSuperClass = LHSInterface->isSuperClassOf(RHS->getInterface());10616if (!IsSuperClass)10617return false;1061810619// If the LHS has protocol qualifiers, determine whether all of them are10620// satisfied by the RHS (i.e., the RHS has a superset of the protocols in the10621// LHS).10622if (LHS->getNumProtocols() > 0) {10623// OK if conversion of LHS to SuperClass results in narrowing of types10624// ; i.e., SuperClass may implement at least one of the protocols10625// in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok.10626// But not SuperObj<P1,P2,P3> = lhs<P1,P2>.10627llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols;10628CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols);10629// Also, if RHS has explicit quelifiers, include them for comparing with LHS's10630// qualifiers.10631for (auto *RHSPI : RHS->quals())10632CollectInheritedProtocols(RHSPI, SuperClassInheritedProtocols);10633// If there is no protocols associated with RHS, it is not a match.10634if (SuperClassInheritedProtocols.empty())10635return false;1063610637for (const auto *LHSProto : LHS->quals()) {10638bool SuperImplementsProtocol = false;10639for (auto *SuperClassProto : SuperClassInheritedProtocols)10640if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) {10641SuperImplementsProtocol = true;10642break;10643}10644if (!SuperImplementsProtocol)10645return false;10646}10647}1064810649// If the LHS is specialized, we may need to check type arguments.10650if (LHS->isSpecialized()) {10651// Follow the superclass chain until we've matched the LHS class in the10652// hierarchy. This substitutes type arguments through.10653const ObjCObjectType *RHSSuper = RHS;10654while (!declaresSameEntity(RHSSuper->getInterface(), LHSInterface))10655RHSSuper = RHSSuper->getSuperClassType()->castAs<ObjCObjectType>();1065610657// If the RHS is specializd, compare type arguments.10658if (RHSSuper->isSpecialized() &&10659!sameObjCTypeArgs(*this, LHS->getInterface(),10660LHS->getTypeArgs(), RHSSuper->getTypeArgs(),10661/*stripKindOf=*/true)) {10662return false;10663}10664}1066510666return true;10667}1066810669bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) {10670// get the "pointed to" types10671const auto *LHSOPT = LHS->getAs<ObjCObjectPointerType>();10672const auto *RHSOPT = RHS->getAs<ObjCObjectPointerType>();1067310674if (!LHSOPT || !RHSOPT)10675return false;1067610677return canAssignObjCInterfaces(LHSOPT, RHSOPT) ||10678canAssignObjCInterfaces(RHSOPT, LHSOPT);10679}1068010681bool ASTContext::canBindObjCObjectType(QualType To, QualType From) {10682return canAssignObjCInterfaces(10683getObjCObjectPointerType(To)->castAs<ObjCObjectPointerType>(),10684getObjCObjectPointerType(From)->castAs<ObjCObjectPointerType>());10685}1068610687/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,10688/// both shall have the identically qualified version of a compatible type.10689/// C99 6.2.7p1: Two types have compatible types if their types are the10690/// same. See 6.7.[2,3,5] for additional rules.10691bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS,10692bool CompareUnqualified) {10693if (getLangOpts().CPlusPlus)10694return hasSameType(LHS, RHS);1069510696return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull();10697}1069810699bool ASTContext::propertyTypesAreCompatible(QualType LHS, QualType RHS) {10700return typesAreCompatible(LHS, RHS);10701}1070210703bool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) {10704return !mergeTypes(LHS, RHS, true).isNull();10705}1070610707/// mergeTransparentUnionType - if T is a transparent union type and a member10708/// of T is compatible with SubType, return the merged type, else return10709/// QualType()10710QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,10711bool OfBlockPointer,10712bool Unqualified) {10713if (const RecordType *UT = T->getAsUnionType()) {10714RecordDecl *UD = UT->getDecl();10715if (UD->hasAttr<TransparentUnionAttr>()) {10716for (const auto *I : UD->fields()) {10717QualType ET = I->getType().getUnqualifiedType();10718QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified);10719if (!MT.isNull())10720return MT;10721}10722}10723}1072410725return {};10726}1072710728/// mergeFunctionParameterTypes - merge two types which appear as function10729/// parameter types10730QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,10731bool OfBlockPointer,10732bool Unqualified) {10733// GNU extension: two types are compatible if they appear as a function10734// argument, one of the types is a transparent union type and the other10735// type is compatible with a union member10736QualType lmerge = mergeTransparentUnionType(lhs, rhs, OfBlockPointer,10737Unqualified);10738if (!lmerge.isNull())10739return lmerge;1074010741QualType rmerge = mergeTransparentUnionType(rhs, lhs, OfBlockPointer,10742Unqualified);10743if (!rmerge.isNull())10744return rmerge;1074510746return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified);10747}1074810749QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,10750bool OfBlockPointer, bool Unqualified,10751bool AllowCXX,10752bool IsConditionalOperator) {10753const auto *lbase = lhs->castAs<FunctionType>();10754const auto *rbase = rhs->castAs<FunctionType>();10755const auto *lproto = dyn_cast<FunctionProtoType>(lbase);10756const auto *rproto = dyn_cast<FunctionProtoType>(rbase);10757bool allLTypes = true;10758bool allRTypes = true;1075910760// Check return type10761QualType retType;10762if (OfBlockPointer) {10763QualType RHS = rbase->getReturnType();10764QualType LHS = lbase->getReturnType();10765bool UnqualifiedResult = Unqualified;10766if (!UnqualifiedResult)10767UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());10768retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true);10769}10770else10771retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,10772Unqualified);10773if (retType.isNull())10774return {};1077510776if (Unqualified)10777retType = retType.getUnqualifiedType();1077810779CanQualType LRetType = getCanonicalType(lbase->getReturnType());10780CanQualType RRetType = getCanonicalType(rbase->getReturnType());10781if (Unqualified) {10782LRetType = LRetType.getUnqualifiedType();10783RRetType = RRetType.getUnqualifiedType();10784}1078510786if (getCanonicalType(retType) != LRetType)10787allLTypes = false;10788if (getCanonicalType(retType) != RRetType)10789allRTypes = false;1079010791// FIXME: double check this10792// FIXME: should we error if lbase->getRegParmAttr() != 0 &&10793// rbase->getRegParmAttr() != 0 &&10794// lbase->getRegParmAttr() != rbase->getRegParmAttr()?10795FunctionType::ExtInfo lbaseInfo = lbase->getExtInfo();10796FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo();1079710798// Compatible functions must have compatible calling conventions10799if (lbaseInfo.getCC() != rbaseInfo.getCC())10800return {};1080110802// Regparm is part of the calling convention.10803if (lbaseInfo.getHasRegParm() != rbaseInfo.getHasRegParm())10804return {};10805if (lbaseInfo.getRegParm() != rbaseInfo.getRegParm())10806return {};1080710808if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())10809return {};10810if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs())10811return {};10812if (lbaseInfo.getNoCfCheck() != rbaseInfo.getNoCfCheck())10813return {};1081410815// When merging declarations, it's common for supplemental information like10816// attributes to only be present in one of the declarations, and we generally10817// want type merging to preserve the union of information. So a merged10818// function type should be noreturn if it was noreturn in *either* operand10819// type.10820//10821// But for the conditional operator, this is backwards. The result of the10822// operator could be either operand, and its type should conservatively10823// reflect that. So a function type in a composite type is noreturn only10824// if it's noreturn in *both* operand types.10825//10826// Arguably, noreturn is a kind of subtype, and the conditional operator10827// ought to produce the most specific common supertype of its operand types.10828// That would differ from this rule in contravariant positions. However,10829// neither C nor C++ generally uses this kind of subtype reasoning. Also,10830// as a practical matter, it would only affect C code that does abstraction of10831// higher-order functions (taking noreturn callbacks!), which is uncommon to10832// say the least. So we use the simpler rule.10833bool NoReturn = IsConditionalOperator10834? lbaseInfo.getNoReturn() && rbaseInfo.getNoReturn()10835: lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();10836if (lbaseInfo.getNoReturn() != NoReturn)10837allLTypes = false;10838if (rbaseInfo.getNoReturn() != NoReturn)10839allRTypes = false;1084010841FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn);1084210843std::optional<FunctionEffectSet> MergedFX;1084410845if (lproto && rproto) { // two C99 style function prototypes10846assert((AllowCXX ||10847(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec())) &&10848"C++ shouldn't be here");10849// Compatible functions must have the same number of parameters10850if (lproto->getNumParams() != rproto->getNumParams())10851return {};1085210853// Variadic and non-variadic functions aren't compatible10854if (lproto->isVariadic() != rproto->isVariadic())10855return {};1085610857if (lproto->getMethodQuals() != rproto->getMethodQuals())10858return {};1085910860// Function effects are handled similarly to noreturn, see above.10861FunctionEffectsRef LHSFX = lproto->getFunctionEffects();10862FunctionEffectsRef RHSFX = rproto->getFunctionEffects();10863if (LHSFX != RHSFX) {10864if (IsConditionalOperator)10865MergedFX = FunctionEffectSet::getIntersection(LHSFX, RHSFX);10866else {10867FunctionEffectSet::Conflicts Errs;10868MergedFX = FunctionEffectSet::getUnion(LHSFX, RHSFX, Errs);10869// Here we're discarding a possible error due to conflicts in the effect10870// sets. But we're not in a context where we can report it. The10871// operation does however guarantee maintenance of invariants.10872}10873if (*MergedFX != LHSFX)10874allLTypes = false;10875if (*MergedFX != RHSFX)10876allRTypes = false;10877}1087810879SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos;10880bool canUseLeft, canUseRight;10881if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight,10882newParamInfos))10883return {};1088410885if (!canUseLeft)10886allLTypes = false;10887if (!canUseRight)10888allRTypes = false;1088910890// Check parameter type compatibility10891SmallVector<QualType, 10> types;10892for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) {10893QualType lParamType = lproto->getParamType(i).getUnqualifiedType();10894QualType rParamType = rproto->getParamType(i).getUnqualifiedType();10895QualType paramType = mergeFunctionParameterTypes(10896lParamType, rParamType, OfBlockPointer, Unqualified);10897if (paramType.isNull())10898return {};1089910900if (Unqualified)10901paramType = paramType.getUnqualifiedType();1090210903types.push_back(paramType);10904if (Unqualified) {10905lParamType = lParamType.getUnqualifiedType();10906rParamType = rParamType.getUnqualifiedType();10907}1090810909if (getCanonicalType(paramType) != getCanonicalType(lParamType))10910allLTypes = false;10911if (getCanonicalType(paramType) != getCanonicalType(rParamType))10912allRTypes = false;10913}1091410915if (allLTypes) return lhs;10916if (allRTypes) return rhs;1091710918FunctionProtoType::ExtProtoInfo EPI = lproto->getExtProtoInfo();10919EPI.ExtInfo = einfo;10920EPI.ExtParameterInfos =10921newParamInfos.empty() ? nullptr : newParamInfos.data();10922if (MergedFX)10923EPI.FunctionEffects = *MergedFX;10924return getFunctionType(retType, types, EPI);10925}1092610927if (lproto) allRTypes = false;10928if (rproto) allLTypes = false;1092910930const FunctionProtoType *proto = lproto ? lproto : rproto;10931if (proto) {10932assert((AllowCXX || !proto->hasExceptionSpec()) && "C++ shouldn't be here");10933if (proto->isVariadic())10934return {};10935// Check that the types are compatible with the types that10936// would result from default argument promotions (C99 6.7.5.3p15).10937// The only types actually affected are promotable integer10938// types and floats, which would be passed as a different10939// type depending on whether the prototype is visible.10940for (unsigned i = 0, n = proto->getNumParams(); i < n; ++i) {10941QualType paramTy = proto->getParamType(i);1094210943// Look at the converted type of enum types, since that is the type used10944// to pass enum values.10945if (const auto *Enum = paramTy->getAs<EnumType>()) {10946paramTy = Enum->getDecl()->getIntegerType();10947if (paramTy.isNull())10948return {};10949}1095010951if (isPromotableIntegerType(paramTy) ||10952getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)10953return {};10954}1095510956if (allLTypes) return lhs;10957if (allRTypes) return rhs;1095810959FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo();10960EPI.ExtInfo = einfo;10961if (MergedFX)10962EPI.FunctionEffects = *MergedFX;10963return getFunctionType(retType, proto->getParamTypes(), EPI);10964}1096510966if (allLTypes) return lhs;10967if (allRTypes) return rhs;10968return getFunctionNoProtoType(retType, einfo);10969}1097010971/// Given that we have an enum type and a non-enum type, try to merge them.10972static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,10973QualType other, bool isBlockReturnType) {10974// C99 6.7.2.2p4: Each enumerated type shall be compatible with char,10975// a signed integer type, or an unsigned integer type.10976// Compatibility is based on the underlying type, not the promotion10977// type.10978QualType underlyingType = ET->getDecl()->getIntegerType();10979if (underlyingType.isNull())10980return {};10981if (Context.hasSameType(underlyingType, other))10982return other;1098310984// In block return types, we're more permissive and accept any10985// integral type of the same size.10986if (isBlockReturnType && other->isIntegerType() &&10987Context.getTypeSize(underlyingType) == Context.getTypeSize(other))10988return other;1098910990return {};10991}1099210993QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer,10994bool Unqualified, bool BlockReturnType,10995bool IsConditionalOperator) {10996// For C++ we will not reach this code with reference types (see below),10997// for OpenMP variant call overloading we might.10998//10999// C++ [expr]: If an expression initially has the type "reference to T", the11000// type is adjusted to "T" prior to any further analysis, the expression11001// designates the object or function denoted by the reference, and the11002// expression is an lvalue unless the reference is an rvalue reference and11003// the expression is a function call (possibly inside parentheses).11004auto *LHSRefTy = LHS->getAs<ReferenceType>();11005auto *RHSRefTy = RHS->getAs<ReferenceType>();11006if (LangOpts.OpenMP && LHSRefTy && RHSRefTy &&11007LHS->getTypeClass() == RHS->getTypeClass())11008return mergeTypes(LHSRefTy->getPointeeType(), RHSRefTy->getPointeeType(),11009OfBlockPointer, Unqualified, BlockReturnType);11010if (LHSRefTy || RHSRefTy)11011return {};1101211013if (Unqualified) {11014LHS = LHS.getUnqualifiedType();11015RHS = RHS.getUnqualifiedType();11016}1101711018QualType LHSCan = getCanonicalType(LHS),11019RHSCan = getCanonicalType(RHS);1102011021// If two types are identical, they are compatible.11022if (LHSCan == RHSCan)11023return LHS;1102411025// If the qualifiers are different, the types aren't compatible... mostly.11026Qualifiers LQuals = LHSCan.getLocalQualifiers();11027Qualifiers RQuals = RHSCan.getLocalQualifiers();11028if (LQuals != RQuals) {11029// If any of these qualifiers are different, we have a type11030// mismatch.11031if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||11032LQuals.getAddressSpace() != RQuals.getAddressSpace() ||11033LQuals.getObjCLifetime() != RQuals.getObjCLifetime() ||11034LQuals.hasUnaligned() != RQuals.hasUnaligned())11035return {};1103611037// Exactly one GC qualifier difference is allowed: __strong is11038// okay if the other type has no GC qualifier but is an Objective11039// C object pointer (i.e. implicitly strong by default). We fix11040// this by pretending that the unqualified type was actually11041// qualified __strong.11042Qualifiers::GC GC_L = LQuals.getObjCGCAttr();11043Qualifiers::GC GC_R = RQuals.getObjCGCAttr();11044assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");1104511046if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)11047return {};1104811049if (GC_L == Qualifiers::Strong && RHSCan->isObjCObjectPointerType()) {11050return mergeTypes(LHS, getObjCGCQualType(RHS, Qualifiers::Strong));11051}11052if (GC_R == Qualifiers::Strong && LHSCan->isObjCObjectPointerType()) {11053return mergeTypes(getObjCGCQualType(LHS, Qualifiers::Strong), RHS);11054}11055return {};11056}1105711058// Okay, qualifiers are equal.1105911060Type::TypeClass LHSClass = LHSCan->getTypeClass();11061Type::TypeClass RHSClass = RHSCan->getTypeClass();1106211063// We want to consider the two function types to be the same for these11064// comparisons, just force one to the other.11065if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto;11066if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto;1106711068// Same as above for arrays11069if (LHSClass == Type::VariableArray || LHSClass == Type::IncompleteArray)11070LHSClass = Type::ConstantArray;11071if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray)11072RHSClass = Type::ConstantArray;1107311074// ObjCInterfaces are just specialized ObjCObjects.11075if (LHSClass == Type::ObjCInterface) LHSClass = Type::ObjCObject;11076if (RHSClass == Type::ObjCInterface) RHSClass = Type::ObjCObject;1107711078// Canonicalize ExtVector -> Vector.11079if (LHSClass == Type::ExtVector) LHSClass = Type::Vector;11080if (RHSClass == Type::ExtVector) RHSClass = Type::Vector;1108111082// If the canonical type classes don't match.11083if (LHSClass != RHSClass) {11084// Note that we only have special rules for turning block enum11085// returns into block int returns, not vice-versa.11086if (const auto *ETy = LHS->getAs<EnumType>()) {11087return mergeEnumWithInteger(*this, ETy, RHS, false);11088}11089if (const EnumType* ETy = RHS->getAs<EnumType>()) {11090return mergeEnumWithInteger(*this, ETy, LHS, BlockReturnType);11091}11092// allow block pointer type to match an 'id' type.11093if (OfBlockPointer && !BlockReturnType) {11094if (LHS->isObjCIdType() && RHS->isBlockPointerType())11095return LHS;11096if (RHS->isObjCIdType() && LHS->isBlockPointerType())11097return RHS;11098}11099// Allow __auto_type to match anything; it merges to the type with more11100// information.11101if (const auto *AT = LHS->getAs<AutoType>()) {11102if (!AT->isDeduced() && AT->isGNUAutoType())11103return RHS;11104}11105if (const auto *AT = RHS->getAs<AutoType>()) {11106if (!AT->isDeduced() && AT->isGNUAutoType())11107return LHS;11108}11109return {};11110}1111111112// The canonical type classes match.11113switch (LHSClass) {11114#define TYPE(Class, Base)11115#define ABSTRACT_TYPE(Class, Base)11116#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:11117#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:11118#define DEPENDENT_TYPE(Class, Base) case Type::Class:11119#include "clang/AST/TypeNodes.inc"11120llvm_unreachable("Non-canonical and dependent types shouldn't get here");1112111122case Type::Auto:11123case Type::DeducedTemplateSpecialization:11124case Type::LValueReference:11125case Type::RValueReference:11126case Type::MemberPointer:11127llvm_unreachable("C++ should never be in mergeTypes");1112811129case Type::ObjCInterface:11130case Type::IncompleteArray:11131case Type::VariableArray:11132case Type::FunctionProto:11133case Type::ExtVector:11134llvm_unreachable("Types are eliminated above");1113511136case Type::Pointer:11137{11138// Merge two pointer types, while trying to preserve typedef info11139QualType LHSPointee = LHS->castAs<PointerType>()->getPointeeType();11140QualType RHSPointee = RHS->castAs<PointerType>()->getPointeeType();11141if (Unqualified) {11142LHSPointee = LHSPointee.getUnqualifiedType();11143RHSPointee = RHSPointee.getUnqualifiedType();11144}11145QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false,11146Unqualified);11147if (ResultType.isNull())11148return {};11149if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))11150return LHS;11151if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))11152return RHS;11153return getPointerType(ResultType);11154}11155case Type::BlockPointer:11156{11157// Merge two block pointer types, while trying to preserve typedef info11158QualType LHSPointee = LHS->castAs<BlockPointerType>()->getPointeeType();11159QualType RHSPointee = RHS->castAs<BlockPointerType>()->getPointeeType();11160if (Unqualified) {11161LHSPointee = LHSPointee.getUnqualifiedType();11162RHSPointee = RHSPointee.getUnqualifiedType();11163}11164if (getLangOpts().OpenCL) {11165Qualifiers LHSPteeQual = LHSPointee.getQualifiers();11166Qualifiers RHSPteeQual = RHSPointee.getQualifiers();11167// Blocks can't be an expression in a ternary operator (OpenCL v2.011168// 6.12.5) thus the following check is asymmetric.11169if (!LHSPteeQual.isAddressSpaceSupersetOf(RHSPteeQual))11170return {};11171LHSPteeQual.removeAddressSpace();11172RHSPteeQual.removeAddressSpace();11173LHSPointee =11174QualType(LHSPointee.getTypePtr(), LHSPteeQual.getAsOpaqueValue());11175RHSPointee =11176QualType(RHSPointee.getTypePtr(), RHSPteeQual.getAsOpaqueValue());11177}11178QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,11179Unqualified);11180if (ResultType.isNull())11181return {};11182if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))11183return LHS;11184if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))11185return RHS;11186return getBlockPointerType(ResultType);11187}11188case Type::Atomic:11189{11190// Merge two pointer types, while trying to preserve typedef info11191QualType LHSValue = LHS->castAs<AtomicType>()->getValueType();11192QualType RHSValue = RHS->castAs<AtomicType>()->getValueType();11193if (Unqualified) {11194LHSValue = LHSValue.getUnqualifiedType();11195RHSValue = RHSValue.getUnqualifiedType();11196}11197QualType ResultType = mergeTypes(LHSValue, RHSValue, false,11198Unqualified);11199if (ResultType.isNull())11200return {};11201if (getCanonicalType(LHSValue) == getCanonicalType(ResultType))11202return LHS;11203if (getCanonicalType(RHSValue) == getCanonicalType(ResultType))11204return RHS;11205return getAtomicType(ResultType);11206}11207case Type::ConstantArray:11208{11209const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);11210const ConstantArrayType* RCAT = getAsConstantArrayType(RHS);11211if (LCAT && RCAT && RCAT->getZExtSize() != LCAT->getZExtSize())11212return {};1121311214QualType LHSElem = getAsArrayType(LHS)->getElementType();11215QualType RHSElem = getAsArrayType(RHS)->getElementType();11216if (Unqualified) {11217LHSElem = LHSElem.getUnqualifiedType();11218RHSElem = RHSElem.getUnqualifiedType();11219}1122011221QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified);11222if (ResultType.isNull())11223return {};1122411225const VariableArrayType* LVAT = getAsVariableArrayType(LHS);11226const VariableArrayType* RVAT = getAsVariableArrayType(RHS);1122711228// If either side is a variable array, and both are complete, check whether11229// the current dimension is definite.11230if (LVAT || RVAT) {11231auto SizeFetch = [this](const VariableArrayType* VAT,11232const ConstantArrayType* CAT)11233-> std::pair<bool,llvm::APInt> {11234if (VAT) {11235std::optional<llvm::APSInt> TheInt;11236Expr *E = VAT->getSizeExpr();11237if (E && (TheInt = E->getIntegerConstantExpr(*this)))11238return std::make_pair(true, *TheInt);11239return std::make_pair(false, llvm::APSInt());11240}11241if (CAT)11242return std::make_pair(true, CAT->getSize());11243return std::make_pair(false, llvm::APInt());11244};1124511246bool HaveLSize, HaveRSize;11247llvm::APInt LSize, RSize;11248std::tie(HaveLSize, LSize) = SizeFetch(LVAT, LCAT);11249std::tie(HaveRSize, RSize) = SizeFetch(RVAT, RCAT);11250if (HaveLSize && HaveRSize && !llvm::APInt::isSameValue(LSize, RSize))11251return {}; // Definite, but unequal, array dimension11252}1125311254if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))11255return LHS;11256if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))11257return RHS;11258if (LCAT)11259return getConstantArrayType(ResultType, LCAT->getSize(),11260LCAT->getSizeExpr(), ArraySizeModifier(), 0);11261if (RCAT)11262return getConstantArrayType(ResultType, RCAT->getSize(),11263RCAT->getSizeExpr(), ArraySizeModifier(), 0);11264if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))11265return LHS;11266if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))11267return RHS;11268if (LVAT) {11269// FIXME: This isn't correct! But tricky to implement because11270// the array's size has to be the size of LHS, but the type11271// has to be different.11272return LHS;11273}11274if (RVAT) {11275// FIXME: This isn't correct! But tricky to implement because11276// the array's size has to be the size of RHS, but the type11277// has to be different.11278return RHS;11279}11280if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS;11281if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS;11282return getIncompleteArrayType(ResultType, ArraySizeModifier(), 0);11283}11284case Type::FunctionNoProto:11285return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified,11286/*AllowCXX=*/false, IsConditionalOperator);11287case Type::Record:11288case Type::Enum:11289return {};11290case Type::Builtin:11291// Only exactly equal builtin types are compatible, which is tested above.11292return {};11293case Type::Complex:11294// Distinct complex types are incompatible.11295return {};11296case Type::Vector:11297// FIXME: The merged type should be an ExtVector!11298if (areCompatVectorTypes(LHSCan->castAs<VectorType>(),11299RHSCan->castAs<VectorType>()))11300return LHS;11301return {};11302case Type::ConstantMatrix:11303if (areCompatMatrixTypes(LHSCan->castAs<ConstantMatrixType>(),11304RHSCan->castAs<ConstantMatrixType>()))11305return LHS;11306return {};11307case Type::ObjCObject: {11308// Check if the types are assignment compatible.11309// FIXME: This should be type compatibility, e.g. whether11310// "LHS x; RHS x;" at global scope is legal.11311if (canAssignObjCInterfaces(LHS->castAs<ObjCObjectType>(),11312RHS->castAs<ObjCObjectType>()))11313return LHS;11314return {};11315}11316case Type::ObjCObjectPointer:11317if (OfBlockPointer) {11318if (canAssignObjCInterfacesInBlockPointer(11319LHS->castAs<ObjCObjectPointerType>(),11320RHS->castAs<ObjCObjectPointerType>(), BlockReturnType))11321return LHS;11322return {};11323}11324if (canAssignObjCInterfaces(LHS->castAs<ObjCObjectPointerType>(),11325RHS->castAs<ObjCObjectPointerType>()))11326return LHS;11327return {};11328case Type::Pipe:11329assert(LHS != RHS &&11330"Equivalent pipe types should have already been handled!");11331return {};11332case Type::ArrayParameter:11333assert(LHS != RHS &&11334"Equivalent ArrayParameter types should have already been handled!");11335return {};11336case Type::BitInt: {11337// Merge two bit-precise int types, while trying to preserve typedef info.11338bool LHSUnsigned = LHS->castAs<BitIntType>()->isUnsigned();11339bool RHSUnsigned = RHS->castAs<BitIntType>()->isUnsigned();11340unsigned LHSBits = LHS->castAs<BitIntType>()->getNumBits();11341unsigned RHSBits = RHS->castAs<BitIntType>()->getNumBits();1134211343// Like unsigned/int, shouldn't have a type if they don't match.11344if (LHSUnsigned != RHSUnsigned)11345return {};1134611347if (LHSBits != RHSBits)11348return {};11349return LHS;11350}11351}1135211353llvm_unreachable("Invalid Type::Class!");11354}1135511356bool ASTContext::mergeExtParameterInfo(11357const FunctionProtoType *FirstFnType, const FunctionProtoType *SecondFnType,11358bool &CanUseFirst, bool &CanUseSecond,11359SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos) {11360assert(NewParamInfos.empty() && "param info list not empty");11361CanUseFirst = CanUseSecond = true;11362bool FirstHasInfo = FirstFnType->hasExtParameterInfos();11363bool SecondHasInfo = SecondFnType->hasExtParameterInfos();1136411365// Fast path: if the first type doesn't have ext parameter infos,11366// we match if and only if the second type also doesn't have them.11367if (!FirstHasInfo && !SecondHasInfo)11368return true;1136911370bool NeedParamInfo = false;11371size_t E = FirstHasInfo ? FirstFnType->getExtParameterInfos().size()11372: SecondFnType->getExtParameterInfos().size();1137311374for (size_t I = 0; I < E; ++I) {11375FunctionProtoType::ExtParameterInfo FirstParam, SecondParam;11376if (FirstHasInfo)11377FirstParam = FirstFnType->getExtParameterInfo(I);11378if (SecondHasInfo)11379SecondParam = SecondFnType->getExtParameterInfo(I);1138011381// Cannot merge unless everything except the noescape flag matches.11382if (FirstParam.withIsNoEscape(false) != SecondParam.withIsNoEscape(false))11383return false;1138411385bool FirstNoEscape = FirstParam.isNoEscape();11386bool SecondNoEscape = SecondParam.isNoEscape();11387bool IsNoEscape = FirstNoEscape && SecondNoEscape;11388NewParamInfos.push_back(FirstParam.withIsNoEscape(IsNoEscape));11389if (NewParamInfos.back().getOpaqueValue())11390NeedParamInfo = true;11391if (FirstNoEscape != IsNoEscape)11392CanUseFirst = false;11393if (SecondNoEscape != IsNoEscape)11394CanUseSecond = false;11395}1139611397if (!NeedParamInfo)11398NewParamInfos.clear();1139911400return true;11401}1140211403void ASTContext::ResetObjCLayout(const ObjCContainerDecl *CD) {11404ObjCLayouts[CD] = nullptr;11405}1140611407/// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and11408/// 'RHS' attributes and returns the merged version; including for function11409/// return types.11410QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {11411QualType LHSCan = getCanonicalType(LHS),11412RHSCan = getCanonicalType(RHS);11413// If two types are identical, they are compatible.11414if (LHSCan == RHSCan)11415return LHS;11416if (RHSCan->isFunctionType()) {11417if (!LHSCan->isFunctionType())11418return {};11419QualType OldReturnType =11420cast<FunctionType>(RHSCan.getTypePtr())->getReturnType();11421QualType NewReturnType =11422cast<FunctionType>(LHSCan.getTypePtr())->getReturnType();11423QualType ResReturnType =11424mergeObjCGCQualifiers(NewReturnType, OldReturnType);11425if (ResReturnType.isNull())11426return {};11427if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) {11428// id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo();11429// In either case, use OldReturnType to build the new function type.11430const auto *F = LHS->castAs<FunctionType>();11431if (const auto *FPT = cast<FunctionProtoType>(F)) {11432FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();11433EPI.ExtInfo = getFunctionExtInfo(LHS);11434QualType ResultType =11435getFunctionType(OldReturnType, FPT->getParamTypes(), EPI);11436return ResultType;11437}11438}11439return {};11440}1144111442// If the qualifiers are different, the types can still be merged.11443Qualifiers LQuals = LHSCan.getLocalQualifiers();11444Qualifiers RQuals = RHSCan.getLocalQualifiers();11445if (LQuals != RQuals) {11446// If any of these qualifiers are different, we have a type mismatch.11447if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||11448LQuals.getAddressSpace() != RQuals.getAddressSpace())11449return {};1145011451// Exactly one GC qualifier difference is allowed: __strong is11452// okay if the other type has no GC qualifier but is an Objective11453// C object pointer (i.e. implicitly strong by default). We fix11454// this by pretending that the unqualified type was actually11455// qualified __strong.11456Qualifiers::GC GC_L = LQuals.getObjCGCAttr();11457Qualifiers::GC GC_R = RQuals.getObjCGCAttr();11458assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");1145911460if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)11461return {};1146211463if (GC_L == Qualifiers::Strong)11464return LHS;11465if (GC_R == Qualifiers::Strong)11466return RHS;11467return {};11468}1146911470if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) {11471QualType LHSBaseQT = LHS->castAs<ObjCObjectPointerType>()->getPointeeType();11472QualType RHSBaseQT = RHS->castAs<ObjCObjectPointerType>()->getPointeeType();11473QualType ResQT = mergeObjCGCQualifiers(LHSBaseQT, RHSBaseQT);11474if (ResQT == LHSBaseQT)11475return LHS;11476if (ResQT == RHSBaseQT)11477return RHS;11478}11479return {};11480}1148111482//===----------------------------------------------------------------------===//11483// Integer Predicates11484//===----------------------------------------------------------------------===//1148511486unsigned ASTContext::getIntWidth(QualType T) const {11487if (const auto *ET = T->getAs<EnumType>())11488T = ET->getDecl()->getIntegerType();11489if (T->isBooleanType())11490return 1;11491if (const auto *EIT = T->getAs<BitIntType>())11492return EIT->getNumBits();11493// For builtin types, just use the standard type sizing method11494return (unsigned)getTypeSize(T);11495}1149611497QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {11498assert((T->hasIntegerRepresentation() || T->isEnumeralType() ||11499T->isFixedPointType()) &&11500"Unexpected type");1150111502// Turn <4 x signed int> -> <4 x unsigned int>11503if (const auto *VTy = T->getAs<VectorType>())11504return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),11505VTy->getNumElements(), VTy->getVectorKind());1150611507// For _BitInt, return an unsigned _BitInt with same width.11508if (const auto *EITy = T->getAs<BitIntType>())11509return getBitIntType(/*Unsigned=*/true, EITy->getNumBits());1151011511// For enums, get the underlying integer type of the enum, and let the general11512// integer type signchanging code handle it.11513if (const auto *ETy = T->getAs<EnumType>())11514T = ETy->getDecl()->getIntegerType();1151511516switch (T->castAs<BuiltinType>()->getKind()) {11517case BuiltinType::Char_U:11518// Plain `char` is mapped to `unsigned char` even if it's already unsigned11519case BuiltinType::Char_S:11520case BuiltinType::SChar:11521case BuiltinType::Char8:11522return UnsignedCharTy;11523case BuiltinType::Short:11524return UnsignedShortTy;11525case BuiltinType::Int:11526return UnsignedIntTy;11527case BuiltinType::Long:11528return UnsignedLongTy;11529case BuiltinType::LongLong:11530return UnsignedLongLongTy;11531case BuiltinType::Int128:11532return UnsignedInt128Ty;11533// wchar_t is special. It is either signed or not, but when it's signed,11534// there's no matching "unsigned wchar_t". Therefore we return the unsigned11535// version of its underlying type instead.11536case BuiltinType::WChar_S:11537return getUnsignedWCharType();1153811539case BuiltinType::ShortAccum:11540return UnsignedShortAccumTy;11541case BuiltinType::Accum:11542return UnsignedAccumTy;11543case BuiltinType::LongAccum:11544return UnsignedLongAccumTy;11545case BuiltinType::SatShortAccum:11546return SatUnsignedShortAccumTy;11547case BuiltinType::SatAccum:11548return SatUnsignedAccumTy;11549case BuiltinType::SatLongAccum:11550return SatUnsignedLongAccumTy;11551case BuiltinType::ShortFract:11552return UnsignedShortFractTy;11553case BuiltinType::Fract:11554return UnsignedFractTy;11555case BuiltinType::LongFract:11556return UnsignedLongFractTy;11557case BuiltinType::SatShortFract:11558return SatUnsignedShortFractTy;11559case BuiltinType::SatFract:11560return SatUnsignedFractTy;11561case BuiltinType::SatLongFract:11562return SatUnsignedLongFractTy;11563default:11564assert((T->hasUnsignedIntegerRepresentation() ||11565T->isUnsignedFixedPointType()) &&11566"Unexpected signed integer or fixed point type");11567return T;11568}11569}1157011571QualType ASTContext::getCorrespondingSignedType(QualType T) const {11572assert((T->hasIntegerRepresentation() || T->isEnumeralType() ||11573T->isFixedPointType()) &&11574"Unexpected type");1157511576// Turn <4 x unsigned int> -> <4 x signed int>11577if (const auto *VTy = T->getAs<VectorType>())11578return getVectorType(getCorrespondingSignedType(VTy->getElementType()),11579VTy->getNumElements(), VTy->getVectorKind());1158011581// For _BitInt, return a signed _BitInt with same width.11582if (const auto *EITy = T->getAs<BitIntType>())11583return getBitIntType(/*Unsigned=*/false, EITy->getNumBits());1158411585// For enums, get the underlying integer type of the enum, and let the general11586// integer type signchanging code handle it.11587if (const auto *ETy = T->getAs<EnumType>())11588T = ETy->getDecl()->getIntegerType();1158911590switch (T->castAs<BuiltinType>()->getKind()) {11591case BuiltinType::Char_S:11592// Plain `char` is mapped to `signed char` even if it's already signed11593case BuiltinType::Char_U:11594case BuiltinType::UChar:11595case BuiltinType::Char8:11596return SignedCharTy;11597case BuiltinType::UShort:11598return ShortTy;11599case BuiltinType::UInt:11600return IntTy;11601case BuiltinType::ULong:11602return LongTy;11603case BuiltinType::ULongLong:11604return LongLongTy;11605case BuiltinType::UInt128:11606return Int128Ty;11607// wchar_t is special. It is either unsigned or not, but when it's unsigned,11608// there's no matching "signed wchar_t". Therefore we return the signed11609// version of its underlying type instead.11610case BuiltinType::WChar_U:11611return getSignedWCharType();1161211613case BuiltinType::UShortAccum:11614return ShortAccumTy;11615case BuiltinType::UAccum:11616return AccumTy;11617case BuiltinType::ULongAccum:11618return LongAccumTy;11619case BuiltinType::SatUShortAccum:11620return SatShortAccumTy;11621case BuiltinType::SatUAccum:11622return SatAccumTy;11623case BuiltinType::SatULongAccum:11624return SatLongAccumTy;11625case BuiltinType::UShortFract:11626return ShortFractTy;11627case BuiltinType::UFract:11628return FractTy;11629case BuiltinType::ULongFract:11630return LongFractTy;11631case BuiltinType::SatUShortFract:11632return SatShortFractTy;11633case BuiltinType::SatUFract:11634return SatFractTy;11635case BuiltinType::SatULongFract:11636return SatLongFractTy;11637default:11638assert(11639(T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&11640"Unexpected signed integer or fixed point type");11641return T;11642}11643}1164411645ASTMutationListener::~ASTMutationListener() = default;1164611647void ASTMutationListener::DeducedReturnType(const FunctionDecl *FD,11648QualType ReturnType) {}1164911650//===----------------------------------------------------------------------===//11651// Builtin Type Computation11652//===----------------------------------------------------------------------===//1165311654/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the11655/// pointer over the consumed characters. This returns the resultant type. If11656/// AllowTypeModifiers is false then modifier like * are not parsed, just basic11657/// types. This allows "v2i*" to be parsed as a pointer to a v2i instead of11658/// a vector of "i*".11659///11660/// RequiresICE is filled in on return to indicate whether the value is required11661/// to be an Integer Constant Expression.11662static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,11663ASTContext::GetBuiltinTypeError &Error,11664bool &RequiresICE,11665bool AllowTypeModifiers) {11666// Modifiers.11667int HowLong = 0;11668bool Signed = false, Unsigned = false;11669RequiresICE = false;1167011671// Read the prefixed modifiers first.11672bool Done = false;11673#ifndef NDEBUG11674bool IsSpecial = false;11675#endif11676while (!Done) {11677switch (*Str++) {11678default: Done = true; --Str; break;11679case 'I':11680RequiresICE = true;11681break;11682case 'S':11683assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");11684assert(!Signed && "Can't use 'S' modifier multiple times!");11685Signed = true;11686break;11687case 'U':11688assert(!Signed && "Can't use both 'S' and 'U' modifiers!");11689assert(!Unsigned && "Can't use 'U' modifier multiple times!");11690Unsigned = true;11691break;11692case 'L':11693assert(!IsSpecial && "Can't use 'L' with 'W', 'N', 'Z' or 'O' modifiers");11694assert(HowLong <= 2 && "Can't have LLLL modifier");11695++HowLong;11696break;11697case 'N':11698// 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise.11699assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");11700assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!");11701#ifndef NDEBUG11702IsSpecial = true;11703#endif11704if (Context.getTargetInfo().getLongWidth() == 32)11705++HowLong;11706break;11707case 'W':11708// This modifier represents int64 type.11709assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");11710assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");11711#ifndef NDEBUG11712IsSpecial = true;11713#endif11714switch (Context.getTargetInfo().getInt64Type()) {11715default:11716llvm_unreachable("Unexpected integer type");11717case TargetInfo::SignedLong:11718HowLong = 1;11719break;11720case TargetInfo::SignedLongLong:11721HowLong = 2;11722break;11723}11724break;11725case 'Z':11726// This modifier represents int32 type.11727assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");11728assert(HowLong == 0 && "Can't use both 'L' and 'Z' modifiers!");11729#ifndef NDEBUG11730IsSpecial = true;11731#endif11732switch (Context.getTargetInfo().getIntTypeByWidth(32, true)) {11733default:11734llvm_unreachable("Unexpected integer type");11735case TargetInfo::SignedInt:11736HowLong = 0;11737break;11738case TargetInfo::SignedLong:11739HowLong = 1;11740break;11741case TargetInfo::SignedLongLong:11742HowLong = 2;11743break;11744}11745break;11746case 'O':11747assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");11748assert(HowLong == 0 && "Can't use both 'L' and 'O' modifiers!");11749#ifndef NDEBUG11750IsSpecial = true;11751#endif11752if (Context.getLangOpts().OpenCL)11753HowLong = 1;11754else11755HowLong = 2;11756break;11757}11758}1175911760QualType Type;1176111762// Read the base type.11763switch (*Str++) {11764default: llvm_unreachable("Unknown builtin type letter!");11765case 'x':11766assert(HowLong == 0 && !Signed && !Unsigned &&11767"Bad modifiers used with 'x'!");11768Type = Context.Float16Ty;11769break;11770case 'y':11771assert(HowLong == 0 && !Signed && !Unsigned &&11772"Bad modifiers used with 'y'!");11773Type = Context.BFloat16Ty;11774break;11775case 'v':11776assert(HowLong == 0 && !Signed && !Unsigned &&11777"Bad modifiers used with 'v'!");11778Type = Context.VoidTy;11779break;11780case 'h':11781assert(HowLong == 0 && !Signed && !Unsigned &&11782"Bad modifiers used with 'h'!");11783Type = Context.HalfTy;11784break;11785case 'f':11786assert(HowLong == 0 && !Signed && !Unsigned &&11787"Bad modifiers used with 'f'!");11788Type = Context.FloatTy;11789break;11790case 'd':11791assert(HowLong < 3 && !Signed && !Unsigned &&11792"Bad modifiers used with 'd'!");11793if (HowLong == 1)11794Type = Context.LongDoubleTy;11795else if (HowLong == 2)11796Type = Context.Float128Ty;11797else11798Type = Context.DoubleTy;11799break;11800case 's':11801assert(HowLong == 0 && "Bad modifiers used with 's'!");11802if (Unsigned)11803Type = Context.UnsignedShortTy;11804else11805Type = Context.ShortTy;11806break;11807case 'i':11808if (HowLong == 3)11809Type = Unsigned ? Context.UnsignedInt128Ty : Context.Int128Ty;11810else if (HowLong == 2)11811Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;11812else if (HowLong == 1)11813Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy;11814else11815Type = Unsigned ? Context.UnsignedIntTy : Context.IntTy;11816break;11817case 'c':11818assert(HowLong == 0 && "Bad modifiers used with 'c'!");11819if (Signed)11820Type = Context.SignedCharTy;11821else if (Unsigned)11822Type = Context.UnsignedCharTy;11823else11824Type = Context.CharTy;11825break;11826case 'b': // boolean11827assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!");11828Type = Context.BoolTy;11829break;11830case 'z': // size_t.11831assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!");11832Type = Context.getSizeType();11833break;11834case 'w': // wchar_t.11835assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'w'!");11836Type = Context.getWideCharType();11837break;11838case 'F':11839Type = Context.getCFConstantStringType();11840break;11841case 'G':11842Type = Context.getObjCIdType();11843break;11844case 'H':11845Type = Context.getObjCSelType();11846break;11847case 'M':11848Type = Context.getObjCSuperType();11849break;11850case 'a':11851Type = Context.getBuiltinVaListType();11852assert(!Type.isNull() && "builtin va list type not initialized!");11853break;11854case 'A':11855// This is a "reference" to a va_list; however, what exactly11856// this means depends on how va_list is defined. There are two11857// different kinds of va_list: ones passed by value, and ones11858// passed by reference. An example of a by-value va_list is11859// x86, where va_list is a char*. An example of by-ref va_list11860// is x86-64, where va_list is a __va_list_tag[1]. For x86,11861// we want this argument to be a char*&; for x86-64, we want11862// it to be a __va_list_tag*.11863Type = Context.getBuiltinVaListType();11864assert(!Type.isNull() && "builtin va list type not initialized!");11865if (Type->isArrayType())11866Type = Context.getArrayDecayedType(Type);11867else11868Type = Context.getLValueReferenceType(Type);11869break;11870case 'q': {11871char *End;11872unsigned NumElements = strtoul(Str, &End, 10);11873assert(End != Str && "Missing vector size");11874Str = End;1187511876QualType ElementType = DecodeTypeFromStr(Str, Context, Error,11877RequiresICE, false);11878assert(!RequiresICE && "Can't require vector ICE");1187911880Type = Context.getScalableVectorType(ElementType, NumElements);11881break;11882}11883case 'Q': {11884switch (*Str++) {11885case 'a': {11886Type = Context.SveCountTy;11887break;11888}11889case 'b': {11890Type = Context.AMDGPUBufferRsrcTy;11891break;11892}11893default:11894llvm_unreachable("Unexpected target builtin type");11895}11896break;11897}11898case 'V': {11899char *End;11900unsigned NumElements = strtoul(Str, &End, 10);11901assert(End != Str && "Missing vector size");11902Str = End;1190311904QualType ElementType = DecodeTypeFromStr(Str, Context, Error,11905RequiresICE, false);11906assert(!RequiresICE && "Can't require vector ICE");1190711908// TODO: No way to make AltiVec vectors in builtins yet.11909Type = Context.getVectorType(ElementType, NumElements, VectorKind::Generic);11910break;11911}11912case 'E': {11913char *End;1191411915unsigned NumElements = strtoul(Str, &End, 10);11916assert(End != Str && "Missing vector size");1191711918Str = End;1191911920QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE,11921false);11922Type = Context.getExtVectorType(ElementType, NumElements);11923break;11924}11925case 'X': {11926QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE,11927false);11928assert(!RequiresICE && "Can't require complex ICE");11929Type = Context.getComplexType(ElementType);11930break;11931}11932case 'Y':11933Type = Context.getPointerDiffType();11934break;11935case 'P':11936Type = Context.getFILEType();11937if (Type.isNull()) {11938Error = ASTContext::GE_Missing_stdio;11939return {};11940}11941break;11942case 'J':11943if (Signed)11944Type = Context.getsigjmp_bufType();11945else11946Type = Context.getjmp_bufType();1194711948if (Type.isNull()) {11949Error = ASTContext::GE_Missing_setjmp;11950return {};11951}11952break;11953case 'K':11954assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'K'!");11955Type = Context.getucontext_tType();1195611957if (Type.isNull()) {11958Error = ASTContext::GE_Missing_ucontext;11959return {};11960}11961break;11962case 'p':11963Type = Context.getProcessIDType();11964break;11965}1196611967// If there are modifiers and if we're allowed to parse them, go for it.11968Done = !AllowTypeModifiers;11969while (!Done) {11970switch (char c = *Str++) {11971default: Done = true; --Str; break;11972case '*':11973case '&': {11974// Both pointers and references can have their pointee types11975// qualified with an address space.11976char *End;11977unsigned AddrSpace = strtoul(Str, &End, 10);11978if (End != Str) {11979// Note AddrSpace == 0 is not the same as an unspecified address space.11980Type = Context.getAddrSpaceQualType(11981Type,11982Context.getLangASForBuiltinAddressSpace(AddrSpace));11983Str = End;11984}11985if (c == '*')11986Type = Context.getPointerType(Type);11987else11988Type = Context.getLValueReferenceType(Type);11989break;11990}11991// FIXME: There's no way to have a built-in with an rvalue ref arg.11992case 'C':11993Type = Type.withConst();11994break;11995case 'D':11996Type = Context.getVolatileType(Type);11997break;11998case 'R':11999Type = Type.withRestrict();12000break;12001}12002}1200312004assert((!RequiresICE || Type->isIntegralOrEnumerationType()) &&12005"Integer constant 'I' type must be an integer");1200612007return Type;12008}1200912010// On some targets such as PowerPC, some of the builtins are defined with custom12011// type descriptors for target-dependent types. These descriptors are decoded in12012// other functions, but it may be useful to be able to fall back to default12013// descriptor decoding to define builtins mixing target-dependent and target-12014// independent types. This function allows decoding one type descriptor with12015// default decoding.12016QualType ASTContext::DecodeTypeStr(const char *&Str, const ASTContext &Context,12017GetBuiltinTypeError &Error, bool &RequireICE,12018bool AllowTypeModifiers) const {12019return DecodeTypeFromStr(Str, Context, Error, RequireICE, AllowTypeModifiers);12020}1202112022/// GetBuiltinType - Return the type for the specified builtin.12023QualType ASTContext::GetBuiltinType(unsigned Id,12024GetBuiltinTypeError &Error,12025unsigned *IntegerConstantArgs) const {12026const char *TypeStr = BuiltinInfo.getTypeString(Id);12027if (TypeStr[0] == '\0') {12028Error = GE_Missing_type;12029return {};12030}1203112032SmallVector<QualType, 8> ArgTypes;1203312034bool RequiresICE = false;12035Error = GE_None;12036QualType ResType = DecodeTypeFromStr(TypeStr, *this, Error,12037RequiresICE, true);12038if (Error != GE_None)12039return {};1204012041assert(!RequiresICE && "Result of intrinsic cannot be required to be an ICE");1204212043while (TypeStr[0] && TypeStr[0] != '.') {12044QualType Ty = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true);12045if (Error != GE_None)12046return {};1204712048// If this argument is required to be an IntegerConstantExpression and the12049// caller cares, fill in the bitmask we return.12050if (RequiresICE && IntegerConstantArgs)12051*IntegerConstantArgs |= 1 << ArgTypes.size();1205212053// Do array -> pointer decay. The builtin should use the decayed type.12054if (Ty->isArrayType())12055Ty = getArrayDecayedType(Ty);1205612057ArgTypes.push_back(Ty);12058}1205912060if (Id == Builtin::BI__GetExceptionInfo)12061return {};1206212063assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&12064"'.' should only occur at end of builtin type list!");1206512066bool Variadic = (TypeStr[0] == '.');1206712068FunctionType::ExtInfo EI(getDefaultCallingConvention(12069Variadic, /*IsCXXMethod=*/false, /*IsBuiltin=*/true));12070if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true);120711207212073// We really shouldn't be making a no-proto type here.12074if (ArgTypes.empty() && Variadic && !getLangOpts().requiresStrictPrototypes())12075return getFunctionNoProtoType(ResType, EI);1207612077FunctionProtoType::ExtProtoInfo EPI;12078EPI.ExtInfo = EI;12079EPI.Variadic = Variadic;12080if (getLangOpts().CPlusPlus && BuiltinInfo.isNoThrow(Id))12081EPI.ExceptionSpec.Type =12082getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone;1208312084return getFunctionType(ResType, ArgTypes, EPI);12085}1208612087static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,12088const FunctionDecl *FD) {12089if (!FD->isExternallyVisible())12090return GVA_Internal;1209112092// Non-user-provided functions get emitted as weak definitions with every12093// use, no matter whether they've been explicitly instantiated etc.12094if (!FD->isUserProvided())12095return GVA_DiscardableODR;1209612097GVALinkage External;12098switch (FD->getTemplateSpecializationKind()) {12099case TSK_Undeclared:12100case TSK_ExplicitSpecialization:12101External = GVA_StrongExternal;12102break;1210312104case TSK_ExplicitInstantiationDefinition:12105return GVA_StrongODR;1210612107// C++11 [temp.explicit]p10:12108// [ Note: The intent is that an inline function that is the subject of12109// an explicit instantiation declaration will still be implicitly12110// instantiated when used so that the body can be considered for12111// inlining, but that no out-of-line copy of the inline function would be12112// generated in the translation unit. -- end note ]12113case TSK_ExplicitInstantiationDeclaration:12114return GVA_AvailableExternally;1211512116case TSK_ImplicitInstantiation:12117External = GVA_DiscardableODR;12118break;12119}1212012121if (!FD->isInlined())12122return External;1212312124if ((!Context.getLangOpts().CPlusPlus &&12125!Context.getTargetInfo().getCXXABI().isMicrosoft() &&12126!FD->hasAttr<DLLExportAttr>()) ||12127FD->hasAttr<GNUInlineAttr>()) {12128// FIXME: This doesn't match gcc's behavior for dllexport inline functions.1212912130// GNU or C99 inline semantics. Determine whether this symbol should be12131// externally visible.12132if (FD->isInlineDefinitionExternallyVisible())12133return External;1213412135// C99 inline semantics, where the symbol is not externally visible.12136return GVA_AvailableExternally;12137}1213812139// Functions specified with extern and inline in -fms-compatibility mode12140// forcibly get emitted. While the body of the function cannot be later12141// replaced, the function definition cannot be discarded.12142if (FD->isMSExternInline())12143return GVA_StrongODR;1214412145if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&12146isa<CXXConstructorDecl>(FD) &&12147cast<CXXConstructorDecl>(FD)->isInheritingConstructor())12148// Our approach to inheriting constructors is fundamentally different from12149// that used by the MS ABI, so keep our inheriting constructor thunks12150// internal rather than trying to pick an unambiguous mangling for them.12151return GVA_Internal;1215212153return GVA_DiscardableODR;12154}1215512156static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,12157const Decl *D, GVALinkage L) {12158// See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx12159// dllexport/dllimport on inline functions.12160if (D->hasAttr<DLLImportAttr>()) {12161if (L == GVA_DiscardableODR || L == GVA_StrongODR)12162return GVA_AvailableExternally;12163} else if (D->hasAttr<DLLExportAttr>()) {12164if (L == GVA_DiscardableODR)12165return GVA_StrongODR;12166} else if (Context.getLangOpts().CUDA && Context.getLangOpts().CUDAIsDevice) {12167// Device-side functions with __global__ attribute must always be12168// visible externally so they can be launched from host.12169if (D->hasAttr<CUDAGlobalAttr>() &&12170(L == GVA_DiscardableODR || L == GVA_Internal))12171return GVA_StrongODR;12172// Single source offloading languages like CUDA/HIP need to be able to12173// access static device variables from host code of the same compilation12174// unit. This is done by externalizing the static variable with a shared12175// name between the host and device compilation which is the same for the12176// same compilation unit whereas different among different compilation12177// units.12178if (Context.shouldExternalize(D))12179return GVA_StrongExternal;12180}12181return L;12182}1218312184/// Adjust the GVALinkage for a declaration based on what an external AST source12185/// knows about whether there can be other definitions of this declaration.12186static GVALinkage12187adjustGVALinkageForExternalDefinitionKind(const ASTContext &Ctx, const Decl *D,12188GVALinkage L) {12189ExternalASTSource *Source = Ctx.getExternalSource();12190if (!Source)12191return L;1219212193switch (Source->hasExternalDefinitions(D)) {12194case ExternalASTSource::EK_Never:12195// Other translation units rely on us to provide the definition.12196if (L == GVA_DiscardableODR)12197return GVA_StrongODR;12198break;1219912200case ExternalASTSource::EK_Always:12201return GVA_AvailableExternally;1220212203case ExternalASTSource::EK_ReplyHazy:12204break;12205}12206return L;12207}1220812209GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {12210return adjustGVALinkageForExternalDefinitionKind(*this, FD,12211adjustGVALinkageForAttributes(*this, FD,12212basicGVALinkageForFunction(*this, FD)));12213}1221412215static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,12216const VarDecl *VD) {12217// As an extension for interactive REPLs, make sure constant variables are12218// only emitted once instead of LinkageComputer::getLVForNamespaceScopeDecl12219// marking them as internal.12220if (Context.getLangOpts().CPlusPlus &&12221Context.getLangOpts().IncrementalExtensions &&12222VD->getType().isConstQualified() &&12223!VD->getType().isVolatileQualified() && !VD->isInline() &&12224!isa<VarTemplateSpecializationDecl>(VD) && !VD->getDescribedVarTemplate())12225return GVA_DiscardableODR;1222612227if (!VD->isExternallyVisible())12228return GVA_Internal;1222912230if (VD->isStaticLocal()) {12231const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();12232while (LexicalContext && !isa<FunctionDecl>(LexicalContext))12233LexicalContext = LexicalContext->getLexicalParent();1223412235// ObjC Blocks can create local variables that don't have a FunctionDecl12236// LexicalContext.12237if (!LexicalContext)12238return GVA_DiscardableODR;1223912240// Otherwise, let the static local variable inherit its linkage from the12241// nearest enclosing function.12242auto StaticLocalLinkage =12243Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));1224412245// Itanium ABI 5.2.2: "Each COMDAT group [for a static local variable] must12246// be emitted in any object with references to the symbol for the object it12247// contains, whether inline or out-of-line."12248// Similar behavior is observed with MSVC. An alternative ABI could use12249// StrongODR/AvailableExternally to match the function, but none are12250// known/supported currently.12251if (StaticLocalLinkage == GVA_StrongODR ||12252StaticLocalLinkage == GVA_AvailableExternally)12253return GVA_DiscardableODR;12254return StaticLocalLinkage;12255}1225612257// MSVC treats in-class initialized static data members as definitions.12258// By giving them non-strong linkage, out-of-line definitions won't12259// cause link errors.12260if (Context.isMSStaticDataMemberInlineDefinition(VD))12261return GVA_DiscardableODR;1226212263// Most non-template variables have strong linkage; inline variables are12264// linkonce_odr or (occasionally, for compatibility) weak_odr.12265GVALinkage StrongLinkage;12266switch (Context.getInlineVariableDefinitionKind(VD)) {12267case ASTContext::InlineVariableDefinitionKind::None:12268StrongLinkage = GVA_StrongExternal;12269break;12270case ASTContext::InlineVariableDefinitionKind::Weak:12271case ASTContext::InlineVariableDefinitionKind::WeakUnknown:12272StrongLinkage = GVA_DiscardableODR;12273break;12274case ASTContext::InlineVariableDefinitionKind::Strong:12275StrongLinkage = GVA_StrongODR;12276break;12277}1227812279switch (VD->getTemplateSpecializationKind()) {12280case TSK_Undeclared:12281return StrongLinkage;1228212283case TSK_ExplicitSpecialization:12284return Context.getTargetInfo().getCXXABI().isMicrosoft() &&12285VD->isStaticDataMember()12286? GVA_StrongODR12287: StrongLinkage;1228812289case TSK_ExplicitInstantiationDefinition:12290return GVA_StrongODR;1229112292case TSK_ExplicitInstantiationDeclaration:12293return GVA_AvailableExternally;1229412295case TSK_ImplicitInstantiation:12296return GVA_DiscardableODR;12297}1229812299llvm_unreachable("Invalid Linkage!");12300}1230112302GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) const {12303return adjustGVALinkageForExternalDefinitionKind(*this, VD,12304adjustGVALinkageForAttributes(*this, VD,12305basicGVALinkageForVariable(*this, VD)));12306}1230712308bool ASTContext::DeclMustBeEmitted(const Decl *D) {12309if (const auto *VD = dyn_cast<VarDecl>(D)) {12310if (!VD->isFileVarDecl())12311return false;12312// Global named register variables (GNU extension) are never emitted.12313if (VD->getStorageClass() == SC_Register)12314return false;12315if (VD->getDescribedVarTemplate() ||12316isa<VarTemplatePartialSpecializationDecl>(VD))12317return false;12318} else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {12319// We never need to emit an uninstantiated function template.12320if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)12321return false;12322} else if (isa<PragmaCommentDecl>(D))12323return true;12324else if (isa<PragmaDetectMismatchDecl>(D))12325return true;12326else if (isa<OMPRequiresDecl>(D))12327return true;12328else if (isa<OMPThreadPrivateDecl>(D))12329return !D->getDeclContext()->isDependentContext();12330else if (isa<OMPAllocateDecl>(D))12331return !D->getDeclContext()->isDependentContext();12332else if (isa<OMPDeclareReductionDecl>(D) || isa<OMPDeclareMapperDecl>(D))12333return !D->getDeclContext()->isDependentContext();12334else if (isa<ImportDecl>(D))12335return true;12336else12337return false;1233812339// If this is a member of a class template, we do not need to emit it.12340if (D->getDeclContext()->isDependentContext())12341return false;1234212343// Weak references don't produce any output by themselves.12344if (D->hasAttr<WeakRefAttr>())12345return false;1234612347// Aliases and used decls are required.12348if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())12349return true;1235012351if (const auto *FD = dyn_cast<FunctionDecl>(D)) {12352// Forward declarations aren't required.12353if (!FD->doesThisDeclarationHaveABody())12354return FD->doesDeclarationForceExternallyVisibleDefinition();1235512356// Constructors and destructors are required.12357if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())12358return true;1235912360// The key function for a class is required. This rule only comes12361// into play when inline functions can be key functions, though.12362if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {12363if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {12364const CXXRecordDecl *RD = MD->getParent();12365if (MD->isOutOfLine() && RD->isDynamicClass()) {12366const CXXMethodDecl *KeyFunc = getCurrentKeyFunction(RD);12367if (KeyFunc && KeyFunc->getCanonicalDecl() == MD->getCanonicalDecl())12368return true;12369}12370}12371}1237212373GVALinkage Linkage = GetGVALinkageForFunction(FD);1237412375// static, static inline, always_inline, and extern inline functions can12376// always be deferred. Normal inline functions can be deferred in C99/C++.12377// Implicit template instantiations can also be deferred in C++.12378return !isDiscardableGVALinkage(Linkage);12379}1238012381const auto *VD = cast<VarDecl>(D);12382assert(VD->isFileVarDecl() && "Expected file scoped var");1238312384// If the decl is marked as `declare target to`, it should be emitted for the12385// host and for the device.12386if (LangOpts.OpenMP &&12387OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))12388return true;1238912390if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&12391!isMSStaticDataMemberInlineDefinition(VD))12392return false;1239312394if (VD->shouldEmitInExternalSource())12395return false;1239612397// Variables that can be needed in other TUs are required.12398auto Linkage = GetGVALinkageForVariable(VD);12399if (!isDiscardableGVALinkage(Linkage))12400return true;1240112402// We never need to emit a variable that is available in another TU.12403if (Linkage == GVA_AvailableExternally)12404return false;1240512406// Variables that have destruction with side-effects are required.12407if (VD->needsDestruction(*this))12408return true;1240912410// Variables that have initialization with side-effects are required.12411if (VD->getInit() && VD->getInit()->HasSideEffects(*this) &&12412// We can get a value-dependent initializer during error recovery.12413(VD->getInit()->isValueDependent() || !VD->evaluateValue()))12414return true;1241512416// Likewise, variables with tuple-like bindings are required if their12417// bindings have side-effects.12418if (const auto *DD = dyn_cast<DecompositionDecl>(VD))12419for (const auto *BD : DD->bindings())12420if (const auto *BindingVD = BD->getHoldingVar())12421if (DeclMustBeEmitted(BindingVD))12422return true;1242312424return false;12425}1242612427void ASTContext::forEachMultiversionedFunctionVersion(12428const FunctionDecl *FD,12429llvm::function_ref<void(FunctionDecl *)> Pred) const {12430assert(FD->isMultiVersion() && "Only valid for multiversioned functions");12431llvm::SmallDenseSet<const FunctionDecl*, 4> SeenDecls;12432FD = FD->getMostRecentDecl();12433// FIXME: The order of traversal here matters and depends on the order of12434// lookup results, which happens to be (mostly) oldest-to-newest, but we12435// shouldn't rely on that.12436for (auto *CurDecl :12437FD->getDeclContext()->getRedeclContext()->lookup(FD->getDeclName())) {12438FunctionDecl *CurFD = CurDecl->getAsFunction()->getMostRecentDecl();12439if (CurFD && hasSameType(CurFD->getType(), FD->getType()) &&12440!SeenDecls.contains(CurFD)) {12441SeenDecls.insert(CurFD);12442Pred(CurFD);12443}12444}12445}1244612447CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,12448bool IsCXXMethod,12449bool IsBuiltin) const {12450// Pass through to the C++ ABI object12451if (IsCXXMethod)12452return ABI->getDefaultMethodCallConv(IsVariadic);1245312454// Builtins ignore user-specified default calling convention and remain the12455// Target's default calling convention.12456if (!IsBuiltin) {12457switch (LangOpts.getDefaultCallingConv()) {12458case LangOptions::DCC_None:12459break;12460case LangOptions::DCC_CDecl:12461return CC_C;12462case LangOptions::DCC_FastCall:12463if (getTargetInfo().hasFeature("sse2") && !IsVariadic)12464return CC_X86FastCall;12465break;12466case LangOptions::DCC_StdCall:12467if (!IsVariadic)12468return CC_X86StdCall;12469break;12470case LangOptions::DCC_VectorCall:12471// __vectorcall cannot be applied to variadic functions.12472if (!IsVariadic)12473return CC_X86VectorCall;12474break;12475case LangOptions::DCC_RegCall:12476// __regcall cannot be applied to variadic functions.12477if (!IsVariadic)12478return CC_X86RegCall;12479break;12480case LangOptions::DCC_RtdCall:12481if (!IsVariadic)12482return CC_M68kRTD;12483break;12484}12485}12486return Target->getDefaultCallingConv();12487}1248812489bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {12490// Pass through to the C++ ABI object12491return ABI->isNearlyEmpty(RD);12492}1249312494VTableContextBase *ASTContext::getVTableContext() {12495if (!VTContext.get()) {12496auto ABI = Target->getCXXABI();12497if (ABI.isMicrosoft())12498VTContext.reset(new MicrosoftVTableContext(*this));12499else {12500auto ComponentLayout = getLangOpts().RelativeCXXABIVTables12501? ItaniumVTableContext::Relative12502: ItaniumVTableContext::Pointer;12503VTContext.reset(new ItaniumVTableContext(*this, ComponentLayout));12504}12505}12506return VTContext.get();12507}1250812509MangleContext *ASTContext::createMangleContext(const TargetInfo *T) {12510if (!T)12511T = Target;12512switch (T->getCXXABI().getKind()) {12513case TargetCXXABI::AppleARM64:12514case TargetCXXABI::Fuchsia:12515case TargetCXXABI::GenericAArch64:12516case TargetCXXABI::GenericItanium:12517case TargetCXXABI::GenericARM:12518case TargetCXXABI::GenericMIPS:12519case TargetCXXABI::iOS:12520case TargetCXXABI::WebAssembly:12521case TargetCXXABI::WatchOS:12522case TargetCXXABI::XL:12523return ItaniumMangleContext::create(*this, getDiagnostics());12524case TargetCXXABI::Microsoft:12525return MicrosoftMangleContext::create(*this, getDiagnostics());12526}12527llvm_unreachable("Unsupported ABI");12528}1252912530MangleContext *ASTContext::createDeviceMangleContext(const TargetInfo &T) {12531assert(T.getCXXABI().getKind() != TargetCXXABI::Microsoft &&12532"Device mangle context does not support Microsoft mangling.");12533switch (T.getCXXABI().getKind()) {12534case TargetCXXABI::AppleARM64:12535case TargetCXXABI::Fuchsia:12536case TargetCXXABI::GenericAArch64:12537case TargetCXXABI::GenericItanium:12538case TargetCXXABI::GenericARM:12539case TargetCXXABI::GenericMIPS:12540case TargetCXXABI::iOS:12541case TargetCXXABI::WebAssembly:12542case TargetCXXABI::WatchOS:12543case TargetCXXABI::XL:12544return ItaniumMangleContext::create(12545*this, getDiagnostics(),12546[](ASTContext &, const NamedDecl *ND) -> std::optional<unsigned> {12547if (const auto *RD = dyn_cast<CXXRecordDecl>(ND))12548return RD->getDeviceLambdaManglingNumber();12549return std::nullopt;12550},12551/*IsAux=*/true);12552case TargetCXXABI::Microsoft:12553return MicrosoftMangleContext::create(*this, getDiagnostics(),12554/*IsAux=*/true);12555}12556llvm_unreachable("Unsupported ABI");12557}1255812559CXXABI::~CXXABI() = default;1256012561size_t ASTContext::getSideTableAllocatedMemory() const {12562return ASTRecordLayouts.getMemorySize() +12563llvm::capacity_in_bytes(ObjCLayouts) +12564llvm::capacity_in_bytes(KeyFunctions) +12565llvm::capacity_in_bytes(ObjCImpls) +12566llvm::capacity_in_bytes(BlockVarCopyInits) +12567llvm::capacity_in_bytes(DeclAttrs) +12568llvm::capacity_in_bytes(TemplateOrInstantiation) +12569llvm::capacity_in_bytes(InstantiatedFromUsingDecl) +12570llvm::capacity_in_bytes(InstantiatedFromUsingShadowDecl) +12571llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) +12572llvm::capacity_in_bytes(OverriddenMethods) +12573llvm::capacity_in_bytes(Types) +12574llvm::capacity_in_bytes(VariableArrayTypes);12575}1257612577/// getIntTypeForBitwidth -12578/// sets integer QualTy according to specified details:12579/// bitwidth, signed/unsigned.12580/// Returns empty type if there is no appropriate target types.12581QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth,12582unsigned Signed) const {12583TargetInfo::IntType Ty = getTargetInfo().getIntTypeByWidth(DestWidth, Signed);12584CanQualType QualTy = getFromTargetType(Ty);12585if (!QualTy && DestWidth == 128)12586return Signed ? Int128Ty : UnsignedInt128Ty;12587return QualTy;12588}1258912590/// getRealTypeForBitwidth -12591/// sets floating point QualTy according to specified bitwidth.12592/// Returns empty type if there is no appropriate target types.12593QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth,12594FloatModeKind ExplicitType) const {12595FloatModeKind Ty =12596getTargetInfo().getRealTypeByWidth(DestWidth, ExplicitType);12597switch (Ty) {12598case FloatModeKind::Half:12599return HalfTy;12600case FloatModeKind::Float:12601return FloatTy;12602case FloatModeKind::Double:12603return DoubleTy;12604case FloatModeKind::LongDouble:12605return LongDoubleTy;12606case FloatModeKind::Float128:12607return Float128Ty;12608case FloatModeKind::Ibm128:12609return Ibm128Ty;12610case FloatModeKind::NoFloat:12611return {};12612}1261312614llvm_unreachable("Unhandled TargetInfo::RealType value");12615}1261612617void ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) {12618if (Number <= 1)12619return;1262012621MangleNumbers[ND] = Number;1262212623if (Listener)12624Listener->AddedManglingNumber(ND, Number);12625}1262612627unsigned ASTContext::getManglingNumber(const NamedDecl *ND,12628bool ForAuxTarget) const {12629auto I = MangleNumbers.find(ND);12630unsigned Res = I != MangleNumbers.end() ? I->second : 1;12631// CUDA/HIP host compilation encodes host and device mangling numbers12632// as lower and upper half of 32 bit integer.12633if (LangOpts.CUDA && !LangOpts.CUDAIsDevice) {12634Res = ForAuxTarget ? Res >> 16 : Res & 0xFFFF;12635} else {12636assert(!ForAuxTarget && "Only CUDA/HIP host compilation supports mangling "12637"number for aux target");12638}12639return Res > 1 ? Res : 1;12640}1264112642void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) {12643if (Number <= 1)12644return;1264512646StaticLocalNumbers[VD] = Number;1264712648if (Listener)12649Listener->AddedStaticLocalNumbers(VD, Number);12650}1265112652unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const {12653auto I = StaticLocalNumbers.find(VD);12654return I != StaticLocalNumbers.end() ? I->second : 1;12655}1265612657MangleNumberingContext &12658ASTContext::getManglingNumberContext(const DeclContext *DC) {12659assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.12660std::unique_ptr<MangleNumberingContext> &MCtx = MangleNumberingContexts[DC];12661if (!MCtx)12662MCtx = createMangleNumberingContext();12663return *MCtx;12664}1266512666MangleNumberingContext &12667ASTContext::getManglingNumberContext(NeedExtraManglingDecl_t, const Decl *D) {12668assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.12669std::unique_ptr<MangleNumberingContext> &MCtx =12670ExtraMangleNumberingContexts[D];12671if (!MCtx)12672MCtx = createMangleNumberingContext();12673return *MCtx;12674}1267512676std::unique_ptr<MangleNumberingContext>12677ASTContext::createMangleNumberingContext() const {12678return ABI->createMangleNumberingContext();12679}1268012681const CXXConstructorDecl *12682ASTContext::getCopyConstructorForExceptionObject(CXXRecordDecl *RD) {12683return ABI->getCopyConstructorForExceptionObject(12684cast<CXXRecordDecl>(RD->getFirstDecl()));12685}1268612687void ASTContext::addCopyConstructorForExceptionObject(CXXRecordDecl *RD,12688CXXConstructorDecl *CD) {12689return ABI->addCopyConstructorForExceptionObject(12690cast<CXXRecordDecl>(RD->getFirstDecl()),12691cast<CXXConstructorDecl>(CD->getFirstDecl()));12692}1269312694void ASTContext::addTypedefNameForUnnamedTagDecl(TagDecl *TD,12695TypedefNameDecl *DD) {12696return ABI->addTypedefNameForUnnamedTagDecl(TD, DD);12697}1269812699TypedefNameDecl *12700ASTContext::getTypedefNameForUnnamedTagDecl(const TagDecl *TD) {12701return ABI->getTypedefNameForUnnamedTagDecl(TD);12702}1270312704void ASTContext::addDeclaratorForUnnamedTagDecl(TagDecl *TD,12705DeclaratorDecl *DD) {12706return ABI->addDeclaratorForUnnamedTagDecl(TD, DD);12707}1270812709DeclaratorDecl *ASTContext::getDeclaratorForUnnamedTagDecl(const TagDecl *TD) {12710return ABI->getDeclaratorForUnnamedTagDecl(TD);12711}1271212713void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {12714ParamIndices[D] = index;12715}1271612717unsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const {12718ParameterIndexTable::const_iterator I = ParamIndices.find(D);12719assert(I != ParamIndices.end() &&12720"ParmIndices lacks entry set by ParmVarDecl");12721return I->second;12722}1272312724QualType ASTContext::getStringLiteralArrayType(QualType EltTy,12725unsigned Length) const {12726// A C++ string literal has a const-qualified element type (C++ 2.13.4p1).12727if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)12728EltTy = EltTy.withConst();1272912730EltTy = adjustStringLiteralBaseType(EltTy);1273112732// Get an array type for the string, according to C99 6.4.5. This includes12733// the null terminator character.12734return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1), nullptr,12735ArraySizeModifier::Normal, /*IndexTypeQuals*/ 0);12736}1273712738StringLiteral *12739ASTContext::getPredefinedStringLiteralFromCache(StringRef Key) const {12740StringLiteral *&Result = StringLiteralCache[Key];12741if (!Result)12742Result = StringLiteral::Create(12743*this, Key, StringLiteralKind::Ordinary,12744/*Pascal*/ false, getStringLiteralArrayType(CharTy, Key.size()),12745SourceLocation());12746return Result;12747}1274812749MSGuidDecl *12750ASTContext::getMSGuidDecl(MSGuidDecl::Parts Parts) const {12751assert(MSGuidTagDecl && "building MS GUID without MS extensions?");1275212753llvm::FoldingSetNodeID ID;12754MSGuidDecl::Profile(ID, Parts);1275512756void *InsertPos;12757if (MSGuidDecl *Existing = MSGuidDecls.FindNodeOrInsertPos(ID, InsertPos))12758return Existing;1275912760QualType GUIDType = getMSGuidType().withConst();12761MSGuidDecl *New = MSGuidDecl::Create(*this, GUIDType, Parts);12762MSGuidDecls.InsertNode(New, InsertPos);12763return New;12764}1276512766UnnamedGlobalConstantDecl *12767ASTContext::getUnnamedGlobalConstantDecl(QualType Ty,12768const APValue &APVal) const {12769llvm::FoldingSetNodeID ID;12770UnnamedGlobalConstantDecl::Profile(ID, Ty, APVal);1277112772void *InsertPos;12773if (UnnamedGlobalConstantDecl *Existing =12774UnnamedGlobalConstantDecls.FindNodeOrInsertPos(ID, InsertPos))12775return Existing;1277612777UnnamedGlobalConstantDecl *New =12778UnnamedGlobalConstantDecl::Create(*this, Ty, APVal);12779UnnamedGlobalConstantDecls.InsertNode(New, InsertPos);12780return New;12781}1278212783TemplateParamObjectDecl *12784ASTContext::getTemplateParamObjectDecl(QualType T, const APValue &V) const {12785assert(T->isRecordType() && "template param object of unexpected type");1278612787// C++ [temp.param]p8:12788// [...] a static storage duration object of type 'const T' [...]12789T.addConst();1279012791llvm::FoldingSetNodeID ID;12792TemplateParamObjectDecl::Profile(ID, T, V);1279312794void *InsertPos;12795if (TemplateParamObjectDecl *Existing =12796TemplateParamObjectDecls.FindNodeOrInsertPos(ID, InsertPos))12797return Existing;1279812799TemplateParamObjectDecl *New = TemplateParamObjectDecl::Create(*this, T, V);12800TemplateParamObjectDecls.InsertNode(New, InsertPos);12801return New;12802}1280312804bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {12805const llvm::Triple &T = getTargetInfo().getTriple();12806if (!T.isOSDarwin())12807return false;1280812809if (!(T.isiOS() && T.isOSVersionLT(7)) &&12810!(T.isMacOSX() && T.isOSVersionLT(10, 9)))12811return false;1281212813QualType AtomicTy = E->getPtr()->getType()->getPointeeType();12814CharUnits sizeChars = getTypeSizeInChars(AtomicTy);12815uint64_t Size = sizeChars.getQuantity();12816CharUnits alignChars = getTypeAlignInChars(AtomicTy);12817unsigned Align = alignChars.getQuantity();12818unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth();12819return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits);12820}1282112822bool12823ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,12824const ObjCMethodDecl *MethodImpl) {12825// No point trying to match an unavailable/deprecated mothod.12826if (MethodDecl->hasAttr<UnavailableAttr>()12827|| MethodDecl->hasAttr<DeprecatedAttr>())12828return false;12829if (MethodDecl->getObjCDeclQualifier() !=12830MethodImpl->getObjCDeclQualifier())12831return false;12832if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType()))12833return false;1283412835if (MethodDecl->param_size() != MethodImpl->param_size())12836return false;1283712838for (ObjCMethodDecl::param_const_iterator IM = MethodImpl->param_begin(),12839IF = MethodDecl->param_begin(), EM = MethodImpl->param_end(),12840EF = MethodDecl->param_end();12841IM != EM && IF != EF; ++IM, ++IF) {12842const ParmVarDecl *DeclVar = (*IF);12843const ParmVarDecl *ImplVar = (*IM);12844if (ImplVar->getObjCDeclQualifier() != DeclVar->getObjCDeclQualifier())12845return false;12846if (!hasSameType(DeclVar->getType(), ImplVar->getType()))12847return false;12848}1284912850return (MethodDecl->isVariadic() == MethodImpl->isVariadic());12851}1285212853uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {12854LangAS AS;12855if (QT->getUnqualifiedDesugaredType()->isNullPtrType())12856AS = LangAS::Default;12857else12858AS = QT->getPointeeType().getAddressSpace();1285912860return getTargetInfo().getNullPointerValue(AS);12861}1286212863unsigned ASTContext::getTargetAddressSpace(LangAS AS) const {12864return getTargetInfo().getTargetAddressSpace(AS);12865}1286612867bool ASTContext::hasSameExpr(const Expr *X, const Expr *Y) const {12868if (X == Y)12869return true;12870if (!X || !Y)12871return false;12872llvm::FoldingSetNodeID IDX, IDY;12873X->Profile(IDX, *this, /*Canonical=*/true);12874Y->Profile(IDY, *this, /*Canonical=*/true);12875return IDX == IDY;12876}1287712878// The getCommon* helpers return, for given 'same' X and Y entities given as12879// inputs, another entity which is also the 'same' as the inputs, but which12880// is closer to the canonical form of the inputs, each according to a given12881// criteria.12882// The getCommon*Checked variants are 'null inputs not-allowed' equivalents of12883// the regular ones.1288412885static Decl *getCommonDecl(Decl *X, Decl *Y) {12886if (!declaresSameEntity(X, Y))12887return nullptr;12888for (const Decl *DX : X->redecls()) {12889// If we reach Y before reaching the first decl, that means X is older.12890if (DX == Y)12891return X;12892// If we reach the first decl, then Y is older.12893if (DX->isFirstDecl())12894return Y;12895}12896llvm_unreachable("Corrupt redecls chain");12897}1289812899template <class T, std::enable_if_t<std::is_base_of_v<Decl, T>, bool> = true>12900static T *getCommonDecl(T *X, T *Y) {12901return cast_or_null<T>(12902getCommonDecl(const_cast<Decl *>(cast_or_null<Decl>(X)),12903const_cast<Decl *>(cast_or_null<Decl>(Y))));12904}1290512906template <class T, std::enable_if_t<std::is_base_of_v<Decl, T>, bool> = true>12907static T *getCommonDeclChecked(T *X, T *Y) {12908return cast<T>(getCommonDecl(const_cast<Decl *>(cast<Decl>(X)),12909const_cast<Decl *>(cast<Decl>(Y))));12910}1291112912static TemplateName getCommonTemplateName(ASTContext &Ctx, TemplateName X,12913TemplateName Y) {12914if (X.getAsVoidPointer() == Y.getAsVoidPointer())12915return X;12916// FIXME: There are cases here where we could find a common template name12917// with more sugar. For example one could be a SubstTemplateTemplate*12918// replacing the other.12919TemplateName CX = Ctx.getCanonicalTemplateName(X);12920if (CX.getAsVoidPointer() !=12921Ctx.getCanonicalTemplateName(Y).getAsVoidPointer())12922return TemplateName();12923return CX;12924}1292512926static TemplateName12927getCommonTemplateNameChecked(ASTContext &Ctx, TemplateName X, TemplateName Y) {12928TemplateName R = getCommonTemplateName(Ctx, X, Y);12929assert(R.getAsVoidPointer() != nullptr);12930return R;12931}1293212933static auto getCommonTypes(ASTContext &Ctx, ArrayRef<QualType> Xs,12934ArrayRef<QualType> Ys, bool Unqualified = false) {12935assert(Xs.size() == Ys.size());12936SmallVector<QualType, 8> Rs(Xs.size());12937for (size_t I = 0; I < Rs.size(); ++I)12938Rs[I] = Ctx.getCommonSugaredType(Xs[I], Ys[I], Unqualified);12939return Rs;12940}1294112942template <class T>12943static SourceLocation getCommonAttrLoc(const T *X, const T *Y) {12944return X->getAttributeLoc() == Y->getAttributeLoc() ? X->getAttributeLoc()12945: SourceLocation();12946}1294712948static TemplateArgument getCommonTemplateArgument(ASTContext &Ctx,12949const TemplateArgument &X,12950const TemplateArgument &Y) {12951if (X.getKind() != Y.getKind())12952return TemplateArgument();1295312954switch (X.getKind()) {12955case TemplateArgument::ArgKind::Type:12956if (!Ctx.hasSameType(X.getAsType(), Y.getAsType()))12957return TemplateArgument();12958return TemplateArgument(12959Ctx.getCommonSugaredType(X.getAsType(), Y.getAsType()));12960case TemplateArgument::ArgKind::NullPtr:12961if (!Ctx.hasSameType(X.getNullPtrType(), Y.getNullPtrType()))12962return TemplateArgument();12963return TemplateArgument(12964Ctx.getCommonSugaredType(X.getNullPtrType(), Y.getNullPtrType()),12965/*Unqualified=*/true);12966case TemplateArgument::ArgKind::Expression:12967if (!Ctx.hasSameType(X.getAsExpr()->getType(), Y.getAsExpr()->getType()))12968return TemplateArgument();12969// FIXME: Try to keep the common sugar.12970return X;12971case TemplateArgument::ArgKind::Template: {12972TemplateName TX = X.getAsTemplate(), TY = Y.getAsTemplate();12973TemplateName CTN = ::getCommonTemplateName(Ctx, TX, TY);12974if (!CTN.getAsVoidPointer())12975return TemplateArgument();12976return TemplateArgument(CTN);12977}12978case TemplateArgument::ArgKind::TemplateExpansion: {12979TemplateName TX = X.getAsTemplateOrTemplatePattern(),12980TY = Y.getAsTemplateOrTemplatePattern();12981TemplateName CTN = ::getCommonTemplateName(Ctx, TX, TY);12982if (!CTN.getAsVoidPointer())12983return TemplateName();12984auto NExpX = X.getNumTemplateExpansions();12985assert(NExpX == Y.getNumTemplateExpansions());12986return TemplateArgument(CTN, NExpX);12987}12988default:12989// FIXME: Handle the other argument kinds.12990return X;12991}12992}1299312994static bool getCommonTemplateArguments(ASTContext &Ctx,12995SmallVectorImpl<TemplateArgument> &R,12996ArrayRef<TemplateArgument> Xs,12997ArrayRef<TemplateArgument> Ys) {12998if (Xs.size() != Ys.size())12999return true;13000R.resize(Xs.size());13001for (size_t I = 0; I < R.size(); ++I) {13002R[I] = getCommonTemplateArgument(Ctx, Xs[I], Ys[I]);13003if (R[I].isNull())13004return true;13005}13006return false;13007}1300813009static auto getCommonTemplateArguments(ASTContext &Ctx,13010ArrayRef<TemplateArgument> Xs,13011ArrayRef<TemplateArgument> Ys) {13012SmallVector<TemplateArgument, 8> R;13013bool Different = getCommonTemplateArguments(Ctx, R, Xs, Ys);13014assert(!Different);13015(void)Different;13016return R;13017}1301813019template <class T>13020static ElaboratedTypeKeyword getCommonTypeKeyword(const T *X, const T *Y) {13021return X->getKeyword() == Y->getKeyword() ? X->getKeyword()13022: ElaboratedTypeKeyword::None;13023}1302413025template <class T>13026static NestedNameSpecifier *getCommonNNS(ASTContext &Ctx, const T *X,13027const T *Y) {13028// FIXME: Try to keep the common NNS sugar.13029return X->getQualifier() == Y->getQualifier()13030? X->getQualifier()13031: Ctx.getCanonicalNestedNameSpecifier(X->getQualifier());13032}1303313034template <class T>13035static QualType getCommonElementType(ASTContext &Ctx, const T *X, const T *Y) {13036return Ctx.getCommonSugaredType(X->getElementType(), Y->getElementType());13037}1303813039template <class T>13040static QualType getCommonArrayElementType(ASTContext &Ctx, const T *X,13041Qualifiers &QX, const T *Y,13042Qualifiers &QY) {13043QualType EX = X->getElementType(), EY = Y->getElementType();13044QualType R = Ctx.getCommonSugaredType(EX, EY,13045/*Unqualified=*/true);13046Qualifiers RQ = R.getQualifiers();13047QX += EX.getQualifiers() - RQ;13048QY += EY.getQualifiers() - RQ;13049return R;13050}1305113052template <class T>13053static QualType getCommonPointeeType(ASTContext &Ctx, const T *X, const T *Y) {13054return Ctx.getCommonSugaredType(X->getPointeeType(), Y->getPointeeType());13055}1305613057template <class T> static auto *getCommonSizeExpr(ASTContext &Ctx, T *X, T *Y) {13058assert(Ctx.hasSameExpr(X->getSizeExpr(), Y->getSizeExpr()));13059return X->getSizeExpr();13060}1306113062static auto getCommonSizeModifier(const ArrayType *X, const ArrayType *Y) {13063assert(X->getSizeModifier() == Y->getSizeModifier());13064return X->getSizeModifier();13065}1306613067static auto getCommonIndexTypeCVRQualifiers(const ArrayType *X,13068const ArrayType *Y) {13069assert(X->getIndexTypeCVRQualifiers() == Y->getIndexTypeCVRQualifiers());13070return X->getIndexTypeCVRQualifiers();13071}1307213073// Merges two type lists such that the resulting vector will contain13074// each type (in a canonical sense) only once, in the order they appear13075// from X to Y. If they occur in both X and Y, the result will contain13076// the common sugared type between them.13077static void mergeTypeLists(ASTContext &Ctx, SmallVectorImpl<QualType> &Out,13078ArrayRef<QualType> X, ArrayRef<QualType> Y) {13079llvm::DenseMap<QualType, unsigned> Found;13080for (auto Ts : {X, Y}) {13081for (QualType T : Ts) {13082auto Res = Found.try_emplace(Ctx.getCanonicalType(T), Out.size());13083if (!Res.second) {13084QualType &U = Out[Res.first->second];13085U = Ctx.getCommonSugaredType(U, T);13086} else {13087Out.emplace_back(T);13088}13089}13090}13091}1309213093FunctionProtoType::ExceptionSpecInfo13094ASTContext::mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,13095FunctionProtoType::ExceptionSpecInfo ESI2,13096SmallVectorImpl<QualType> &ExceptionTypeStorage,13097bool AcceptDependent) {13098ExceptionSpecificationType EST1 = ESI1.Type, EST2 = ESI2.Type;1309913100// If either of them can throw anything, that is the result.13101for (auto I : {EST_None, EST_MSAny, EST_NoexceptFalse}) {13102if (EST1 == I)13103return ESI1;13104if (EST2 == I)13105return ESI2;13106}1310713108// If either of them is non-throwing, the result is the other.13109for (auto I :13110{EST_NoThrow, EST_DynamicNone, EST_BasicNoexcept, EST_NoexceptTrue}) {13111if (EST1 == I)13112return ESI2;13113if (EST2 == I)13114return ESI1;13115}1311613117// If we're left with value-dependent computed noexcept expressions, we're13118// stuck. Before C++17, we can just drop the exception specification entirely,13119// since it's not actually part of the canonical type. And this should never13120// happen in C++17, because it would mean we were computing the composite13121// pointer type of dependent types, which should never happen.13122if (EST1 == EST_DependentNoexcept || EST2 == EST_DependentNoexcept) {13123assert(AcceptDependent &&13124"computing composite pointer type of dependent types");13125return FunctionProtoType::ExceptionSpecInfo();13126}1312713128// Switch over the possibilities so that people adding new values know to13129// update this function.13130switch (EST1) {13131case EST_None:13132case EST_DynamicNone:13133case EST_MSAny:13134case EST_BasicNoexcept:13135case EST_DependentNoexcept:13136case EST_NoexceptFalse:13137case EST_NoexceptTrue:13138case EST_NoThrow:13139llvm_unreachable("These ESTs should be handled above");1314013141case EST_Dynamic: {13142// This is the fun case: both exception specifications are dynamic. Form13143// the union of the two lists.13144assert(EST2 == EST_Dynamic && "other cases should already be handled");13145mergeTypeLists(*this, ExceptionTypeStorage, ESI1.Exceptions,13146ESI2.Exceptions);13147FunctionProtoType::ExceptionSpecInfo Result(EST_Dynamic);13148Result.Exceptions = ExceptionTypeStorage;13149return Result;13150}1315113152case EST_Unevaluated:13153case EST_Uninstantiated:13154case EST_Unparsed:13155llvm_unreachable("shouldn't see unresolved exception specifications here");13156}1315713158llvm_unreachable("invalid ExceptionSpecificationType");13159}1316013161static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,13162Qualifiers &QX, const Type *Y,13163Qualifiers &QY) {13164Type::TypeClass TC = X->getTypeClass();13165assert(TC == Y->getTypeClass());13166switch (TC) {13167#define UNEXPECTED_TYPE(Class, Kind) \13168case Type::Class: \13169llvm_unreachable("Unexpected " Kind ": " #Class);1317013171#define NON_CANONICAL_TYPE(Class, Base) UNEXPECTED_TYPE(Class, "non-canonical")13172#define TYPE(Class, Base)13173#include "clang/AST/TypeNodes.inc"1317413175#define SUGAR_FREE_TYPE(Class) UNEXPECTED_TYPE(Class, "sugar-free")13176SUGAR_FREE_TYPE(Builtin)13177SUGAR_FREE_TYPE(DeducedTemplateSpecialization)13178SUGAR_FREE_TYPE(DependentBitInt)13179SUGAR_FREE_TYPE(Enum)13180SUGAR_FREE_TYPE(BitInt)13181SUGAR_FREE_TYPE(ObjCInterface)13182SUGAR_FREE_TYPE(Record)13183SUGAR_FREE_TYPE(SubstTemplateTypeParmPack)13184SUGAR_FREE_TYPE(UnresolvedUsing)13185#undef SUGAR_FREE_TYPE13186#define NON_UNIQUE_TYPE(Class) UNEXPECTED_TYPE(Class, "non-unique")13187NON_UNIQUE_TYPE(TypeOfExpr)13188NON_UNIQUE_TYPE(VariableArray)13189#undef NON_UNIQUE_TYPE1319013191UNEXPECTED_TYPE(TypeOf, "sugar")1319213193#undef UNEXPECTED_TYPE1319413195case Type::Auto: {13196const auto *AX = cast<AutoType>(X), *AY = cast<AutoType>(Y);13197assert(AX->getDeducedType().isNull());13198assert(AY->getDeducedType().isNull());13199assert(AX->getKeyword() == AY->getKeyword());13200assert(AX->isInstantiationDependentType() ==13201AY->isInstantiationDependentType());13202auto As = getCommonTemplateArguments(Ctx, AX->getTypeConstraintArguments(),13203AY->getTypeConstraintArguments());13204return Ctx.getAutoType(QualType(), AX->getKeyword(),13205AX->isInstantiationDependentType(),13206AX->containsUnexpandedParameterPack(),13207getCommonDeclChecked(AX->getTypeConstraintConcept(),13208AY->getTypeConstraintConcept()),13209As);13210}13211case Type::IncompleteArray: {13212const auto *AX = cast<IncompleteArrayType>(X),13213*AY = cast<IncompleteArrayType>(Y);13214return Ctx.getIncompleteArrayType(13215getCommonArrayElementType(Ctx, AX, QX, AY, QY),13216getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY));13217}13218case Type::DependentSizedArray: {13219const auto *AX = cast<DependentSizedArrayType>(X),13220*AY = cast<DependentSizedArrayType>(Y);13221return Ctx.getDependentSizedArrayType(13222getCommonArrayElementType(Ctx, AX, QX, AY, QY),13223getCommonSizeExpr(Ctx, AX, AY), getCommonSizeModifier(AX, AY),13224getCommonIndexTypeCVRQualifiers(AX, AY),13225AX->getBracketsRange() == AY->getBracketsRange()13226? AX->getBracketsRange()13227: SourceRange());13228}13229case Type::ConstantArray: {13230const auto *AX = cast<ConstantArrayType>(X),13231*AY = cast<ConstantArrayType>(Y);13232assert(AX->getSize() == AY->getSize());13233const Expr *SizeExpr = Ctx.hasSameExpr(AX->getSizeExpr(), AY->getSizeExpr())13234? AX->getSizeExpr()13235: nullptr;13236return Ctx.getConstantArrayType(13237getCommonArrayElementType(Ctx, AX, QX, AY, QY), AX->getSize(), SizeExpr,13238getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY));13239}13240case Type::ArrayParameter: {13241const auto *AX = cast<ArrayParameterType>(X),13242*AY = cast<ArrayParameterType>(Y);13243assert(AX->getSize() == AY->getSize());13244const Expr *SizeExpr = Ctx.hasSameExpr(AX->getSizeExpr(), AY->getSizeExpr())13245? AX->getSizeExpr()13246: nullptr;13247auto ArrayTy = Ctx.getConstantArrayType(13248getCommonArrayElementType(Ctx, AX, QX, AY, QY), AX->getSize(), SizeExpr,13249getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY));13250return Ctx.getArrayParameterType(ArrayTy);13251}13252case Type::Atomic: {13253const auto *AX = cast<AtomicType>(X), *AY = cast<AtomicType>(Y);13254return Ctx.getAtomicType(13255Ctx.getCommonSugaredType(AX->getValueType(), AY->getValueType()));13256}13257case Type::Complex: {13258const auto *CX = cast<ComplexType>(X), *CY = cast<ComplexType>(Y);13259return Ctx.getComplexType(getCommonArrayElementType(Ctx, CX, QX, CY, QY));13260}13261case Type::Pointer: {13262const auto *PX = cast<PointerType>(X), *PY = cast<PointerType>(Y);13263return Ctx.getPointerType(getCommonPointeeType(Ctx, PX, PY));13264}13265case Type::BlockPointer: {13266const auto *PX = cast<BlockPointerType>(X), *PY = cast<BlockPointerType>(Y);13267return Ctx.getBlockPointerType(getCommonPointeeType(Ctx, PX, PY));13268}13269case Type::ObjCObjectPointer: {13270const auto *PX = cast<ObjCObjectPointerType>(X),13271*PY = cast<ObjCObjectPointerType>(Y);13272return Ctx.getObjCObjectPointerType(getCommonPointeeType(Ctx, PX, PY));13273}13274case Type::MemberPointer: {13275const auto *PX = cast<MemberPointerType>(X),13276*PY = cast<MemberPointerType>(Y);13277return Ctx.getMemberPointerType(13278getCommonPointeeType(Ctx, PX, PY),13279Ctx.getCommonSugaredType(QualType(PX->getClass(), 0),13280QualType(PY->getClass(), 0))13281.getTypePtr());13282}13283case Type::LValueReference: {13284const auto *PX = cast<LValueReferenceType>(X),13285*PY = cast<LValueReferenceType>(Y);13286// FIXME: Preserve PointeeTypeAsWritten.13287return Ctx.getLValueReferenceType(getCommonPointeeType(Ctx, PX, PY),13288PX->isSpelledAsLValue() ||13289PY->isSpelledAsLValue());13290}13291case Type::RValueReference: {13292const auto *PX = cast<RValueReferenceType>(X),13293*PY = cast<RValueReferenceType>(Y);13294// FIXME: Preserve PointeeTypeAsWritten.13295return Ctx.getRValueReferenceType(getCommonPointeeType(Ctx, PX, PY));13296}13297case Type::DependentAddressSpace: {13298const auto *PX = cast<DependentAddressSpaceType>(X),13299*PY = cast<DependentAddressSpaceType>(Y);13300assert(Ctx.hasSameExpr(PX->getAddrSpaceExpr(), PY->getAddrSpaceExpr()));13301return Ctx.getDependentAddressSpaceType(getCommonPointeeType(Ctx, PX, PY),13302PX->getAddrSpaceExpr(),13303getCommonAttrLoc(PX, PY));13304}13305case Type::FunctionNoProto: {13306const auto *FX = cast<FunctionNoProtoType>(X),13307*FY = cast<FunctionNoProtoType>(Y);13308assert(FX->getExtInfo() == FY->getExtInfo());13309return Ctx.getFunctionNoProtoType(13310Ctx.getCommonSugaredType(FX->getReturnType(), FY->getReturnType()),13311FX->getExtInfo());13312}13313case Type::FunctionProto: {13314const auto *FX = cast<FunctionProtoType>(X),13315*FY = cast<FunctionProtoType>(Y);13316FunctionProtoType::ExtProtoInfo EPIX = FX->getExtProtoInfo(),13317EPIY = FY->getExtProtoInfo();13318assert(EPIX.ExtInfo == EPIY.ExtInfo);13319assert(EPIX.ExtParameterInfos == EPIY.ExtParameterInfos);13320assert(EPIX.RefQualifier == EPIY.RefQualifier);13321assert(EPIX.TypeQuals == EPIY.TypeQuals);13322assert(EPIX.Variadic == EPIY.Variadic);1332313324// FIXME: Can we handle an empty EllipsisLoc?13325// Use emtpy EllipsisLoc if X and Y differ.1332613327EPIX.HasTrailingReturn = EPIX.HasTrailingReturn && EPIY.HasTrailingReturn;1332813329QualType R =13330Ctx.getCommonSugaredType(FX->getReturnType(), FY->getReturnType());13331auto P = getCommonTypes(Ctx, FX->param_types(), FY->param_types(),13332/*Unqualified=*/true);1333313334SmallVector<QualType, 8> Exceptions;13335EPIX.ExceptionSpec = Ctx.mergeExceptionSpecs(13336EPIX.ExceptionSpec, EPIY.ExceptionSpec, Exceptions, true);13337return Ctx.getFunctionType(R, P, EPIX);13338}13339case Type::ObjCObject: {13340const auto *OX = cast<ObjCObjectType>(X), *OY = cast<ObjCObjectType>(Y);13341assert(13342std::equal(OX->getProtocols().begin(), OX->getProtocols().end(),13343OY->getProtocols().begin(), OY->getProtocols().end(),13344[](const ObjCProtocolDecl *P0, const ObjCProtocolDecl *P1) {13345return P0->getCanonicalDecl() == P1->getCanonicalDecl();13346}) &&13347"protocol lists must be the same");13348auto TAs = getCommonTypes(Ctx, OX->getTypeArgsAsWritten(),13349OY->getTypeArgsAsWritten());13350return Ctx.getObjCObjectType(13351Ctx.getCommonSugaredType(OX->getBaseType(), OY->getBaseType()), TAs,13352OX->getProtocols(),13353OX->isKindOfTypeAsWritten() && OY->isKindOfTypeAsWritten());13354}13355case Type::ConstantMatrix: {13356const auto *MX = cast<ConstantMatrixType>(X),13357*MY = cast<ConstantMatrixType>(Y);13358assert(MX->getNumRows() == MY->getNumRows());13359assert(MX->getNumColumns() == MY->getNumColumns());13360return Ctx.getConstantMatrixType(getCommonElementType(Ctx, MX, MY),13361MX->getNumRows(), MX->getNumColumns());13362}13363case Type::DependentSizedMatrix: {13364const auto *MX = cast<DependentSizedMatrixType>(X),13365*MY = cast<DependentSizedMatrixType>(Y);13366assert(Ctx.hasSameExpr(MX->getRowExpr(), MY->getRowExpr()));13367assert(Ctx.hasSameExpr(MX->getColumnExpr(), MY->getColumnExpr()));13368return Ctx.getDependentSizedMatrixType(13369getCommonElementType(Ctx, MX, MY), MX->getRowExpr(),13370MX->getColumnExpr(), getCommonAttrLoc(MX, MY));13371}13372case Type::Vector: {13373const auto *VX = cast<VectorType>(X), *VY = cast<VectorType>(Y);13374assert(VX->getNumElements() == VY->getNumElements());13375assert(VX->getVectorKind() == VY->getVectorKind());13376return Ctx.getVectorType(getCommonElementType(Ctx, VX, VY),13377VX->getNumElements(), VX->getVectorKind());13378}13379case Type::ExtVector: {13380const auto *VX = cast<ExtVectorType>(X), *VY = cast<ExtVectorType>(Y);13381assert(VX->getNumElements() == VY->getNumElements());13382return Ctx.getExtVectorType(getCommonElementType(Ctx, VX, VY),13383VX->getNumElements());13384}13385case Type::DependentSizedExtVector: {13386const auto *VX = cast<DependentSizedExtVectorType>(X),13387*VY = cast<DependentSizedExtVectorType>(Y);13388return Ctx.getDependentSizedExtVectorType(getCommonElementType(Ctx, VX, VY),13389getCommonSizeExpr(Ctx, VX, VY),13390getCommonAttrLoc(VX, VY));13391}13392case Type::DependentVector: {13393const auto *VX = cast<DependentVectorType>(X),13394*VY = cast<DependentVectorType>(Y);13395assert(VX->getVectorKind() == VY->getVectorKind());13396return Ctx.getDependentVectorType(13397getCommonElementType(Ctx, VX, VY), getCommonSizeExpr(Ctx, VX, VY),13398getCommonAttrLoc(VX, VY), VX->getVectorKind());13399}13400case Type::InjectedClassName: {13401const auto *IX = cast<InjectedClassNameType>(X),13402*IY = cast<InjectedClassNameType>(Y);13403return Ctx.getInjectedClassNameType(13404getCommonDeclChecked(IX->getDecl(), IY->getDecl()),13405Ctx.getCommonSugaredType(IX->getInjectedSpecializationType(),13406IY->getInjectedSpecializationType()));13407}13408case Type::TemplateSpecialization: {13409const auto *TX = cast<TemplateSpecializationType>(X),13410*TY = cast<TemplateSpecializationType>(Y);13411auto As = getCommonTemplateArguments(Ctx, TX->template_arguments(),13412TY->template_arguments());13413return Ctx.getTemplateSpecializationType(13414::getCommonTemplateNameChecked(Ctx, TX->getTemplateName(),13415TY->getTemplateName()),13416As, X->getCanonicalTypeInternal());13417}13418case Type::Decltype: {13419const auto *DX = cast<DecltypeType>(X);13420[[maybe_unused]] const auto *DY = cast<DecltypeType>(Y);13421assert(DX->isDependentType());13422assert(DY->isDependentType());13423assert(Ctx.hasSameExpr(DX->getUnderlyingExpr(), DY->getUnderlyingExpr()));13424// As Decltype is not uniqued, building a common type would be wasteful.13425return QualType(DX, 0);13426}13427case Type::PackIndexing: {13428const auto *DX = cast<PackIndexingType>(X);13429[[maybe_unused]] const auto *DY = cast<PackIndexingType>(Y);13430assert(DX->isDependentType());13431assert(DY->isDependentType());13432assert(Ctx.hasSameExpr(DX->getIndexExpr(), DY->getIndexExpr()));13433return QualType(DX, 0);13434}13435case Type::DependentName: {13436const auto *NX = cast<DependentNameType>(X),13437*NY = cast<DependentNameType>(Y);13438assert(NX->getIdentifier() == NY->getIdentifier());13439return Ctx.getDependentNameType(13440getCommonTypeKeyword(NX, NY), getCommonNNS(Ctx, NX, NY),13441NX->getIdentifier(), NX->getCanonicalTypeInternal());13442}13443case Type::DependentTemplateSpecialization: {13444const auto *TX = cast<DependentTemplateSpecializationType>(X),13445*TY = cast<DependentTemplateSpecializationType>(Y);13446assert(TX->getIdentifier() == TY->getIdentifier());13447auto As = getCommonTemplateArguments(Ctx, TX->template_arguments(),13448TY->template_arguments());13449return Ctx.getDependentTemplateSpecializationType(13450getCommonTypeKeyword(TX, TY), getCommonNNS(Ctx, TX, TY),13451TX->getIdentifier(), As);13452}13453case Type::UnaryTransform: {13454const auto *TX = cast<UnaryTransformType>(X),13455*TY = cast<UnaryTransformType>(Y);13456assert(TX->getUTTKind() == TY->getUTTKind());13457return Ctx.getUnaryTransformType(13458Ctx.getCommonSugaredType(TX->getBaseType(), TY->getBaseType()),13459Ctx.getCommonSugaredType(TX->getUnderlyingType(),13460TY->getUnderlyingType()),13461TX->getUTTKind());13462}13463case Type::PackExpansion: {13464const auto *PX = cast<PackExpansionType>(X),13465*PY = cast<PackExpansionType>(Y);13466assert(PX->getNumExpansions() == PY->getNumExpansions());13467return Ctx.getPackExpansionType(13468Ctx.getCommonSugaredType(PX->getPattern(), PY->getPattern()),13469PX->getNumExpansions(), false);13470}13471case Type::Pipe: {13472const auto *PX = cast<PipeType>(X), *PY = cast<PipeType>(Y);13473assert(PX->isReadOnly() == PY->isReadOnly());13474auto MP = PX->isReadOnly() ? &ASTContext::getReadPipeType13475: &ASTContext::getWritePipeType;13476return (Ctx.*MP)(getCommonElementType(Ctx, PX, PY));13477}13478case Type::TemplateTypeParm: {13479const auto *TX = cast<TemplateTypeParmType>(X),13480*TY = cast<TemplateTypeParmType>(Y);13481assert(TX->getDepth() == TY->getDepth());13482assert(TX->getIndex() == TY->getIndex());13483assert(TX->isParameterPack() == TY->isParameterPack());13484return Ctx.getTemplateTypeParmType(13485TX->getDepth(), TX->getIndex(), TX->isParameterPack(),13486getCommonDecl(TX->getDecl(), TY->getDecl()));13487}13488}13489llvm_unreachable("Unknown Type Class");13490}1349113492static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,13493const Type *Y,13494SplitQualType Underlying) {13495Type::TypeClass TC = X->getTypeClass();13496if (TC != Y->getTypeClass())13497return QualType();13498switch (TC) {13499#define UNEXPECTED_TYPE(Class, Kind) \13500case Type::Class: \13501llvm_unreachable("Unexpected " Kind ": " #Class);13502#define TYPE(Class, Base)13503#define DEPENDENT_TYPE(Class, Base) UNEXPECTED_TYPE(Class, "dependent")13504#include "clang/AST/TypeNodes.inc"1350513506#define CANONICAL_TYPE(Class) UNEXPECTED_TYPE(Class, "canonical")13507CANONICAL_TYPE(Atomic)13508CANONICAL_TYPE(BitInt)13509CANONICAL_TYPE(BlockPointer)13510CANONICAL_TYPE(Builtin)13511CANONICAL_TYPE(Complex)13512CANONICAL_TYPE(ConstantArray)13513CANONICAL_TYPE(ArrayParameter)13514CANONICAL_TYPE(ConstantMatrix)13515CANONICAL_TYPE(Enum)13516CANONICAL_TYPE(ExtVector)13517CANONICAL_TYPE(FunctionNoProto)13518CANONICAL_TYPE(FunctionProto)13519CANONICAL_TYPE(IncompleteArray)13520CANONICAL_TYPE(LValueReference)13521CANONICAL_TYPE(MemberPointer)13522CANONICAL_TYPE(ObjCInterface)13523CANONICAL_TYPE(ObjCObject)13524CANONICAL_TYPE(ObjCObjectPointer)13525CANONICAL_TYPE(Pipe)13526CANONICAL_TYPE(Pointer)13527CANONICAL_TYPE(Record)13528CANONICAL_TYPE(RValueReference)13529CANONICAL_TYPE(VariableArray)13530CANONICAL_TYPE(Vector)13531#undef CANONICAL_TYPE1353213533#undef UNEXPECTED_TYPE1353413535case Type::Adjusted: {13536const auto *AX = cast<AdjustedType>(X), *AY = cast<AdjustedType>(Y);13537QualType OX = AX->getOriginalType(), OY = AY->getOriginalType();13538if (!Ctx.hasSameType(OX, OY))13539return QualType();13540// FIXME: It's inefficient to have to unify the original types.13541return Ctx.getAdjustedType(Ctx.getCommonSugaredType(OX, OY),13542Ctx.getQualifiedType(Underlying));13543}13544case Type::Decayed: {13545const auto *DX = cast<DecayedType>(X), *DY = cast<DecayedType>(Y);13546QualType OX = DX->getOriginalType(), OY = DY->getOriginalType();13547if (!Ctx.hasSameType(OX, OY))13548return QualType();13549// FIXME: It's inefficient to have to unify the original types.13550return Ctx.getDecayedType(Ctx.getCommonSugaredType(OX, OY),13551Ctx.getQualifiedType(Underlying));13552}13553case Type::Attributed: {13554const auto *AX = cast<AttributedType>(X), *AY = cast<AttributedType>(Y);13555AttributedType::Kind Kind = AX->getAttrKind();13556if (Kind != AY->getAttrKind())13557return QualType();13558QualType MX = AX->getModifiedType(), MY = AY->getModifiedType();13559if (!Ctx.hasSameType(MX, MY))13560return QualType();13561// FIXME: It's inefficient to have to unify the modified types.13562return Ctx.getAttributedType(Kind, Ctx.getCommonSugaredType(MX, MY),13563Ctx.getQualifiedType(Underlying));13564}13565case Type::BTFTagAttributed: {13566const auto *BX = cast<BTFTagAttributedType>(X);13567const BTFTypeTagAttr *AX = BX->getAttr();13568// The attribute is not uniqued, so just compare the tag.13569if (AX->getBTFTypeTag() !=13570cast<BTFTagAttributedType>(Y)->getAttr()->getBTFTypeTag())13571return QualType();13572return Ctx.getBTFTagAttributedType(AX, Ctx.getQualifiedType(Underlying));13573}13574case Type::Auto: {13575const auto *AX = cast<AutoType>(X), *AY = cast<AutoType>(Y);1357613577AutoTypeKeyword KW = AX->getKeyword();13578if (KW != AY->getKeyword())13579return QualType();1358013581ConceptDecl *CD = ::getCommonDecl(AX->getTypeConstraintConcept(),13582AY->getTypeConstraintConcept());13583SmallVector<TemplateArgument, 8> As;13584if (CD &&13585getCommonTemplateArguments(Ctx, As, AX->getTypeConstraintArguments(),13586AY->getTypeConstraintArguments())) {13587CD = nullptr; // The arguments differ, so make it unconstrained.13588As.clear();13589}1359013591// Both auto types can't be dependent, otherwise they wouldn't have been13592// sugar. This implies they can't contain unexpanded packs either.13593return Ctx.getAutoType(Ctx.getQualifiedType(Underlying), AX->getKeyword(),13594/*IsDependent=*/false, /*IsPack=*/false, CD, As);13595}13596case Type::PackIndexing:13597case Type::Decltype:13598return QualType();13599case Type::DeducedTemplateSpecialization:13600// FIXME: Try to merge these.13601return QualType();1360213603case Type::Elaborated: {13604const auto *EX = cast<ElaboratedType>(X), *EY = cast<ElaboratedType>(Y);13605return Ctx.getElaboratedType(13606::getCommonTypeKeyword(EX, EY), ::getCommonNNS(Ctx, EX, EY),13607Ctx.getQualifiedType(Underlying),13608::getCommonDecl(EX->getOwnedTagDecl(), EY->getOwnedTagDecl()));13609}13610case Type::MacroQualified: {13611const auto *MX = cast<MacroQualifiedType>(X),13612*MY = cast<MacroQualifiedType>(Y);13613const IdentifierInfo *IX = MX->getMacroIdentifier();13614if (IX != MY->getMacroIdentifier())13615return QualType();13616return Ctx.getMacroQualifiedType(Ctx.getQualifiedType(Underlying), IX);13617}13618case Type::SubstTemplateTypeParm: {13619const auto *SX = cast<SubstTemplateTypeParmType>(X),13620*SY = cast<SubstTemplateTypeParmType>(Y);13621Decl *CD =13622::getCommonDecl(SX->getAssociatedDecl(), SY->getAssociatedDecl());13623if (!CD)13624return QualType();13625unsigned Index = SX->getIndex();13626if (Index != SY->getIndex())13627return QualType();13628auto PackIndex = SX->getPackIndex();13629if (PackIndex != SY->getPackIndex())13630return QualType();13631return Ctx.getSubstTemplateTypeParmType(Ctx.getQualifiedType(Underlying),13632CD, Index, PackIndex);13633}13634case Type::ObjCTypeParam:13635// FIXME: Try to merge these.13636return QualType();13637case Type::Paren:13638return Ctx.getParenType(Ctx.getQualifiedType(Underlying));1363913640case Type::TemplateSpecialization: {13641const auto *TX = cast<TemplateSpecializationType>(X),13642*TY = cast<TemplateSpecializationType>(Y);13643TemplateName CTN = ::getCommonTemplateName(Ctx, TX->getTemplateName(),13644TY->getTemplateName());13645if (!CTN.getAsVoidPointer())13646return QualType();13647SmallVector<TemplateArgument, 8> Args;13648if (getCommonTemplateArguments(Ctx, Args, TX->template_arguments(),13649TY->template_arguments()))13650return QualType();13651return Ctx.getTemplateSpecializationType(CTN, Args,13652Ctx.getQualifiedType(Underlying));13653}13654case Type::Typedef: {13655const auto *TX = cast<TypedefType>(X), *TY = cast<TypedefType>(Y);13656const TypedefNameDecl *CD = ::getCommonDecl(TX->getDecl(), TY->getDecl());13657if (!CD)13658return QualType();13659return Ctx.getTypedefType(CD, Ctx.getQualifiedType(Underlying));13660}13661case Type::TypeOf: {13662// The common sugar between two typeof expressions, where one is13663// potentially a typeof_unqual and the other is not, we unify to the13664// qualified type as that retains the most information along with the type.13665// We only return a typeof_unqual type when both types are unqual types.13666TypeOfKind Kind = TypeOfKind::Qualified;13667if (cast<TypeOfType>(X)->getKind() == cast<TypeOfType>(Y)->getKind() &&13668cast<TypeOfType>(X)->getKind() == TypeOfKind::Unqualified)13669Kind = TypeOfKind::Unqualified;13670return Ctx.getTypeOfType(Ctx.getQualifiedType(Underlying), Kind);13671}13672case Type::TypeOfExpr:13673return QualType();1367413675case Type::UnaryTransform: {13676const auto *UX = cast<UnaryTransformType>(X),13677*UY = cast<UnaryTransformType>(Y);13678UnaryTransformType::UTTKind KX = UX->getUTTKind();13679if (KX != UY->getUTTKind())13680return QualType();13681QualType BX = UX->getBaseType(), BY = UY->getBaseType();13682if (!Ctx.hasSameType(BX, BY))13683return QualType();13684// FIXME: It's inefficient to have to unify the base types.13685return Ctx.getUnaryTransformType(Ctx.getCommonSugaredType(BX, BY),13686Ctx.getQualifiedType(Underlying), KX);13687}13688case Type::Using: {13689const auto *UX = cast<UsingType>(X), *UY = cast<UsingType>(Y);13690const UsingShadowDecl *CD =13691::getCommonDecl(UX->getFoundDecl(), UY->getFoundDecl());13692if (!CD)13693return QualType();13694return Ctx.getUsingType(CD, Ctx.getQualifiedType(Underlying));13695}13696case Type::CountAttributed: {13697const auto *DX = cast<CountAttributedType>(X),13698*DY = cast<CountAttributedType>(Y);13699if (DX->isCountInBytes() != DY->isCountInBytes())13700return QualType();13701if (DX->isOrNull() != DY->isOrNull())13702return QualType();13703Expr *CEX = DX->getCountExpr();13704Expr *CEY = DY->getCountExpr();13705llvm::ArrayRef<clang::TypeCoupledDeclRefInfo> CDX = DX->getCoupledDecls();13706if (Ctx.hasSameExpr(CEX, CEY))13707return Ctx.getCountAttributedType(Ctx.getQualifiedType(Underlying), CEX,13708DX->isCountInBytes(), DX->isOrNull(),13709CDX);13710if (!CEX->isIntegerConstantExpr(Ctx) || !CEY->isIntegerConstantExpr(Ctx))13711return QualType();13712// Two declarations with the same integer constant may still differ in their13713// expression pointers, so we need to evaluate them.13714llvm::APSInt VX = *CEX->getIntegerConstantExpr(Ctx);13715llvm::APSInt VY = *CEY->getIntegerConstantExpr(Ctx);13716if (VX != VY)13717return QualType();13718return Ctx.getCountAttributedType(Ctx.getQualifiedType(Underlying), CEX,13719DX->isCountInBytes(), DX->isOrNull(),13720CDX);13721}13722}13723llvm_unreachable("Unhandled Type Class");13724}1372513726static auto unwrapSugar(SplitQualType &T, Qualifiers &QTotal) {13727SmallVector<SplitQualType, 8> R;13728while (true) {13729QTotal.addConsistentQualifiers(T.Quals);13730QualType NT = T.Ty->getLocallyUnqualifiedSingleStepDesugaredType();13731if (NT == QualType(T.Ty, 0))13732break;13733R.push_back(T);13734T = NT.split();13735}13736return R;13737}1373813739QualType ASTContext::getCommonSugaredType(QualType X, QualType Y,13740bool Unqualified) {13741assert(Unqualified ? hasSameUnqualifiedType(X, Y) : hasSameType(X, Y));13742if (X == Y)13743return X;13744if (!Unqualified) {13745if (X.isCanonical())13746return X;13747if (Y.isCanonical())13748return Y;13749}1375013751SplitQualType SX = X.split(), SY = Y.split();13752Qualifiers QX, QY;13753// Desugar SX and SY, setting the sugar and qualifiers aside into Xs and Ys,13754// until we reach their underlying "canonical nodes". Note these are not13755// necessarily canonical types, as they may still have sugared properties.13756// QX and QY will store the sum of all qualifiers in Xs and Ys respectively.13757auto Xs = ::unwrapSugar(SX, QX), Ys = ::unwrapSugar(SY, QY);13758if (SX.Ty != SY.Ty) {13759// The canonical nodes differ. Build a common canonical node out of the two,13760// unifying their sugar. This may recurse back here.13761SX.Ty =13762::getCommonNonSugarTypeNode(*this, SX.Ty, QX, SY.Ty, QY).getTypePtr();13763} else {13764// The canonical nodes were identical: We may have desugared too much.13765// Add any common sugar back in.13766while (!Xs.empty() && !Ys.empty() && Xs.back().Ty == Ys.back().Ty) {13767QX -= SX.Quals;13768QY -= SY.Quals;13769SX = Xs.pop_back_val();13770SY = Ys.pop_back_val();13771}13772}13773if (Unqualified)13774QX = Qualifiers::removeCommonQualifiers(QX, QY);13775else13776assert(QX == QY);1377713778// Even though the remaining sugar nodes in Xs and Ys differ, some may be13779// related. Walk up these nodes, unifying them and adding the result.13780while (!Xs.empty() && !Ys.empty()) {13781auto Underlying = SplitQualType(13782SX.Ty, Qualifiers::removeCommonQualifiers(SX.Quals, SY.Quals));13783SX = Xs.pop_back_val();13784SY = Ys.pop_back_val();13785SX.Ty = ::getCommonSugarTypeNode(*this, SX.Ty, SY.Ty, Underlying)13786.getTypePtrOrNull();13787// Stop at the first pair which is unrelated.13788if (!SX.Ty) {13789SX.Ty = Underlying.Ty;13790break;13791}13792QX -= Underlying.Quals;13793};1379413795// Add back the missing accumulated qualifiers, which were stripped off13796// with the sugar nodes we could not unify.13797QualType R = getQualifiedType(SX.Ty, QX);13798assert(Unqualified ? hasSameUnqualifiedType(R, X) : hasSameType(R, X));13799return R;13800}1380113802QualType ASTContext::getCorrespondingUnsaturatedType(QualType Ty) const {13803assert(Ty->isFixedPointType());1380413805if (Ty->isUnsaturatedFixedPointType())13806return Ty;1380713808switch (Ty->castAs<BuiltinType>()->getKind()) {13809default:13810llvm_unreachable("Not a saturated fixed point type!");13811case BuiltinType::SatShortAccum:13812return ShortAccumTy;13813case BuiltinType::SatAccum:13814return AccumTy;13815case BuiltinType::SatLongAccum:13816return LongAccumTy;13817case BuiltinType::SatUShortAccum:13818return UnsignedShortAccumTy;13819case BuiltinType::SatUAccum:13820return UnsignedAccumTy;13821case BuiltinType::SatULongAccum:13822return UnsignedLongAccumTy;13823case BuiltinType::SatShortFract:13824return ShortFractTy;13825case BuiltinType::SatFract:13826return FractTy;13827case BuiltinType::SatLongFract:13828return LongFractTy;13829case BuiltinType::SatUShortFract:13830return UnsignedShortFractTy;13831case BuiltinType::SatUFract:13832return UnsignedFractTy;13833case BuiltinType::SatULongFract:13834return UnsignedLongFractTy;13835}13836}1383713838QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const {13839assert(Ty->isFixedPointType());1384013841if (Ty->isSaturatedFixedPointType()) return Ty;1384213843switch (Ty->castAs<BuiltinType>()->getKind()) {13844default:13845llvm_unreachable("Not a fixed point type!");13846case BuiltinType::ShortAccum:13847return SatShortAccumTy;13848case BuiltinType::Accum:13849return SatAccumTy;13850case BuiltinType::LongAccum:13851return SatLongAccumTy;13852case BuiltinType::UShortAccum:13853return SatUnsignedShortAccumTy;13854case BuiltinType::UAccum:13855return SatUnsignedAccumTy;13856case BuiltinType::ULongAccum:13857return SatUnsignedLongAccumTy;13858case BuiltinType::ShortFract:13859return SatShortFractTy;13860case BuiltinType::Fract:13861return SatFractTy;13862case BuiltinType::LongFract:13863return SatLongFractTy;13864case BuiltinType::UShortFract:13865return SatUnsignedShortFractTy;13866case BuiltinType::UFract:13867return SatUnsignedFractTy;13868case BuiltinType::ULongFract:13869return SatUnsignedLongFractTy;13870}13871}1387213873LangAS ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const {13874if (LangOpts.OpenCL)13875return getTargetInfo().getOpenCLBuiltinAddressSpace(AS);1387613877if (LangOpts.CUDA)13878return getTargetInfo().getCUDABuiltinAddressSpace(AS);1387913880return getLangASFromTargetAS(AS);13881}1388213883// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that13884// doesn't include ASTContext.h13885template13886clang::LazyGenerationalUpdatePtr<13887const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType13888clang::LazyGenerationalUpdatePtr<13889const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(13890const clang::ASTContext &Ctx, Decl *Value);1389113892unsigned char ASTContext::getFixedPointScale(QualType Ty) const {13893assert(Ty->isFixedPointType());1389413895const TargetInfo &Target = getTargetInfo();13896switch (Ty->castAs<BuiltinType>()->getKind()) {13897default:13898llvm_unreachable("Not a fixed point type!");13899case BuiltinType::ShortAccum:13900case BuiltinType::SatShortAccum:13901return Target.getShortAccumScale();13902case BuiltinType::Accum:13903case BuiltinType::SatAccum:13904return Target.getAccumScale();13905case BuiltinType::LongAccum:13906case BuiltinType::SatLongAccum:13907return Target.getLongAccumScale();13908case BuiltinType::UShortAccum:13909case BuiltinType::SatUShortAccum:13910return Target.getUnsignedShortAccumScale();13911case BuiltinType::UAccum:13912case BuiltinType::SatUAccum:13913return Target.getUnsignedAccumScale();13914case BuiltinType::ULongAccum:13915case BuiltinType::SatULongAccum:13916return Target.getUnsignedLongAccumScale();13917case BuiltinType::ShortFract:13918case BuiltinType::SatShortFract:13919return Target.getShortFractScale();13920case BuiltinType::Fract:13921case BuiltinType::SatFract:13922return Target.getFractScale();13923case BuiltinType::LongFract:13924case BuiltinType::SatLongFract:13925return Target.getLongFractScale();13926case BuiltinType::UShortFract:13927case BuiltinType::SatUShortFract:13928return Target.getUnsignedShortFractScale();13929case BuiltinType::UFract:13930case BuiltinType::SatUFract:13931return Target.getUnsignedFractScale();13932case BuiltinType::ULongFract:13933case BuiltinType::SatULongFract:13934return Target.getUnsignedLongFractScale();13935}13936}1393713938unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {13939assert(Ty->isFixedPointType());1394013941const TargetInfo &Target = getTargetInfo();13942switch (Ty->castAs<BuiltinType>()->getKind()) {13943default:13944llvm_unreachable("Not a fixed point type!");13945case BuiltinType::ShortAccum:13946case BuiltinType::SatShortAccum:13947return Target.getShortAccumIBits();13948case BuiltinType::Accum:13949case BuiltinType::SatAccum:13950return Target.getAccumIBits();13951case BuiltinType::LongAccum:13952case BuiltinType::SatLongAccum:13953return Target.getLongAccumIBits();13954case BuiltinType::UShortAccum:13955case BuiltinType::SatUShortAccum:13956return Target.getUnsignedShortAccumIBits();13957case BuiltinType::UAccum:13958case BuiltinType::SatUAccum:13959return Target.getUnsignedAccumIBits();13960case BuiltinType::ULongAccum:13961case BuiltinType::SatULongAccum:13962return Target.getUnsignedLongAccumIBits();13963case BuiltinType::ShortFract:13964case BuiltinType::SatShortFract:13965case BuiltinType::Fract:13966case BuiltinType::SatFract:13967case BuiltinType::LongFract:13968case BuiltinType::SatLongFract:13969case BuiltinType::UShortFract:13970case BuiltinType::SatUShortFract:13971case BuiltinType::UFract:13972case BuiltinType::SatUFract:13973case BuiltinType::ULongFract:13974case BuiltinType::SatULongFract:13975return 0;13976}13977}1397813979llvm::FixedPointSemantics13980ASTContext::getFixedPointSemantics(QualType Ty) const {13981assert((Ty->isFixedPointType() || Ty->isIntegerType()) &&13982"Can only get the fixed point semantics for a "13983"fixed point or integer type.");13984if (Ty->isIntegerType())13985return llvm::FixedPointSemantics::GetIntegerSemantics(13986getIntWidth(Ty), Ty->isSignedIntegerType());1398713988bool isSigned = Ty->isSignedFixedPointType();13989return llvm::FixedPointSemantics(13990static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned,13991Ty->isSaturatedFixedPointType(),13992!isSigned && getTargetInfo().doUnsignedFixedPointTypesHavePadding());13993}1399413995llvm::APFixedPoint ASTContext::getFixedPointMax(QualType Ty) const {13996assert(Ty->isFixedPointType());13997return llvm::APFixedPoint::getMax(getFixedPointSemantics(Ty));13998}1399914000llvm::APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {14001assert(Ty->isFixedPointType());14002return llvm::APFixedPoint::getMin(getFixedPointSemantics(Ty));14003}1400414005QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {14006assert(Ty->isUnsignedFixedPointType() &&14007"Expected unsigned fixed point type");1400814009switch (Ty->castAs<BuiltinType>()->getKind()) {14010case BuiltinType::UShortAccum:14011return ShortAccumTy;14012case BuiltinType::UAccum:14013return AccumTy;14014case BuiltinType::ULongAccum:14015return LongAccumTy;14016case BuiltinType::SatUShortAccum:14017return SatShortAccumTy;14018case BuiltinType::SatUAccum:14019return SatAccumTy;14020case BuiltinType::SatULongAccum:14021return SatLongAccumTy;14022case BuiltinType::UShortFract:14023return ShortFractTy;14024case BuiltinType::UFract:14025return FractTy;14026case BuiltinType::ULongFract:14027return LongFractTy;14028case BuiltinType::SatUShortFract:14029return SatShortFractTy;14030case BuiltinType::SatUFract:14031return SatFractTy;14032case BuiltinType::SatULongFract:14033return SatLongFractTy;14034default:14035llvm_unreachable("Unexpected unsigned fixed point type");14036}14037}1403814039// Given a list of FMV features, return a concatenated list of the14040// corresponding backend features (which may contain duplicates).14041static std::vector<std::string> getFMVBackendFeaturesFor(14042const llvm::SmallVectorImpl<StringRef> &FMVFeatStrings) {14043std::vector<std::string> BackendFeats;14044for (StringRef F : FMVFeatStrings)14045if (auto FMVExt = llvm::AArch64::parseFMVExtension(F))14046for (StringRef F : FMVExt->getImpliedFeatures())14047BackendFeats.push_back(F.str());14048return BackendFeats;14049}1405014051ParsedTargetAttr14052ASTContext::filterFunctionTargetAttrs(const TargetAttr *TD) const {14053assert(TD != nullptr);14054ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(TD->getFeaturesStr());1405514056llvm::erase_if(ParsedAttr.Features, [&](const std::string &Feat) {14057return !Target->isValidFeatureName(StringRef{Feat}.substr(1));14058});14059return ParsedAttr;14060}1406114062void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,14063const FunctionDecl *FD) const {14064if (FD)14065getFunctionFeatureMap(FeatureMap, GlobalDecl().getWithDecl(FD));14066else14067Target->initFeatureMap(FeatureMap, getDiagnostics(),14068Target->getTargetOpts().CPU,14069Target->getTargetOpts().Features);14070}1407114072// Fills in the supplied string map with the set of target features for the14073// passed in function.14074void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,14075GlobalDecl GD) const {14076StringRef TargetCPU = Target->getTargetOpts().CPU;14077const FunctionDecl *FD = GD.getDecl()->getAsFunction();14078if (const auto *TD = FD->getAttr<TargetAttr>()) {14079ParsedTargetAttr ParsedAttr = filterFunctionTargetAttrs(TD);1408014081// Make a copy of the features as passed on the command line into the14082// beginning of the additional features from the function to override.14083// AArch64 handles command line option features in parseTargetAttr().14084if (!Target->getTriple().isAArch64())14085ParsedAttr.Features.insert(14086ParsedAttr.Features.begin(),14087Target->getTargetOpts().FeaturesAsWritten.begin(),14088Target->getTargetOpts().FeaturesAsWritten.end());1408914090if (ParsedAttr.CPU != "" && Target->isValidCPUName(ParsedAttr.CPU))14091TargetCPU = ParsedAttr.CPU;1409214093// Now populate the feature map, first with the TargetCPU which is either14094// the default or a new one from the target attribute string. Then we'll use14095// the passed in features (FeaturesAsWritten) along with the new ones from14096// the attribute.14097Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU,14098ParsedAttr.Features);14099} else if (const auto *SD = FD->getAttr<CPUSpecificAttr>()) {14100llvm::SmallVector<StringRef, 32> FeaturesTmp;14101Target->getCPUSpecificCPUDispatchFeatures(14102SD->getCPUName(GD.getMultiVersionIndex())->getName(), FeaturesTmp);14103std::vector<std::string> Features(FeaturesTmp.begin(), FeaturesTmp.end());14104Features.insert(Features.begin(),14105Target->getTargetOpts().FeaturesAsWritten.begin(),14106Target->getTargetOpts().FeaturesAsWritten.end());14107Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);14108} else if (const auto *TC = FD->getAttr<TargetClonesAttr>()) {14109if (Target->getTriple().isAArch64()) {14110llvm::SmallVector<StringRef, 8> Feats;14111TC->getFeatures(Feats, GD.getMultiVersionIndex());14112std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);14113Features.insert(Features.begin(),14114Target->getTargetOpts().FeaturesAsWritten.begin(),14115Target->getTargetOpts().FeaturesAsWritten.end());14116Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);14117} else {14118std::vector<std::string> Features;14119StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());14120if (VersionStr.starts_with("arch="))14121TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);14122else if (VersionStr != "default")14123Features.push_back((StringRef{"+"} + VersionStr).str());14124Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);14125}14126} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {14127llvm::SmallVector<StringRef, 8> Feats;14128TV->getFeatures(Feats);14129std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);14130Features.insert(Features.begin(),14131Target->getTargetOpts().FeaturesAsWritten.begin(),14132Target->getTargetOpts().FeaturesAsWritten.end());14133Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);14134} else {14135FeatureMap = Target->getTargetOpts().FeatureMap;14136}14137}1413814139OMPTraitInfo &ASTContext::getNewOMPTraitInfo() {14140OMPTraitInfoVector.emplace_back(new OMPTraitInfo());14141return *OMPTraitInfoVector.back();14142}1414314144const StreamingDiagnostic &clang::14145operator<<(const StreamingDiagnostic &DB,14146const ASTContext::SectionInfo &Section) {14147if (Section.Decl)14148return DB << Section.Decl;14149return DB << "a prior #pragma section";14150}1415114152bool ASTContext::mayExternalize(const Decl *D) const {14153bool IsInternalVar =14154isa<VarDecl>(D) &&14155basicGVALinkageForVariable(*this, cast<VarDecl>(D)) == GVA_Internal;14156bool IsExplicitDeviceVar = (D->hasAttr<CUDADeviceAttr>() &&14157!D->getAttr<CUDADeviceAttr>()->isImplicit()) ||14158(D->hasAttr<CUDAConstantAttr>() &&14159!D->getAttr<CUDAConstantAttr>()->isImplicit());14160// CUDA/HIP: managed variables need to be externalized since it is14161// a declaration in IR, therefore cannot have internal linkage. Kernels in14162// anonymous name space needs to be externalized to avoid duplicate symbols.14163return (IsInternalVar &&14164(D->hasAttr<HIPManagedAttr>() || IsExplicitDeviceVar)) ||14165(D->hasAttr<CUDAGlobalAttr>() &&14166basicGVALinkageForFunction(*this, cast<FunctionDecl>(D)) ==14167GVA_Internal);14168}1416914170bool ASTContext::shouldExternalize(const Decl *D) const {14171return mayExternalize(D) &&14172(D->hasAttr<HIPManagedAttr>() || D->hasAttr<CUDAGlobalAttr>() ||14173CUDADeviceVarODRUsedByHost.count(cast<VarDecl>(D)));14174}1417514176StringRef ASTContext::getCUIDHash() const {14177if (!CUIDHash.empty())14178return CUIDHash;14179if (LangOpts.CUID.empty())14180return StringRef();14181CUIDHash = llvm::utohexstr(llvm::MD5Hash(LangOpts.CUID), /*LowerCase=*/true);14182return CUIDHash;14183}1418414185const CXXRecordDecl *14186ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) {14187assert(ThisClass);14188assert(ThisClass->isPolymorphic());14189const CXXRecordDecl *PrimaryBase = ThisClass;14190while (1) {14191assert(PrimaryBase);14192assert(PrimaryBase->isPolymorphic());14193auto &Layout = getASTRecordLayout(PrimaryBase);14194auto Base = Layout.getPrimaryBase();14195if (!Base || Base == PrimaryBase || !Base->isPolymorphic())14196break;14197PrimaryBase = Base;14198}14199return PrimaryBase;14200}1420114202bool ASTContext::useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,14203StringRef MangledName) {14204auto *Method = cast<CXXMethodDecl>(VirtualMethodDecl.getDecl());14205assert(Method->isVirtual());14206bool DefaultIncludesPointerAuth =14207LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;1420814209if (!DefaultIncludesPointerAuth)14210return true;1421114212auto Existing = ThunksToBeAbbreviated.find(VirtualMethodDecl);14213if (Existing != ThunksToBeAbbreviated.end())14214return Existing->second.contains(MangledName.str());1421514216std::unique_ptr<MangleContext> Mangler(createMangleContext());14217llvm::StringMap<llvm::SmallVector<std::string, 2>> Thunks;14218auto VtableContext = getVTableContext();14219if (const auto *ThunkInfos = VtableContext->getThunkInfo(VirtualMethodDecl)) {14220auto *Destructor = dyn_cast<CXXDestructorDecl>(Method);14221for (const auto &Thunk : *ThunkInfos) {14222SmallString<256> ElidedName;14223llvm::raw_svector_ostream ElidedNameStream(ElidedName);14224if (Destructor)14225Mangler->mangleCXXDtorThunk(Destructor, VirtualMethodDecl.getDtorType(),14226Thunk, /* elideOverrideInfo */ true,14227ElidedNameStream);14228else14229Mangler->mangleThunk(Method, Thunk, /* elideOverrideInfo */ true,14230ElidedNameStream);14231SmallString<256> MangledName;14232llvm::raw_svector_ostream mangledNameStream(MangledName);14233if (Destructor)14234Mangler->mangleCXXDtorThunk(Destructor, VirtualMethodDecl.getDtorType(),14235Thunk, /* elideOverrideInfo */ false,14236mangledNameStream);14237else14238Mangler->mangleThunk(Method, Thunk, /* elideOverrideInfo */ false,14239mangledNameStream);1424014241if (Thunks.find(ElidedName) == Thunks.end())14242Thunks[ElidedName] = {};14243Thunks[ElidedName].push_back(std::string(MangledName));14244}14245}14246llvm::StringSet<> SimplifiedThunkNames;14247for (auto &ThunkList : Thunks) {14248llvm::sort(ThunkList.second);14249SimplifiedThunkNames.insert(ThunkList.second[0]);14250}14251bool Result = SimplifiedThunkNames.contains(MangledName);14252ThunksToBeAbbreviated[VirtualMethodDecl] = std::move(SimplifiedThunkNames);14253return Result;14254}142551425614257