1193326Sed//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the ASTContext interface. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/AST/ASTContext.h" 15249423Sdim#include "CXXABI.h" 16249423Sdim#include "clang/AST/ASTMutationListener.h" 17249423Sdim#include "clang/AST/Attr.h" 18201361Srdivacky#include "clang/AST/CharUnits.h" 19249423Sdim#include "clang/AST/Comment.h" 20239462Sdim#include "clang/AST/CommentCommandTraits.h" 21193326Sed#include "clang/AST/DeclCXX.h" 22193326Sed#include "clang/AST/DeclObjC.h" 23193326Sed#include "clang/AST/DeclTemplate.h" 24193326Sed#include "clang/AST/Expr.h" 25208600Srdivacky#include "clang/AST/ExprCXX.h" 26193326Sed#include "clang/AST/ExternalASTSource.h" 27249423Sdim#include "clang/AST/Mangle.h" 28263508Sdim#include "clang/AST/MangleNumberingContext.h" 29193326Sed#include "clang/AST/RecordLayout.h" 30263508Sdim#include "clang/AST/RecursiveASTVisitor.h" 31249423Sdim#include "clang/AST/TypeLoc.h" 32194179Sed#include "clang/Basic/Builtins.h" 33193326Sed#include "clang/Basic/SourceManager.h" 34193326Sed#include "clang/Basic/TargetInfo.h" 35198893Srdivacky#include "llvm/ADT/SmallString.h" 36193326Sed#include "llvm/ADT/StringExtras.h" 37263508Sdim#include "llvm/ADT/Triple.h" 38249423Sdim#include "llvm/Support/Capacity.h" 39193326Sed#include "llvm/Support/MathExtras.h" 40198893Srdivacky#include "llvm/Support/raw_ostream.h" 41223017Sdim#include <map> 42198092Srdivacky 43193326Sedusing namespace clang; 44193326Sed 45210299Sedunsigned ASTContext::NumImplicitDefaultConstructors; 46210299Sedunsigned ASTContext::NumImplicitDefaultConstructorsDeclared; 47210299Sedunsigned ASTContext::NumImplicitCopyConstructors; 48210299Sedunsigned ASTContext::NumImplicitCopyConstructorsDeclared; 49223017Sdimunsigned ASTContext::NumImplicitMoveConstructors; 50223017Sdimunsigned ASTContext::NumImplicitMoveConstructorsDeclared; 51210299Sedunsigned ASTContext::NumImplicitCopyAssignmentOperators; 52210299Sedunsigned ASTContext::NumImplicitCopyAssignmentOperatorsDeclared; 53223017Sdimunsigned ASTContext::NumImplicitMoveAssignmentOperators; 54223017Sdimunsigned ASTContext::NumImplicitMoveAssignmentOperatorsDeclared; 55210299Sedunsigned ASTContext::NumImplicitDestructors; 56210299Sedunsigned ASTContext::NumImplicitDestructorsDeclared; 57210299Sed 58193326Sedenum FloatingRank { 59226633Sdim HalfRank, FloatRank, DoubleRank, LongDoubleRank 60193326Sed}; 61193326Sed 62239462SdimRawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { 63239462Sdim if (!CommentsLoaded && ExternalSource) { 64239462Sdim ExternalSource->ReadComments(); 65239462Sdim CommentsLoaded = true; 66239462Sdim } 67239462Sdim 68239462Sdim assert(D); 69239462Sdim 70239462Sdim // User can not attach documentation to implicit declarations. 71239462Sdim if (D->isImplicit()) 72239462Sdim return NULL; 73239462Sdim 74239462Sdim // User can not attach documentation to implicit instantiations. 75239462Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 76239462Sdim if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) 77239462Sdim return NULL; 78239462Sdim } 79239462Sdim 80243830Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 81243830Sdim if (VD->isStaticDataMember() && 82243830Sdim VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) 83243830Sdim return NULL; 84243830Sdim } 85243830Sdim 86243830Sdim if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) { 87243830Sdim if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) 88243830Sdim return NULL; 89243830Sdim } 90243830Sdim 91249423Sdim if (const ClassTemplateSpecializationDecl *CTSD = 92249423Sdim dyn_cast<ClassTemplateSpecializationDecl>(D)) { 93249423Sdim TemplateSpecializationKind TSK = CTSD->getSpecializationKind(); 94249423Sdim if (TSK == TSK_ImplicitInstantiation || 95249423Sdim TSK == TSK_Undeclared) 96249423Sdim return NULL; 97249423Sdim } 98249423Sdim 99243830Sdim if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) { 100243830Sdim if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) 101243830Sdim return NULL; 102243830Sdim } 103251662Sdim if (const TagDecl *TD = dyn_cast<TagDecl>(D)) { 104251662Sdim // When tag declaration (but not definition!) is part of the 105251662Sdim // decl-specifier-seq of some other declaration, it doesn't get comment 106251662Sdim if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition()) 107251662Sdim return NULL; 108251662Sdim } 109239462Sdim // TODO: handle comments for function parameters properly. 110239462Sdim if (isa<ParmVarDecl>(D)) 111239462Sdim return NULL; 112239462Sdim 113239462Sdim // TODO: we could look up template parameter documentation in the template 114239462Sdim // documentation. 115239462Sdim if (isa<TemplateTypeParmDecl>(D) || 116239462Sdim isa<NonTypeTemplateParmDecl>(D) || 117239462Sdim isa<TemplateTemplateParmDecl>(D)) 118239462Sdim return NULL; 119239462Sdim 120239462Sdim ArrayRef<RawComment *> RawComments = Comments.getComments(); 121239462Sdim 122239462Sdim // If there are no comments anywhere, we won't find anything. 123239462Sdim if (RawComments.empty()) 124239462Sdim return NULL; 125239462Sdim 126239462Sdim // Find declaration location. 127239462Sdim // For Objective-C declarations we generally don't expect to have multiple 128239462Sdim // declarators, thus use declaration starting location as the "declaration 129239462Sdim // location". 130239462Sdim // For all other declarations multiple declarators are used quite frequently, 131239462Sdim // so we use the location of the identifier as the "declaration location". 132239462Sdim SourceLocation DeclLoc; 133239462Sdim if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) || 134239462Sdim isa<ObjCPropertyDecl>(D) || 135239462Sdim isa<RedeclarableTemplateDecl>(D) || 136239462Sdim isa<ClassTemplateSpecializationDecl>(D)) 137239462Sdim DeclLoc = D->getLocStart(); 138263508Sdim else { 139239462Sdim DeclLoc = D->getLocation(); 140263508Sdim // If location of the typedef name is in a macro, it is because being 141263508Sdim // declared via a macro. Try using declaration's starting location 142263508Sdim // as the "declaration location". 143263508Sdim if (DeclLoc.isMacroID() && isa<TypedefDecl>(D)) 144263508Sdim DeclLoc = D->getLocStart(); 145263508Sdim } 146239462Sdim 147239462Sdim // If the declaration doesn't map directly to a location in a file, we 148239462Sdim // can't find the comment. 149239462Sdim if (DeclLoc.isInvalid() || !DeclLoc.isFileID()) 150239462Sdim return NULL; 151239462Sdim 152239462Sdim // Find the comment that occurs just after this declaration. 153239462Sdim ArrayRef<RawComment *>::iterator Comment; 154239462Sdim { 155239462Sdim // When searching for comments during parsing, the comment we are looking 156239462Sdim // for is usually among the last two comments we parsed -- check them 157239462Sdim // first. 158251662Sdim RawComment CommentAtDeclLoc( 159251662Sdim SourceMgr, SourceRange(DeclLoc), false, 160251662Sdim LangOpts.CommentOpts.ParseAllComments); 161239462Sdim BeforeThanCompare<RawComment> Compare(SourceMgr); 162239462Sdim ArrayRef<RawComment *>::iterator MaybeBeforeDecl = RawComments.end() - 1; 163239462Sdim bool Found = Compare(*MaybeBeforeDecl, &CommentAtDeclLoc); 164239462Sdim if (!Found && RawComments.size() >= 2) { 165239462Sdim MaybeBeforeDecl--; 166239462Sdim Found = Compare(*MaybeBeforeDecl, &CommentAtDeclLoc); 167239462Sdim } 168239462Sdim 169239462Sdim if (Found) { 170239462Sdim Comment = MaybeBeforeDecl + 1; 171239462Sdim assert(Comment == std::lower_bound(RawComments.begin(), RawComments.end(), 172239462Sdim &CommentAtDeclLoc, Compare)); 173239462Sdim } else { 174239462Sdim // Slow path. 175239462Sdim Comment = std::lower_bound(RawComments.begin(), RawComments.end(), 176239462Sdim &CommentAtDeclLoc, Compare); 177239462Sdim } 178239462Sdim } 179239462Sdim 180239462Sdim // Decompose the location for the declaration and find the beginning of the 181239462Sdim // file buffer. 182239462Sdim std::pair<FileID, unsigned> DeclLocDecomp = SourceMgr.getDecomposedLoc(DeclLoc); 183239462Sdim 184239462Sdim // First check whether we have a trailing comment. 185239462Sdim if (Comment != RawComments.end() && 186239462Sdim (*Comment)->isDocumentation() && (*Comment)->isTrailingComment() && 187263508Sdim (isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) || 188263508Sdim isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) { 189239462Sdim std::pair<FileID, unsigned> CommentBeginDecomp 190239462Sdim = SourceMgr.getDecomposedLoc((*Comment)->getSourceRange().getBegin()); 191239462Sdim // Check that Doxygen trailing comment comes after the declaration, starts 192239462Sdim // on the same line and in the same file as the declaration. 193239462Sdim if (DeclLocDecomp.first == CommentBeginDecomp.first && 194239462Sdim SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second) 195239462Sdim == SourceMgr.getLineNumber(CommentBeginDecomp.first, 196239462Sdim CommentBeginDecomp.second)) { 197239462Sdim return *Comment; 198239462Sdim } 199239462Sdim } 200239462Sdim 201239462Sdim // The comment just after the declaration was not a trailing comment. 202239462Sdim // Let's look at the previous comment. 203239462Sdim if (Comment == RawComments.begin()) 204239462Sdim return NULL; 205239462Sdim --Comment; 206239462Sdim 207239462Sdim // Check that we actually have a non-member Doxygen comment. 208239462Sdim if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment()) 209239462Sdim return NULL; 210239462Sdim 211239462Sdim // Decompose the end of the comment. 212239462Sdim std::pair<FileID, unsigned> CommentEndDecomp 213239462Sdim = SourceMgr.getDecomposedLoc((*Comment)->getSourceRange().getEnd()); 214239462Sdim 215239462Sdim // If the comment and the declaration aren't in the same file, then they 216239462Sdim // aren't related. 217239462Sdim if (DeclLocDecomp.first != CommentEndDecomp.first) 218239462Sdim return NULL; 219239462Sdim 220239462Sdim // Get the corresponding buffer. 221239462Sdim bool Invalid = false; 222239462Sdim const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first, 223239462Sdim &Invalid).data(); 224239462Sdim if (Invalid) 225239462Sdim return NULL; 226239462Sdim 227239462Sdim // Extract text between the comment and declaration. 228239462Sdim StringRef Text(Buffer + CommentEndDecomp.second, 229239462Sdim DeclLocDecomp.second - CommentEndDecomp.second); 230239462Sdim 231239462Sdim // There should be no other declarations or preprocessor directives between 232239462Sdim // comment and declaration. 233263508Sdim if (Text.find_first_of(";{}#@") != StringRef::npos) 234239462Sdim return NULL; 235239462Sdim 236239462Sdim return *Comment; 237239462Sdim} 238239462Sdim 239239462Sdimnamespace { 240239462Sdim/// If we have a 'templated' declaration for a template, adjust 'D' to 241239462Sdim/// refer to the actual template. 242243830Sdim/// If we have an implicit instantiation, adjust 'D' to refer to template. 243239462Sdimconst Decl *adjustDeclToTemplate(const Decl *D) { 244239462Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 245243830Sdim // Is this function declaration part of a function template? 246239462Sdim if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) 247243830Sdim return FTD; 248243830Sdim 249243830Sdim // Nothing to do if function is not an implicit instantiation. 250243830Sdim if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) 251243830Sdim return D; 252243830Sdim 253243830Sdim // Function is an implicit instantiation of a function template? 254243830Sdim if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate()) 255243830Sdim return FTD; 256243830Sdim 257243830Sdim // Function is instantiated from a member definition of a class template? 258243830Sdim if (const FunctionDecl *MemberDecl = 259243830Sdim FD->getInstantiatedFromMemberFunction()) 260243830Sdim return MemberDecl; 261243830Sdim 262243830Sdim return D; 263239462Sdim } 264243830Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 265243830Sdim // Static data member is instantiated from a member definition of a class 266243830Sdim // template? 267243830Sdim if (VD->isStaticDataMember()) 268243830Sdim if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember()) 269243830Sdim return MemberDecl; 270243830Sdim 271243830Sdim return D; 272243830Sdim } 273243830Sdim if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) { 274243830Sdim // Is this class declaration part of a class template? 275243830Sdim if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate()) 276243830Sdim return CTD; 277243830Sdim 278243830Sdim // Class is an implicit instantiation of a class template or partial 279243830Sdim // specialization? 280243830Sdim if (const ClassTemplateSpecializationDecl *CTSD = 281243830Sdim dyn_cast<ClassTemplateSpecializationDecl>(CRD)) { 282243830Sdim if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation) 283243830Sdim return D; 284243830Sdim llvm::PointerUnion<ClassTemplateDecl *, 285243830Sdim ClassTemplatePartialSpecializationDecl *> 286243830Sdim PU = CTSD->getSpecializedTemplateOrPartial(); 287243830Sdim return PU.is<ClassTemplateDecl*>() ? 288243830Sdim static_cast<const Decl*>(PU.get<ClassTemplateDecl *>()) : 289243830Sdim static_cast<const Decl*>( 290243830Sdim PU.get<ClassTemplatePartialSpecializationDecl *>()); 291243830Sdim } 292243830Sdim 293243830Sdim // Class is instantiated from a member definition of a class template? 294243830Sdim if (const MemberSpecializationInfo *Info = 295243830Sdim CRD->getMemberSpecializationInfo()) 296243830Sdim return Info->getInstantiatedFrom(); 297243830Sdim 298243830Sdim return D; 299243830Sdim } 300243830Sdim if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) { 301243830Sdim // Enum is instantiated from a member definition of a class template? 302243830Sdim if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum()) 303243830Sdim return MemberDecl; 304243830Sdim 305243830Sdim return D; 306243830Sdim } 307243830Sdim // FIXME: Adjust alias templates? 308239462Sdim return D; 309239462Sdim} 310239462Sdim} // unnamed namespace 311239462Sdim 312239462Sdimconst RawComment *ASTContext::getRawCommentForAnyRedecl( 313239462Sdim const Decl *D, 314239462Sdim const Decl **OriginalDecl) const { 315239462Sdim D = adjustDeclToTemplate(D); 316239462Sdim 317239462Sdim // Check whether we have cached a comment for this declaration already. 318239462Sdim { 319239462Sdim llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos = 320239462Sdim RedeclComments.find(D); 321239462Sdim if (Pos != RedeclComments.end()) { 322239462Sdim const RawCommentAndCacheFlags &Raw = Pos->second; 323239462Sdim if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) { 324239462Sdim if (OriginalDecl) 325239462Sdim *OriginalDecl = Raw.getOriginalDecl(); 326239462Sdim return Raw.getRaw(); 327239462Sdim } 328239462Sdim } 329239462Sdim } 330239462Sdim 331239462Sdim // Search for comments attached to declarations in the redeclaration chain. 332239462Sdim const RawComment *RC = NULL; 333239462Sdim const Decl *OriginalDeclForRC = NULL; 334239462Sdim for (Decl::redecl_iterator I = D->redecls_begin(), 335239462Sdim E = D->redecls_end(); 336239462Sdim I != E; ++I) { 337239462Sdim llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos = 338239462Sdim RedeclComments.find(*I); 339239462Sdim if (Pos != RedeclComments.end()) { 340239462Sdim const RawCommentAndCacheFlags &Raw = Pos->second; 341239462Sdim if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) { 342239462Sdim RC = Raw.getRaw(); 343239462Sdim OriginalDeclForRC = Raw.getOriginalDecl(); 344239462Sdim break; 345239462Sdim } 346239462Sdim } else { 347239462Sdim RC = getRawCommentForDeclNoCache(*I); 348239462Sdim OriginalDeclForRC = *I; 349239462Sdim RawCommentAndCacheFlags Raw; 350239462Sdim if (RC) { 351239462Sdim Raw.setRaw(RC); 352239462Sdim Raw.setKind(RawCommentAndCacheFlags::FromDecl); 353239462Sdim } else 354239462Sdim Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl); 355239462Sdim Raw.setOriginalDecl(*I); 356239462Sdim RedeclComments[*I] = Raw; 357239462Sdim if (RC) 358239462Sdim break; 359239462Sdim } 360239462Sdim } 361239462Sdim 362239462Sdim // If we found a comment, it should be a documentation comment. 363239462Sdim assert(!RC || RC->isDocumentation()); 364239462Sdim 365239462Sdim if (OriginalDecl) 366239462Sdim *OriginalDecl = OriginalDeclForRC; 367239462Sdim 368239462Sdim // Update cache for every declaration in the redeclaration chain. 369239462Sdim RawCommentAndCacheFlags Raw; 370239462Sdim Raw.setRaw(RC); 371239462Sdim Raw.setKind(RawCommentAndCacheFlags::FromRedecl); 372239462Sdim Raw.setOriginalDecl(OriginalDeclForRC); 373239462Sdim 374239462Sdim for (Decl::redecl_iterator I = D->redecls_begin(), 375239462Sdim E = D->redecls_end(); 376239462Sdim I != E; ++I) { 377239462Sdim RawCommentAndCacheFlags &R = RedeclComments[*I]; 378239462Sdim if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl) 379239462Sdim R = Raw; 380239462Sdim } 381239462Sdim 382239462Sdim return RC; 383239462Sdim} 384239462Sdim 385243830Sdimstatic void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod, 386243830Sdim SmallVectorImpl<const NamedDecl *> &Redeclared) { 387243830Sdim const DeclContext *DC = ObjCMethod->getDeclContext(); 388243830Sdim if (const ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(DC)) { 389243830Sdim const ObjCInterfaceDecl *ID = IMD->getClassInterface(); 390243830Sdim if (!ID) 391243830Sdim return; 392243830Sdim // Add redeclared method here. 393249423Sdim for (ObjCInterfaceDecl::known_extensions_iterator 394249423Sdim Ext = ID->known_extensions_begin(), 395249423Sdim ExtEnd = ID->known_extensions_end(); 396249423Sdim Ext != ExtEnd; ++Ext) { 397243830Sdim if (ObjCMethodDecl *RedeclaredMethod = 398249423Sdim Ext->getMethod(ObjCMethod->getSelector(), 399243830Sdim ObjCMethod->isInstanceMethod())) 400243830Sdim Redeclared.push_back(RedeclaredMethod); 401243830Sdim } 402243830Sdim } 403243830Sdim} 404243830Sdim 405243830Sdimcomments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC, 406243830Sdim const Decl *D) const { 407243830Sdim comments::DeclInfo *ThisDeclInfo = new (*this) comments::DeclInfo; 408243830Sdim ThisDeclInfo->CommentDecl = D; 409243830Sdim ThisDeclInfo->IsFilled = false; 410243830Sdim ThisDeclInfo->fill(); 411243830Sdim ThisDeclInfo->CommentDecl = FC->getDecl(); 412243830Sdim comments::FullComment *CFC = 413243830Sdim new (*this) comments::FullComment(FC->getBlocks(), 414243830Sdim ThisDeclInfo); 415243830Sdim return CFC; 416243830Sdim 417243830Sdim} 418243830Sdim 419263508Sdimcomments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const { 420263508Sdim const RawComment *RC = getRawCommentForDeclNoCache(D); 421263508Sdim return RC ? RC->parse(*this, 0, D) : 0; 422263508Sdim} 423263508Sdim 424243830Sdimcomments::FullComment *ASTContext::getCommentForDecl( 425243830Sdim const Decl *D, 426243830Sdim const Preprocessor *PP) const { 427263508Sdim if (D->isInvalidDecl()) 428263508Sdim return NULL; 429239462Sdim D = adjustDeclToTemplate(D); 430243830Sdim 431239462Sdim const Decl *Canonical = D->getCanonicalDecl(); 432239462Sdim llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos = 433239462Sdim ParsedComments.find(Canonical); 434243830Sdim 435243830Sdim if (Pos != ParsedComments.end()) { 436243830Sdim if (Canonical != D) { 437243830Sdim comments::FullComment *FC = Pos->second; 438243830Sdim comments::FullComment *CFC = cloneFullComment(FC, D); 439243830Sdim return CFC; 440243830Sdim } 441239462Sdim return Pos->second; 442243830Sdim } 443243830Sdim 444239462Sdim const Decl *OriginalDecl; 445243830Sdim 446239462Sdim const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl); 447243830Sdim if (!RC) { 448243830Sdim if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) { 449243830Sdim SmallVector<const NamedDecl*, 8> Overridden; 450249423Sdim const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D); 451249423Sdim if (OMD && OMD->isPropertyAccessor()) 452249423Sdim if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl()) 453249423Sdim if (comments::FullComment *FC = getCommentForDecl(PDecl, PP)) 454249423Sdim return cloneFullComment(FC, D); 455249423Sdim if (OMD) 456243830Sdim addRedeclaredMethods(OMD, Overridden); 457243830Sdim getOverriddenMethods(dyn_cast<NamedDecl>(D), Overridden); 458249423Sdim for (unsigned i = 0, e = Overridden.size(); i < e; i++) 459249423Sdim if (comments::FullComment *FC = getCommentForDecl(Overridden[i], PP)) 460249423Sdim return cloneFullComment(FC, D); 461243830Sdim } 462251662Sdim else if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 463249423Sdim // Attach any tag type's documentation to its typedef if latter 464249423Sdim // does not have one of its own. 465249423Sdim QualType QT = TD->getUnderlyingType(); 466249423Sdim if (const TagType *TT = QT->getAs<TagType>()) 467249423Sdim if (const Decl *TD = TT->getDecl()) 468249423Sdim if (comments::FullComment *FC = getCommentForDecl(TD, PP)) 469249423Sdim return cloneFullComment(FC, D); 470249423Sdim } 471251662Sdim else if (const ObjCInterfaceDecl *IC = dyn_cast<ObjCInterfaceDecl>(D)) { 472251662Sdim while (IC->getSuperClass()) { 473251662Sdim IC = IC->getSuperClass(); 474251662Sdim if (comments::FullComment *FC = getCommentForDecl(IC, PP)) 475251662Sdim return cloneFullComment(FC, D); 476251662Sdim } 477251662Sdim } 478251662Sdim else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { 479251662Sdim if (const ObjCInterfaceDecl *IC = CD->getClassInterface()) 480251662Sdim if (comments::FullComment *FC = getCommentForDecl(IC, PP)) 481251662Sdim return cloneFullComment(FC, D); 482251662Sdim } 483251662Sdim else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 484251662Sdim if (!(RD = RD->getDefinition())) 485251662Sdim return NULL; 486251662Sdim // Check non-virtual bases. 487251662Sdim for (CXXRecordDecl::base_class_const_iterator I = 488251662Sdim RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { 489251662Sdim if (I->isVirtual() || (I->getAccessSpecifier() != AS_public)) 490251662Sdim continue; 491251662Sdim QualType Ty = I->getType(); 492251662Sdim if (Ty.isNull()) 493251662Sdim continue; 494251662Sdim if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) { 495251662Sdim if (!(NonVirtualBase= NonVirtualBase->getDefinition())) 496251662Sdim continue; 497251662Sdim 498251662Sdim if (comments::FullComment *FC = getCommentForDecl((NonVirtualBase), PP)) 499251662Sdim return cloneFullComment(FC, D); 500251662Sdim } 501251662Sdim } 502251662Sdim // Check virtual bases. 503251662Sdim for (CXXRecordDecl::base_class_const_iterator I = 504251662Sdim RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) { 505251662Sdim if (I->getAccessSpecifier() != AS_public) 506251662Sdim continue; 507251662Sdim QualType Ty = I->getType(); 508251662Sdim if (Ty.isNull()) 509251662Sdim continue; 510251662Sdim if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) { 511251662Sdim if (!(VirtualBase= VirtualBase->getDefinition())) 512251662Sdim continue; 513251662Sdim if (comments::FullComment *FC = getCommentForDecl((VirtualBase), PP)) 514251662Sdim return cloneFullComment(FC, D); 515251662Sdim } 516251662Sdim } 517251662Sdim } 518239462Sdim return NULL; 519243830Sdim } 520243830Sdim 521243830Sdim // If the RawComment was attached to other redeclaration of this Decl, we 522243830Sdim // should parse the comment in context of that other Decl. This is important 523243830Sdim // because comments can contain references to parameter names which can be 524243830Sdim // different across redeclarations. 525239462Sdim if (D != OriginalDecl) 526243830Sdim return getCommentForDecl(OriginalDecl, PP); 527239462Sdim 528243830Sdim comments::FullComment *FC = RC->parse(*this, PP, D); 529239462Sdim ParsedComments[Canonical] = FC; 530239462Sdim return FC; 531239462Sdim} 532239462Sdim 533210299Sedvoid 534210299SedASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID, 535210299Sed TemplateTemplateParmDecl *Parm) { 536210299Sed ID.AddInteger(Parm->getDepth()); 537210299Sed ID.AddInteger(Parm->getPosition()); 538218893Sdim ID.AddBoolean(Parm->isParameterPack()); 539210299Sed 540210299Sed TemplateParameterList *Params = Parm->getTemplateParameters(); 541210299Sed ID.AddInteger(Params->size()); 542210299Sed for (TemplateParameterList::const_iterator P = Params->begin(), 543210299Sed PEnd = Params->end(); 544210299Sed P != PEnd; ++P) { 545210299Sed if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 546210299Sed ID.AddInteger(0); 547210299Sed ID.AddBoolean(TTP->isParameterPack()); 548210299Sed continue; 549210299Sed } 550210299Sed 551210299Sed if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 552210299Sed ID.AddInteger(1); 553218893Sdim ID.AddBoolean(NTTP->isParameterPack()); 554234353Sdim ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr()); 555218893Sdim if (NTTP->isExpandedParameterPack()) { 556218893Sdim ID.AddBoolean(true); 557218893Sdim ID.AddInteger(NTTP->getNumExpansionTypes()); 558234353Sdim for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) { 559234353Sdim QualType T = NTTP->getExpansionType(I); 560234353Sdim ID.AddPointer(T.getCanonicalType().getAsOpaquePtr()); 561234353Sdim } 562218893Sdim } else 563218893Sdim ID.AddBoolean(false); 564210299Sed continue; 565210299Sed } 566210299Sed 567210299Sed TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); 568210299Sed ID.AddInteger(2); 569210299Sed Profile(ID, TTP); 570210299Sed } 571210299Sed} 572210299Sed 573210299SedTemplateTemplateParmDecl * 574210299SedASTContext::getCanonicalTemplateTemplateParmDecl( 575218893Sdim TemplateTemplateParmDecl *TTP) const { 576210299Sed // Check if we already have a canonical template template parameter. 577210299Sed llvm::FoldingSetNodeID ID; 578210299Sed CanonicalTemplateTemplateParm::Profile(ID, TTP); 579210299Sed void *InsertPos = 0; 580210299Sed CanonicalTemplateTemplateParm *Canonical 581210299Sed = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); 582210299Sed if (Canonical) 583210299Sed return Canonical->getParam(); 584210299Sed 585210299Sed // Build a canonical template parameter list. 586210299Sed TemplateParameterList *Params = TTP->getTemplateParameters(); 587226633Sdim SmallVector<NamedDecl *, 4> CanonParams; 588210299Sed CanonParams.reserve(Params->size()); 589210299Sed for (TemplateParameterList::const_iterator P = Params->begin(), 590210299Sed PEnd = Params->end(); 591210299Sed P != PEnd; ++P) { 592210299Sed if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) 593210299Sed CanonParams.push_back( 594210299Sed TemplateTypeParmDecl::Create(*this, getTranslationUnitDecl(), 595221345Sdim SourceLocation(), 596221345Sdim SourceLocation(), 597221345Sdim TTP->getDepth(), 598210299Sed TTP->getIndex(), 0, false, 599210299Sed TTP->isParameterPack())); 600210299Sed else if (NonTypeTemplateParmDecl *NTTP 601218893Sdim = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 602218893Sdim QualType T = getCanonicalType(NTTP->getType()); 603218893Sdim TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T); 604218893Sdim NonTypeTemplateParmDecl *Param; 605218893Sdim if (NTTP->isExpandedParameterPack()) { 606226633Sdim SmallVector<QualType, 2> ExpandedTypes; 607226633Sdim SmallVector<TypeSourceInfo *, 2> ExpandedTInfos; 608218893Sdim for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) { 609218893Sdim ExpandedTypes.push_back(getCanonicalType(NTTP->getExpansionType(I))); 610218893Sdim ExpandedTInfos.push_back( 611218893Sdim getTrivialTypeSourceInfo(ExpandedTypes.back())); 612218893Sdim } 613218893Sdim 614218893Sdim Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(), 615221345Sdim SourceLocation(), 616221345Sdim SourceLocation(), 617218893Sdim NTTP->getDepth(), 618218893Sdim NTTP->getPosition(), 0, 619218893Sdim T, 620218893Sdim TInfo, 621218893Sdim ExpandedTypes.data(), 622218893Sdim ExpandedTypes.size(), 623218893Sdim ExpandedTInfos.data()); 624218893Sdim } else { 625218893Sdim Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(), 626221345Sdim SourceLocation(), 627221345Sdim SourceLocation(), 628218893Sdim NTTP->getDepth(), 629218893Sdim NTTP->getPosition(), 0, 630218893Sdim T, 631218893Sdim NTTP->isParameterPack(), 632218893Sdim TInfo); 633218893Sdim } 634218893Sdim CanonParams.push_back(Param); 635218893Sdim 636218893Sdim } else 637210299Sed CanonParams.push_back(getCanonicalTemplateTemplateParmDecl( 638210299Sed cast<TemplateTemplateParmDecl>(*P))); 639210299Sed } 640210299Sed 641210299Sed TemplateTemplateParmDecl *CanonTTP 642210299Sed = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(), 643210299Sed SourceLocation(), TTP->getDepth(), 644218893Sdim TTP->getPosition(), 645218893Sdim TTP->isParameterPack(), 646218893Sdim 0, 647210299Sed TemplateParameterList::Create(*this, SourceLocation(), 648210299Sed SourceLocation(), 649210299Sed CanonParams.data(), 650210299Sed CanonParams.size(), 651210299Sed SourceLocation())); 652210299Sed 653210299Sed // Get the new insert position for the node we care about. 654210299Sed Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); 655210299Sed assert(Canonical == 0 && "Shouldn't be in the map!"); 656210299Sed (void)Canonical; 657210299Sed 658210299Sed // Create the canonical template template parameter entry. 659210299Sed Canonical = new (*this) CanonicalTemplateTemplateParm(CanonTTP); 660210299Sed CanonTemplateTemplateParms.InsertNode(Canonical, InsertPos); 661210299Sed return CanonTTP; 662210299Sed} 663210299Sed 664212904SdimCXXABI *ASTContext::createCXXABI(const TargetInfo &T) { 665212904Sdim if (!LangOpts.CPlusPlus) return 0; 666212904Sdim 667249423Sdim switch (T.getCXXABI().getKind()) { 668249423Sdim case TargetCXXABI::GenericARM: 669249423Sdim case TargetCXXABI::iOS: 670212904Sdim return CreateARMCXXABI(*this); 671249423Sdim case TargetCXXABI::GenericAArch64: // Same as Itanium at this level 672249423Sdim case TargetCXXABI::GenericItanium: 673212904Sdim return CreateItaniumCXXABI(*this); 674249423Sdim case TargetCXXABI::Microsoft: 675212904Sdim return CreateMicrosoftCXXABI(*this); 676212904Sdim } 677234353Sdim llvm_unreachable("Invalid CXXABI type!"); 678212904Sdim} 679212904Sdim 680226633Sdimstatic const LangAS::Map *getAddressSpaceMap(const TargetInfo &T, 681221345Sdim const LangOptions &LOpts) { 682221345Sdim if (LOpts.FakeAddressSpaceMap) { 683221345Sdim // The fake address space map must have a distinct entry for each 684221345Sdim // language-specific address space. 685221345Sdim static const unsigned FakeAddrSpaceMap[] = { 686221345Sdim 1, // opencl_global 687221345Sdim 2, // opencl_local 688239462Sdim 3, // opencl_constant 689239462Sdim 4, // cuda_device 690239462Sdim 5, // cuda_constant 691239462Sdim 6 // cuda_shared 692221345Sdim }; 693226633Sdim return &FakeAddrSpaceMap; 694221345Sdim } else { 695226633Sdim return &T.getAddressSpaceMap(); 696221345Sdim } 697221345Sdim} 698221345Sdim 699263508Sdimstatic bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, 700263508Sdim const LangOptions &LangOpts) { 701263508Sdim switch (LangOpts.getAddressSpaceMapMangling()) { 702263508Sdim case LangOptions::ASMM_Target: 703263508Sdim return TI.useAddressSpaceMapMangling(); 704263508Sdim case LangOptions::ASMM_On: 705263508Sdim return true; 706263508Sdim case LangOptions::ASMM_Off: 707263508Sdim return false; 708263508Sdim } 709263508Sdim llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything."); 710263508Sdim} 711263508Sdim 712226633SdimASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM, 713226633Sdim const TargetInfo *t, 714193326Sed IdentifierTable &idents, SelectorTable &sels, 715194179Sed Builtin::Context &builtins, 716226633Sdim unsigned size_reserve, 717226633Sdim bool DelayInitialization) 718226633Sdim : FunctionProtoTypes(this_()), 719226633Sdim TemplateSpecializationTypes(this_()), 720226633Sdim DependentTemplateSpecializationTypes(this_()), 721226633Sdim SubstTemplateTemplateParmPacks(this_()), 722226633Sdim GlobalNestedNameSpecifier(0), 723263508Sdim Int128Decl(0), UInt128Decl(0), Float128StubDecl(0), 724239462Sdim BuiltinVaListDecl(0), 725234353Sdim ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0), 726243830Sdim BOOLDecl(0), 727226633Sdim CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0), 728226633Sdim FILEDecl(0), 729227737Sdim jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0), 730227737Sdim BlockDescriptorType(0), BlockDescriptorExtendedType(0), 731227737Sdim cudaConfigureCallDecl(0), 732234353Sdim NullTypeSourceInfo(QualType()), 733234353Sdim FirstLocalImport(), LastLocalImport(), 734226633Sdim SourceMgr(SM), LangOpts(LOpts), 735226633Sdim AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts), 736226633Sdim Idents(idents), Selectors(sels), 737226633Sdim BuiltinInfo(builtins), 738226633Sdim DeclarationNames(*this), 739226633Sdim ExternalSource(0), Listener(0), 740239462Sdim Comments(SM), CommentsLoaded(false), 741249423Sdim CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), 742263508Sdim LastSDM(0, 0) 743226633Sdim{ 744198092Srdivacky if (size_reserve > 0) Types.reserve(size_reserve); 745198092Srdivacky TUDecl = TranslationUnitDecl::Create(*this); 746226633Sdim 747226633Sdim if (!DelayInitialization) { 748226633Sdim assert(t && "No target supplied for ASTContext initialization"); 749226633Sdim InitBuiltinTypes(*t); 750226633Sdim } 751193326Sed} 752193326Sed 753193326SedASTContext::~ASTContext() { 754203955Srdivacky // Release the DenseMaps associated with DeclContext objects. 755203955Srdivacky // FIXME: Is this the ideal solution? 756203955Srdivacky ReleaseDeclContextMaps(); 757204643Srdivacky 758263508Sdim // Call all of the deallocation functions on all of their targets. 759263508Sdim for (DeallocationMap::const_iterator I = Deallocations.begin(), 760263508Sdim E = Deallocations.end(); I != E; ++I) 761263508Sdim for (unsigned J = 0, N = I->second.size(); J != N; ++J) 762263508Sdim (I->first)((I->second)[J]); 763263508Sdim 764212904Sdim // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed 765212904Sdim // because they can contain DenseMaps. 766212904Sdim for (llvm::DenseMap<const ObjCContainerDecl*, 767212904Sdim const ASTRecordLayout*>::iterator 768212904Sdim I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) 769212904Sdim // Increment in loop to prevent using deallocated memory. 770212904Sdim if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second)) 771212904Sdim R->Destroy(*this); 772193326Sed 773210299Sed for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator 774210299Sed I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) { 775210299Sed // Increment in loop to prevent using deallocated memory. 776210299Sed if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second)) 777210299Sed R->Destroy(*this); 778210299Sed } 779212904Sdim 780212904Sdim for (llvm::DenseMap<const Decl*, AttrVec*>::iterator A = DeclAttrs.begin(), 781212904Sdim AEnd = DeclAttrs.end(); 782212904Sdim A != AEnd; ++A) 783212904Sdim A->second->~AttrVec(); 784263508Sdim 785263508Sdim for (llvm::DenseMap<const DeclContext *, MangleNumberingContext *>::iterator 786263508Sdim I = MangleNumberingContexts.begin(), 787263508Sdim E = MangleNumberingContexts.end(); 788263508Sdim I != E; ++I) 789263508Sdim delete I->second; 790193326Sed} 791193326Sed 792208600Srdivackyvoid ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { 793263508Sdim Deallocations[Callback].push_back(Data); 794208600Srdivacky} 795208600Srdivacky 796198092Srdivackyvoid 797234353SdimASTContext::setExternalSource(OwningPtr<ExternalASTSource> &Source) { 798193326Sed ExternalSource.reset(Source.take()); 799193326Sed} 800193326Sed 801193326Sedvoid ASTContext::PrintStats() const { 802224145Sdim llvm::errs() << "\n*** AST Context Stats:\n"; 803224145Sdim llvm::errs() << " " << Types.size() << " types total.\n"; 804193326Sed 805193326Sed unsigned counts[] = { 806198092Srdivacky#define TYPE(Name, Parent) 0, 807193326Sed#define ABSTRACT_TYPE(Name, Parent) 808193326Sed#include "clang/AST/TypeNodes.def" 809193326Sed 0 // Extra 810193326Sed }; 811193326Sed 812193326Sed for (unsigned i = 0, e = Types.size(); i != e; ++i) { 813193326Sed Type *T = Types[i]; 814193326Sed counts[(unsigned)T->getTypeClass()]++; 815193326Sed } 816193326Sed 817193326Sed unsigned Idx = 0; 818193326Sed unsigned TotalBytes = 0; 819193326Sed#define TYPE(Name, Parent) \ 820193326Sed if (counts[Idx]) \ 821224145Sdim llvm::errs() << " " << counts[Idx] << " " << #Name \ 822224145Sdim << " types\n"; \ 823193326Sed TotalBytes += counts[Idx] * sizeof(Name##Type); \ 824193326Sed ++Idx; 825193326Sed#define ABSTRACT_TYPE(Name, Parent) 826193326Sed#include "clang/AST/TypeNodes.def" 827198092Srdivacky 828224145Sdim llvm::errs() << "Total bytes = " << TotalBytes << "\n"; 829224145Sdim 830210299Sed // Implicit special member functions. 831224145Sdim llvm::errs() << NumImplicitDefaultConstructorsDeclared << "/" 832224145Sdim << NumImplicitDefaultConstructors 833224145Sdim << " implicit default constructors created\n"; 834224145Sdim llvm::errs() << NumImplicitCopyConstructorsDeclared << "/" 835224145Sdim << NumImplicitCopyConstructors 836224145Sdim << " implicit copy constructors created\n"; 837234353Sdim if (getLangOpts().CPlusPlus) 838224145Sdim llvm::errs() << NumImplicitMoveConstructorsDeclared << "/" 839224145Sdim << NumImplicitMoveConstructors 840224145Sdim << " implicit move constructors created\n"; 841224145Sdim llvm::errs() << NumImplicitCopyAssignmentOperatorsDeclared << "/" 842224145Sdim << NumImplicitCopyAssignmentOperators 843224145Sdim << " implicit copy assignment operators created\n"; 844234353Sdim if (getLangOpts().CPlusPlus) 845224145Sdim llvm::errs() << NumImplicitMoveAssignmentOperatorsDeclared << "/" 846224145Sdim << NumImplicitMoveAssignmentOperators 847224145Sdim << " implicit move assignment operators created\n"; 848224145Sdim llvm::errs() << NumImplicitDestructorsDeclared << "/" 849224145Sdim << NumImplicitDestructors 850224145Sdim << " implicit destructors created\n"; 851224145Sdim 852193326Sed if (ExternalSource.get()) { 853224145Sdim llvm::errs() << "\n"; 854193326Sed ExternalSource->PrintStats(); 855193326Sed } 856224145Sdim 857212904Sdim BumpAlloc.PrintStats(); 858193326Sed} 859193326Sed 860226633SdimTypedefDecl *ASTContext::getInt128Decl() const { 861226633Sdim if (!Int128Decl) { 862226633Sdim TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(Int128Ty); 863226633Sdim Int128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 864226633Sdim getTranslationUnitDecl(), 865226633Sdim SourceLocation(), 866226633Sdim SourceLocation(), 867226633Sdim &Idents.get("__int128_t"), 868226633Sdim TInfo); 869226633Sdim } 870226633Sdim 871226633Sdim return Int128Decl; 872226633Sdim} 873193326Sed 874226633SdimTypedefDecl *ASTContext::getUInt128Decl() const { 875226633Sdim if (!UInt128Decl) { 876226633Sdim TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(UnsignedInt128Ty); 877226633Sdim UInt128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 878226633Sdim getTranslationUnitDecl(), 879226633Sdim SourceLocation(), 880226633Sdim SourceLocation(), 881226633Sdim &Idents.get("__uint128_t"), 882226633Sdim TInfo); 883226633Sdim } 884226633Sdim 885226633Sdim return UInt128Decl; 886226633Sdim} 887226633Sdim 888263508SdimTypeDecl *ASTContext::getFloat128StubType() const { 889263508Sdim assert(LangOpts.CPlusPlus && "should only be called for c++"); 890263508Sdim if (!Float128StubDecl) { 891263508Sdim Float128StubDecl = CXXRecordDecl::Create(const_cast<ASTContext &>(*this), 892263508Sdim TTK_Struct, 893263508Sdim getTranslationUnitDecl(), 894263508Sdim SourceLocation(), 895263508Sdim SourceLocation(), 896263508Sdim &Idents.get("__float128")); 897263508Sdim } 898263508Sdim 899263508Sdim return Float128StubDecl; 900263508Sdim} 901263508Sdim 902198893Srdivackyvoid ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) { 903198092Srdivacky BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K); 904198893Srdivacky R = CanQualType::CreateUnsafe(QualType(Ty, 0)); 905198092Srdivacky Types.push_back(Ty); 906193326Sed} 907193326Sed 908226633Sdimvoid ASTContext::InitBuiltinTypes(const TargetInfo &Target) { 909226633Sdim assert((!this->Target || this->Target == &Target) && 910226633Sdim "Incorrect target reinitialization"); 911193326Sed assert(VoidTy.isNull() && "Context reinitialized?"); 912198092Srdivacky 913226633Sdim this->Target = &Target; 914226633Sdim 915226633Sdim ABI.reset(createCXXABI(Target)); 916226633Sdim AddrSpaceMap = getAddressSpaceMap(Target, LangOpts); 917263508Sdim AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts); 918226633Sdim 919193326Sed // C99 6.2.5p19. 920193326Sed InitBuiltinType(VoidTy, BuiltinType::Void); 921198092Srdivacky 922193326Sed // C99 6.2.5p2. 923193326Sed InitBuiltinType(BoolTy, BuiltinType::Bool); 924193326Sed // C99 6.2.5p3. 925193576Sed if (LangOpts.CharIsSigned) 926193326Sed InitBuiltinType(CharTy, BuiltinType::Char_S); 927193326Sed else 928193326Sed InitBuiltinType(CharTy, BuiltinType::Char_U); 929193326Sed // C99 6.2.5p4. 930193326Sed InitBuiltinType(SignedCharTy, BuiltinType::SChar); 931193326Sed InitBuiltinType(ShortTy, BuiltinType::Short); 932193326Sed InitBuiltinType(IntTy, BuiltinType::Int); 933193326Sed InitBuiltinType(LongTy, BuiltinType::Long); 934193326Sed InitBuiltinType(LongLongTy, BuiltinType::LongLong); 935198092Srdivacky 936193326Sed // C99 6.2.5p6. 937193326Sed InitBuiltinType(UnsignedCharTy, BuiltinType::UChar); 938193326Sed InitBuiltinType(UnsignedShortTy, BuiltinType::UShort); 939193326Sed InitBuiltinType(UnsignedIntTy, BuiltinType::UInt); 940193326Sed InitBuiltinType(UnsignedLongTy, BuiltinType::ULong); 941193326Sed InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong); 942198092Srdivacky 943193326Sed // C99 6.2.5p10. 944193326Sed InitBuiltinType(FloatTy, BuiltinType::Float); 945193326Sed InitBuiltinType(DoubleTy, BuiltinType::Double); 946193326Sed InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble); 947193326Sed 948193326Sed // GNU extension, 128-bit integers. 949193326Sed InitBuiltinType(Int128Ty, BuiltinType::Int128); 950193326Sed InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128); 951193326Sed 952263508Sdim // C++ 3.9.1p5 953263508Sdim if (TargetInfo::isTypeSigned(Target.getWCharType())) 954263508Sdim InitBuiltinType(WCharTy, BuiltinType::WChar_S); 955263508Sdim else // -fshort-wchar makes wchar_t be unsigned. 956263508Sdim InitBuiltinType(WCharTy, BuiltinType::WChar_U); 957263508Sdim if (LangOpts.CPlusPlus && LangOpts.WChar) 958263508Sdim WideCharTy = WCharTy; 959263508Sdim else { 960263508Sdim // C99 (or C++ using -fno-wchar). 961263508Sdim WideCharTy = getFromTargetType(Target.getWCharType()); 962263508Sdim } 963193326Sed 964239462Sdim WIntTy = getFromTargetType(Target.getWIntType()); 965239462Sdim 966198092Srdivacky if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++ 967198092Srdivacky InitBuiltinType(Char16Ty, BuiltinType::Char16); 968198092Srdivacky else // C99 969198092Srdivacky Char16Ty = getFromTargetType(Target.getChar16Type()); 970198092Srdivacky 971198092Srdivacky if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++ 972198092Srdivacky InitBuiltinType(Char32Ty, BuiltinType::Char32); 973198092Srdivacky else // C99 974198092Srdivacky Char32Ty = getFromTargetType(Target.getChar32Type()); 975198092Srdivacky 976193326Sed // Placeholder type for type-dependent expressions whose type is 977193326Sed // completely unknown. No code should ever check a type against 978193326Sed // DependentTy and users should never see it; however, it is here to 979193326Sed // help diagnose failures to properly check for type-dependent 980193326Sed // expressions. 981193326Sed InitBuiltinType(DependentTy, BuiltinType::Dependent); 982193326Sed 983218893Sdim // Placeholder type for functions. 984218893Sdim InitBuiltinType(OverloadTy, BuiltinType::Overload); 985198092Srdivacky 986221345Sdim // Placeholder type for bound members. 987221345Sdim InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember); 988221345Sdim 989234353Sdim // Placeholder type for pseudo-objects. 990234353Sdim InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject); 991234353Sdim 992221345Sdim // "any" type; useful for debugger-like clients. 993221345Sdim InitBuiltinType(UnknownAnyTy, BuiltinType::UnknownAny); 994221345Sdim 995234353Sdim // Placeholder type for unbridged ARC casts. 996234353Sdim InitBuiltinType(ARCUnbridgedCastTy, BuiltinType::ARCUnbridgedCast); 997234353Sdim 998243830Sdim // Placeholder type for builtin functions. 999243830Sdim InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn); 1000243830Sdim 1001193326Sed // C99 6.2.5p11. 1002193326Sed FloatComplexTy = getComplexType(FloatTy); 1003193326Sed DoubleComplexTy = getComplexType(DoubleTy); 1004193326Sed LongDoubleComplexTy = getComplexType(LongDoubleTy); 1005193326Sed 1006199990Srdivacky // Builtin types for 'id', 'Class', and 'SEL'. 1007198092Srdivacky InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId); 1008198092Srdivacky InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); 1009199990Srdivacky InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); 1010249423Sdim 1011249423Sdim if (LangOpts.OpenCL) { 1012249423Sdim InitBuiltinType(OCLImage1dTy, BuiltinType::OCLImage1d); 1013249423Sdim InitBuiltinType(OCLImage1dArrayTy, BuiltinType::OCLImage1dArray); 1014249423Sdim InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer); 1015249423Sdim InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d); 1016249423Sdim InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray); 1017249423Sdim InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d); 1018249423Sdim 1019249423Sdim InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); 1020249423Sdim InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); 1021249423Sdim } 1022234353Sdim 1023234353Sdim // Builtin type for __objc_yes and __objc_no 1024234982Sdim ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ? 1025234982Sdim SignedCharTy : BoolTy); 1026234353Sdim 1027193326Sed ObjCConstantStringType = QualType(); 1028249423Sdim 1029249423Sdim ObjCSuperType = QualType(); 1030198092Srdivacky 1031193326Sed // void * type 1032193326Sed VoidPtrTy = getPointerType(VoidTy); 1033193326Sed 1034193326Sed // nullptr type (C++0x 2.14.7) 1035193326Sed InitBuiltinType(NullPtrTy, BuiltinType::NullPtr); 1036226633Sdim 1037226633Sdim // half type (OpenCL 6.1.1.1) / ARM NEON __fp16 1038226633Sdim InitBuiltinType(HalfTy, BuiltinType::Half); 1039239462Sdim 1040239462Sdim // Builtin type used to help define __builtin_va_list. 1041239462Sdim VaListTagTy = QualType(); 1042193326Sed} 1043193326Sed 1044226633SdimDiagnosticsEngine &ASTContext::getDiagnostics() const { 1045218893Sdim return SourceMgr.getDiagnostics(); 1046218893Sdim} 1047218893Sdim 1048212904SdimAttrVec& ASTContext::getDeclAttrs(const Decl *D) { 1049212904Sdim AttrVec *&Result = DeclAttrs[D]; 1050212904Sdim if (!Result) { 1051212904Sdim void *Mem = Allocate(sizeof(AttrVec)); 1052212904Sdim Result = new (Mem) AttrVec; 1053212904Sdim } 1054212904Sdim 1055212904Sdim return *Result; 1056212904Sdim} 1057212904Sdim 1058212904Sdim/// \brief Erase the attributes corresponding to the given declaration. 1059212904Sdimvoid ASTContext::eraseDeclAttrs(const Decl *D) { 1060212904Sdim llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D); 1061212904Sdim if (Pos != DeclAttrs.end()) { 1062212904Sdim Pos->second->~AttrVec(); 1063212904Sdim DeclAttrs.erase(Pos); 1064212904Sdim } 1065212904Sdim} 1066212904Sdim 1067263508Sdim// FIXME: Remove ? 1068198092SrdivackyMemberSpecializationInfo * 1069198112SrdivackyASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) { 1070198092Srdivacky assert(Var->isStaticDataMember() && "Not a static data member"); 1071263508Sdim return getTemplateOrSpecializationInfo(Var) 1072263508Sdim .dyn_cast<MemberSpecializationInfo *>(); 1073263508Sdim} 1074198092Srdivacky 1075263508SdimASTContext::TemplateOrSpecializationInfo 1076263508SdimASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) { 1077263508Sdim llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos = 1078263508Sdim TemplateOrInstantiation.find(Var); 1079263508Sdim if (Pos == TemplateOrInstantiation.end()) 1080263508Sdim return TemplateOrSpecializationInfo(); 1081263508Sdim 1082198092Srdivacky return Pos->second; 1083198092Srdivacky} 1084198092Srdivacky 1085198092Srdivackyvoid 1086198092SrdivackyASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, 1087210299Sed TemplateSpecializationKind TSK, 1088210299Sed SourceLocation PointOfInstantiation) { 1089198092Srdivacky assert(Inst->isStaticDataMember() && "Not a static data member"); 1090198092Srdivacky assert(Tmpl->isStaticDataMember() && "Not a static data member"); 1091263508Sdim setTemplateOrSpecializationInfo(Inst, new (*this) MemberSpecializationInfo( 1092263508Sdim Tmpl, TSK, PointOfInstantiation)); 1093198092Srdivacky} 1094198092Srdivacky 1095263508Sdimvoid 1096263508SdimASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst, 1097263508Sdim TemplateOrSpecializationInfo TSI) { 1098263508Sdim assert(!TemplateOrInstantiation[Inst] && 1099263508Sdim "Already noted what the variable was instantiated from"); 1100263508Sdim TemplateOrInstantiation[Inst] = TSI; 1101263508Sdim} 1102263508Sdim 1103226633SdimFunctionDecl *ASTContext::getClassScopeSpecializationPattern( 1104226633Sdim const FunctionDecl *FD){ 1105226633Sdim assert(FD && "Specialization is 0"); 1106226633Sdim llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos 1107226633Sdim = ClassScopeSpecializationPattern.find(FD); 1108226633Sdim if (Pos == ClassScopeSpecializationPattern.end()) 1109226633Sdim return 0; 1110226633Sdim 1111226633Sdim return Pos->second; 1112226633Sdim} 1113226633Sdim 1114226633Sdimvoid ASTContext::setClassScopeSpecializationPattern(FunctionDecl *FD, 1115226633Sdim FunctionDecl *Pattern) { 1116226633Sdim assert(FD && "Specialization is 0"); 1117226633Sdim assert(Pattern && "Class scope specialization pattern is 0"); 1118226633Sdim ClassScopeSpecializationPattern[FD] = Pattern; 1119226633Sdim} 1120226633Sdim 1121199482SrdivackyNamedDecl * 1122200583SrdivackyASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) { 1123199482Srdivacky llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos 1124200583Srdivacky = InstantiatedFromUsingDecl.find(UUD); 1125200583Srdivacky if (Pos == InstantiatedFromUsingDecl.end()) 1126198092Srdivacky return 0; 1127198092Srdivacky 1128198092Srdivacky return Pos->second; 1129198092Srdivacky} 1130198092Srdivacky 1131198092Srdivackyvoid 1132200583SrdivackyASTContext::setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern) { 1133200583Srdivacky assert((isa<UsingDecl>(Pattern) || 1134200583Srdivacky isa<UnresolvedUsingValueDecl>(Pattern) || 1135200583Srdivacky isa<UnresolvedUsingTypenameDecl>(Pattern)) && 1136200583Srdivacky "pattern decl is not a using decl"); 1137200583Srdivacky assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists"); 1138200583Srdivacky InstantiatedFromUsingDecl[Inst] = Pattern; 1139198092Srdivacky} 1140198092Srdivacky 1141200583SrdivackyUsingShadowDecl * 1142200583SrdivackyASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) { 1143200583Srdivacky llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos 1144200583Srdivacky = InstantiatedFromUsingShadowDecl.find(Inst); 1145200583Srdivacky if (Pos == InstantiatedFromUsingShadowDecl.end()) 1146200583Srdivacky return 0; 1147200583Srdivacky 1148200583Srdivacky return Pos->second; 1149200583Srdivacky} 1150200583Srdivacky 1151200583Srdivackyvoid 1152200583SrdivackyASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst, 1153200583Srdivacky UsingShadowDecl *Pattern) { 1154200583Srdivacky assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists"); 1155200583Srdivacky InstantiatedFromUsingShadowDecl[Inst] = Pattern; 1156200583Srdivacky} 1157200583Srdivacky 1158198092SrdivackyFieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) { 1159198092Srdivacky llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos 1160198092Srdivacky = InstantiatedFromUnnamedFieldDecl.find(Field); 1161198092Srdivacky if (Pos == InstantiatedFromUnnamedFieldDecl.end()) 1162198092Srdivacky return 0; 1163198092Srdivacky 1164198092Srdivacky return Pos->second; 1165198092Srdivacky} 1166198092Srdivacky 1167198092Srdivackyvoid ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, 1168198092Srdivacky FieldDecl *Tmpl) { 1169198092Srdivacky assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed"); 1170198092Srdivacky assert(!Tmpl->getDeclName() && "Template field decl is not unnamed"); 1171198092Srdivacky assert(!InstantiatedFromUnnamedFieldDecl[Inst] && 1172198092Srdivacky "Already noted what unnamed field was instantiated from"); 1173198092Srdivacky 1174198092Srdivacky InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl; 1175198092Srdivacky} 1176198092Srdivacky 1177204643SrdivackyASTContext::overridden_cxx_method_iterator 1178204643SrdivackyASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { 1179204643Srdivacky llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos 1180243830Sdim = OverriddenMethods.find(Method->getCanonicalDecl()); 1181204643Srdivacky if (Pos == OverriddenMethods.end()) 1182204643Srdivacky return 0; 1183204643Srdivacky 1184204643Srdivacky return Pos->second.begin(); 1185204643Srdivacky} 1186204643Srdivacky 1187204643SrdivackyASTContext::overridden_cxx_method_iterator 1188204643SrdivackyASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { 1189204643Srdivacky llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos 1190243830Sdim = OverriddenMethods.find(Method->getCanonicalDecl()); 1191204643Srdivacky if (Pos == OverriddenMethods.end()) 1192204643Srdivacky return 0; 1193204643Srdivacky 1194204643Srdivacky return Pos->second.end(); 1195204643Srdivacky} 1196204643Srdivacky 1197210299Sedunsigned 1198210299SedASTContext::overridden_methods_size(const CXXMethodDecl *Method) const { 1199210299Sed llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos 1200243830Sdim = OverriddenMethods.find(Method->getCanonicalDecl()); 1201210299Sed if (Pos == OverriddenMethods.end()) 1202210299Sed return 0; 1203210299Sed 1204210299Sed return Pos->second.size(); 1205210299Sed} 1206210299Sed 1207204643Srdivackyvoid ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, 1208204643Srdivacky const CXXMethodDecl *Overridden) { 1209243830Sdim assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl()); 1210204643Srdivacky OverriddenMethods[Method].push_back(Overridden); 1211204643Srdivacky} 1212204643Srdivacky 1213243830Sdimvoid ASTContext::getOverriddenMethods( 1214243830Sdim const NamedDecl *D, 1215243830Sdim SmallVectorImpl<const NamedDecl *> &Overridden) const { 1216243830Sdim assert(D); 1217243830Sdim 1218243830Sdim if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) { 1219251662Sdim Overridden.append(overridden_methods_begin(CXXMethod), 1220251662Sdim overridden_methods_end(CXXMethod)); 1221243830Sdim return; 1222243830Sdim } 1223243830Sdim 1224243830Sdim const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D); 1225243830Sdim if (!Method) 1226243830Sdim return; 1227243830Sdim 1228243830Sdim SmallVector<const ObjCMethodDecl *, 8> OverDecls; 1229243830Sdim Method->getOverriddenMethods(OverDecls); 1230243830Sdim Overridden.append(OverDecls.begin(), OverDecls.end()); 1231243830Sdim} 1232243830Sdim 1233234353Sdimvoid ASTContext::addedLocalImportDecl(ImportDecl *Import) { 1234234353Sdim assert(!Import->NextLocalImport && "Import declaration already in the chain"); 1235234353Sdim assert(!Import->isFromASTFile() && "Non-local import declaration"); 1236234353Sdim if (!FirstLocalImport) { 1237234353Sdim FirstLocalImport = Import; 1238234353Sdim LastLocalImport = Import; 1239234353Sdim return; 1240234353Sdim } 1241234353Sdim 1242234353Sdim LastLocalImport->NextLocalImport = Import; 1243234353Sdim LastLocalImport = Import; 1244234353Sdim} 1245234353Sdim 1246193326Sed//===----------------------------------------------------------------------===// 1247193326Sed// Type Sizing and Analysis 1248193326Sed//===----------------------------------------------------------------------===// 1249193326Sed 1250193326Sed/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified 1251193326Sed/// scalar floating point type. 1252193326Sedconst llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { 1253198092Srdivacky const BuiltinType *BT = T->getAs<BuiltinType>(); 1254193326Sed assert(BT && "Not a floating point type!"); 1255193326Sed switch (BT->getKind()) { 1256226633Sdim default: llvm_unreachable("Not a floating point type!"); 1257226633Sdim case BuiltinType::Half: return Target->getHalfFormat(); 1258226633Sdim case BuiltinType::Float: return Target->getFloatFormat(); 1259226633Sdim case BuiltinType::Double: return Target->getDoubleFormat(); 1260226633Sdim case BuiltinType::LongDouble: return Target->getLongDoubleFormat(); 1261193326Sed } 1262193326Sed} 1263193326Sed 1264263508SdimCharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { 1265226633Sdim unsigned Align = Target->getCharWidth(); 1266193326Sed 1267218893Sdim bool UseAlignAttrOnly = false; 1268218893Sdim if (unsigned AlignFromAttr = D->getMaxAlignment()) { 1269218893Sdim Align = AlignFromAttr; 1270193326Sed 1271218893Sdim // __attribute__((aligned)) can increase or decrease alignment 1272218893Sdim // *except* on a struct or struct member, where it only increases 1273218893Sdim // alignment unless 'packed' is also specified. 1274218893Sdim // 1275226633Sdim // It is an error for alignas to decrease alignment, so we can 1276218893Sdim // ignore that possibility; Sema should diagnose it. 1277218893Sdim if (isa<FieldDecl>(D)) { 1278218893Sdim UseAlignAttrOnly = D->hasAttr<PackedAttr>() || 1279218893Sdim cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>(); 1280218893Sdim } else { 1281218893Sdim UseAlignAttrOnly = true; 1282218893Sdim } 1283218893Sdim } 1284223017Sdim else if (isa<FieldDecl>(D)) 1285223017Sdim UseAlignAttrOnly = 1286223017Sdim D->hasAttr<PackedAttr>() || 1287223017Sdim cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>(); 1288218893Sdim 1289218893Sdim // If we're using the align attribute only, just ignore everything 1290218893Sdim // else about the declaration and its type. 1291218893Sdim if (UseAlignAttrOnly) { 1292218893Sdim // do nothing 1293218893Sdim 1294218893Sdim } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 1295193326Sed QualType T = VD->getType(); 1296198092Srdivacky if (const ReferenceType* RT = T->getAs<ReferenceType>()) { 1297263508Sdim if (ForAlignof) 1298199990Srdivacky T = RT->getPointeeType(); 1299199990Srdivacky else 1300199990Srdivacky T = getPointerType(RT->getPointeeType()); 1301199990Srdivacky } 1302199990Srdivacky if (!T->isIncompleteType() && !T->isFunctionType()) { 1303218893Sdim // Adjust alignments of declarations with array type by the 1304218893Sdim // large-array alignment on the target. 1305263508Sdim if (const ArrayType *arrayType = getAsArrayType(T)) { 1306263508Sdim unsigned MinWidth = Target->getLargeArrayMinWidth(); 1307263508Sdim if (!ForAlignof && MinWidth) { 1308263508Sdim if (isa<VariableArrayType>(arrayType)) 1309263508Sdim Align = std::max(Align, Target->getLargeArrayAlign()); 1310263508Sdim else if (isa<ConstantArrayType>(arrayType) && 1311263508Sdim MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType))) 1312263508Sdim Align = std::max(Align, Target->getLargeArrayAlign()); 1313263508Sdim } 1314218893Sdim 1315218893Sdim // Walk through any array types while we're at it. 1316218893Sdim T = getBaseElementType(arrayType); 1317210299Sed } 1318193326Sed Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); 1319251662Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1320251662Sdim if (VD->hasGlobalStorage()) 1321251662Sdim Align = std::max(Align, getTargetInfo().getMinGlobalAlign()); 1322251662Sdim } 1323193326Sed } 1324218893Sdim 1325218893Sdim // Fields can be subject to extra alignment constraints, like if 1326218893Sdim // the field is packed, the struct is packed, or the struct has a 1327218893Sdim // a max-field-alignment constraint (#pragma pack). So calculate 1328218893Sdim // the actual alignment of the field within the struct, and then 1329218893Sdim // (as we're expected to) constrain that by the alignment of the type. 1330263508Sdim if (const FieldDecl *Field = dyn_cast<FieldDecl>(VD)) { 1331263508Sdim const RecordDecl *Parent = Field->getParent(); 1332263508Sdim // We can only produce a sensible answer if the record is valid. 1333263508Sdim if (!Parent->isInvalidDecl()) { 1334263508Sdim const ASTRecordLayout &Layout = getASTRecordLayout(Parent); 1335218893Sdim 1336263508Sdim // Start with the record's overall alignment. 1337263508Sdim unsigned FieldAlign = toBits(Layout.getAlignment()); 1338218893Sdim 1339263508Sdim // Use the GCD of that and the offset within the record. 1340263508Sdim uint64_t Offset = Layout.getFieldOffset(Field->getFieldIndex()); 1341263508Sdim if (Offset > 0) { 1342263508Sdim // Alignment is always a power of 2, so the GCD will be a power of 2, 1343263508Sdim // which means we get to do this crazy thing instead of Euclid's. 1344263508Sdim uint64_t LowBitOfOffset = Offset & (~Offset + 1); 1345263508Sdim if (LowBitOfOffset < FieldAlign) 1346263508Sdim FieldAlign = static_cast<unsigned>(LowBitOfOffset); 1347263508Sdim } 1348263508Sdim 1349263508Sdim Align = std::min(Align, FieldAlign); 1350218893Sdim } 1351204643Srdivacky } 1352193326Sed } 1353193326Sed 1354218893Sdim return toCharUnitsFromBits(Align); 1355193326Sed} 1356193326Sed 1357243830Sdim// getTypeInfoDataSizeInChars - Return the size of a type, in 1358243830Sdim// chars. If the type is a record, its data size is returned. This is 1359243830Sdim// the size of the memcpy that's performed when assigning this type 1360243830Sdim// using a trivial copy/move assignment operator. 1361208600Srdivackystd::pair<CharUnits, CharUnits> 1362243830SdimASTContext::getTypeInfoDataSizeInChars(QualType T) const { 1363243830Sdim std::pair<CharUnits, CharUnits> sizeAndAlign = getTypeInfoInChars(T); 1364243830Sdim 1365243830Sdim // In C++, objects can sometimes be allocated into the tail padding 1366243830Sdim // of a base-class subobject. We decide whether that's possible 1367243830Sdim // during class layout, so here we can just trust the layout results. 1368243830Sdim if (getLangOpts().CPlusPlus) { 1369243830Sdim if (const RecordType *RT = T->getAs<RecordType>()) { 1370243830Sdim const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl()); 1371243830Sdim sizeAndAlign.first = layout.getDataSize(); 1372243830Sdim } 1373243830Sdim } 1374243830Sdim 1375243830Sdim return sizeAndAlign; 1376243830Sdim} 1377243830Sdim 1378263508Sdim/// getConstantArrayInfoInChars - Performing the computation in CharUnits 1379263508Sdim/// instead of in bits prevents overflowing the uint64_t for some large arrays. 1380243830Sdimstd::pair<CharUnits, CharUnits> 1381263508Sdimstatic getConstantArrayInfoInChars(const ASTContext &Context, 1382263508Sdim const ConstantArrayType *CAT) { 1383263508Sdim std::pair<CharUnits, CharUnits> EltInfo = 1384263508Sdim Context.getTypeInfoInChars(CAT->getElementType()); 1385263508Sdim uint64_t Size = CAT->getSize().getZExtValue(); 1386263508Sdim assert((Size == 0 || static_cast<uint64_t>(EltInfo.first.getQuantity()) <= 1387263508Sdim (uint64_t)(-1)/Size) && 1388263508Sdim "Overflow in array type char size evaluation"); 1389263508Sdim uint64_t Width = EltInfo.first.getQuantity() * Size; 1390263508Sdim unsigned Align = EltInfo.second.getQuantity(); 1391263508Sdim if (!Context.getTargetInfo().getCXXABI().isMicrosoft() || 1392263508Sdim Context.getTargetInfo().getPointerWidth(0) == 64) 1393263508Sdim Width = llvm::RoundUpToAlignment(Width, Align); 1394263508Sdim return std::make_pair(CharUnits::fromQuantity(Width), 1395263508Sdim CharUnits::fromQuantity(Align)); 1396263508Sdim} 1397263508Sdim 1398263508Sdimstd::pair<CharUnits, CharUnits> 1399218893SdimASTContext::getTypeInfoInChars(const Type *T) const { 1400263508Sdim if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) 1401263508Sdim return getConstantArrayInfoInChars(*this, CAT); 1402208600Srdivacky std::pair<uint64_t, unsigned> Info = getTypeInfo(T); 1403218893Sdim return std::make_pair(toCharUnitsFromBits(Info.first), 1404218893Sdim toCharUnitsFromBits(Info.second)); 1405208600Srdivacky} 1406208600Srdivacky 1407208600Srdivackystd::pair<CharUnits, CharUnits> 1408218893SdimASTContext::getTypeInfoInChars(QualType T) const { 1409208600Srdivacky return getTypeInfoInChars(T.getTypePtr()); 1410208600Srdivacky} 1411208600Srdivacky 1412234353Sdimstd::pair<uint64_t, unsigned> ASTContext::getTypeInfo(const Type *T) const { 1413234353Sdim TypeInfoMap::iterator it = MemoizedTypeInfo.find(T); 1414234353Sdim if (it != MemoizedTypeInfo.end()) 1415234353Sdim return it->second; 1416234353Sdim 1417234353Sdim std::pair<uint64_t, unsigned> Info = getTypeInfoImpl(T); 1418234353Sdim MemoizedTypeInfo.insert(std::make_pair(T, Info)); 1419234353Sdim return Info; 1420234353Sdim} 1421234353Sdim 1422234353Sdim/// getTypeInfoImpl - Return the size of the specified type, in bits. This 1423234353Sdim/// method does not work on incomplete types. 1424198092Srdivacky/// 1425198092Srdivacky/// FIXME: Pointers into different addr spaces could have different sizes and 1426198092Srdivacky/// alignment requirements: getPointerInfo should take an AddrSpace, this 1427198092Srdivacky/// should take a QualType, &c. 1428193326Sedstd::pair<uint64_t, unsigned> 1429234353SdimASTContext::getTypeInfoImpl(const Type *T) const { 1430193326Sed uint64_t Width=0; 1431193326Sed unsigned Align=8; 1432193326Sed switch (T->getTypeClass()) { 1433193326Sed#define TYPE(Class, Base) 1434193326Sed#define ABSTRACT_TYPE(Class, Base) 1435193326Sed#define NON_CANONICAL_TYPE(Class, Base) 1436193326Sed#define DEPENDENT_TYPE(Class, Base) case Type::Class: 1437263508Sdim#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) \ 1438263508Sdim case Type::Class: \ 1439263508Sdim assert(!T->isDependentType() && "should not see dependent types here"); \ 1440263508Sdim return getTypeInfo(cast<Class##Type>(T)->desugar().getTypePtr()); 1441193326Sed#include "clang/AST/TypeNodes.def" 1442224145Sdim llvm_unreachable("Should not see dependent types"); 1443193326Sed 1444193326Sed case Type::FunctionNoProto: 1445193326Sed case Type::FunctionProto: 1446193326Sed // GCC extension: alignof(function) = 32 bits 1447193326Sed Width = 0; 1448193326Sed Align = 32; 1449193326Sed break; 1450193326Sed 1451193326Sed case Type::IncompleteArray: 1452193326Sed case Type::VariableArray: 1453193326Sed Width = 0; 1454193326Sed Align = getTypeAlign(cast<ArrayType>(T)->getElementType()); 1455193326Sed break; 1456193326Sed 1457193326Sed case Type::ConstantArray: { 1458193326Sed const ConstantArrayType *CAT = cast<ConstantArrayType>(T); 1459198092Srdivacky 1460193326Sed std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType()); 1461234353Sdim uint64_t Size = CAT->getSize().getZExtValue(); 1462234353Sdim assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && 1463234353Sdim "Overflow in array type bit size evaluation"); 1464234353Sdim Width = EltInfo.first*Size; 1465193326Sed Align = EltInfo.second; 1466263508Sdim if (!getTargetInfo().getCXXABI().isMicrosoft() || 1467263508Sdim getTargetInfo().getPointerWidth(0) == 64) 1468263508Sdim Width = llvm::RoundUpToAlignment(Width, Align); 1469193326Sed break; 1470193326Sed } 1471193326Sed case Type::ExtVector: 1472193326Sed case Type::Vector: { 1473198398Srdivacky const VectorType *VT = cast<VectorType>(T); 1474198398Srdivacky std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(VT->getElementType()); 1475198398Srdivacky Width = EltInfo.first*VT->getNumElements(); 1476193326Sed Align = Width; 1477193326Sed // If the alignment is not a power of 2, round up to the next power of 2. 1478193326Sed // This happens for non-power-of-2 length vectors. 1479207619Srdivacky if (Align & (Align-1)) { 1480198398Srdivacky Align = llvm::NextPowerOf2(Align); 1481198398Srdivacky Width = llvm::RoundUpToAlignment(Width, Align); 1482198398Srdivacky } 1483239462Sdim // Adjust the alignment based on the target max. 1484239462Sdim uint64_t TargetVectorAlign = Target->getMaxVectorAlign(); 1485239462Sdim if (TargetVectorAlign && TargetVectorAlign < Align) 1486239462Sdim Align = TargetVectorAlign; 1487193326Sed break; 1488193326Sed } 1489193326Sed 1490193326Sed case Type::Builtin: 1491193326Sed switch (cast<BuiltinType>(T)->getKind()) { 1492226633Sdim default: llvm_unreachable("Unknown builtin type!"); 1493193326Sed case BuiltinType::Void: 1494193326Sed // GCC extension: alignof(void) = 8 bits. 1495193326Sed Width = 0; 1496193326Sed Align = 8; 1497193326Sed break; 1498193326Sed 1499193326Sed case BuiltinType::Bool: 1500226633Sdim Width = Target->getBoolWidth(); 1501226633Sdim Align = Target->getBoolAlign(); 1502193326Sed break; 1503193326Sed case BuiltinType::Char_S: 1504193326Sed case BuiltinType::Char_U: 1505193326Sed case BuiltinType::UChar: 1506193326Sed case BuiltinType::SChar: 1507226633Sdim Width = Target->getCharWidth(); 1508226633Sdim Align = Target->getCharAlign(); 1509193326Sed break; 1510218893Sdim case BuiltinType::WChar_S: 1511218893Sdim case BuiltinType::WChar_U: 1512226633Sdim Width = Target->getWCharWidth(); 1513226633Sdim Align = Target->getWCharAlign(); 1514193326Sed break; 1515198092Srdivacky case BuiltinType::Char16: 1516226633Sdim Width = Target->getChar16Width(); 1517226633Sdim Align = Target->getChar16Align(); 1518198092Srdivacky break; 1519198092Srdivacky case BuiltinType::Char32: 1520226633Sdim Width = Target->getChar32Width(); 1521226633Sdim Align = Target->getChar32Align(); 1522198092Srdivacky break; 1523193326Sed case BuiltinType::UShort: 1524193326Sed case BuiltinType::Short: 1525226633Sdim Width = Target->getShortWidth(); 1526226633Sdim Align = Target->getShortAlign(); 1527193326Sed break; 1528193326Sed case BuiltinType::UInt: 1529193326Sed case BuiltinType::Int: 1530226633Sdim Width = Target->getIntWidth(); 1531226633Sdim Align = Target->getIntAlign(); 1532193326Sed break; 1533193326Sed case BuiltinType::ULong: 1534193326Sed case BuiltinType::Long: 1535226633Sdim Width = Target->getLongWidth(); 1536226633Sdim Align = Target->getLongAlign(); 1537193326Sed break; 1538193326Sed case BuiltinType::ULongLong: 1539193326Sed case BuiltinType::LongLong: 1540226633Sdim Width = Target->getLongLongWidth(); 1541226633Sdim Align = Target->getLongLongAlign(); 1542193326Sed break; 1543193326Sed case BuiltinType::Int128: 1544193326Sed case BuiltinType::UInt128: 1545193326Sed Width = 128; 1546193326Sed Align = 128; // int128_t is 128-bit aligned on all targets. 1547193326Sed break; 1548226633Sdim case BuiltinType::Half: 1549226633Sdim Width = Target->getHalfWidth(); 1550226633Sdim Align = Target->getHalfAlign(); 1551226633Sdim break; 1552193326Sed case BuiltinType::Float: 1553226633Sdim Width = Target->getFloatWidth(); 1554226633Sdim Align = Target->getFloatAlign(); 1555193326Sed break; 1556193326Sed case BuiltinType::Double: 1557226633Sdim Width = Target->getDoubleWidth(); 1558226633Sdim Align = Target->getDoubleAlign(); 1559193326Sed break; 1560193326Sed case BuiltinType::LongDouble: 1561226633Sdim Width = Target->getLongDoubleWidth(); 1562226633Sdim Align = Target->getLongDoubleAlign(); 1563193326Sed break; 1564193326Sed case BuiltinType::NullPtr: 1565226633Sdim Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t) 1566226633Sdim Align = Target->getPointerAlign(0); // == sizeof(void*) 1567193326Sed break; 1568212904Sdim case BuiltinType::ObjCId: 1569212904Sdim case BuiltinType::ObjCClass: 1570212904Sdim case BuiltinType::ObjCSel: 1571226633Sdim Width = Target->getPointerWidth(0); 1572226633Sdim Align = Target->getPointerAlign(0); 1573212904Sdim break; 1574249423Sdim case BuiltinType::OCLSampler: 1575249423Sdim // Samplers are modeled as integers. 1576249423Sdim Width = Target->getIntWidth(); 1577249423Sdim Align = Target->getIntAlign(); 1578249423Sdim break; 1579249423Sdim case BuiltinType::OCLEvent: 1580249423Sdim case BuiltinType::OCLImage1d: 1581249423Sdim case BuiltinType::OCLImage1dArray: 1582249423Sdim case BuiltinType::OCLImage1dBuffer: 1583249423Sdim case BuiltinType::OCLImage2d: 1584249423Sdim case BuiltinType::OCLImage2dArray: 1585249423Sdim case BuiltinType::OCLImage3d: 1586249423Sdim // Currently these types are pointers to opaque types. 1587249423Sdim Width = Target->getPointerWidth(0); 1588249423Sdim Align = Target->getPointerAlign(0); 1589249423Sdim break; 1590193326Sed } 1591193326Sed break; 1592194613Sed case Type::ObjCObjectPointer: 1593226633Sdim Width = Target->getPointerWidth(0); 1594226633Sdim Align = Target->getPointerAlign(0); 1595193326Sed break; 1596193326Sed case Type::BlockPointer: { 1597221345Sdim unsigned AS = getTargetAddressSpace( 1598221345Sdim cast<BlockPointerType>(T)->getPointeeType()); 1599226633Sdim Width = Target->getPointerWidth(AS); 1600226633Sdim Align = Target->getPointerAlign(AS); 1601193326Sed break; 1602193326Sed } 1603199990Srdivacky case Type::LValueReference: 1604199990Srdivacky case Type::RValueReference: { 1605199990Srdivacky // alignof and sizeof should never enter this code path here, so we go 1606199990Srdivacky // the pointer route. 1607221345Sdim unsigned AS = getTargetAddressSpace( 1608221345Sdim cast<ReferenceType>(T)->getPointeeType()); 1609226633Sdim Width = Target->getPointerWidth(AS); 1610226633Sdim Align = Target->getPointerAlign(AS); 1611199990Srdivacky break; 1612199990Srdivacky } 1613193326Sed case Type::Pointer: { 1614221345Sdim unsigned AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType()); 1615226633Sdim Width = Target->getPointerWidth(AS); 1616226633Sdim Align = Target->getPointerAlign(AS); 1617193326Sed break; 1618193326Sed } 1619193326Sed case Type::MemberPointer: { 1620212904Sdim const MemberPointerType *MPT = cast<MemberPointerType>(T); 1621249423Sdim llvm::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT); 1622193326Sed break; 1623193326Sed } 1624193326Sed case Type::Complex: { 1625193326Sed // Complex types have the same alignment as their elements, but twice the 1626193326Sed // size. 1627198092Srdivacky std::pair<uint64_t, unsigned> EltInfo = 1628193326Sed getTypeInfo(cast<ComplexType>(T)->getElementType()); 1629193326Sed Width = EltInfo.first*2; 1630193326Sed Align = EltInfo.second; 1631193326Sed break; 1632193326Sed } 1633208600Srdivacky case Type::ObjCObject: 1634208600Srdivacky return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr()); 1635263508Sdim case Type::Decayed: 1636263508Sdim return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr()); 1637193326Sed case Type::ObjCInterface: { 1638193326Sed const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T); 1639193326Sed const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); 1640218893Sdim Width = toBits(Layout.getSize()); 1641218893Sdim Align = toBits(Layout.getAlignment()); 1642193326Sed break; 1643193326Sed } 1644193326Sed case Type::Record: 1645193326Sed case Type::Enum: { 1646193326Sed const TagType *TT = cast<TagType>(T); 1647193326Sed 1648193326Sed if (TT->getDecl()->isInvalidDecl()) { 1649221345Sdim Width = 8; 1650221345Sdim Align = 8; 1651193326Sed break; 1652193326Sed } 1653198092Srdivacky 1654193326Sed if (const EnumType *ET = dyn_cast<EnumType>(TT)) 1655193326Sed return getTypeInfo(ET->getDecl()->getIntegerType()); 1656193326Sed 1657193326Sed const RecordType *RT = cast<RecordType>(TT); 1658193326Sed const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl()); 1659218893Sdim Width = toBits(Layout.getSize()); 1660218893Sdim Align = toBits(Layout.getAlignment()); 1661193326Sed break; 1662193326Sed } 1663193326Sed 1664198398Srdivacky case Type::SubstTemplateTypeParm: 1665198398Srdivacky return getTypeInfo(cast<SubstTemplateTypeParmType>(T)-> 1666198398Srdivacky getReplacementType().getTypePtr()); 1667198092Srdivacky 1668218893Sdim case Type::Auto: { 1669218893Sdim const AutoType *A = cast<AutoType>(T); 1670251662Sdim assert(!A->getDeducedType().isNull() && 1671251662Sdim "cannot request the size of an undeduced or dependent auto type"); 1672219077Sdim return getTypeInfo(A->getDeducedType().getTypePtr()); 1673218893Sdim } 1674218893Sdim 1675218893Sdim case Type::Paren: 1676218893Sdim return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr()); 1677218893Sdim 1678193326Sed case Type::Typedef: { 1679221345Sdim const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl(); 1680212904Sdim std::pair<uint64_t, unsigned> Info 1681212904Sdim = getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); 1682218893Sdim // If the typedef has an aligned attribute on it, it overrides any computed 1683218893Sdim // alignment we have. This violates the GCC documentation (which says that 1684218893Sdim // attribute(aligned) can only round up) but matches its implementation. 1685218893Sdim if (unsigned AttrAlign = Typedef->getMaxAlignment()) 1686218893Sdim Align = AttrAlign; 1687218893Sdim else 1688218893Sdim Align = Info.second; 1689212904Sdim Width = Info.first; 1690193326Sed break; 1691193326Sed } 1692193326Sed 1693208600Srdivacky case Type::Elaborated: 1694208600Srdivacky return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr()); 1695198092Srdivacky 1696218893Sdim case Type::Attributed: 1697218893Sdim return getTypeInfo( 1698218893Sdim cast<AttributedType>(T)->getEquivalentType().getTypePtr()); 1699218893Sdim 1700226633Sdim case Type::Atomic: { 1701249423Sdim // Start with the base type information. 1702226633Sdim std::pair<uint64_t, unsigned> Info 1703226633Sdim = getTypeInfo(cast<AtomicType>(T)->getValueType()); 1704226633Sdim Width = Info.first; 1705226633Sdim Align = Info.second; 1706249423Sdim 1707249423Sdim // If the size of the type doesn't exceed the platform's max 1708249423Sdim // atomic promotion width, make the size and alignment more 1709249423Sdim // favorable to atomic operations: 1710249423Sdim if (Width != 0 && Width <= Target->getMaxAtomicPromoteWidth()) { 1711249423Sdim // Round the size up to a power of 2. 1712249423Sdim if (!llvm::isPowerOf2_64(Width)) 1713249423Sdim Width = llvm::NextPowerOf2(Width); 1714249423Sdim 1715249423Sdim // Set the alignment equal to the size. 1716226633Sdim Align = static_cast<unsigned>(Width); 1717226633Sdim } 1718223017Sdim } 1719223017Sdim 1720226633Sdim } 1721226633Sdim 1722226633Sdim assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2"); 1723193326Sed return std::make_pair(Width, Align); 1724193326Sed} 1725193326Sed 1726218893Sdim/// toCharUnitsFromBits - Convert a size in bits to a size in characters. 1727218893SdimCharUnits ASTContext::toCharUnitsFromBits(int64_t BitSize) const { 1728218893Sdim return CharUnits::fromQuantity(BitSize / getCharWidth()); 1729218893Sdim} 1730218893Sdim 1731218893Sdim/// toBits - Convert a size in characters to a size in characters. 1732218893Sdimint64_t ASTContext::toBits(CharUnits CharSize) const { 1733218893Sdim return CharSize.getQuantity() * getCharWidth(); 1734218893Sdim} 1735218893Sdim 1736201361Srdivacky/// getTypeSizeInChars - Return the size of the specified type, in characters. 1737201361Srdivacky/// This method does not work on incomplete types. 1738218893SdimCharUnits ASTContext::getTypeSizeInChars(QualType T) const { 1739263508Sdim return getTypeInfoInChars(T).first; 1740201361Srdivacky} 1741218893SdimCharUnits ASTContext::getTypeSizeInChars(const Type *T) const { 1742263508Sdim return getTypeInfoInChars(T).first; 1743201361Srdivacky} 1744201361Srdivacky 1745203955Srdivacky/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in 1746203955Srdivacky/// characters. This method does not work on incomplete types. 1747218893SdimCharUnits ASTContext::getTypeAlignInChars(QualType T) const { 1748218893Sdim return toCharUnitsFromBits(getTypeAlign(T)); 1749203955Srdivacky} 1750218893SdimCharUnits ASTContext::getTypeAlignInChars(const Type *T) const { 1751218893Sdim return toCharUnitsFromBits(getTypeAlign(T)); 1752203955Srdivacky} 1753203955Srdivacky 1754193326Sed/// getPreferredTypeAlign - Return the "preferred" alignment of the specified 1755193326Sed/// type for the current target in bits. This can be different than the ABI 1756193326Sed/// alignment in cases where it is beneficial for performance to overalign 1757193326Sed/// a data type. 1758218893Sdimunsigned ASTContext::getPreferredTypeAlign(const Type *T) const { 1759193326Sed unsigned ABIAlign = getTypeAlign(T); 1760193326Sed 1761263508Sdim if (Target->getTriple().getArch() == llvm::Triple::xcore) 1762263508Sdim return ABIAlign; // Never overalign on XCore. 1763263508Sdim 1764193326Sed // Double and long long should be naturally aligned if possible. 1765198092Srdivacky if (const ComplexType* CT = T->getAs<ComplexType>()) 1766193326Sed T = CT->getElementType().getTypePtr(); 1767193326Sed if (T->isSpecificBuiltinType(BuiltinType::Double) || 1768234353Sdim T->isSpecificBuiltinType(BuiltinType::LongLong) || 1769234353Sdim T->isSpecificBuiltinType(BuiltinType::ULongLong)) 1770193326Sed return std::max(ABIAlign, (unsigned)getTypeSize(T)); 1771193326Sed 1772193326Sed return ABIAlign; 1773193326Sed} 1774193326Sed 1775251662Sdim/// getAlignOfGlobalVar - Return the alignment in bits that should be given 1776251662Sdim/// to a global variable of the specified type. 1777251662Sdimunsigned ASTContext::getAlignOfGlobalVar(QualType T) const { 1778251662Sdim return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign()); 1779251662Sdim} 1780251662Sdim 1781251662Sdim/// getAlignOfGlobalVarInChars - Return the alignment in characters that 1782251662Sdim/// should be given to a global variable of the specified type. 1783251662SdimCharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T) const { 1784251662Sdim return toCharUnitsFromBits(getAlignOfGlobalVar(T)); 1785251662Sdim} 1786251662Sdim 1787212904Sdim/// DeepCollectObjCIvars - 1788212904Sdim/// This routine first collects all declared, but not synthesized, ivars in 1789212904Sdim/// super class and then collects all ivars, including those synthesized for 1790212904Sdim/// current class. This routine is used for implementation of current class 1791212904Sdim/// when all ivars, declared and synthesized are known. 1792193326Sed/// 1793212904Sdimvoid ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, 1794212904Sdim bool leafClass, 1795226633Sdim SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const { 1796212904Sdim if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass()) 1797212904Sdim DeepCollectObjCIvars(SuperClass, false, Ivars); 1798212904Sdim if (!leafClass) { 1799212904Sdim for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), 1800212904Sdim E = OI->ivar_end(); I != E; ++I) 1801204643Srdivacky Ivars.push_back(*I); 1802226633Sdim } else { 1803224145Sdim ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI); 1804226633Sdim for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv; 1805224145Sdim Iv= Iv->getNextIvar()) 1806224145Sdim Ivars.push_back(Iv); 1807224145Sdim } 1808193326Sed} 1809193326Sed 1810198893Srdivacky/// CollectInheritedProtocols - Collect all protocols in current class and 1811198893Srdivacky/// those inherited by it. 1812198893Srdivackyvoid ASTContext::CollectInheritedProtocols(const Decl *CDecl, 1813203955Srdivacky llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) { 1814198893Srdivacky if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1815212904Sdim // We can use protocol_iterator here instead of 1816212904Sdim // all_referenced_protocol_iterator since we are walking all categories. 1817212904Sdim for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(), 1818212904Sdim PE = OI->all_referenced_protocol_end(); P != PE; ++P) { 1819198893Srdivacky ObjCProtocolDecl *Proto = (*P); 1820234353Sdim Protocols.insert(Proto->getCanonicalDecl()); 1821198893Srdivacky for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), 1822204643Srdivacky PE = Proto->protocol_end(); P != PE; ++P) { 1823234353Sdim Protocols.insert((*P)->getCanonicalDecl()); 1824198893Srdivacky CollectInheritedProtocols(*P, Protocols); 1825198893Srdivacky } 1826204643Srdivacky } 1827198893Srdivacky 1828198893Srdivacky // Categories of this Interface. 1829249423Sdim for (ObjCInterfaceDecl::visible_categories_iterator 1830249423Sdim Cat = OI->visible_categories_begin(), 1831249423Sdim CatEnd = OI->visible_categories_end(); 1832249423Sdim Cat != CatEnd; ++Cat) { 1833249423Sdim CollectInheritedProtocols(*Cat, Protocols); 1834249423Sdim } 1835249423Sdim 1836198893Srdivacky if (ObjCInterfaceDecl *SD = OI->getSuperClass()) 1837198893Srdivacky while (SD) { 1838198893Srdivacky CollectInheritedProtocols(SD, Protocols); 1839198893Srdivacky SD = SD->getSuperClass(); 1840198893Srdivacky } 1841207619Srdivacky } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1842212904Sdim for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(), 1843198893Srdivacky PE = OC->protocol_end(); P != PE; ++P) { 1844198893Srdivacky ObjCProtocolDecl *Proto = (*P); 1845234353Sdim Protocols.insert(Proto->getCanonicalDecl()); 1846198893Srdivacky for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), 1847198893Srdivacky PE = Proto->protocol_end(); P != PE; ++P) 1848198893Srdivacky CollectInheritedProtocols(*P, Protocols); 1849198893Srdivacky } 1850207619Srdivacky } else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1851198893Srdivacky for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(), 1852198893Srdivacky PE = OP->protocol_end(); P != PE; ++P) { 1853198893Srdivacky ObjCProtocolDecl *Proto = (*P); 1854234353Sdim Protocols.insert(Proto->getCanonicalDecl()); 1855198893Srdivacky for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), 1856198893Srdivacky PE = Proto->protocol_end(); P != PE; ++P) 1857198893Srdivacky CollectInheritedProtocols(*P, Protocols); 1858198893Srdivacky } 1859198893Srdivacky } 1860198893Srdivacky} 1861198893Srdivacky 1862218893Sdimunsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const { 1863206084Srdivacky unsigned count = 0; 1864206084Srdivacky // Count ivars declared in class extension. 1865249423Sdim for (ObjCInterfaceDecl::known_extensions_iterator 1866249423Sdim Ext = OI->known_extensions_begin(), 1867249423Sdim ExtEnd = OI->known_extensions_end(); 1868249423Sdim Ext != ExtEnd; ++Ext) { 1869249423Sdim count += Ext->ivar_size(); 1870249423Sdim } 1871249423Sdim 1872206084Srdivacky // Count ivar defined in this class's implementation. This 1873206084Srdivacky // includes synthesized ivars. 1874206084Srdivacky if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) 1875207619Srdivacky count += ImplDecl->ivar_size(); 1876207619Srdivacky 1877193576Sed return count; 1878193576Sed} 1879193576Sed 1880234353Sdimbool ASTContext::isSentinelNullExpr(const Expr *E) { 1881234353Sdim if (!E) 1882234353Sdim return false; 1883234353Sdim 1884234353Sdim // nullptr_t is always treated as null. 1885234353Sdim if (E->getType()->isNullPtrType()) return true; 1886234353Sdim 1887234353Sdim if (E->getType()->isAnyPointerType() && 1888234353Sdim E->IgnoreParenCasts()->isNullPointerConstant(*this, 1889234353Sdim Expr::NPC_ValueDependentIsNull)) 1890234353Sdim return true; 1891234353Sdim 1892234353Sdim // Unfortunately, __null has type 'int'. 1893234353Sdim if (isa<GNUNullExpr>(E)) return true; 1894234353Sdim 1895234353Sdim return false; 1896234353Sdim} 1897234353Sdim 1898198092Srdivacky/// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists. 1899198092SrdivackyObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) { 1900198092Srdivacky llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator 1901198092Srdivacky I = ObjCImpls.find(D); 1902198092Srdivacky if (I != ObjCImpls.end()) 1903198092Srdivacky return cast<ObjCImplementationDecl>(I->second); 1904198092Srdivacky return 0; 1905198092Srdivacky} 1906198092Srdivacky/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. 1907198092SrdivackyObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) { 1908198092Srdivacky llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator 1909198092Srdivacky I = ObjCImpls.find(D); 1910198092Srdivacky if (I != ObjCImpls.end()) 1911198092Srdivacky return cast<ObjCCategoryImplDecl>(I->second); 1912198092Srdivacky return 0; 1913198092Srdivacky} 1914198092Srdivacky 1915198092Srdivacky/// \brief Set the implementation of ObjCInterfaceDecl. 1916198092Srdivackyvoid ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD, 1917198092Srdivacky ObjCImplementationDecl *ImplD) { 1918198092Srdivacky assert(IFaceD && ImplD && "Passed null params"); 1919198092Srdivacky ObjCImpls[IFaceD] = ImplD; 1920198092Srdivacky} 1921198092Srdivacky/// \brief Set the implementation of ObjCCategoryDecl. 1922198092Srdivackyvoid ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD, 1923198092Srdivacky ObjCCategoryImplDecl *ImplD) { 1924198092Srdivacky assert(CatD && ImplD && "Passed null params"); 1925198092Srdivacky ObjCImpls[CatD] = ImplD; 1926198092Srdivacky} 1927198092Srdivacky 1928249423Sdimconst ObjCInterfaceDecl *ASTContext::getObjContainingInterface( 1929249423Sdim const NamedDecl *ND) const { 1930249423Sdim if (const ObjCInterfaceDecl *ID = 1931249423Sdim dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext())) 1932234353Sdim return ID; 1933249423Sdim if (const ObjCCategoryDecl *CD = 1934249423Sdim dyn_cast<ObjCCategoryDecl>(ND->getDeclContext())) 1935234353Sdim return CD->getClassInterface(); 1936249423Sdim if (const ObjCImplDecl *IMD = 1937249423Sdim dyn_cast<ObjCImplDecl>(ND->getDeclContext())) 1938234353Sdim return IMD->getClassInterface(); 1939234353Sdim 1940234353Sdim return 0; 1941234353Sdim} 1942234353Sdim 1943218893Sdim/// \brief Get the copy initialization expression of VarDecl,or NULL if 1944218893Sdim/// none exists. 1945218893SdimExpr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) { 1946218893Sdim assert(VD && "Passed null params"); 1947218893Sdim assert(VD->hasAttr<BlocksAttr>() && 1948218893Sdim "getBlockVarCopyInits - not __block var"); 1949218893Sdim llvm::DenseMap<const VarDecl*, Expr*>::iterator 1950218893Sdim I = BlockVarCopyInits.find(VD); 1951218893Sdim return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : 0; 1952218893Sdim} 1953218893Sdim 1954218893Sdim/// \brief Set the copy inialization expression of a block var decl. 1955218893Sdimvoid ASTContext::setBlockVarCopyInits(VarDecl*VD, Expr* Init) { 1956218893Sdim assert(VD && Init && "Passed null params"); 1957218893Sdim assert(VD->hasAttr<BlocksAttr>() && 1958218893Sdim "setBlockVarCopyInits - not __block var"); 1959218893Sdim BlockVarCopyInits[VD] = Init; 1960218893Sdim} 1961218893Sdim 1962200583SrdivackyTypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T, 1963218893Sdim unsigned DataSize) const { 1964198398Srdivacky if (!DataSize) 1965198398Srdivacky DataSize = TypeLoc::getFullDataSizeForType(T); 1966198398Srdivacky else 1967198398Srdivacky assert(DataSize == TypeLoc::getFullDataSizeForType(T) && 1968200583Srdivacky "incorrect data size provided to CreateTypeSourceInfo!"); 1969198398Srdivacky 1970200583Srdivacky TypeSourceInfo *TInfo = 1971200583Srdivacky (TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8); 1972200583Srdivacky new (TInfo) TypeSourceInfo(T); 1973200583Srdivacky return TInfo; 1974198092Srdivacky} 1975198092Srdivacky 1976200583SrdivackyTypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T, 1977218893Sdim SourceLocation L) const { 1978200583Srdivacky TypeSourceInfo *DI = CreateTypeSourceInfo(T); 1979218893Sdim DI->getTypeLoc().initialize(const_cast<ASTContext &>(*this), L); 1980198893Srdivacky return DI; 1981198893Srdivacky} 1982198893Srdivacky 1983193326Sedconst ASTRecordLayout & 1984218893SdimASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const { 1985193326Sed return getObjCLayout(D, 0); 1986193326Sed} 1987193326Sed 1988193326Sedconst ASTRecordLayout & 1989218893SdimASTContext::getASTObjCImplementationLayout( 1990218893Sdim const ObjCImplementationDecl *D) const { 1991193326Sed return getObjCLayout(D->getClassInterface(), D); 1992193326Sed} 1993193326Sed 1994193326Sed//===----------------------------------------------------------------------===// 1995193326Sed// Type creation/memoization methods 1996193326Sed//===----------------------------------------------------------------------===// 1997193326Sed 1998218893SdimQualType 1999218893SdimASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const { 2000218893Sdim unsigned fastQuals = quals.getFastQualifiers(); 2001218893Sdim quals.removeFastQualifiers(); 2002198092Srdivacky 2003198092Srdivacky // Check if we've already instantiated this type. 2004198092Srdivacky llvm::FoldingSetNodeID ID; 2005218893Sdim ExtQuals::Profile(ID, baseType, quals); 2006218893Sdim void *insertPos = 0; 2007218893Sdim if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) { 2008218893Sdim assert(eq->getQualifiers() == quals); 2009218893Sdim return QualType(eq, fastQuals); 2010198092Srdivacky } 2011198092Srdivacky 2012218893Sdim // If the base type is not canonical, make the appropriate canonical type. 2013218893Sdim QualType canon; 2014218893Sdim if (!baseType->isCanonicalUnqualified()) { 2015218893Sdim SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split(); 2016234353Sdim canonSplit.Quals.addConsistentQualifiers(quals); 2017234353Sdim canon = getExtQualType(canonSplit.Ty, canonSplit.Quals); 2018198092Srdivacky 2019218893Sdim // Re-find the insert position. 2020218893Sdim (void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos); 2021218893Sdim } 2022198092Srdivacky 2023218893Sdim ExtQuals *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals); 2024218893Sdim ExtQualNodes.InsertNode(eq, insertPos); 2025218893Sdim return QualType(eq, fastQuals); 2026198092Srdivacky} 2027198092Srdivacky 2028218893SdimQualType 2029218893SdimASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const { 2030193326Sed QualType CanT = getCanonicalType(T); 2031193326Sed if (CanT.getAddressSpace() == AddressSpace) 2032193326Sed return T; 2033193326Sed 2034198092Srdivacky // If we are composing extended qualifiers together, merge together 2035198092Srdivacky // into one ExtQuals node. 2036198092Srdivacky QualifierCollector Quals; 2037198092Srdivacky const Type *TypeNode = Quals.strip(T); 2038193326Sed 2039198092Srdivacky // If this type already has an address space specified, it cannot get 2040198092Srdivacky // another one. 2041198092Srdivacky assert(!Quals.hasAddressSpace() && 2042198092Srdivacky "Type cannot be in multiple addr spaces!"); 2043198092Srdivacky Quals.addAddressSpace(AddressSpace); 2044198092Srdivacky 2045198092Srdivacky return getExtQualType(TypeNode, Quals); 2046193326Sed} 2047193326Sed 2048193326SedQualType ASTContext::getObjCGCQualType(QualType T, 2049218893Sdim Qualifiers::GC GCAttr) const { 2050193326Sed QualType CanT = getCanonicalType(T); 2051193326Sed if (CanT.getObjCGCAttr() == GCAttr) 2052193326Sed return T; 2053198092Srdivacky 2054218893Sdim if (const PointerType *ptr = T->getAs<PointerType>()) { 2055218893Sdim QualType Pointee = ptr->getPointeeType(); 2056198092Srdivacky if (Pointee->isAnyPointerType()) { 2057193401Sed QualType ResultType = getObjCGCQualType(Pointee, GCAttr); 2058193401Sed return getPointerType(ResultType); 2059193401Sed } 2060193401Sed } 2061198092Srdivacky 2062198092Srdivacky // If we are composing extended qualifiers together, merge together 2063198092Srdivacky // into one ExtQuals node. 2064198092Srdivacky QualifierCollector Quals; 2065198092Srdivacky const Type *TypeNode = Quals.strip(T); 2066198092Srdivacky 2067198092Srdivacky // If this type already has an ObjCGC specified, it cannot get 2068198092Srdivacky // another one. 2069198092Srdivacky assert(!Quals.hasObjCGCAttr() && 2070198092Srdivacky "Type cannot have multiple ObjCGCs!"); 2071198092Srdivacky Quals.addObjCGCAttr(GCAttr); 2072198092Srdivacky 2073198092Srdivacky return getExtQualType(TypeNode, Quals); 2074198092Srdivacky} 2075198092Srdivacky 2076218893Sdimconst FunctionType *ASTContext::adjustFunctionType(const FunctionType *T, 2077218893Sdim FunctionType::ExtInfo Info) { 2078218893Sdim if (T->getExtInfo() == Info) 2079200583Srdivacky return T; 2080202879Srdivacky 2081218893Sdim QualType Result; 2082218893Sdim if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) { 2083218893Sdim Result = getFunctionNoProtoType(FNPT->getResultType(), Info); 2084218893Sdim } else { 2085218893Sdim const FunctionProtoType *FPT = cast<FunctionProtoType>(T); 2086218893Sdim FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 2087218893Sdim EPI.ExtInfo = Info; 2088263508Sdim Result = getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI); 2089218893Sdim } 2090193326Sed 2091218893Sdim return cast<FunctionType>(Result.getTypePtr()); 2092202879Srdivacky} 2093202879Srdivacky 2094251662Sdimvoid ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD, 2095251662Sdim QualType ResultType) { 2096263508Sdim FD = FD->getMostRecentDecl(); 2097263508Sdim while (true) { 2098251662Sdim const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>(); 2099251662Sdim FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 2100251662Sdim FD->setType(getFunctionType(ResultType, FPT->getArgTypes(), EPI)); 2101263508Sdim if (FunctionDecl *Next = FD->getPreviousDecl()) 2102263508Sdim FD = Next; 2103263508Sdim else 2104263508Sdim break; 2105251662Sdim } 2106263508Sdim if (ASTMutationListener *L = getASTMutationListener()) 2107263508Sdim L->DeducedReturnType(FD, ResultType); 2108251662Sdim} 2109251662Sdim 2110193326Sed/// getComplexType - Return the uniqued reference to the type for a complex 2111193326Sed/// number with the specified element type. 2112218893SdimQualType ASTContext::getComplexType(QualType T) const { 2113193326Sed // Unique pointers, to guarantee there is only one pointer of a particular 2114193326Sed // structure. 2115193326Sed llvm::FoldingSetNodeID ID; 2116193326Sed ComplexType::Profile(ID, T); 2117198092Srdivacky 2118193326Sed void *InsertPos = 0; 2119193326Sed if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos)) 2120193326Sed return QualType(CT, 0); 2121198092Srdivacky 2122193326Sed // If the pointee type isn't canonical, this won't be a canonical type either, 2123193326Sed // so fill in the canonical type field. 2124193326Sed QualType Canonical; 2125198398Srdivacky if (!T.isCanonical()) { 2126193326Sed Canonical = getComplexType(getCanonicalType(T)); 2127198092Srdivacky 2128193326Sed // Get the new insert position for the node we care about. 2129193326Sed ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos); 2130218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2131193326Sed } 2132198092Srdivacky ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical); 2133193326Sed Types.push_back(New); 2134193326Sed ComplexTypes.InsertNode(New, InsertPos); 2135193326Sed return QualType(New, 0); 2136193326Sed} 2137193326Sed 2138193326Sed/// getPointerType - Return the uniqued reference to the type for a pointer to 2139193326Sed/// the specified type. 2140218893SdimQualType ASTContext::getPointerType(QualType T) const { 2141193326Sed // Unique pointers, to guarantee there is only one pointer of a particular 2142193326Sed // structure. 2143193326Sed llvm::FoldingSetNodeID ID; 2144193326Sed PointerType::Profile(ID, T); 2145198092Srdivacky 2146193326Sed void *InsertPos = 0; 2147193326Sed if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos)) 2148193326Sed return QualType(PT, 0); 2149198092Srdivacky 2150193326Sed // If the pointee type isn't canonical, this won't be a canonical type either, 2151193326Sed // so fill in the canonical type field. 2152193326Sed QualType Canonical; 2153198398Srdivacky if (!T.isCanonical()) { 2154193326Sed Canonical = getPointerType(getCanonicalType(T)); 2155198092Srdivacky 2156193326Sed // Get the new insert position for the node we care about. 2157193326Sed PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos); 2158218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2159193326Sed } 2160198092Srdivacky PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical); 2161193326Sed Types.push_back(New); 2162193326Sed PointerTypes.InsertNode(New, InsertPos); 2163193326Sed return QualType(New, 0); 2164193326Sed} 2165193326Sed 2166263508SdimQualType ASTContext::getDecayedType(QualType T) const { 2167263508Sdim assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); 2168263508Sdim 2169263508Sdim llvm::FoldingSetNodeID ID; 2170263508Sdim DecayedType::Profile(ID, T); 2171263508Sdim void *InsertPos = 0; 2172263508Sdim if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos)) 2173263508Sdim return QualType(DT, 0); 2174263508Sdim 2175263508Sdim QualType Decayed; 2176263508Sdim 2177263508Sdim // C99 6.7.5.3p7: 2178263508Sdim // A declaration of a parameter as "array of type" shall be 2179263508Sdim // adjusted to "qualified pointer to type", where the type 2180263508Sdim // qualifiers (if any) are those specified within the [ and ] of 2181263508Sdim // the array type derivation. 2182263508Sdim if (T->isArrayType()) 2183263508Sdim Decayed = getArrayDecayedType(T); 2184263508Sdim 2185263508Sdim // C99 6.7.5.3p8: 2186263508Sdim // A declaration of a parameter as "function returning type" 2187263508Sdim // shall be adjusted to "pointer to function returning type", as 2188263508Sdim // in 6.3.2.1. 2189263508Sdim if (T->isFunctionType()) 2190263508Sdim Decayed = getPointerType(T); 2191263508Sdim 2192263508Sdim QualType Canonical = getCanonicalType(Decayed); 2193263508Sdim 2194263508Sdim // Get the new insert position for the node we care about. 2195263508Sdim DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos); 2196263508Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2197263508Sdim 2198263508Sdim DecayedType *New = 2199263508Sdim new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); 2200263508Sdim Types.push_back(New); 2201263508Sdim DecayedTypes.InsertNode(New, InsertPos); 2202263508Sdim return QualType(New, 0); 2203263508Sdim} 2204263508Sdim 2205198092Srdivacky/// getBlockPointerType - Return the uniqued reference to the type for 2206193326Sed/// a pointer to the specified block. 2207218893SdimQualType ASTContext::getBlockPointerType(QualType T) const { 2208193326Sed assert(T->isFunctionType() && "block of function types only"); 2209193326Sed // Unique pointers, to guarantee there is only one block of a particular 2210193326Sed // structure. 2211193326Sed llvm::FoldingSetNodeID ID; 2212193326Sed BlockPointerType::Profile(ID, T); 2213198092Srdivacky 2214193326Sed void *InsertPos = 0; 2215193326Sed if (BlockPointerType *PT = 2216193326Sed BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) 2217193326Sed return QualType(PT, 0); 2218198092Srdivacky 2219198092Srdivacky // If the block pointee type isn't canonical, this won't be a canonical 2220193326Sed // type either so fill in the canonical type field. 2221193326Sed QualType Canonical; 2222198398Srdivacky if (!T.isCanonical()) { 2223193326Sed Canonical = getBlockPointerType(getCanonicalType(T)); 2224198092Srdivacky 2225193326Sed // Get the new insert position for the node we care about. 2226193326Sed BlockPointerType *NewIP = 2227193326Sed BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos); 2228218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2229193326Sed } 2230198092Srdivacky BlockPointerType *New 2231198092Srdivacky = new (*this, TypeAlignment) BlockPointerType(T, Canonical); 2232193326Sed Types.push_back(New); 2233193326Sed BlockPointerTypes.InsertNode(New, InsertPos); 2234193326Sed return QualType(New, 0); 2235193326Sed} 2236193326Sed 2237193326Sed/// getLValueReferenceType - Return the uniqued reference to the type for an 2238193326Sed/// lvalue reference to the specified type. 2239218893SdimQualType 2240218893SdimASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const { 2241223017Sdim assert(getCanonicalType(T) != OverloadTy && 2242223017Sdim "Unresolved overloaded function type"); 2243223017Sdim 2244193326Sed // Unique pointers, to guarantee there is only one pointer of a particular 2245193326Sed // structure. 2246193326Sed llvm::FoldingSetNodeID ID; 2247198398Srdivacky ReferenceType::Profile(ID, T, SpelledAsLValue); 2248193326Sed 2249193326Sed void *InsertPos = 0; 2250193326Sed if (LValueReferenceType *RT = 2251193326Sed LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) 2252193326Sed return QualType(RT, 0); 2253193326Sed 2254198398Srdivacky const ReferenceType *InnerRef = T->getAs<ReferenceType>(); 2255198398Srdivacky 2256193326Sed // If the referencee type isn't canonical, this won't be a canonical type 2257193326Sed // either, so fill in the canonical type field. 2258193326Sed QualType Canonical; 2259198398Srdivacky if (!SpelledAsLValue || InnerRef || !T.isCanonical()) { 2260198398Srdivacky QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); 2261198398Srdivacky Canonical = getLValueReferenceType(getCanonicalType(PointeeType)); 2262193326Sed 2263193326Sed // Get the new insert position for the node we care about. 2264193326Sed LValueReferenceType *NewIP = 2265193326Sed LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); 2266218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2267193326Sed } 2268193326Sed 2269198092Srdivacky LValueReferenceType *New 2270198398Srdivacky = new (*this, TypeAlignment) LValueReferenceType(T, Canonical, 2271198398Srdivacky SpelledAsLValue); 2272193326Sed Types.push_back(New); 2273193326Sed LValueReferenceTypes.InsertNode(New, InsertPos); 2274198398Srdivacky 2275193326Sed return QualType(New, 0); 2276193326Sed} 2277193326Sed 2278193326Sed/// getRValueReferenceType - Return the uniqued reference to the type for an 2279193326Sed/// rvalue reference to the specified type. 2280218893SdimQualType ASTContext::getRValueReferenceType(QualType T) const { 2281193326Sed // Unique pointers, to guarantee there is only one pointer of a particular 2282193326Sed // structure. 2283193326Sed llvm::FoldingSetNodeID ID; 2284198398Srdivacky ReferenceType::Profile(ID, T, false); 2285193326Sed 2286193326Sed void *InsertPos = 0; 2287193326Sed if (RValueReferenceType *RT = 2288193326Sed RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) 2289193326Sed return QualType(RT, 0); 2290193326Sed 2291198398Srdivacky const ReferenceType *InnerRef = T->getAs<ReferenceType>(); 2292198398Srdivacky 2293193326Sed // If the referencee type isn't canonical, this won't be a canonical type 2294193326Sed // either, so fill in the canonical type field. 2295193326Sed QualType Canonical; 2296198398Srdivacky if (InnerRef || !T.isCanonical()) { 2297198398Srdivacky QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); 2298198398Srdivacky Canonical = getRValueReferenceType(getCanonicalType(PointeeType)); 2299193326Sed 2300193326Sed // Get the new insert position for the node we care about. 2301193326Sed RValueReferenceType *NewIP = 2302193326Sed RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); 2303218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2304193326Sed } 2305193326Sed 2306198092Srdivacky RValueReferenceType *New 2307198092Srdivacky = new (*this, TypeAlignment) RValueReferenceType(T, Canonical); 2308193326Sed Types.push_back(New); 2309193326Sed RValueReferenceTypes.InsertNode(New, InsertPos); 2310193326Sed return QualType(New, 0); 2311193326Sed} 2312193326Sed 2313193326Sed/// getMemberPointerType - Return the uniqued reference to the type for a 2314193326Sed/// member pointer to the specified type, in the specified class. 2315218893SdimQualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const { 2316193326Sed // Unique pointers, to guarantee there is only one pointer of a particular 2317193326Sed // structure. 2318193326Sed llvm::FoldingSetNodeID ID; 2319193326Sed MemberPointerType::Profile(ID, T, Cls); 2320193326Sed 2321193326Sed void *InsertPos = 0; 2322193326Sed if (MemberPointerType *PT = 2323193326Sed MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) 2324193326Sed return QualType(PT, 0); 2325193326Sed 2326193326Sed // If the pointee or class type isn't canonical, this won't be a canonical 2327193326Sed // type either, so fill in the canonical type field. 2328193326Sed QualType Canonical; 2329198954Srdivacky if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) { 2330193326Sed Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); 2331193326Sed 2332193326Sed // Get the new insert position for the node we care about. 2333193326Sed MemberPointerType *NewIP = 2334193326Sed MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos); 2335218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2336193326Sed } 2337198092Srdivacky MemberPointerType *New 2338198092Srdivacky = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical); 2339193326Sed Types.push_back(New); 2340193326Sed MemberPointerTypes.InsertNode(New, InsertPos); 2341193326Sed return QualType(New, 0); 2342193326Sed} 2343193326Sed 2344198092Srdivacky/// getConstantArrayType - Return the unique reference to the type for an 2345193326Sed/// array of the specified element type. 2346198092SrdivackyQualType ASTContext::getConstantArrayType(QualType EltTy, 2347193326Sed const llvm::APInt &ArySizeIn, 2348193326Sed ArrayType::ArraySizeModifier ASM, 2349218893Sdim unsigned IndexTypeQuals) const { 2350198954Srdivacky assert((EltTy->isDependentType() || 2351198954Srdivacky EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && 2352193326Sed "Constant array of VLAs is illegal!"); 2353193326Sed 2354193326Sed // Convert the array size into a canonical width matching the pointer size for 2355193326Sed // the target. 2356193326Sed llvm::APInt ArySize(ArySizeIn); 2357218893Sdim ArySize = 2358226633Sdim ArySize.zextOrTrunc(Target->getPointerWidth(getTargetAddressSpace(EltTy))); 2359198092Srdivacky 2360193326Sed llvm::FoldingSetNodeID ID; 2361218893Sdim ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals); 2362198092Srdivacky 2363193326Sed void *InsertPos = 0; 2364198092Srdivacky if (ConstantArrayType *ATP = 2365193326Sed ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) 2366193326Sed return QualType(ATP, 0); 2367198092Srdivacky 2368218893Sdim // If the element type isn't canonical or has qualifiers, this won't 2369218893Sdim // be a canonical type either, so fill in the canonical type field. 2370218893Sdim QualType Canon; 2371218893Sdim if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { 2372218893Sdim SplitQualType canonSplit = getCanonicalType(EltTy).split(); 2373234353Sdim Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, 2374218893Sdim ASM, IndexTypeQuals); 2375234353Sdim Canon = getQualifiedType(Canon, canonSplit.Quals); 2376218893Sdim 2377193326Sed // Get the new insert position for the node we care about. 2378198092Srdivacky ConstantArrayType *NewIP = 2379193326Sed ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos); 2380218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2381193326Sed } 2382198092Srdivacky 2383198092Srdivacky ConstantArrayType *New = new(*this,TypeAlignment) 2384218893Sdim ConstantArrayType(EltTy, Canon, ArySize, ASM, IndexTypeQuals); 2385193326Sed ConstantArrayTypes.InsertNode(New, InsertPos); 2386193326Sed Types.push_back(New); 2387193326Sed return QualType(New, 0); 2388193326Sed} 2389193326Sed 2390218893Sdim/// getVariableArrayDecayedType - Turns the given type, which may be 2391218893Sdim/// variably-modified, into the corresponding type with all the known 2392218893Sdim/// sizes replaced with [*]. 2393218893SdimQualType ASTContext::getVariableArrayDecayedType(QualType type) const { 2394218893Sdim // Vastly most common case. 2395218893Sdim if (!type->isVariablyModifiedType()) return type; 2396218893Sdim 2397218893Sdim QualType result; 2398218893Sdim 2399218893Sdim SplitQualType split = type.getSplitDesugaredType(); 2400234353Sdim const Type *ty = split.Ty; 2401218893Sdim switch (ty->getTypeClass()) { 2402218893Sdim#define TYPE(Class, Base) 2403218893Sdim#define ABSTRACT_TYPE(Class, Base) 2404218893Sdim#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 2405218893Sdim#include "clang/AST/TypeNodes.def" 2406218893Sdim llvm_unreachable("didn't desugar past all non-canonical types?"); 2407218893Sdim 2408218893Sdim // These types should never be variably-modified. 2409218893Sdim case Type::Builtin: 2410218893Sdim case Type::Complex: 2411218893Sdim case Type::Vector: 2412218893Sdim case Type::ExtVector: 2413218893Sdim case Type::DependentSizedExtVector: 2414218893Sdim case Type::ObjCObject: 2415218893Sdim case Type::ObjCInterface: 2416218893Sdim case Type::ObjCObjectPointer: 2417218893Sdim case Type::Record: 2418218893Sdim case Type::Enum: 2419218893Sdim case Type::UnresolvedUsing: 2420218893Sdim case Type::TypeOfExpr: 2421218893Sdim case Type::TypeOf: 2422218893Sdim case Type::Decltype: 2423223017Sdim case Type::UnaryTransform: 2424218893Sdim case Type::DependentName: 2425218893Sdim case Type::InjectedClassName: 2426218893Sdim case Type::TemplateSpecialization: 2427218893Sdim case Type::DependentTemplateSpecialization: 2428218893Sdim case Type::TemplateTypeParm: 2429218893Sdim case Type::SubstTemplateTypeParmPack: 2430218893Sdim case Type::Auto: 2431218893Sdim case Type::PackExpansion: 2432218893Sdim llvm_unreachable("type should never be variably-modified"); 2433218893Sdim 2434218893Sdim // These types can be variably-modified but should never need to 2435218893Sdim // further decay. 2436218893Sdim case Type::FunctionNoProto: 2437218893Sdim case Type::FunctionProto: 2438218893Sdim case Type::BlockPointer: 2439218893Sdim case Type::MemberPointer: 2440218893Sdim return type; 2441218893Sdim 2442218893Sdim // These types can be variably-modified. All these modifications 2443218893Sdim // preserve structure except as noted by comments. 2444218893Sdim // TODO: if we ever care about optimizing VLAs, there are no-op 2445218893Sdim // optimizations available here. 2446218893Sdim case Type::Pointer: 2447218893Sdim result = getPointerType(getVariableArrayDecayedType( 2448218893Sdim cast<PointerType>(ty)->getPointeeType())); 2449218893Sdim break; 2450218893Sdim 2451218893Sdim case Type::LValueReference: { 2452218893Sdim const LValueReferenceType *lv = cast<LValueReferenceType>(ty); 2453218893Sdim result = getLValueReferenceType( 2454218893Sdim getVariableArrayDecayedType(lv->getPointeeType()), 2455218893Sdim lv->isSpelledAsLValue()); 2456218893Sdim break; 2457218893Sdim } 2458218893Sdim 2459218893Sdim case Type::RValueReference: { 2460218893Sdim const RValueReferenceType *lv = cast<RValueReferenceType>(ty); 2461218893Sdim result = getRValueReferenceType( 2462218893Sdim getVariableArrayDecayedType(lv->getPointeeType())); 2463218893Sdim break; 2464218893Sdim } 2465218893Sdim 2466226633Sdim case Type::Atomic: { 2467226633Sdim const AtomicType *at = cast<AtomicType>(ty); 2468226633Sdim result = getAtomicType(getVariableArrayDecayedType(at->getValueType())); 2469226633Sdim break; 2470226633Sdim } 2471226633Sdim 2472218893Sdim case Type::ConstantArray: { 2473218893Sdim const ConstantArrayType *cat = cast<ConstantArrayType>(ty); 2474218893Sdim result = getConstantArrayType( 2475218893Sdim getVariableArrayDecayedType(cat->getElementType()), 2476218893Sdim cat->getSize(), 2477218893Sdim cat->getSizeModifier(), 2478218893Sdim cat->getIndexTypeCVRQualifiers()); 2479218893Sdim break; 2480218893Sdim } 2481218893Sdim 2482218893Sdim case Type::DependentSizedArray: { 2483218893Sdim const DependentSizedArrayType *dat = cast<DependentSizedArrayType>(ty); 2484218893Sdim result = getDependentSizedArrayType( 2485218893Sdim getVariableArrayDecayedType(dat->getElementType()), 2486218893Sdim dat->getSizeExpr(), 2487218893Sdim dat->getSizeModifier(), 2488218893Sdim dat->getIndexTypeCVRQualifiers(), 2489218893Sdim dat->getBracketsRange()); 2490218893Sdim break; 2491218893Sdim } 2492218893Sdim 2493218893Sdim // Turn incomplete types into [*] types. 2494218893Sdim case Type::IncompleteArray: { 2495218893Sdim const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty); 2496218893Sdim result = getVariableArrayType( 2497218893Sdim getVariableArrayDecayedType(iat->getElementType()), 2498218893Sdim /*size*/ 0, 2499218893Sdim ArrayType::Normal, 2500218893Sdim iat->getIndexTypeCVRQualifiers(), 2501218893Sdim SourceRange()); 2502218893Sdim break; 2503218893Sdim } 2504218893Sdim 2505218893Sdim // Turn VLA types into [*] types. 2506218893Sdim case Type::VariableArray: { 2507218893Sdim const VariableArrayType *vat = cast<VariableArrayType>(ty); 2508218893Sdim result = getVariableArrayType( 2509218893Sdim getVariableArrayDecayedType(vat->getElementType()), 2510218893Sdim /*size*/ 0, 2511218893Sdim ArrayType::Star, 2512218893Sdim vat->getIndexTypeCVRQualifiers(), 2513218893Sdim vat->getBracketsRange()); 2514218893Sdim break; 2515218893Sdim } 2516218893Sdim } 2517218893Sdim 2518218893Sdim // Apply the top-level qualifiers from the original. 2519234353Sdim return getQualifiedType(result, split.Quals); 2520218893Sdim} 2521218893Sdim 2522193326Sed/// getVariableArrayType - Returns a non-unique reference to the type for a 2523193326Sed/// variable array of the specified element type. 2524198092SrdivackyQualType ASTContext::getVariableArrayType(QualType EltTy, 2525198092Srdivacky Expr *NumElts, 2526193326Sed ArrayType::ArraySizeModifier ASM, 2527218893Sdim unsigned IndexTypeQuals, 2528218893Sdim SourceRange Brackets) const { 2529193326Sed // Since we don't unique expressions, it isn't possible to unique VLA's 2530193326Sed // that have an expression provided for their size. 2531218893Sdim QualType Canon; 2532208600Srdivacky 2533218893Sdim // Be sure to pull qualifiers off the element type. 2534218893Sdim if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { 2535218893Sdim SplitQualType canonSplit = getCanonicalType(EltTy).split(); 2536234353Sdim Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM, 2537218893Sdim IndexTypeQuals, Brackets); 2538234353Sdim Canon = getQualifiedType(Canon, canonSplit.Quals); 2539208600Srdivacky } 2540208600Srdivacky 2541198092Srdivacky VariableArrayType *New = new(*this, TypeAlignment) 2542218893Sdim VariableArrayType(EltTy, Canon, NumElts, ASM, IndexTypeQuals, Brackets); 2543193326Sed 2544193326Sed VariableArrayTypes.push_back(New); 2545193326Sed Types.push_back(New); 2546193326Sed return QualType(New, 0); 2547193326Sed} 2548193326Sed 2549193326Sed/// getDependentSizedArrayType - Returns a non-unique reference to 2550193326Sed/// the type for a dependently-sized array of the specified element 2551198092Srdivacky/// type. 2552218893SdimQualType ASTContext::getDependentSizedArrayType(QualType elementType, 2553218893Sdim Expr *numElements, 2554193326Sed ArrayType::ArraySizeModifier ASM, 2555218893Sdim unsigned elementTypeQuals, 2556218893Sdim SourceRange brackets) const { 2557218893Sdim assert((!numElements || numElements->isTypeDependent() || 2558218893Sdim numElements->isValueDependent()) && 2559193326Sed "Size must be type- or value-dependent!"); 2560193326Sed 2561218893Sdim // Dependently-sized array types that do not have a specified number 2562218893Sdim // of elements will have their sizes deduced from a dependent 2563218893Sdim // initializer. We do no canonicalization here at all, which is okay 2564218893Sdim // because they can't be used in most locations. 2565218893Sdim if (!numElements) { 2566218893Sdim DependentSizedArrayType *newType 2567218893Sdim = new (*this, TypeAlignment) 2568218893Sdim DependentSizedArrayType(*this, elementType, QualType(), 2569218893Sdim numElements, ASM, elementTypeQuals, 2570218893Sdim brackets); 2571218893Sdim Types.push_back(newType); 2572218893Sdim return QualType(newType, 0); 2573218893Sdim } 2574218893Sdim 2575218893Sdim // Otherwise, we actually build a new type every time, but we 2576218893Sdim // also build a canonical type. 2577218893Sdim 2578218893Sdim SplitQualType canonElementType = getCanonicalType(elementType).split(); 2579218893Sdim 2580218893Sdim void *insertPos = 0; 2581203955Srdivacky llvm::FoldingSetNodeID ID; 2582218893Sdim DependentSizedArrayType::Profile(ID, *this, 2583234353Sdim QualType(canonElementType.Ty, 0), 2584218893Sdim ASM, elementTypeQuals, numElements); 2585193326Sed 2586218893Sdim // Look for an existing type with these properties. 2587218893Sdim DependentSizedArrayType *canonTy = 2588218893Sdim DependentSizedArrayTypes.FindNodeOrInsertPos(ID, insertPos); 2589199990Srdivacky 2590218893Sdim // If we don't have one, build one. 2591218893Sdim if (!canonTy) { 2592218893Sdim canonTy = new (*this, TypeAlignment) 2593234353Sdim DependentSizedArrayType(*this, QualType(canonElementType.Ty, 0), 2594218893Sdim QualType(), numElements, ASM, elementTypeQuals, 2595218893Sdim brackets); 2596218893Sdim DependentSizedArrayTypes.InsertNode(canonTy, insertPos); 2597218893Sdim Types.push_back(canonTy); 2598199990Srdivacky } 2599199990Srdivacky 2600218893Sdim // Apply qualifiers from the element type to the array. 2601218893Sdim QualType canon = getQualifiedType(QualType(canonTy,0), 2602234353Sdim canonElementType.Quals); 2603199990Srdivacky 2604218893Sdim // If we didn't need extra canonicalization for the element type, 2605218893Sdim // then just use that as our result. 2606234353Sdim if (QualType(canonElementType.Ty, 0) == elementType) 2607218893Sdim return canon; 2608193326Sed 2609218893Sdim // Otherwise, we need to build a type which follows the spelling 2610218893Sdim // of the element type. 2611218893Sdim DependentSizedArrayType *sugaredType 2612218893Sdim = new (*this, TypeAlignment) 2613218893Sdim DependentSizedArrayType(*this, elementType, canon, numElements, 2614218893Sdim ASM, elementTypeQuals, brackets); 2615218893Sdim Types.push_back(sugaredType); 2616218893Sdim return QualType(sugaredType, 0); 2617193326Sed} 2618193326Sed 2619218893SdimQualType ASTContext::getIncompleteArrayType(QualType elementType, 2620193326Sed ArrayType::ArraySizeModifier ASM, 2621218893Sdim unsigned elementTypeQuals) const { 2622193326Sed llvm::FoldingSetNodeID ID; 2623218893Sdim IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals); 2624193326Sed 2625218893Sdim void *insertPos = 0; 2626218893Sdim if (IncompleteArrayType *iat = 2627218893Sdim IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos)) 2628218893Sdim return QualType(iat, 0); 2629193326Sed 2630193326Sed // If the element type isn't canonical, this won't be a canonical type 2631218893Sdim // either, so fill in the canonical type field. We also have to pull 2632218893Sdim // qualifiers off the element type. 2633218893Sdim QualType canon; 2634193326Sed 2635218893Sdim if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) { 2636218893Sdim SplitQualType canonSplit = getCanonicalType(elementType).split(); 2637234353Sdim canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0), 2638218893Sdim ASM, elementTypeQuals); 2639234353Sdim canon = getQualifiedType(canon, canonSplit.Quals); 2640193326Sed 2641193326Sed // Get the new insert position for the node we care about. 2642218893Sdim IncompleteArrayType *existing = 2643218893Sdim IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos); 2644218893Sdim assert(!existing && "Shouldn't be in the map!"); (void) existing; 2645193326Sed } 2646193326Sed 2647218893Sdim IncompleteArrayType *newType = new (*this, TypeAlignment) 2648218893Sdim IncompleteArrayType(elementType, canon, ASM, elementTypeQuals); 2649193326Sed 2650218893Sdim IncompleteArrayTypes.InsertNode(newType, insertPos); 2651218893Sdim Types.push_back(newType); 2652218893Sdim return QualType(newType, 0); 2653193326Sed} 2654193326Sed 2655193326Sed/// getVectorType - Return the unique reference to a vector type of 2656193326Sed/// the specified element type and size. VectorType must be a built-in type. 2657203955SrdivackyQualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, 2658218893Sdim VectorType::VectorKind VecKind) const { 2659218893Sdim assert(vecType->isBuiltinType()); 2660198092Srdivacky 2661193326Sed // Check if we've already instantiated a vector of this type. 2662193326Sed llvm::FoldingSetNodeID ID; 2663218893Sdim VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind); 2664210299Sed 2665193326Sed void *InsertPos = 0; 2666193326Sed if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) 2667193326Sed return QualType(VTP, 0); 2668193326Sed 2669193326Sed // If the element type isn't canonical, this won't be a canonical type either, 2670193326Sed // so fill in the canonical type field. 2671193326Sed QualType Canonical; 2672212904Sdim if (!vecType.isCanonical()) { 2673218893Sdim Canonical = getVectorType(getCanonicalType(vecType), NumElts, VecKind); 2674198092Srdivacky 2675193326Sed // Get the new insert position for the node we care about. 2676193326Sed VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); 2677218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2678193326Sed } 2679198092Srdivacky VectorType *New = new (*this, TypeAlignment) 2680218893Sdim VectorType(vecType, NumElts, Canonical, VecKind); 2681193326Sed VectorTypes.InsertNode(New, InsertPos); 2682193326Sed Types.push_back(New); 2683193326Sed return QualType(New, 0); 2684193326Sed} 2685193326Sed 2686193326Sed/// getExtVectorType - Return the unique reference to an extended vector type of 2687193326Sed/// the specified element type and size. VectorType must be a built-in type. 2688218893SdimQualType 2689218893SdimASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const { 2690224145Sdim assert(vecType->isBuiltinType() || vecType->isDependentType()); 2691198092Srdivacky 2692193326Sed // Check if we've already instantiated a vector of this type. 2693193326Sed llvm::FoldingSetNodeID ID; 2694210299Sed VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, 2695218893Sdim VectorType::GenericVector); 2696193326Sed void *InsertPos = 0; 2697193326Sed if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) 2698193326Sed return QualType(VTP, 0); 2699193326Sed 2700193326Sed // If the element type isn't canonical, this won't be a canonical type either, 2701193326Sed // so fill in the canonical type field. 2702193326Sed QualType Canonical; 2703198398Srdivacky if (!vecType.isCanonical()) { 2704193326Sed Canonical = getExtVectorType(getCanonicalType(vecType), NumElts); 2705198092Srdivacky 2706193326Sed // Get the new insert position for the node we care about. 2707193326Sed VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); 2708218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2709193326Sed } 2710198092Srdivacky ExtVectorType *New = new (*this, TypeAlignment) 2711198092Srdivacky ExtVectorType(vecType, NumElts, Canonical); 2712193326Sed VectorTypes.InsertNode(New, InsertPos); 2713193326Sed Types.push_back(New); 2714193326Sed return QualType(New, 0); 2715193326Sed} 2716193326Sed 2717218893SdimQualType 2718218893SdimASTContext::getDependentSizedExtVectorType(QualType vecType, 2719218893Sdim Expr *SizeExpr, 2720218893Sdim SourceLocation AttrLoc) const { 2721198092Srdivacky llvm::FoldingSetNodeID ID; 2722198092Srdivacky DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType), 2723198092Srdivacky SizeExpr); 2724194613Sed 2725198092Srdivacky void *InsertPos = 0; 2726198092Srdivacky DependentSizedExtVectorType *Canon 2727198092Srdivacky = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos); 2728198092Srdivacky DependentSizedExtVectorType *New; 2729198092Srdivacky if (Canon) { 2730198092Srdivacky // We already have a canonical version of this array type; use it as 2731198092Srdivacky // the canonical type for a newly-built type. 2732198092Srdivacky New = new (*this, TypeAlignment) 2733198092Srdivacky DependentSizedExtVectorType(*this, vecType, QualType(Canon, 0), 2734198092Srdivacky SizeExpr, AttrLoc); 2735198092Srdivacky } else { 2736198092Srdivacky QualType CanonVecTy = getCanonicalType(vecType); 2737198092Srdivacky if (CanonVecTy == vecType) { 2738198092Srdivacky New = new (*this, TypeAlignment) 2739198092Srdivacky DependentSizedExtVectorType(*this, vecType, QualType(), SizeExpr, 2740198092Srdivacky AttrLoc); 2741203955Srdivacky 2742203955Srdivacky DependentSizedExtVectorType *CanonCheck 2743203955Srdivacky = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos); 2744203955Srdivacky assert(!CanonCheck && "Dependent-sized ext_vector canonical type broken"); 2745203955Srdivacky (void)CanonCheck; 2746198092Srdivacky DependentSizedExtVectorTypes.InsertNode(New, InsertPos); 2747198092Srdivacky } else { 2748198092Srdivacky QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr, 2749198092Srdivacky SourceLocation()); 2750198092Srdivacky New = new (*this, TypeAlignment) 2751198092Srdivacky DependentSizedExtVectorType(*this, vecType, Canon, SizeExpr, AttrLoc); 2752198092Srdivacky } 2753198092Srdivacky } 2754198092Srdivacky 2755194613Sed Types.push_back(New); 2756194613Sed return QualType(New, 0); 2757194613Sed} 2758194613Sed 2759193326Sed/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. 2760193326Sed/// 2761218893SdimQualType 2762218893SdimASTContext::getFunctionNoProtoType(QualType ResultTy, 2763218893Sdim const FunctionType::ExtInfo &Info) const { 2764263508Sdim const CallingConv CallConv = Info.getCC(); 2765263508Sdim 2766193326Sed // Unique functions, to guarantee there is only one function of a particular 2767193326Sed // structure. 2768193326Sed llvm::FoldingSetNodeID ID; 2769206084Srdivacky FunctionNoProtoType::Profile(ID, ResultTy, Info); 2770198092Srdivacky 2771193326Sed void *InsertPos = 0; 2772198092Srdivacky if (FunctionNoProtoType *FT = 2773193326Sed FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) 2774193326Sed return QualType(FT, 0); 2775198092Srdivacky 2776193326Sed QualType Canonical; 2777263508Sdim if (!ResultTy.isCanonical()) { 2778263508Sdim Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), Info); 2779198092Srdivacky 2780193326Sed // Get the new insert position for the node we care about. 2781193326Sed FunctionNoProtoType *NewIP = 2782193326Sed FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos); 2783218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2784193326Sed } 2785198092Srdivacky 2786221345Sdim FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv); 2787198092Srdivacky FunctionNoProtoType *New = new (*this, TypeAlignment) 2788221345Sdim FunctionNoProtoType(ResultTy, Canonical, newInfo); 2789193326Sed Types.push_back(New); 2790193326Sed FunctionNoProtoTypes.InsertNode(New, InsertPos); 2791193326Sed return QualType(New, 0); 2792193326Sed} 2793193326Sed 2794249423Sdim/// \brief Determine whether \p T is canonical as the result type of a function. 2795249423Sdimstatic bool isCanonicalResultType(QualType T) { 2796249423Sdim return T.isCanonical() && 2797249423Sdim (T.getObjCLifetime() == Qualifiers::OCL_None || 2798249423Sdim T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); 2799249423Sdim} 2800249423Sdim 2801193326Sed/// getFunctionType - Return a normal function type with a typed argument 2802193326Sed/// list. isVariadic indicates whether the argument list includes '...'. 2803218893SdimQualType 2804249423SdimASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, 2805218893Sdim const FunctionProtoType::ExtProtoInfo &EPI) const { 2806249423Sdim size_t NumArgs = ArgArray.size(); 2807249423Sdim 2808193326Sed // Unique functions, to guarantee there is only one function of a particular 2809193326Sed // structure. 2810193326Sed llvm::FoldingSetNodeID ID; 2811249423Sdim FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI, 2812249423Sdim *this); 2813193326Sed 2814193326Sed void *InsertPos = 0; 2815198092Srdivacky if (FunctionProtoType *FTP = 2816193326Sed FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) 2817193326Sed return QualType(FTP, 0); 2818193326Sed 2819193326Sed // Determine whether the type being created is already canonical or not. 2820234353Sdim bool isCanonical = 2821249423Sdim EPI.ExceptionSpecType == EST_None && isCanonicalResultType(ResultTy) && 2822234353Sdim !EPI.HasTrailingReturn; 2823193326Sed for (unsigned i = 0; i != NumArgs && isCanonical; ++i) 2824198398Srdivacky if (!ArgArray[i].isCanonicalAsParam()) 2825193326Sed isCanonical = false; 2826193326Sed 2827193326Sed // If this type isn't canonical, get the canonical version of it. 2828193326Sed // The exception spec is not part of the canonical type. 2829193326Sed QualType Canonical; 2830263508Sdim if (!isCanonical) { 2831226633Sdim SmallVector<QualType, 16> CanonicalArgs; 2832193326Sed CanonicalArgs.reserve(NumArgs); 2833193326Sed for (unsigned i = 0; i != NumArgs; ++i) 2834198398Srdivacky CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i])); 2835193326Sed 2836218893Sdim FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI; 2837234353Sdim CanonicalEPI.HasTrailingReturn = false; 2838221345Sdim CanonicalEPI.ExceptionSpecType = EST_None; 2839221345Sdim CanonicalEPI.NumExceptions = 0; 2840218893Sdim 2841249423Sdim // Result types do not have ARC lifetime qualifiers. 2842249423Sdim QualType CanResultTy = getCanonicalType(ResultTy); 2843249423Sdim if (ResultTy.getQualifiers().hasObjCLifetime()) { 2844249423Sdim Qualifiers Qs = CanResultTy.getQualifiers(); 2845249423Sdim Qs.removeObjCLifetime(); 2846249423Sdim CanResultTy = getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); 2847249423Sdim } 2848193326Sed 2849249423Sdim Canonical = getFunctionType(CanResultTy, CanonicalArgs, CanonicalEPI); 2850249423Sdim 2851193326Sed // Get the new insert position for the node we care about. 2852193326Sed FunctionProtoType *NewIP = 2853193326Sed FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos); 2854218893Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 2855193326Sed } 2856193326Sed 2857224145Sdim // FunctionProtoType objects are allocated with extra bytes after 2858224145Sdim // them for three variable size arrays at the end: 2859224145Sdim // - parameter types 2860224145Sdim // - exception types 2861224145Sdim // - consumed-arguments flags 2862224145Sdim // Instead of the exception types, there could be a noexcept 2863239462Sdim // expression, or information used to resolve the exception 2864239462Sdim // specification. 2865218893Sdim size_t Size = sizeof(FunctionProtoType) + 2866221345Sdim NumArgs * sizeof(QualType); 2867239462Sdim if (EPI.ExceptionSpecType == EST_Dynamic) { 2868221345Sdim Size += EPI.NumExceptions * sizeof(QualType); 2869239462Sdim } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 2870221345Sdim Size += sizeof(Expr*); 2871234982Sdim } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { 2872234982Sdim Size += 2 * sizeof(FunctionDecl*); 2873239462Sdim } else if (EPI.ExceptionSpecType == EST_Unevaluated) { 2874239462Sdim Size += sizeof(FunctionDecl*); 2875221345Sdim } 2876224145Sdim if (EPI.ConsumedArguments) 2877224145Sdim Size += NumArgs * sizeof(bool); 2878224145Sdim 2879218893Sdim FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment); 2880221345Sdim FunctionProtoType::ExtProtoInfo newEPI = EPI; 2881249423Sdim new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI); 2882193326Sed Types.push_back(FTP); 2883193326Sed FunctionProtoTypes.InsertNode(FTP, InsertPos); 2884193326Sed return QualType(FTP, 0); 2885193326Sed} 2886193326Sed 2887204962Srdivacky#ifndef NDEBUG 2888204962Srdivackystatic bool NeedsInjectedClassNameType(const RecordDecl *D) { 2889204962Srdivacky if (!isa<CXXRecordDecl>(D)) return false; 2890204962Srdivacky const CXXRecordDecl *RD = cast<CXXRecordDecl>(D); 2891204962Srdivacky if (isa<ClassTemplatePartialSpecializationDecl>(RD)) 2892204962Srdivacky return true; 2893204962Srdivacky if (RD->getDescribedClassTemplate() && 2894204962Srdivacky !isa<ClassTemplateSpecializationDecl>(RD)) 2895204962Srdivacky return true; 2896204962Srdivacky return false; 2897204962Srdivacky} 2898204962Srdivacky#endif 2899204962Srdivacky 2900204962Srdivacky/// getInjectedClassNameType - Return the unique reference to the 2901204962Srdivacky/// injected class name type for the specified templated declaration. 2902204962SrdivackyQualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl, 2903218893Sdim QualType TST) const { 2904204962Srdivacky assert(NeedsInjectedClassNameType(Decl)); 2905204962Srdivacky if (Decl->TypeForDecl) { 2906204962Srdivacky assert(isa<InjectedClassNameType>(Decl->TypeForDecl)); 2907234353Sdim } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDecl()) { 2908204962Srdivacky assert(PrevDecl->TypeForDecl && "previous declaration has no type"); 2909204962Srdivacky Decl->TypeForDecl = PrevDecl->TypeForDecl; 2910204962Srdivacky assert(isa<InjectedClassNameType>(Decl->TypeForDecl)); 2911204962Srdivacky } else { 2912218893Sdim Type *newType = 2913207619Srdivacky new (*this, TypeAlignment) InjectedClassNameType(Decl, TST); 2914218893Sdim Decl->TypeForDecl = newType; 2915218893Sdim Types.push_back(newType); 2916204962Srdivacky } 2917204962Srdivacky return QualType(Decl->TypeForDecl, 0); 2918204962Srdivacky} 2919204962Srdivacky 2920193326Sed/// getTypeDeclType - Return the unique reference to the type for the 2921193326Sed/// specified type declaration. 2922218893SdimQualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const { 2923193326Sed assert(Decl && "Passed null for Decl param"); 2924204962Srdivacky assert(!Decl->TypeForDecl && "TypeForDecl present in slow case"); 2925198092Srdivacky 2926221345Sdim if (const TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Decl)) 2927193326Sed return getTypedefType(Typedef); 2928204962Srdivacky 2929204962Srdivacky assert(!isa<TemplateTypeParmDecl>(Decl) && 2930204962Srdivacky "Template type parameter types are always available."); 2931204962Srdivacky 2932203955Srdivacky if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) { 2933263508Sdim assert(Record->isFirstDecl() && "struct/union has previous declaration"); 2934204962Srdivacky assert(!NeedsInjectedClassNameType(Record)); 2935210299Sed return getRecordType(Record); 2936203955Srdivacky } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) { 2937263508Sdim assert(Enum->isFirstDecl() && "enum has previous declaration"); 2938210299Sed return getEnumType(Enum); 2939203955Srdivacky } else if (const UnresolvedUsingTypenameDecl *Using = 2940200583Srdivacky dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) { 2941218893Sdim Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using); 2942218893Sdim Decl->TypeForDecl = newType; 2943218893Sdim Types.push_back(newType); 2944198092Srdivacky } else 2945204962Srdivacky llvm_unreachable("TypeDecl without a type?"); 2946193326Sed 2947193326Sed return QualType(Decl->TypeForDecl, 0); 2948193326Sed} 2949193326Sed 2950193326Sed/// getTypedefType - Return the unique reference to the type for the 2951221345Sdim/// specified typedef name decl. 2952210299SedQualType 2953221345SdimASTContext::getTypedefType(const TypedefNameDecl *Decl, 2954221345Sdim QualType Canonical) const { 2955193326Sed if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); 2956198092Srdivacky 2957210299Sed if (Canonical.isNull()) 2958210299Sed Canonical = getCanonicalType(Decl->getUnderlyingType()); 2959218893Sdim TypedefType *newType = new(*this, TypeAlignment) 2960198092Srdivacky TypedefType(Type::Typedef, Decl, Canonical); 2961218893Sdim Decl->TypeForDecl = newType; 2962218893Sdim Types.push_back(newType); 2963218893Sdim return QualType(newType, 0); 2964193326Sed} 2965193326Sed 2966218893SdimQualType ASTContext::getRecordType(const RecordDecl *Decl) const { 2967210299Sed if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); 2968210299Sed 2969234353Sdim if (const RecordDecl *PrevDecl = Decl->getPreviousDecl()) 2970210299Sed if (PrevDecl->TypeForDecl) 2971210299Sed return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); 2972210299Sed 2973218893Sdim RecordType *newType = new (*this, TypeAlignment) RecordType(Decl); 2974218893Sdim Decl->TypeForDecl = newType; 2975218893Sdim Types.push_back(newType); 2976218893Sdim return QualType(newType, 0); 2977210299Sed} 2978210299Sed 2979218893SdimQualType ASTContext::getEnumType(const EnumDecl *Decl) const { 2980210299Sed if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); 2981210299Sed 2982234353Sdim if (const EnumDecl *PrevDecl = Decl->getPreviousDecl()) 2983210299Sed if (PrevDecl->TypeForDecl) 2984210299Sed return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); 2985210299Sed 2986218893Sdim EnumType *newType = new (*this, TypeAlignment) EnumType(Decl); 2987218893Sdim Decl->TypeForDecl = newType; 2988218893Sdim Types.push_back(newType); 2989218893Sdim return QualType(newType, 0); 2990210299Sed} 2991210299Sed 2992218893SdimQualType ASTContext::getAttributedType(AttributedType::Kind attrKind, 2993218893Sdim QualType modifiedType, 2994218893Sdim QualType equivalentType) { 2995218893Sdim llvm::FoldingSetNodeID id; 2996218893Sdim AttributedType::Profile(id, attrKind, modifiedType, equivalentType); 2997218893Sdim 2998218893Sdim void *insertPos = 0; 2999218893Sdim AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos); 3000218893Sdim if (type) return QualType(type, 0); 3001218893Sdim 3002218893Sdim QualType canon = getCanonicalType(equivalentType); 3003218893Sdim type = new (*this, TypeAlignment) 3004218893Sdim AttributedType(canon, attrKind, modifiedType, equivalentType); 3005218893Sdim 3006218893Sdim Types.push_back(type); 3007218893Sdim AttributedTypes.InsertNode(type, insertPos); 3008218893Sdim 3009218893Sdim return QualType(type, 0); 3010218893Sdim} 3011218893Sdim 3012218893Sdim 3013198398Srdivacky/// \brief Retrieve a substitution-result type. 3014198398SrdivackyQualType 3015198398SrdivackyASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, 3016218893Sdim QualType Replacement) const { 3017198398Srdivacky assert(Replacement.isCanonical() 3018198398Srdivacky && "replacement types must always be canonical"); 3019198398Srdivacky 3020198398Srdivacky llvm::FoldingSetNodeID ID; 3021198398Srdivacky SubstTemplateTypeParmType::Profile(ID, Parm, Replacement); 3022198398Srdivacky void *InsertPos = 0; 3023198398Srdivacky SubstTemplateTypeParmType *SubstParm 3024198398Srdivacky = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); 3025198398Srdivacky 3026198398Srdivacky if (!SubstParm) { 3027198398Srdivacky SubstParm = new (*this, TypeAlignment) 3028198398Srdivacky SubstTemplateTypeParmType(Parm, Replacement); 3029198398Srdivacky Types.push_back(SubstParm); 3030198398Srdivacky SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos); 3031198398Srdivacky } 3032198398Srdivacky 3033198398Srdivacky return QualType(SubstParm, 0); 3034198398Srdivacky} 3035198398Srdivacky 3036218893Sdim/// \brief Retrieve a 3037218893SdimQualType ASTContext::getSubstTemplateTypeParmPackType( 3038218893Sdim const TemplateTypeParmType *Parm, 3039218893Sdim const TemplateArgument &ArgPack) { 3040218893Sdim#ifndef NDEBUG 3041218893Sdim for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(), 3042218893Sdim PEnd = ArgPack.pack_end(); 3043218893Sdim P != PEnd; ++P) { 3044218893Sdim assert(P->getKind() == TemplateArgument::Type &&"Pack contains a non-type"); 3045218893Sdim assert(P->getAsType().isCanonical() && "Pack contains non-canonical type"); 3046218893Sdim } 3047218893Sdim#endif 3048218893Sdim 3049218893Sdim llvm::FoldingSetNodeID ID; 3050218893Sdim SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack); 3051218893Sdim void *InsertPos = 0; 3052218893Sdim if (SubstTemplateTypeParmPackType *SubstParm 3053218893Sdim = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos)) 3054218893Sdim return QualType(SubstParm, 0); 3055218893Sdim 3056218893Sdim QualType Canon; 3057218893Sdim if (!Parm->isCanonicalUnqualified()) { 3058218893Sdim Canon = getCanonicalType(QualType(Parm, 0)); 3059218893Sdim Canon = getSubstTemplateTypeParmPackType(cast<TemplateTypeParmType>(Canon), 3060218893Sdim ArgPack); 3061218893Sdim SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos); 3062218893Sdim } 3063218893Sdim 3064218893Sdim SubstTemplateTypeParmPackType *SubstParm 3065218893Sdim = new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon, 3066218893Sdim ArgPack); 3067218893Sdim Types.push_back(SubstParm); 3068218893Sdim SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos); 3069218893Sdim return QualType(SubstParm, 0); 3070218893Sdim} 3071218893Sdim 3072193326Sed/// \brief Retrieve the template type parameter type for a template 3073198092Srdivacky/// parameter or parameter pack with the given depth, index, and (optionally) 3074194613Sed/// name. 3075198092SrdivackyQualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, 3076194613Sed bool ParameterPack, 3077221345Sdim TemplateTypeParmDecl *TTPDecl) const { 3078193326Sed llvm::FoldingSetNodeID ID; 3079221345Sdim TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl); 3080193326Sed void *InsertPos = 0; 3081198092Srdivacky TemplateTypeParmType *TypeParm 3082193326Sed = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); 3083193326Sed 3084193326Sed if (TypeParm) 3085193326Sed return QualType(TypeParm, 0); 3086198092Srdivacky 3087221345Sdim if (TTPDecl) { 3088194613Sed QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack); 3089221345Sdim TypeParm = new (*this, TypeAlignment) TemplateTypeParmType(TTPDecl, Canon); 3090203955Srdivacky 3091203955Srdivacky TemplateTypeParmType *TypeCheck 3092203955Srdivacky = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); 3093203955Srdivacky assert(!TypeCheck && "Template type parameter canonical type broken"); 3094203955Srdivacky (void)TypeCheck; 3095194613Sed } else 3096198092Srdivacky TypeParm = new (*this, TypeAlignment) 3097198092Srdivacky TemplateTypeParmType(Depth, Index, ParameterPack); 3098193326Sed 3099193326Sed Types.push_back(TypeParm); 3100193326Sed TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos); 3101193326Sed 3102193326Sed return QualType(TypeParm, 0); 3103193326Sed} 3104193326Sed 3105204962SrdivackyTypeSourceInfo * 3106204962SrdivackyASTContext::getTemplateSpecializationTypeInfo(TemplateName Name, 3107204962Srdivacky SourceLocation NameLoc, 3108204962Srdivacky const TemplateArgumentListInfo &Args, 3109223017Sdim QualType Underlying) const { 3110221345Sdim assert(!Name.getAsDependentTemplateName() && 3111221345Sdim "No dependent template names here!"); 3112223017Sdim QualType TST = getTemplateSpecializationType(Name, Args, Underlying); 3113204962Srdivacky 3114204962Srdivacky TypeSourceInfo *DI = CreateTypeSourceInfo(TST); 3115249423Sdim TemplateSpecializationTypeLoc TL = 3116249423Sdim DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>(); 3117234353Sdim TL.setTemplateKeywordLoc(SourceLocation()); 3118204962Srdivacky TL.setTemplateNameLoc(NameLoc); 3119204962Srdivacky TL.setLAngleLoc(Args.getLAngleLoc()); 3120204962Srdivacky TL.setRAngleLoc(Args.getRAngleLoc()); 3121204962Srdivacky for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) 3122204962Srdivacky TL.setArgLocInfo(i, Args[i].getLocInfo()); 3123204962Srdivacky return DI; 3124204962Srdivacky} 3125204962Srdivacky 3126198092SrdivackyQualType 3127193326SedASTContext::getTemplateSpecializationType(TemplateName Template, 3128199990Srdivacky const TemplateArgumentListInfo &Args, 3129223017Sdim QualType Underlying) const { 3130221345Sdim assert(!Template.getAsDependentTemplateName() && 3131221345Sdim "No dependent template names here!"); 3132221345Sdim 3133199990Srdivacky unsigned NumArgs = Args.size(); 3134199990Srdivacky 3135226633Sdim SmallVector<TemplateArgument, 4> ArgVec; 3136198893Srdivacky ArgVec.reserve(NumArgs); 3137198893Srdivacky for (unsigned i = 0; i != NumArgs; ++i) 3138198893Srdivacky ArgVec.push_back(Args[i].getArgument()); 3139198893Srdivacky 3140207619Srdivacky return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, 3141223017Sdim Underlying); 3142198893Srdivacky} 3143198893Srdivacky 3144234353Sdim#ifndef NDEBUG 3145234353Sdimstatic bool hasAnyPackExpansions(const TemplateArgument *Args, 3146234353Sdim unsigned NumArgs) { 3147234353Sdim for (unsigned I = 0; I != NumArgs; ++I) 3148234353Sdim if (Args[I].isPackExpansion()) 3149234353Sdim return true; 3150234353Sdim 3151234353Sdim return true; 3152234353Sdim} 3153234353Sdim#endif 3154234353Sdim 3155198893SrdivackyQualType 3156198893SrdivackyASTContext::getTemplateSpecializationType(TemplateName Template, 3157193326Sed const TemplateArgument *Args, 3158193326Sed unsigned NumArgs, 3159223017Sdim QualType Underlying) const { 3160221345Sdim assert(!Template.getAsDependentTemplateName() && 3161221345Sdim "No dependent template names here!"); 3162221345Sdim // Look through qualified template names. 3163221345Sdim if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) 3164221345Sdim Template = TemplateName(QTN->getTemplateDecl()); 3165221345Sdim 3166234353Sdim bool IsTypeAlias = 3167223017Sdim Template.getAsTemplateDecl() && 3168223017Sdim isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); 3169223017Sdim QualType CanonType; 3170223017Sdim if (!Underlying.isNull()) 3171223017Sdim CanonType = getCanonicalType(Underlying); 3172223017Sdim else { 3173234353Sdim // We can get here with an alias template when the specialization contains 3174234353Sdim // a pack expansion that does not match up with a parameter pack. 3175234353Sdim assert((!IsTypeAlias || hasAnyPackExpansions(Args, NumArgs)) && 3176234353Sdim "Caller must compute aliased type"); 3177234353Sdim IsTypeAlias = false; 3178223017Sdim CanonType = getCanonicalTemplateSpecializationType(Template, Args, 3179223017Sdim NumArgs); 3180223017Sdim } 3181223017Sdim 3182198092Srdivacky // Allocate the (non-canonical) template specialization type, but don't 3183198092Srdivacky // try to unique it: these types typically have location information that 3184198092Srdivacky // we don't unique and don't want to lose. 3185223017Sdim void *Mem = Allocate(sizeof(TemplateSpecializationType) + 3186223017Sdim sizeof(TemplateArgument) * NumArgs + 3187234353Sdim (IsTypeAlias? sizeof(QualType) : 0), 3188198092Srdivacky TypeAlignment); 3189193326Sed TemplateSpecializationType *Spec 3190234353Sdim = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, CanonType, 3191234353Sdim IsTypeAlias ? Underlying : QualType()); 3192193326Sed 3193193326Sed Types.push_back(Spec); 3194198092Srdivacky return QualType(Spec, 0); 3195193326Sed} 3196193326Sed 3197198092SrdivackyQualType 3198210299SedASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, 3199210299Sed const TemplateArgument *Args, 3200218893Sdim unsigned NumArgs) const { 3201221345Sdim assert(!Template.getAsDependentTemplateName() && 3202221345Sdim "No dependent template names here!"); 3203223017Sdim 3204221345Sdim // Look through qualified template names. 3205221345Sdim if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) 3206221345Sdim Template = TemplateName(QTN->getTemplateDecl()); 3207221345Sdim 3208210299Sed // Build the canonical template specialization type. 3209210299Sed TemplateName CanonTemplate = getCanonicalTemplateName(Template); 3210226633Sdim SmallVector<TemplateArgument, 4> CanonArgs; 3211210299Sed CanonArgs.reserve(NumArgs); 3212210299Sed for (unsigned I = 0; I != NumArgs; ++I) 3213210299Sed CanonArgs.push_back(getCanonicalTemplateArgument(Args[I])); 3214210299Sed 3215210299Sed // Determine whether this canonical template specialization type already 3216210299Sed // exists. 3217210299Sed llvm::FoldingSetNodeID ID; 3218210299Sed TemplateSpecializationType::Profile(ID, CanonTemplate, 3219210299Sed CanonArgs.data(), NumArgs, *this); 3220210299Sed 3221210299Sed void *InsertPos = 0; 3222210299Sed TemplateSpecializationType *Spec 3223210299Sed = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); 3224210299Sed 3225210299Sed if (!Spec) { 3226210299Sed // Allocate a new canonical template specialization type. 3227210299Sed void *Mem = Allocate((sizeof(TemplateSpecializationType) + 3228210299Sed sizeof(TemplateArgument) * NumArgs), 3229210299Sed TypeAlignment); 3230210299Sed Spec = new (Mem) TemplateSpecializationType(CanonTemplate, 3231210299Sed CanonArgs.data(), NumArgs, 3232223017Sdim QualType(), QualType()); 3233210299Sed Types.push_back(Spec); 3234210299Sed TemplateSpecializationTypes.InsertNode(Spec, InsertPos); 3235210299Sed } 3236210299Sed 3237210299Sed assert(Spec->isDependentType() && 3238210299Sed "Non-dependent template-id type must have a canonical type"); 3239210299Sed return QualType(Spec, 0); 3240210299Sed} 3241210299Sed 3242210299SedQualType 3243208600SrdivackyASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword, 3244208600Srdivacky NestedNameSpecifier *NNS, 3245218893Sdim QualType NamedType) const { 3246193326Sed llvm::FoldingSetNodeID ID; 3247208600Srdivacky ElaboratedType::Profile(ID, Keyword, NNS, NamedType); 3248193326Sed 3249193326Sed void *InsertPos = 0; 3250208600Srdivacky ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); 3251193326Sed if (T) 3252193326Sed return QualType(T, 0); 3253193326Sed 3254203955Srdivacky QualType Canon = NamedType; 3255203955Srdivacky if (!Canon.isCanonical()) { 3256203955Srdivacky Canon = getCanonicalType(NamedType); 3257208600Srdivacky ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); 3258208600Srdivacky assert(!CheckT && "Elaborated canonical type broken"); 3259203955Srdivacky (void)CheckT; 3260203955Srdivacky } 3261203955Srdivacky 3262208600Srdivacky T = new (*this) ElaboratedType(Keyword, NNS, NamedType, Canon); 3263193326Sed Types.push_back(T); 3264208600Srdivacky ElaboratedTypes.InsertNode(T, InsertPos); 3265193326Sed return QualType(T, 0); 3266193326Sed} 3267193326Sed 3268218893SdimQualType 3269218893SdimASTContext::getParenType(QualType InnerType) const { 3270218893Sdim llvm::FoldingSetNodeID ID; 3271218893Sdim ParenType::Profile(ID, InnerType); 3272218893Sdim 3273218893Sdim void *InsertPos = 0; 3274218893Sdim ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos); 3275218893Sdim if (T) 3276218893Sdim return QualType(T, 0); 3277218893Sdim 3278218893Sdim QualType Canon = InnerType; 3279218893Sdim if (!Canon.isCanonical()) { 3280218893Sdim Canon = getCanonicalType(InnerType); 3281218893Sdim ParenType *CheckT = ParenTypes.FindNodeOrInsertPos(ID, InsertPos); 3282218893Sdim assert(!CheckT && "Paren canonical type broken"); 3283218893Sdim (void)CheckT; 3284218893Sdim } 3285218893Sdim 3286218893Sdim T = new (*this) ParenType(InnerType, Canon); 3287218893Sdim Types.push_back(T); 3288218893Sdim ParenTypes.InsertNode(T, InsertPos); 3289218893Sdim return QualType(T, 0); 3290218893Sdim} 3291218893Sdim 3292206084SrdivackyQualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword, 3293206084Srdivacky NestedNameSpecifier *NNS, 3294206084Srdivacky const IdentifierInfo *Name, 3295218893Sdim QualType Canon) const { 3296193326Sed assert(NNS->isDependent() && "nested-name-specifier must be dependent"); 3297193326Sed 3298193326Sed if (Canon.isNull()) { 3299193326Sed NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); 3300206084Srdivacky ElaboratedTypeKeyword CanonKeyword = Keyword; 3301206084Srdivacky if (Keyword == ETK_None) 3302206084Srdivacky CanonKeyword = ETK_Typename; 3303206084Srdivacky 3304206084Srdivacky if (CanonNNS != NNS || CanonKeyword != Keyword) 3305206084Srdivacky Canon = getDependentNameType(CanonKeyword, CanonNNS, Name); 3306193326Sed } 3307193326Sed 3308193326Sed llvm::FoldingSetNodeID ID; 3309206084Srdivacky DependentNameType::Profile(ID, Keyword, NNS, Name); 3310193326Sed 3311193326Sed void *InsertPos = 0; 3312206084Srdivacky DependentNameType *T 3313206084Srdivacky = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos); 3314193326Sed if (T) 3315193326Sed return QualType(T, 0); 3316193326Sed 3317206084Srdivacky T = new (*this) DependentNameType(Keyword, NNS, Name, Canon); 3318193326Sed Types.push_back(T); 3319206084Srdivacky DependentNameTypes.InsertNode(T, InsertPos); 3320198092Srdivacky return QualType(T, 0); 3321193326Sed} 3322193326Sed 3323198092SrdivackyQualType 3324210299SedASTContext::getDependentTemplateSpecializationType( 3325210299Sed ElaboratedTypeKeyword Keyword, 3326206084Srdivacky NestedNameSpecifier *NNS, 3327210299Sed const IdentifierInfo *Name, 3328218893Sdim const TemplateArgumentListInfo &Args) const { 3329210299Sed // TODO: avoid this copy 3330226633Sdim SmallVector<TemplateArgument, 16> ArgCopy; 3331210299Sed for (unsigned I = 0, E = Args.size(); I != E; ++I) 3332210299Sed ArgCopy.push_back(Args[I].getArgument()); 3333210299Sed return getDependentTemplateSpecializationType(Keyword, NNS, Name, 3334210299Sed ArgCopy.size(), 3335210299Sed ArgCopy.data()); 3336210299Sed} 3337210299Sed 3338210299SedQualType 3339210299SedASTContext::getDependentTemplateSpecializationType( 3340210299Sed ElaboratedTypeKeyword Keyword, 3341210299Sed NestedNameSpecifier *NNS, 3342210299Sed const IdentifierInfo *Name, 3343210299Sed unsigned NumArgs, 3344218893Sdim const TemplateArgument *Args) const { 3345221345Sdim assert((!NNS || NNS->isDependent()) && 3346221345Sdim "nested-name-specifier must be dependent"); 3347193326Sed 3348203955Srdivacky llvm::FoldingSetNodeID ID; 3349210299Sed DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS, 3350210299Sed Name, NumArgs, Args); 3351203955Srdivacky 3352203955Srdivacky void *InsertPos = 0; 3353210299Sed DependentTemplateSpecializationType *T 3354210299Sed = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); 3355203955Srdivacky if (T) 3356203955Srdivacky return QualType(T, 0); 3357203955Srdivacky 3358210299Sed NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); 3359203955Srdivacky 3360210299Sed ElaboratedTypeKeyword CanonKeyword = Keyword; 3361210299Sed if (Keyword == ETK_None) CanonKeyword = ETK_Typename; 3362210299Sed 3363210299Sed bool AnyNonCanonArgs = false; 3364226633Sdim SmallVector<TemplateArgument, 16> CanonArgs(NumArgs); 3365210299Sed for (unsigned I = 0; I != NumArgs; ++I) { 3366210299Sed CanonArgs[I] = getCanonicalTemplateArgument(Args[I]); 3367210299Sed if (!CanonArgs[I].structurallyEquals(Args[I])) 3368210299Sed AnyNonCanonArgs = true; 3369193326Sed } 3370193326Sed 3371210299Sed QualType Canon; 3372210299Sed if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) { 3373210299Sed Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS, 3374210299Sed Name, NumArgs, 3375210299Sed CanonArgs.data()); 3376210299Sed 3377210299Sed // Find the insert position again. 3378210299Sed DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); 3379210299Sed } 3380210299Sed 3381210299Sed void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) + 3382210299Sed sizeof(TemplateArgument) * NumArgs), 3383210299Sed TypeAlignment); 3384210299Sed T = new (Mem) DependentTemplateSpecializationType(Keyword, NNS, 3385210299Sed Name, NumArgs, Args, Canon); 3386193326Sed Types.push_back(T); 3387210299Sed DependentTemplateSpecializationTypes.InsertNode(T, InsertPos); 3388198092Srdivacky return QualType(T, 0); 3389193326Sed} 3390193326Sed 3391218893SdimQualType ASTContext::getPackExpansionType(QualType Pattern, 3392249423Sdim Optional<unsigned> NumExpansions) { 3393218893Sdim llvm::FoldingSetNodeID ID; 3394218893Sdim PackExpansionType::Profile(ID, Pattern, NumExpansions); 3395218893Sdim 3396218893Sdim assert(Pattern->containsUnexpandedParameterPack() && 3397218893Sdim "Pack expansions must expand one or more parameter packs"); 3398218893Sdim void *InsertPos = 0; 3399218893Sdim PackExpansionType *T 3400218893Sdim = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); 3401218893Sdim if (T) 3402218893Sdim return QualType(T, 0); 3403218893Sdim 3404218893Sdim QualType Canon; 3405218893Sdim if (!Pattern.isCanonical()) { 3406239462Sdim Canon = getCanonicalType(Pattern); 3407239462Sdim // The canonical type might not contain an unexpanded parameter pack, if it 3408239462Sdim // contains an alias template specialization which ignores one of its 3409239462Sdim // parameters. 3410239462Sdim if (Canon->containsUnexpandedParameterPack()) { 3411239462Sdim Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions); 3412218893Sdim 3413239462Sdim // Find the insert position again, in case we inserted an element into 3414239462Sdim // PackExpansionTypes and invalidated our insert position. 3415239462Sdim PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); 3416239462Sdim } 3417218893Sdim } 3418218893Sdim 3419218893Sdim T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions); 3420218893Sdim Types.push_back(T); 3421218893Sdim PackExpansionTypes.InsertNode(T, InsertPos); 3422218893Sdim return QualType(T, 0); 3423218893Sdim} 3424218893Sdim 3425193326Sed/// CmpProtocolNames - Comparison predicate for sorting protocols 3426193326Sed/// alphabetically. 3427193326Sedstatic bool CmpProtocolNames(const ObjCProtocolDecl *LHS, 3428193326Sed const ObjCProtocolDecl *RHS) { 3429193326Sed return LHS->getDeclName() < RHS->getDeclName(); 3430193326Sed} 3431193326Sed 3432208600Srdivackystatic bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols, 3433198398Srdivacky unsigned NumProtocols) { 3434198398Srdivacky if (NumProtocols == 0) return true; 3435198398Srdivacky 3436234353Sdim if (Protocols[0]->getCanonicalDecl() != Protocols[0]) 3437234353Sdim return false; 3438234353Sdim 3439198398Srdivacky for (unsigned i = 1; i != NumProtocols; ++i) 3440234353Sdim if (!CmpProtocolNames(Protocols[i-1], Protocols[i]) || 3441234353Sdim Protocols[i]->getCanonicalDecl() != Protocols[i]) 3442198398Srdivacky return false; 3443198398Srdivacky return true; 3444198398Srdivacky} 3445198398Srdivacky 3446198398Srdivackystatic void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols, 3447193326Sed unsigned &NumProtocols) { 3448193326Sed ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols; 3449198092Srdivacky 3450193326Sed // Sort protocols, keyed by name. 3451193326Sed std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames); 3452193326Sed 3453234353Sdim // Canonicalize. 3454234353Sdim for (unsigned I = 0, N = NumProtocols; I != N; ++I) 3455234353Sdim Protocols[I] = Protocols[I]->getCanonicalDecl(); 3456234353Sdim 3457193326Sed // Remove duplicates. 3458193326Sed ProtocolsEnd = std::unique(Protocols, ProtocolsEnd); 3459193326Sed NumProtocols = ProtocolsEnd-Protocols; 3460193326Sed} 3461193326Sed 3462208600SrdivackyQualType ASTContext::getObjCObjectType(QualType BaseType, 3463208600Srdivacky ObjCProtocolDecl * const *Protocols, 3464218893Sdim unsigned NumProtocols) const { 3465208600Srdivacky // If the base type is an interface and there aren't any protocols 3466208600Srdivacky // to add, then the interface type will do just fine. 3467208600Srdivacky if (!NumProtocols && isa<ObjCInterfaceType>(BaseType)) 3468208600Srdivacky return BaseType; 3469208600Srdivacky 3470208600Srdivacky // Look in the folding set for an existing type. 3471194613Sed llvm::FoldingSetNodeID ID; 3472208600Srdivacky ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols); 3473194613Sed void *InsertPos = 0; 3474208600Srdivacky if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos)) 3475208600Srdivacky return QualType(QT, 0); 3476194613Sed 3477208600Srdivacky // Build the canonical type, which has the canonical base type and 3478208600Srdivacky // a sorted-and-uniqued list of protocols. 3479198398Srdivacky QualType Canonical; 3480208600Srdivacky bool ProtocolsSorted = areSortedAndUniqued(Protocols, NumProtocols); 3481208600Srdivacky if (!ProtocolsSorted || !BaseType.isCanonical()) { 3482208600Srdivacky if (!ProtocolsSorted) { 3483226633Sdim SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols, 3484207619Srdivacky Protocols + NumProtocols); 3485198398Srdivacky unsigned UniqueCount = NumProtocols; 3486198398Srdivacky 3487198398Srdivacky SortAndUniqueProtocols(&Sorted[0], UniqueCount); 3488208600Srdivacky Canonical = getObjCObjectType(getCanonicalType(BaseType), 3489208600Srdivacky &Sorted[0], UniqueCount); 3490198398Srdivacky } else { 3491208600Srdivacky Canonical = getObjCObjectType(getCanonicalType(BaseType), 3492208600Srdivacky Protocols, NumProtocols); 3493198398Srdivacky } 3494198398Srdivacky 3495198398Srdivacky // Regenerate InsertPos. 3496208600Srdivacky ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos); 3497198398Srdivacky } 3498198398Srdivacky 3499208600Srdivacky unsigned Size = sizeof(ObjCObjectTypeImpl); 3500208600Srdivacky Size += NumProtocols * sizeof(ObjCProtocolDecl *); 3501203955Srdivacky void *Mem = Allocate(Size, TypeAlignment); 3502208600Srdivacky ObjCObjectTypeImpl *T = 3503208600Srdivacky new (Mem) ObjCObjectTypeImpl(Canonical, BaseType, Protocols, NumProtocols); 3504198092Srdivacky 3505208600Srdivacky Types.push_back(T); 3506208600Srdivacky ObjCObjectTypes.InsertNode(T, InsertPos); 3507208600Srdivacky return QualType(T, 0); 3508194613Sed} 3509194613Sed 3510208600Srdivacky/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for 3511208600Srdivacky/// the given object type. 3512218893SdimQualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const { 3513193326Sed llvm::FoldingSetNodeID ID; 3514208600Srdivacky ObjCObjectPointerType::Profile(ID, ObjectT); 3515198092Srdivacky 3516193326Sed void *InsertPos = 0; 3517208600Srdivacky if (ObjCObjectPointerType *QT = 3518208600Srdivacky ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) 3519193326Sed return QualType(QT, 0); 3520198092Srdivacky 3521208600Srdivacky // Find the canonical object type. 3522198398Srdivacky QualType Canonical; 3523208600Srdivacky if (!ObjectT.isCanonical()) { 3524208600Srdivacky Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT)); 3525198398Srdivacky 3526208600Srdivacky // Regenerate InsertPos. 3527208600Srdivacky ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos); 3528198398Srdivacky } 3529198398Srdivacky 3530208600Srdivacky // No match. 3531208600Srdivacky void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment); 3532208600Srdivacky ObjCObjectPointerType *QType = 3533208600Srdivacky new (Mem) ObjCObjectPointerType(Canonical, ObjectT); 3534198398Srdivacky 3535198092Srdivacky Types.push_back(QType); 3536208600Srdivacky ObjCObjectPointerTypes.InsertNode(QType, InsertPos); 3537198092Srdivacky return QualType(QType, 0); 3538198092Srdivacky} 3539193326Sed 3540208600Srdivacky/// getObjCInterfaceType - Return the unique reference to the type for the 3541208600Srdivacky/// specified ObjC interface decl. The list of protocols is optional. 3542234353SdimQualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, 3543234353Sdim ObjCInterfaceDecl *PrevDecl) const { 3544208600Srdivacky if (Decl->TypeForDecl) 3545208600Srdivacky return QualType(Decl->TypeForDecl, 0); 3546208600Srdivacky 3547234353Sdim if (PrevDecl) { 3548234353Sdim assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl"); 3549234353Sdim Decl->TypeForDecl = PrevDecl->TypeForDecl; 3550234353Sdim return QualType(PrevDecl->TypeForDecl, 0); 3551234353Sdim } 3552234353Sdim 3553234353Sdim // Prefer the definition, if there is one. 3554234353Sdim if (const ObjCInterfaceDecl *Def = Decl->getDefinition()) 3555234353Sdim Decl = Def; 3556234353Sdim 3557208600Srdivacky void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment); 3558208600Srdivacky ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl); 3559208600Srdivacky Decl->TypeForDecl = T; 3560208600Srdivacky Types.push_back(T); 3561208600Srdivacky return QualType(T, 0); 3562208600Srdivacky} 3563208600Srdivacky 3564193326Sed/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique 3565193326Sed/// TypeOfExprType AST's (since expression's are never shared). For example, 3566193326Sed/// multiple declarations that refer to "typeof(x)" all contain different 3567198092Srdivacky/// DeclRefExpr's. This doesn't effect the type checker, since it operates 3568193326Sed/// on canonical type's (which are always unique). 3569218893SdimQualType ASTContext::getTypeOfExprType(Expr *tofExpr) const { 3570198092Srdivacky TypeOfExprType *toe; 3571198092Srdivacky if (tofExpr->isTypeDependent()) { 3572198092Srdivacky llvm::FoldingSetNodeID ID; 3573198092Srdivacky DependentTypeOfExprType::Profile(ID, *this, tofExpr); 3574198092Srdivacky 3575198092Srdivacky void *InsertPos = 0; 3576198092Srdivacky DependentTypeOfExprType *Canon 3577198092Srdivacky = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos); 3578198092Srdivacky if (Canon) { 3579198092Srdivacky // We already have a "canonical" version of an identical, dependent 3580198092Srdivacky // typeof(expr) type. Use that as our canonical type. 3581198092Srdivacky toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr, 3582198092Srdivacky QualType((TypeOfExprType*)Canon, 0)); 3583226633Sdim } else { 3584198092Srdivacky // Build a new, canonical typeof(expr) type. 3585198092Srdivacky Canon 3586198092Srdivacky = new (*this, TypeAlignment) DependentTypeOfExprType(*this, tofExpr); 3587198092Srdivacky DependentTypeOfExprTypes.InsertNode(Canon, InsertPos); 3588198092Srdivacky toe = Canon; 3589198092Srdivacky } 3590198092Srdivacky } else { 3591198092Srdivacky QualType Canonical = getCanonicalType(tofExpr->getType()); 3592198092Srdivacky toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr, Canonical); 3593198092Srdivacky } 3594193326Sed Types.push_back(toe); 3595193326Sed return QualType(toe, 0); 3596193326Sed} 3597193326Sed 3598193326Sed/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique 3599193326Sed/// TypeOfType AST's. The only motivation to unique these nodes would be 3600193326Sed/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be 3601198092Srdivacky/// an issue. This doesn't effect the type checker, since it operates 3602193326Sed/// on canonical type's (which are always unique). 3603218893SdimQualType ASTContext::getTypeOfType(QualType tofType) const { 3604193326Sed QualType Canonical = getCanonicalType(tofType); 3605198092Srdivacky TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical); 3606193326Sed Types.push_back(tot); 3607193326Sed return QualType(tot, 0); 3608193326Sed} 3609193326Sed 3610198092Srdivacky 3611195099Sed/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique 3612195099Sed/// DecltypeType AST's. The only motivation to unique these nodes would be 3613195099Sed/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be 3614198092Srdivacky/// an issue. This doesn't effect the type checker, since it operates 3615234353Sdim/// on canonical types (which are always unique). 3616234353SdimQualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const { 3617198092Srdivacky DecltypeType *dt; 3618224145Sdim 3619224145Sdim // C++0x [temp.type]p2: 3620224145Sdim // If an expression e involves a template parameter, decltype(e) denotes a 3621224145Sdim // unique dependent type. Two such decltype-specifiers refer to the same 3622224145Sdim // type only if their expressions are equivalent (14.5.6.1). 3623224145Sdim if (e->isInstantiationDependent()) { 3624198092Srdivacky llvm::FoldingSetNodeID ID; 3625198092Srdivacky DependentDecltypeType::Profile(ID, *this, e); 3626198092Srdivacky 3627198092Srdivacky void *InsertPos = 0; 3628198092Srdivacky DependentDecltypeType *Canon 3629198092Srdivacky = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos); 3630198092Srdivacky if (Canon) { 3631198092Srdivacky // We already have a "canonical" version of an equivalent, dependent 3632198092Srdivacky // decltype type. Use that as our canonical type. 3633239462Sdim dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, 3634198092Srdivacky QualType((DecltypeType*)Canon, 0)); 3635226633Sdim } else { 3636198092Srdivacky // Build a new, canonical typeof(expr) type. 3637198092Srdivacky Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e); 3638198092Srdivacky DependentDecltypeTypes.InsertNode(Canon, InsertPos); 3639198092Srdivacky dt = Canon; 3640198092Srdivacky } 3641198092Srdivacky } else { 3642234353Sdim dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, 3643234353Sdim getCanonicalType(UnderlyingType)); 3644198092Srdivacky } 3645195099Sed Types.push_back(dt); 3646195099Sed return QualType(dt, 0); 3647195099Sed} 3648195099Sed 3649223017Sdim/// getUnaryTransformationType - We don't unique these, since the memory 3650223017Sdim/// savings are minimal and these are rare. 3651223017SdimQualType ASTContext::getUnaryTransformType(QualType BaseType, 3652223017Sdim QualType UnderlyingType, 3653223017Sdim UnaryTransformType::UTTKind Kind) 3654223017Sdim const { 3655223017Sdim UnaryTransformType *Ty = 3656223017Sdim new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType, 3657223017Sdim Kind, 3658223017Sdim UnderlyingType->isDependentType() ? 3659234353Sdim QualType() : getCanonicalType(UnderlyingType)); 3660223017Sdim Types.push_back(Ty); 3661223017Sdim return QualType(Ty, 0); 3662223017Sdim} 3663223017Sdim 3664251662Sdim/// getAutoType - Return the uniqued reference to the 'auto' type which has been 3665251662Sdim/// deduced to the given type, or to the canonical undeduced 'auto' type, or the 3666251662Sdim/// canonical deduced-but-dependent 'auto' type. 3667251662SdimQualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto, 3668251662Sdim bool IsDependent) const { 3669251662Sdim if (DeducedType.isNull() && !IsDecltypeAuto && !IsDependent) 3670251662Sdim return getAutoDeductType(); 3671251662Sdim 3672251662Sdim // Look in the folding set for an existing type. 3673219077Sdim void *InsertPos = 0; 3674251662Sdim llvm::FoldingSetNodeID ID; 3675251662Sdim AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent); 3676251662Sdim if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) 3677251662Sdim return QualType(AT, 0); 3678219077Sdim 3679251662Sdim AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType, 3680251662Sdim IsDecltypeAuto, 3681251662Sdim IsDependent); 3682219077Sdim Types.push_back(AT); 3683219077Sdim if (InsertPos) 3684219077Sdim AutoTypes.InsertNode(AT, InsertPos); 3685219077Sdim return QualType(AT, 0); 3686218893Sdim} 3687218893Sdim 3688226633Sdim/// getAtomicType - Return the uniqued reference to the atomic type for 3689226633Sdim/// the given value type. 3690226633SdimQualType ASTContext::getAtomicType(QualType T) const { 3691226633Sdim // Unique pointers, to guarantee there is only one pointer of a particular 3692226633Sdim // structure. 3693226633Sdim llvm::FoldingSetNodeID ID; 3694226633Sdim AtomicType::Profile(ID, T); 3695226633Sdim 3696226633Sdim void *InsertPos = 0; 3697226633Sdim if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos)) 3698226633Sdim return QualType(AT, 0); 3699226633Sdim 3700226633Sdim // If the atomic value type isn't canonical, this won't be a canonical type 3701226633Sdim // either, so fill in the canonical type field. 3702226633Sdim QualType Canonical; 3703226633Sdim if (!T.isCanonical()) { 3704226633Sdim Canonical = getAtomicType(getCanonicalType(T)); 3705226633Sdim 3706226633Sdim // Get the new insert position for the node we care about. 3707226633Sdim AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos); 3708226633Sdim assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; 3709226633Sdim } 3710226633Sdim AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical); 3711226633Sdim Types.push_back(New); 3712226633Sdim AtomicTypes.InsertNode(New, InsertPos); 3713226633Sdim return QualType(New, 0); 3714226633Sdim} 3715226633Sdim 3716221345Sdim/// getAutoDeductType - Get type pattern for deducing against 'auto'. 3717221345SdimQualType ASTContext::getAutoDeductType() const { 3718221345Sdim if (AutoDeductTy.isNull()) 3719251662Sdim AutoDeductTy = QualType( 3720251662Sdim new (*this, TypeAlignment) AutoType(QualType(), /*decltype(auto)*/false, 3721251662Sdim /*dependent*/false), 3722251662Sdim 0); 3723221345Sdim return AutoDeductTy; 3724221345Sdim} 3725221345Sdim 3726221345Sdim/// getAutoRRefDeductType - Get type pattern for deducing against 'auto &&'. 3727221345SdimQualType ASTContext::getAutoRRefDeductType() const { 3728221345Sdim if (AutoRRefDeductTy.isNull()) 3729221345Sdim AutoRRefDeductTy = getRValueReferenceType(getAutoDeductType()); 3730221345Sdim assert(!AutoRRefDeductTy.isNull() && "can't build 'auto &&' pattern"); 3731221345Sdim return AutoRRefDeductTy; 3732221345Sdim} 3733221345Sdim 3734193326Sed/// getTagDeclType - Return the unique reference to the type for the 3735193326Sed/// specified TagDecl (struct/union/class/enum) decl. 3736218893SdimQualType ASTContext::getTagDeclType(const TagDecl *Decl) const { 3737193326Sed assert (Decl); 3738198092Srdivacky // FIXME: What is the design on getTagDeclType when it requires casting 3739198092Srdivacky // away const? mutable? 3740198092Srdivacky return getTypeDeclType(const_cast<TagDecl*>(Decl)); 3741193326Sed} 3742193326Sed 3743198092Srdivacky/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result 3744198092Srdivacky/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and 3745198092Srdivacky/// needs to agree with the definition in <stddef.h>. 3746200583SrdivackyCanQualType ASTContext::getSizeType() const { 3747226633Sdim return getFromTargetType(Target->getSizeType()); 3748193326Sed} 3749193326Sed 3750234353Sdim/// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5). 3751234353SdimCanQualType ASTContext::getIntMaxType() const { 3752234353Sdim return getFromTargetType(Target->getIntMaxType()); 3753234353Sdim} 3754234353Sdim 3755234353Sdim/// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5). 3756234353SdimCanQualType ASTContext::getUIntMaxType() const { 3757234353Sdim return getFromTargetType(Target->getUIntMaxType()); 3758234353Sdim} 3759234353Sdim 3760193326Sed/// getSignedWCharType - Return the type of "signed wchar_t". 3761193326Sed/// Used when in C++, as a GCC extension. 3762193326SedQualType ASTContext::getSignedWCharType() const { 3763193326Sed // FIXME: derive from "Target" ? 3764193326Sed return WCharTy; 3765193326Sed} 3766193326Sed 3767193326Sed/// getUnsignedWCharType - Return the type of "unsigned wchar_t". 3768193326Sed/// Used when in C++, as a GCC extension. 3769193326SedQualType ASTContext::getUnsignedWCharType() const { 3770193326Sed // FIXME: derive from "Target" ? 3771193326Sed return UnsignedIntTy; 3772193326Sed} 3773193326Sed 3774249423SdimQualType ASTContext::getIntPtrType() const { 3775249423Sdim return getFromTargetType(Target->getIntPtrType()); 3776249423Sdim} 3777249423Sdim 3778249423SdimQualType ASTContext::getUIntPtrType() const { 3779249423Sdim return getCorrespondingUnsignedType(getIntPtrType()); 3780249423Sdim} 3781249423Sdim 3782234353Sdim/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17) 3783193326Sed/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). 3784193326SedQualType ASTContext::getPointerDiffType() const { 3785226633Sdim return getFromTargetType(Target->getPtrDiffType(0)); 3786193326Sed} 3787193326Sed 3788243830Sdim/// \brief Return the unique type for "pid_t" defined in 3789243830Sdim/// <sys/types.h>. We need this to compute the correct type for vfork(). 3790243830SdimQualType ASTContext::getProcessIDType() const { 3791243830Sdim return getFromTargetType(Target->getProcessIDType()); 3792243830Sdim} 3793243830Sdim 3794193326Sed//===----------------------------------------------------------------------===// 3795193326Sed// Type Operators 3796193326Sed//===----------------------------------------------------------------------===// 3797193326Sed 3798218893SdimCanQualType ASTContext::getCanonicalParamType(QualType T) const { 3799198398Srdivacky // Push qualifiers into arrays, and then discard any remaining 3800198398Srdivacky // qualifiers. 3801198398Srdivacky T = getCanonicalType(T); 3802218893Sdim T = getVariableArrayDecayedType(T); 3803198398Srdivacky const Type *Ty = T.getTypePtr(); 3804198398Srdivacky QualType Result; 3805198398Srdivacky if (isa<ArrayType>(Ty)) { 3806198398Srdivacky Result = getArrayDecayedType(QualType(Ty,0)); 3807198398Srdivacky } else if (isa<FunctionType>(Ty)) { 3808198398Srdivacky Result = getPointerType(QualType(Ty, 0)); 3809198398Srdivacky } else { 3810198398Srdivacky Result = QualType(Ty, 0); 3811198398Srdivacky } 3812198398Srdivacky 3813198398Srdivacky return CanQualType::CreateUnsafe(Result); 3814198398Srdivacky} 3815198398Srdivacky 3816218893SdimQualType ASTContext::getUnqualifiedArrayType(QualType type, 3817218893Sdim Qualifiers &quals) { 3818218893Sdim SplitQualType splitType = type.getSplitUnqualifiedType(); 3819198092Srdivacky 3820218893Sdim // FIXME: getSplitUnqualifiedType() actually walks all the way to 3821218893Sdim // the unqualified desugared type and then drops it on the floor. 3822218893Sdim // We then have to strip that sugar back off with 3823218893Sdim // getUnqualifiedDesugaredType(), which is silly. 3824218893Sdim const ArrayType *AT = 3825234353Sdim dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType()); 3826198092Srdivacky 3827218893Sdim // If we don't have an array, just use the results in splitType. 3828218893Sdim if (!AT) { 3829234353Sdim quals = splitType.Quals; 3830234353Sdim return QualType(splitType.Ty, 0); 3831218893Sdim } 3832198092Srdivacky 3833218893Sdim // Otherwise, recurse on the array's element type. 3834218893Sdim QualType elementType = AT->getElementType(); 3835218893Sdim QualType unqualElementType = getUnqualifiedArrayType(elementType, quals); 3836198092Srdivacky 3837218893Sdim // If that didn't change the element type, AT has no qualifiers, so we 3838218893Sdim // can just use the results in splitType. 3839218893Sdim if (elementType == unqualElementType) { 3840218893Sdim assert(quals.empty()); // from the recursive call 3841234353Sdim quals = splitType.Quals; 3842234353Sdim return QualType(splitType.Ty, 0); 3843201361Srdivacky } 3844201361Srdivacky 3845218893Sdim // Otherwise, add in the qualifiers from the outermost type, then 3846218893Sdim // build the type back up. 3847234353Sdim quals.addConsistentQualifiers(splitType.Quals); 3848201361Srdivacky 3849208600Srdivacky if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { 3850218893Sdim return getConstantArrayType(unqualElementType, CAT->getSize(), 3851201361Srdivacky CAT->getSizeModifier(), 0); 3852201361Srdivacky } 3853201361Srdivacky 3854208600Srdivacky if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) { 3855218893Sdim return getIncompleteArrayType(unqualElementType, IAT->getSizeModifier(), 0); 3856201361Srdivacky } 3857201361Srdivacky 3858208600Srdivacky if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT)) { 3859218893Sdim return getVariableArrayType(unqualElementType, 3860218893Sdim VAT->getSizeExpr(), 3861208600Srdivacky VAT->getSizeModifier(), 3862208600Srdivacky VAT->getIndexTypeCVRQualifiers(), 3863208600Srdivacky VAT->getBracketsRange()); 3864208600Srdivacky } 3865208600Srdivacky 3866208600Srdivacky const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(AT); 3867218893Sdim return getDependentSizedArrayType(unqualElementType, DSAT->getSizeExpr(), 3868201361Srdivacky DSAT->getSizeModifier(), 0, 3869201361Srdivacky SourceRange()); 3870201361Srdivacky} 3871201361Srdivacky 3872210299Sed/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that 3873210299Sed/// may be similar (C++ 4.4), replaces T1 and T2 with the type that 3874210299Sed/// they point to and return true. If T1 and T2 aren't pointer types 3875210299Sed/// or pointer-to-member types, or if they are not similar at this 3876210299Sed/// level, returns false and leaves T1 and T2 unchanged. Top-level 3877210299Sed/// qualifiers on T1 and T2 are ignored. This function will typically 3878210299Sed/// be called in a loop that successively "unwraps" pointer and 3879210299Sed/// pointer-to-member types to compare them at each level. 3880210299Sedbool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) { 3881210299Sed const PointerType *T1PtrType = T1->getAs<PointerType>(), 3882210299Sed *T2PtrType = T2->getAs<PointerType>(); 3883210299Sed if (T1PtrType && T2PtrType) { 3884210299Sed T1 = T1PtrType->getPointeeType(); 3885210299Sed T2 = T2PtrType->getPointeeType(); 3886210299Sed return true; 3887210299Sed } 3888210299Sed 3889210299Sed const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(), 3890210299Sed *T2MPType = T2->getAs<MemberPointerType>(); 3891210299Sed if (T1MPType && T2MPType && 3892210299Sed hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0), 3893210299Sed QualType(T2MPType->getClass(), 0))) { 3894210299Sed T1 = T1MPType->getPointeeType(); 3895210299Sed T2 = T2MPType->getPointeeType(); 3896210299Sed return true; 3897210299Sed } 3898210299Sed 3899234353Sdim if (getLangOpts().ObjC1) { 3900210299Sed const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(), 3901210299Sed *T2OPType = T2->getAs<ObjCObjectPointerType>(); 3902210299Sed if (T1OPType && T2OPType) { 3903210299Sed T1 = T1OPType->getPointeeType(); 3904210299Sed T2 = T2OPType->getPointeeType(); 3905210299Sed return true; 3906210299Sed } 3907210299Sed } 3908210299Sed 3909210299Sed // FIXME: Block pointers, too? 3910210299Sed 3911210299Sed return false; 3912210299Sed} 3913210299Sed 3914218893SdimDeclarationNameInfo 3915218893SdimASTContext::getNameForTemplate(TemplateName Name, 3916218893Sdim SourceLocation NameLoc) const { 3917224145Sdim switch (Name.getKind()) { 3918224145Sdim case TemplateName::QualifiedTemplate: 3919224145Sdim case TemplateName::Template: 3920212904Sdim // DNInfo work in progress: CHECKME: what about DNLoc? 3921224145Sdim return DeclarationNameInfo(Name.getAsTemplateDecl()->getDeclName(), 3922224145Sdim NameLoc); 3923212904Sdim 3924224145Sdim case TemplateName::OverloadedTemplate: { 3925224145Sdim OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate(); 3926224145Sdim // DNInfo work in progress: CHECKME: what about DNLoc? 3927224145Sdim return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc); 3928224145Sdim } 3929224145Sdim 3930224145Sdim case TemplateName::DependentTemplate: { 3931224145Sdim DependentTemplateName *DTN = Name.getAsDependentTemplateName(); 3932212904Sdim DeclarationName DName; 3933199990Srdivacky if (DTN->isIdentifier()) { 3934212904Sdim DName = DeclarationNames.getIdentifier(DTN->getIdentifier()); 3935212904Sdim return DeclarationNameInfo(DName, NameLoc); 3936199990Srdivacky } else { 3937212904Sdim DName = DeclarationNames.getCXXOperatorName(DTN->getOperator()); 3938212904Sdim // DNInfo work in progress: FIXME: source locations? 3939212904Sdim DeclarationNameLoc DNLoc; 3940212904Sdim DNLoc.CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 3941212904Sdim DNLoc.CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 3942212904Sdim return DeclarationNameInfo(DName, NameLoc, DNLoc); 3943199990Srdivacky } 3944199990Srdivacky } 3945199990Srdivacky 3946224145Sdim case TemplateName::SubstTemplateTemplateParm: { 3947224145Sdim SubstTemplateTemplateParmStorage *subst 3948224145Sdim = Name.getAsSubstTemplateTemplateParm(); 3949224145Sdim return DeclarationNameInfo(subst->getParameter()->getDeclName(), 3950224145Sdim NameLoc); 3951224145Sdim } 3952224145Sdim 3953224145Sdim case TemplateName::SubstTemplateTemplateParmPack: { 3954224145Sdim SubstTemplateTemplateParmPackStorage *subst 3955224145Sdim = Name.getAsSubstTemplateTemplateParmPack(); 3956224145Sdim return DeclarationNameInfo(subst->getParameterPack()->getDeclName(), 3957224145Sdim NameLoc); 3958224145Sdim } 3959224145Sdim } 3960224145Sdim 3961224145Sdim llvm_unreachable("bad template name kind!"); 3962199990Srdivacky} 3963199990Srdivacky 3964218893SdimTemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const { 3965224145Sdim switch (Name.getKind()) { 3966224145Sdim case TemplateName::QualifiedTemplate: 3967224145Sdim case TemplateName::Template: { 3968224145Sdim TemplateDecl *Template = Name.getAsTemplateDecl(); 3969210299Sed if (TemplateTemplateParmDecl *TTP 3970224145Sdim = dyn_cast<TemplateTemplateParmDecl>(Template)) 3971210299Sed Template = getCanonicalTemplateTemplateParmDecl(TTP); 3972210299Sed 3973210299Sed // The canonical template name is the canonical template declaration. 3974198092Srdivacky return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl())); 3975210299Sed } 3976193326Sed 3977224145Sdim case TemplateName::OverloadedTemplate: 3978224145Sdim llvm_unreachable("cannot canonicalize overloaded template"); 3979224145Sdim 3980224145Sdim case TemplateName::DependentTemplate: { 3981224145Sdim DependentTemplateName *DTN = Name.getAsDependentTemplateName(); 3982224145Sdim assert(DTN && "Non-dependent template names must refer to template decls."); 3983224145Sdim return DTN->CanonicalTemplateName; 3984218893Sdim } 3985193326Sed 3986224145Sdim case TemplateName::SubstTemplateTemplateParm: { 3987224145Sdim SubstTemplateTemplateParmStorage *subst 3988224145Sdim = Name.getAsSubstTemplateTemplateParm(); 3989224145Sdim return getCanonicalTemplateName(subst->getReplacement()); 3990224145Sdim } 3991224145Sdim 3992224145Sdim case TemplateName::SubstTemplateTemplateParmPack: { 3993224145Sdim SubstTemplateTemplateParmPackStorage *subst 3994224145Sdim = Name.getAsSubstTemplateTemplateParmPack(); 3995224145Sdim TemplateTemplateParmDecl *canonParameter 3996224145Sdim = getCanonicalTemplateTemplateParmDecl(subst->getParameterPack()); 3997224145Sdim TemplateArgument canonArgPack 3998224145Sdim = getCanonicalTemplateArgument(subst->getArgumentPack()); 3999224145Sdim return getSubstTemplateTemplateParmPack(canonParameter, canonArgPack); 4000224145Sdim } 4001224145Sdim } 4002224145Sdim 4003224145Sdim llvm_unreachable("bad template name!"); 4004193326Sed} 4005193326Sed 4006199482Srdivackybool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) { 4007199482Srdivacky X = getCanonicalTemplateName(X); 4008199482Srdivacky Y = getCanonicalTemplateName(Y); 4009199482Srdivacky return X.getAsVoidPointer() == Y.getAsVoidPointer(); 4010199482Srdivacky} 4011199482Srdivacky 4012198092SrdivackyTemplateArgument 4013218893SdimASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { 4014198092Srdivacky switch (Arg.getKind()) { 4015198092Srdivacky case TemplateArgument::Null: 4016198092Srdivacky return Arg; 4017198092Srdivacky 4018198092Srdivacky case TemplateArgument::Expression: 4019198092Srdivacky return Arg; 4020198092Srdivacky 4021234353Sdim case TemplateArgument::Declaration: { 4022243830Sdim ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl()); 4023243830Sdim return TemplateArgument(D, Arg.isDeclForReferenceParam()); 4024234353Sdim } 4025198092Srdivacky 4026243830Sdim case TemplateArgument::NullPtr: 4027243830Sdim return TemplateArgument(getCanonicalType(Arg.getNullPtrType()), 4028243830Sdim /*isNullPtr*/true); 4029243830Sdim 4030199482Srdivacky case TemplateArgument::Template: 4031199482Srdivacky return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate())); 4032218893Sdim 4033218893Sdim case TemplateArgument::TemplateExpansion: 4034218893Sdim return TemplateArgument(getCanonicalTemplateName( 4035218893Sdim Arg.getAsTemplateOrTemplatePattern()), 4036218893Sdim Arg.getNumTemplateExpansions()); 4037218893Sdim 4038198092Srdivacky case TemplateArgument::Integral: 4039239462Sdim return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType())); 4040198092Srdivacky 4041198092Srdivacky case TemplateArgument::Type: 4042198893Srdivacky return TemplateArgument(getCanonicalType(Arg.getAsType())); 4043198092Srdivacky 4044198092Srdivacky case TemplateArgument::Pack: { 4045218893Sdim if (Arg.pack_size() == 0) 4046218893Sdim return Arg; 4047218893Sdim 4048218893Sdim TemplateArgument *CanonArgs 4049218893Sdim = new (*this) TemplateArgument[Arg.pack_size()]; 4050198092Srdivacky unsigned Idx = 0; 4051198092Srdivacky for (TemplateArgument::pack_iterator A = Arg.pack_begin(), 4052198092Srdivacky AEnd = Arg.pack_end(); 4053198092Srdivacky A != AEnd; (void)++A, ++Idx) 4054198092Srdivacky CanonArgs[Idx] = getCanonicalTemplateArgument(*A); 4055198092Srdivacky 4056218893Sdim return TemplateArgument(CanonArgs, Arg.pack_size()); 4057198092Srdivacky } 4058198092Srdivacky } 4059198092Srdivacky 4060198092Srdivacky // Silence GCC warning 4061226633Sdim llvm_unreachable("Unhandled template argument kind"); 4062198092Srdivacky} 4063198092Srdivacky 4064193326SedNestedNameSpecifier * 4065218893SdimASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { 4066198092Srdivacky if (!NNS) 4067193326Sed return 0; 4068193326Sed 4069193326Sed switch (NNS->getKind()) { 4070193326Sed case NestedNameSpecifier::Identifier: 4071193326Sed // Canonicalize the prefix but keep the identifier the same. 4072198092Srdivacky return NestedNameSpecifier::Create(*this, 4073193326Sed getCanonicalNestedNameSpecifier(NNS->getPrefix()), 4074193326Sed NNS->getAsIdentifier()); 4075193326Sed 4076193326Sed case NestedNameSpecifier::Namespace: 4077193326Sed // A namespace is canonical; build a nested-name-specifier with 4078193326Sed // this namespace and no prefix. 4079219077Sdim return NestedNameSpecifier::Create(*this, 0, 4080219077Sdim NNS->getAsNamespace()->getOriginalNamespace()); 4081193326Sed 4082219077Sdim case NestedNameSpecifier::NamespaceAlias: 4083219077Sdim // A namespace is canonical; build a nested-name-specifier with 4084219077Sdim // this namespace and no prefix. 4085219077Sdim return NestedNameSpecifier::Create(*this, 0, 4086219077Sdim NNS->getAsNamespaceAlias()->getNamespace() 4087219077Sdim ->getOriginalNamespace()); 4088219077Sdim 4089193326Sed case NestedNameSpecifier::TypeSpec: 4090193326Sed case NestedNameSpecifier::TypeSpecWithTemplate: { 4091193326Sed QualType T = getCanonicalType(QualType(NNS->getAsType(), 0)); 4092218893Sdim 4093218893Sdim // If we have some kind of dependent-named type (e.g., "typename T::type"), 4094218893Sdim // break it apart into its prefix and identifier, then reconsititute those 4095218893Sdim // as the canonical nested-name-specifier. This is required to canonicalize 4096218893Sdim // a dependent nested-name-specifier involving typedefs of dependent-name 4097218893Sdim // types, e.g., 4098218893Sdim // typedef typename T::type T1; 4099218893Sdim // typedef typename T1::type T2; 4100234353Sdim if (const DependentNameType *DNT = T->getAs<DependentNameType>()) 4101234353Sdim return NestedNameSpecifier::Create(*this, DNT->getQualifier(), 4102218893Sdim const_cast<IdentifierInfo *>(DNT->getIdentifier())); 4103218893Sdim 4104234353Sdim // Otherwise, just canonicalize the type, and force it to be a TypeSpec. 4105234353Sdim // FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the 4106234353Sdim // first place? 4107218893Sdim return NestedNameSpecifier::Create(*this, 0, false, 4108218893Sdim const_cast<Type*>(T.getTypePtr())); 4109193326Sed } 4110193326Sed 4111193326Sed case NestedNameSpecifier::Global: 4112193326Sed // The global specifier is canonical and unique. 4113193326Sed return NNS; 4114193326Sed } 4115193326Sed 4116234353Sdim llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); 4117193326Sed} 4118193326Sed 4119193326Sed 4120218893Sdimconst ArrayType *ASTContext::getAsArrayType(QualType T) const { 4121193326Sed // Handle the non-qualified case efficiently. 4122199482Srdivacky if (!T.hasLocalQualifiers()) { 4123193326Sed // Handle the common positive case fast. 4124193326Sed if (const ArrayType *AT = dyn_cast<ArrayType>(T)) 4125193326Sed return AT; 4126193326Sed } 4127198092Srdivacky 4128198092Srdivacky // Handle the common negative case fast. 4129218893Sdim if (!isa<ArrayType>(T.getCanonicalType())) 4130193326Sed return 0; 4131198092Srdivacky 4132198092Srdivacky // Apply any qualifiers from the array type to the element type. This 4133193326Sed // implements C99 6.7.3p8: "If the specification of an array type includes 4134193326Sed // any type qualifiers, the element type is so qualified, not the array type." 4135198092Srdivacky 4136193326Sed // If we get here, we either have type qualifiers on the type, or we have 4137193326Sed // sugar such as a typedef in the way. If we have type qualifiers on the type 4138198092Srdivacky // we must propagate them down into the element type. 4139198092Srdivacky 4140218893Sdim SplitQualType split = T.getSplitDesugaredType(); 4141234353Sdim Qualifiers qs = split.Quals; 4142198092Srdivacky 4143193326Sed // If we have a simple case, just return now. 4144234353Sdim const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty); 4145218893Sdim if (ATy == 0 || qs.empty()) 4146193326Sed return ATy; 4147198092Srdivacky 4148193326Sed // Otherwise, we have an array and we have qualifiers on it. Push the 4149193326Sed // qualifiers into the array element type and return a new array type. 4150218893Sdim QualType NewEltTy = getQualifiedType(ATy->getElementType(), qs); 4151198092Srdivacky 4152193326Sed if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy)) 4153193326Sed return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(), 4154193326Sed CAT->getSizeModifier(), 4155198092Srdivacky CAT->getIndexTypeCVRQualifiers())); 4156193326Sed if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy)) 4157193326Sed return cast<ArrayType>(getIncompleteArrayType(NewEltTy, 4158193326Sed IAT->getSizeModifier(), 4159198092Srdivacky IAT->getIndexTypeCVRQualifiers())); 4160193326Sed 4161198092Srdivacky if (const DependentSizedArrayType *DSAT 4162193326Sed = dyn_cast<DependentSizedArrayType>(ATy)) 4163193326Sed return cast<ArrayType>( 4164198092Srdivacky getDependentSizedArrayType(NewEltTy, 4165218893Sdim DSAT->getSizeExpr(), 4166193326Sed DSAT->getSizeModifier(), 4167198092Srdivacky DSAT->getIndexTypeCVRQualifiers(), 4168198092Srdivacky DSAT->getBracketsRange())); 4169198092Srdivacky 4170193326Sed const VariableArrayType *VAT = cast<VariableArrayType>(ATy); 4171198092Srdivacky return cast<ArrayType>(getVariableArrayType(NewEltTy, 4172218893Sdim VAT->getSizeExpr(), 4173193326Sed VAT->getSizeModifier(), 4174198092Srdivacky VAT->getIndexTypeCVRQualifiers(), 4175198092Srdivacky VAT->getBracketsRange())); 4176193326Sed} 4177193326Sed 4178239462SdimQualType ASTContext::getAdjustedParameterType(QualType T) const { 4179263508Sdim if (T->isArrayType() || T->isFunctionType()) 4180263508Sdim return getDecayedType(T); 4181263508Sdim return T; 4182224145Sdim} 4183224145Sdim 4184239462SdimQualType ASTContext::getSignatureParameterType(QualType T) const { 4185224145Sdim T = getVariableArrayDecayedType(T); 4186224145Sdim T = getAdjustedParameterType(T); 4187224145Sdim return T.getUnqualifiedType(); 4188224145Sdim} 4189224145Sdim 4190193326Sed/// getArrayDecayedType - Return the properly qualified result of decaying the 4191193326Sed/// specified array type to a pointer. This operation is non-trivial when 4192193326Sed/// handling typedefs etc. The canonical type of "T" must be an array type, 4193193326Sed/// this returns a pointer to a properly qualified element of the array. 4194193326Sed/// 4195193326Sed/// See C99 6.7.5.3p7 and C99 6.3.2.1p3. 4196218893SdimQualType ASTContext::getArrayDecayedType(QualType Ty) const { 4197193326Sed // Get the element type with 'getAsArrayType' so that we don't lose any 4198193326Sed // typedefs in the element type of the array. This also handles propagation 4199193326Sed // of type qualifiers from the array type into the element type if present 4200193326Sed // (C99 6.7.3p8). 4201193326Sed const ArrayType *PrettyArrayType = getAsArrayType(Ty); 4202193326Sed assert(PrettyArrayType && "Not an array type!"); 4203198092Srdivacky 4204193326Sed QualType PtrTy = getPointerType(PrettyArrayType->getElementType()); 4205193326Sed 4206193326Sed // int x[restrict 4] -> int *restrict 4207198092Srdivacky return getQualifiedType(PtrTy, PrettyArrayType->getIndexTypeQualifiers()); 4208193326Sed} 4209193326Sed 4210218893SdimQualType ASTContext::getBaseElementType(const ArrayType *array) const { 4211218893Sdim return getBaseElementType(array->getElementType()); 4212198092Srdivacky} 4213198092Srdivacky 4214218893SdimQualType ASTContext::getBaseElementType(QualType type) const { 4215218893Sdim Qualifiers qs; 4216218893Sdim while (true) { 4217218893Sdim SplitQualType split = type.getSplitDesugaredType(); 4218234353Sdim const ArrayType *array = split.Ty->getAsArrayTypeUnsafe(); 4219218893Sdim if (!array) break; 4220198092Srdivacky 4221218893Sdim type = array->getElementType(); 4222234353Sdim qs.addConsistentQualifiers(split.Quals); 4223218893Sdim } 4224198092Srdivacky 4225218893Sdim return getQualifiedType(type, qs); 4226193326Sed} 4227193326Sed 4228198092Srdivacky/// getConstantArrayElementCount - Returns number of constant array elements. 4229198092Srdivackyuint64_t 4230198092SrdivackyASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const { 4231198092Srdivacky uint64_t ElementCount = 1; 4232198092Srdivacky do { 4233198092Srdivacky ElementCount *= CA->getSize().getZExtValue(); 4234249423Sdim CA = dyn_cast_or_null<ConstantArrayType>( 4235249423Sdim CA->getElementType()->getAsArrayTypeUnsafe()); 4236198092Srdivacky } while (CA); 4237198092Srdivacky return ElementCount; 4238198092Srdivacky} 4239198092Srdivacky 4240193326Sed/// getFloatingRank - Return a relative rank for floating point types. 4241193326Sed/// This routine will assert if passed a built-in type that isn't a float. 4242193326Sedstatic FloatingRank getFloatingRank(QualType T) { 4243198092Srdivacky if (const ComplexType *CT = T->getAs<ComplexType>()) 4244193326Sed return getFloatingRank(CT->getElementType()); 4245193326Sed 4246198092Srdivacky assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type"); 4247198092Srdivacky switch (T->getAs<BuiltinType>()->getKind()) { 4248226633Sdim default: llvm_unreachable("getFloatingRank(): not a floating type"); 4249226633Sdim case BuiltinType::Half: return HalfRank; 4250193326Sed case BuiltinType::Float: return FloatRank; 4251193326Sed case BuiltinType::Double: return DoubleRank; 4252193326Sed case BuiltinType::LongDouble: return LongDoubleRank; 4253193326Sed } 4254193326Sed} 4255193326Sed 4256198092Srdivacky/// getFloatingTypeOfSizeWithinDomain - Returns a real floating 4257198092Srdivacky/// point or a complex type (based on typeDomain/typeSize). 4258193326Sed/// 'typeDomain' is a real floating point or complex type. 4259193326Sed/// 'typeSize' is a real floating point or complex type. 4260193326SedQualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, 4261193326Sed QualType Domain) const { 4262193326Sed FloatingRank EltRank = getFloatingRank(Size); 4263193326Sed if (Domain->isComplexType()) { 4264193326Sed switch (EltRank) { 4265234353Sdim case HalfRank: llvm_unreachable("Complex half is not supported"); 4266193326Sed case FloatRank: return FloatComplexTy; 4267193326Sed case DoubleRank: return DoubleComplexTy; 4268193326Sed case LongDoubleRank: return LongDoubleComplexTy; 4269193326Sed } 4270193326Sed } 4271193326Sed 4272193326Sed assert(Domain->isRealFloatingType() && "Unknown domain!"); 4273193326Sed switch (EltRank) { 4274249423Sdim case HalfRank: return HalfTy; 4275193326Sed case FloatRank: return FloatTy; 4276193326Sed case DoubleRank: return DoubleTy; 4277193326Sed case LongDoubleRank: return LongDoubleTy; 4278193326Sed } 4279234353Sdim llvm_unreachable("getFloatingRank(): illegal value for rank"); 4280193326Sed} 4281193326Sed 4282193326Sed/// getFloatingTypeOrder - Compare the rank of the two specified floating 4283193326Sed/// point types, ignoring the domain of the type (i.e. 'double' == 4284193326Sed/// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If 4285198092Srdivacky/// LHS < RHS, return -1. 4286218893Sdimint ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const { 4287193326Sed FloatingRank LHSR = getFloatingRank(LHS); 4288193326Sed FloatingRank RHSR = getFloatingRank(RHS); 4289198092Srdivacky 4290193326Sed if (LHSR == RHSR) 4291193326Sed return 0; 4292193326Sed if (LHSR > RHSR) 4293193326Sed return 1; 4294193326Sed return -1; 4295193326Sed} 4296193326Sed 4297193326Sed/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This 4298193326Sed/// routine will assert if passed a built-in type that isn't an integer or enum, 4299193326Sed/// or if it is not canonicalized. 4300218893Sdimunsigned ASTContext::getIntegerRank(const Type *T) const { 4301198398Srdivacky assert(T->isCanonicalUnqualified() && "T should be canonicalized"); 4302193326Sed 4303193326Sed switch (cast<BuiltinType>(T)->getKind()) { 4304226633Sdim default: llvm_unreachable("getIntegerRank(): not a built-in integer"); 4305193326Sed case BuiltinType::Bool: 4306193326Sed return 1 + (getIntWidth(BoolTy) << 3); 4307193326Sed case BuiltinType::Char_S: 4308193326Sed case BuiltinType::Char_U: 4309193326Sed case BuiltinType::SChar: 4310193326Sed case BuiltinType::UChar: 4311193326Sed return 2 + (getIntWidth(CharTy) << 3); 4312193326Sed case BuiltinType::Short: 4313193326Sed case BuiltinType::UShort: 4314193326Sed return 3 + (getIntWidth(ShortTy) << 3); 4315193326Sed case BuiltinType::Int: 4316193326Sed case BuiltinType::UInt: 4317193326Sed return 4 + (getIntWidth(IntTy) << 3); 4318193326Sed case BuiltinType::Long: 4319193326Sed case BuiltinType::ULong: 4320193326Sed return 5 + (getIntWidth(LongTy) << 3); 4321193326Sed case BuiltinType::LongLong: 4322193326Sed case BuiltinType::ULongLong: 4323193326Sed return 6 + (getIntWidth(LongLongTy) << 3); 4324193326Sed case BuiltinType::Int128: 4325193326Sed case BuiltinType::UInt128: 4326193326Sed return 7 + (getIntWidth(Int128Ty) << 3); 4327193326Sed } 4328193326Sed} 4329193326Sed 4330198092Srdivacky/// \brief Whether this is a promotable bitfield reference according 4331198092Srdivacky/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions). 4332198092Srdivacky/// 4333198092Srdivacky/// \returns the type this bit-field will promote to, or NULL if no 4334198092Srdivacky/// promotion occurs. 4335218893SdimQualType ASTContext::isPromotableBitField(Expr *E) const { 4336208600Srdivacky if (E->isTypeDependent() || E->isValueDependent()) 4337208600Srdivacky return QualType(); 4338208600Srdivacky 4339251662Sdim FieldDecl *Field = E->getSourceBitField(); // FIXME: conditional bit-fields? 4340198092Srdivacky if (!Field) 4341198092Srdivacky return QualType(); 4342198092Srdivacky 4343198092Srdivacky QualType FT = Field->getType(); 4344198092Srdivacky 4345226633Sdim uint64_t BitWidth = Field->getBitWidthValue(*this); 4346198092Srdivacky uint64_t IntSize = getTypeSize(IntTy); 4347198092Srdivacky // GCC extension compatibility: if the bit-field size is less than or equal 4348198092Srdivacky // to the size of int, it gets promoted no matter what its type is. 4349198092Srdivacky // For instance, unsigned long bf : 4 gets promoted to signed int. 4350198092Srdivacky if (BitWidth < IntSize) 4351198092Srdivacky return IntTy; 4352198092Srdivacky 4353198092Srdivacky if (BitWidth == IntSize) 4354198092Srdivacky return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy; 4355198092Srdivacky 4356198092Srdivacky // Types bigger than int are not subject to promotions, and therefore act 4357198092Srdivacky // like the base type. 4358198092Srdivacky // FIXME: This doesn't quite match what gcc does, but what gcc does here 4359198092Srdivacky // is ridiculous. 4360198092Srdivacky return QualType(); 4361198092Srdivacky} 4362198092Srdivacky 4363198092Srdivacky/// getPromotedIntegerType - Returns the type that Promotable will 4364198092Srdivacky/// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable 4365198092Srdivacky/// integer type. 4366218893SdimQualType ASTContext::getPromotedIntegerType(QualType Promotable) const { 4367198092Srdivacky assert(!Promotable.isNull()); 4368198092Srdivacky assert(Promotable->isPromotableIntegerType()); 4369200583Srdivacky if (const EnumType *ET = Promotable->getAs<EnumType>()) 4370200583Srdivacky return ET->getDecl()->getPromotionType(); 4371234353Sdim 4372234353Sdim if (const BuiltinType *BT = Promotable->getAs<BuiltinType>()) { 4373234353Sdim // C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t 4374234353Sdim // (3.9.1) can be converted to a prvalue of the first of the following 4375234353Sdim // types that can represent all the values of its underlying type: 4376234353Sdim // int, unsigned int, long int, unsigned long int, long long int, or 4377234353Sdim // unsigned long long int [...] 4378234353Sdim // FIXME: Is there some better way to compute this? 4379234353Sdim if (BT->getKind() == BuiltinType::WChar_S || 4380234353Sdim BT->getKind() == BuiltinType::WChar_U || 4381234353Sdim BT->getKind() == BuiltinType::Char16 || 4382234353Sdim BT->getKind() == BuiltinType::Char32) { 4383234353Sdim bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S; 4384234353Sdim uint64_t FromSize = getTypeSize(BT); 4385234353Sdim QualType PromoteTypes[] = { IntTy, UnsignedIntTy, LongTy, UnsignedLongTy, 4386234353Sdim LongLongTy, UnsignedLongLongTy }; 4387234353Sdim for (size_t Idx = 0; Idx < llvm::array_lengthof(PromoteTypes); ++Idx) { 4388234353Sdim uint64_t ToSize = getTypeSize(PromoteTypes[Idx]); 4389234353Sdim if (FromSize < ToSize || 4390234353Sdim (FromSize == ToSize && 4391234353Sdim FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) 4392234353Sdim return PromoteTypes[Idx]; 4393234353Sdim } 4394234353Sdim llvm_unreachable("char type should fit into long long"); 4395234353Sdim } 4396234353Sdim } 4397234353Sdim 4398234353Sdim // At this point, we should have a signed or unsigned integer type. 4399198092Srdivacky if (Promotable->isSignedIntegerType()) 4400198092Srdivacky return IntTy; 4401249423Sdim uint64_t PromotableSize = getIntWidth(Promotable); 4402249423Sdim uint64_t IntSize = getIntWidth(IntTy); 4403198092Srdivacky assert(Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize); 4404198092Srdivacky return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy; 4405198092Srdivacky} 4406198092Srdivacky 4407224145Sdim/// \brief Recurses in pointer/array types until it finds an objc retainable 4408224145Sdim/// type and returns its ownership. 4409224145SdimQualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const { 4410224145Sdim while (!T.isNull()) { 4411224145Sdim if (T.getObjCLifetime() != Qualifiers::OCL_None) 4412224145Sdim return T.getObjCLifetime(); 4413224145Sdim if (T->isArrayType()) 4414224145Sdim T = getBaseElementType(T); 4415224145Sdim else if (const PointerType *PT = T->getAs<PointerType>()) 4416224145Sdim T = PT->getPointeeType(); 4417224145Sdim else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 4418224145Sdim T = RT->getPointeeType(); 4419224145Sdim else 4420224145Sdim break; 4421224145Sdim } 4422224145Sdim 4423224145Sdim return Qualifiers::OCL_None; 4424224145Sdim} 4425224145Sdim 4426263508Sdimstatic const Type *getIntegerTypeForEnum(const EnumType *ET) { 4427263508Sdim // Incomplete enum types are not treated as integer types. 4428263508Sdim // FIXME: In C++, enum types are never integer types. 4429263508Sdim if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) 4430263508Sdim return ET->getDecl()->getIntegerType().getTypePtr(); 4431263508Sdim return NULL; 4432263508Sdim} 4433263508Sdim 4434198092Srdivacky/// getIntegerTypeOrder - Returns the highest ranked integer type: 4435193326Sed/// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If 4436198092Srdivacky/// LHS < RHS, return -1. 4437218893Sdimint ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const { 4438218893Sdim const Type *LHSC = getCanonicalType(LHS).getTypePtr(); 4439218893Sdim const Type *RHSC = getCanonicalType(RHS).getTypePtr(); 4440263508Sdim 4441263508Sdim // Unwrap enums to their underlying type. 4442263508Sdim if (const EnumType *ET = dyn_cast<EnumType>(LHSC)) 4443263508Sdim LHSC = getIntegerTypeForEnum(ET); 4444263508Sdim if (const EnumType *ET = dyn_cast<EnumType>(RHSC)) 4445263508Sdim RHSC = getIntegerTypeForEnum(ET); 4446263508Sdim 4447193326Sed if (LHSC == RHSC) return 0; 4448198092Srdivacky 4449193326Sed bool LHSUnsigned = LHSC->isUnsignedIntegerType(); 4450193326Sed bool RHSUnsigned = RHSC->isUnsignedIntegerType(); 4451198092Srdivacky 4452193326Sed unsigned LHSRank = getIntegerRank(LHSC); 4453193326Sed unsigned RHSRank = getIntegerRank(RHSC); 4454198092Srdivacky 4455193326Sed if (LHSUnsigned == RHSUnsigned) { // Both signed or both unsigned. 4456193326Sed if (LHSRank == RHSRank) return 0; 4457193326Sed return LHSRank > RHSRank ? 1 : -1; 4458193326Sed } 4459198092Srdivacky 4460193326Sed // Otherwise, the LHS is signed and the RHS is unsigned or visa versa. 4461193326Sed if (LHSUnsigned) { 4462193326Sed // If the unsigned [LHS] type is larger, return it. 4463193326Sed if (LHSRank >= RHSRank) 4464193326Sed return 1; 4465198092Srdivacky 4466193326Sed // If the signed type can represent all values of the unsigned type, it 4467193326Sed // wins. Because we are dealing with 2's complement and types that are 4468198092Srdivacky // powers of two larger than each other, this is always safe. 4469193326Sed return -1; 4470193326Sed } 4471193326Sed 4472193326Sed // If the unsigned [RHS] type is larger, return it. 4473193326Sed if (RHSRank >= LHSRank) 4474193326Sed return -1; 4475198092Srdivacky 4476193326Sed // If the signed type can represent all values of the unsigned type, it 4477193326Sed // wins. Because we are dealing with 2's complement and types that are 4478198092Srdivacky // powers of two larger than each other, this is always safe. 4479193326Sed return 1; 4480193326Sed} 4481193326Sed 4482199482Srdivackystatic RecordDecl * 4483221345SdimCreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK, 4484221345Sdim DeclContext *DC, IdentifierInfo *Id) { 4485221345Sdim SourceLocation Loc; 4486234353Sdim if (Ctx.getLangOpts().CPlusPlus) 4487221345Sdim return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); 4488199482Srdivacky else 4489221345Sdim return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); 4490199482Srdivacky} 4491221345Sdim 4492198092Srdivacky// getCFConstantStringType - Return the type used for constant CFStrings. 4493218893SdimQualType ASTContext::getCFConstantStringType() const { 4494193326Sed if (!CFConstantStringTypeDecl) { 4495198092Srdivacky CFConstantStringTypeDecl = 4496221345Sdim CreateRecordDecl(*this, TTK_Struct, TUDecl, 4497199482Srdivacky &Idents.get("NSConstantString")); 4498203955Srdivacky CFConstantStringTypeDecl->startDefinition(); 4499199482Srdivacky 4500193326Sed QualType FieldTypes[4]; 4501198092Srdivacky 4502193326Sed // const int *isa; 4503198092Srdivacky FieldTypes[0] = getPointerType(IntTy.withConst()); 4504193326Sed // int flags; 4505193326Sed FieldTypes[1] = IntTy; 4506193326Sed // const char *str; 4507198092Srdivacky FieldTypes[2] = getPointerType(CharTy.withConst()); 4508193326Sed // long length; 4509198092Srdivacky FieldTypes[3] = LongTy; 4510198092Srdivacky 4511193326Sed // Create fields 4512193326Sed for (unsigned i = 0; i < 4; ++i) { 4513198092Srdivacky FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl, 4514221345Sdim SourceLocation(), 4515193326Sed SourceLocation(), 0, 4516200583Srdivacky FieldTypes[i], /*TInfo=*/0, 4517198092Srdivacky /*BitWidth=*/0, 4518223017Sdim /*Mutable=*/false, 4519239462Sdim ICIS_NoInit); 4520207619Srdivacky Field->setAccess(AS_public); 4521195341Sed CFConstantStringTypeDecl->addDecl(Field); 4522193326Sed } 4523193326Sed 4524203955Srdivacky CFConstantStringTypeDecl->completeDefinition(); 4525193326Sed } 4526198092Srdivacky 4527193326Sed return getTagDeclType(CFConstantStringTypeDecl); 4528193326Sed} 4529193326Sed 4530249423SdimQualType ASTContext::getObjCSuperType() const { 4531249423Sdim if (ObjCSuperType.isNull()) { 4532249423Sdim RecordDecl *ObjCSuperTypeDecl = 4533249423Sdim CreateRecordDecl(*this, TTK_Struct, TUDecl, &Idents.get("objc_super")); 4534249423Sdim TUDecl->addDecl(ObjCSuperTypeDecl); 4535249423Sdim ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl); 4536249423Sdim } 4537249423Sdim return ObjCSuperType; 4538249423Sdim} 4539249423Sdim 4540193326Sedvoid ASTContext::setCFConstantStringType(QualType T) { 4541198092Srdivacky const RecordType *Rec = T->getAs<RecordType>(); 4542193326Sed assert(Rec && "Invalid CFConstantStringType"); 4543193326Sed CFConstantStringTypeDecl = Rec->getDecl(); 4544193326Sed} 4545193326Sed 4546218893SdimQualType ASTContext::getBlockDescriptorType() const { 4547198398Srdivacky if (BlockDescriptorType) 4548198398Srdivacky return getTagDeclType(BlockDescriptorType); 4549198398Srdivacky 4550198398Srdivacky RecordDecl *T; 4551198398Srdivacky // FIXME: Needs the FlagAppleBlock bit. 4552221345Sdim T = CreateRecordDecl(*this, TTK_Struct, TUDecl, 4553199482Srdivacky &Idents.get("__block_descriptor")); 4554203955Srdivacky T->startDefinition(); 4555198398Srdivacky 4556198398Srdivacky QualType FieldTypes[] = { 4557198398Srdivacky UnsignedLongTy, 4558198398Srdivacky UnsignedLongTy, 4559198398Srdivacky }; 4560198398Srdivacky 4561263508Sdim static const char *const FieldNames[] = { 4562198398Srdivacky "reserved", 4563198398Srdivacky "Size" 4564198398Srdivacky }; 4565198398Srdivacky 4566198398Srdivacky for (size_t i = 0; i < 2; ++i) { 4567221345Sdim FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), 4568198398Srdivacky SourceLocation(), 4569198398Srdivacky &Idents.get(FieldNames[i]), 4570200583Srdivacky FieldTypes[i], /*TInfo=*/0, 4571198398Srdivacky /*BitWidth=*/0, 4572223017Sdim /*Mutable=*/false, 4573239462Sdim ICIS_NoInit); 4574207619Srdivacky Field->setAccess(AS_public); 4575198398Srdivacky T->addDecl(Field); 4576198398Srdivacky } 4577198398Srdivacky 4578203955Srdivacky T->completeDefinition(); 4579198398Srdivacky 4580198398Srdivacky BlockDescriptorType = T; 4581198398Srdivacky 4582198398Srdivacky return getTagDeclType(BlockDescriptorType); 4583198398Srdivacky} 4584198398Srdivacky 4585218893SdimQualType ASTContext::getBlockDescriptorExtendedType() const { 4586198398Srdivacky if (BlockDescriptorExtendedType) 4587198398Srdivacky return getTagDeclType(BlockDescriptorExtendedType); 4588198398Srdivacky 4589198398Srdivacky RecordDecl *T; 4590198398Srdivacky // FIXME: Needs the FlagAppleBlock bit. 4591221345Sdim T = CreateRecordDecl(*this, TTK_Struct, TUDecl, 4592199482Srdivacky &Idents.get("__block_descriptor_withcopydispose")); 4593203955Srdivacky T->startDefinition(); 4594198398Srdivacky 4595198398Srdivacky QualType FieldTypes[] = { 4596198398Srdivacky UnsignedLongTy, 4597198398Srdivacky UnsignedLongTy, 4598198398Srdivacky getPointerType(VoidPtrTy), 4599198398Srdivacky getPointerType(VoidPtrTy) 4600198398Srdivacky }; 4601198398Srdivacky 4602263508Sdim static const char *const FieldNames[] = { 4603198398Srdivacky "reserved", 4604198398Srdivacky "Size", 4605198398Srdivacky "CopyFuncPtr", 4606198398Srdivacky "DestroyFuncPtr" 4607198398Srdivacky }; 4608198398Srdivacky 4609198398Srdivacky for (size_t i = 0; i < 4; ++i) { 4610221345Sdim FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), 4611198398Srdivacky SourceLocation(), 4612198398Srdivacky &Idents.get(FieldNames[i]), 4613200583Srdivacky FieldTypes[i], /*TInfo=*/0, 4614198398Srdivacky /*BitWidth=*/0, 4615223017Sdim /*Mutable=*/false, 4616239462Sdim ICIS_NoInit); 4617207619Srdivacky Field->setAccess(AS_public); 4618198398Srdivacky T->addDecl(Field); 4619198398Srdivacky } 4620198398Srdivacky 4621203955Srdivacky T->completeDefinition(); 4622198398Srdivacky 4623198398Srdivacky BlockDescriptorExtendedType = T; 4624198398Srdivacky 4625198398Srdivacky return getTagDeclType(BlockDescriptorExtendedType); 4626198398Srdivacky} 4627198398Srdivacky 4628249423Sdim/// BlockRequiresCopying - Returns true if byref variable "D" of type "Ty" 4629249423Sdim/// requires copy/dispose. Note that this must match the logic 4630249423Sdim/// in buildByrefHelpers. 4631249423Sdimbool ASTContext::BlockRequiresCopying(QualType Ty, 4632249423Sdim const VarDecl *D) { 4633249423Sdim if (const CXXRecordDecl *record = Ty->getAsCXXRecordDecl()) { 4634249423Sdim const Expr *copyExpr = getBlockVarCopyInits(D); 4635249423Sdim if (!copyExpr && record->hasTrivialDestructor()) return false; 4636249423Sdim 4637198398Srdivacky return true; 4638249423Sdim } 4639249423Sdim 4640249423Sdim if (!Ty->isObjCRetainableType()) return false; 4641249423Sdim 4642249423Sdim Qualifiers qs = Ty.getQualifiers(); 4643249423Sdim 4644249423Sdim // If we have lifetime, that dominates. 4645249423Sdim if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) { 4646249423Sdim assert(getLangOpts().ObjCAutoRefCount); 4647249423Sdim 4648249423Sdim switch (lifetime) { 4649249423Sdim case Qualifiers::OCL_None: llvm_unreachable("impossible"); 4650249423Sdim 4651249423Sdim // These are just bits as far as the runtime is concerned. 4652249423Sdim case Qualifiers::OCL_ExplicitNone: 4653249423Sdim case Qualifiers::OCL_Autoreleasing: 4654249423Sdim return false; 4655249423Sdim 4656249423Sdim // Tell the runtime that this is ARC __weak, called by the 4657249423Sdim // byref routines. 4658249423Sdim case Qualifiers::OCL_Weak: 4659249423Sdim // ARC __strong __block variables need to be retained. 4660249423Sdim case Qualifiers::OCL_Strong: 4661249423Sdim return true; 4662218893Sdim } 4663249423Sdim llvm_unreachable("fell out of lifetime switch!"); 4664218893Sdim } 4665249423Sdim return (Ty->isBlockPointerType() || isObjCNSObjectType(Ty) || 4666249423Sdim Ty->isObjCObjectPointerType()); 4667198398Srdivacky} 4668198398Srdivacky 4669249423Sdimbool ASTContext::getByrefLifetime(QualType Ty, 4670249423Sdim Qualifiers::ObjCLifetime &LifeTime, 4671249423Sdim bool &HasByrefExtendedLayout) const { 4672249423Sdim 4673249423Sdim if (!getLangOpts().ObjC1 || 4674249423Sdim getLangOpts().getGC() != LangOptions::NonGC) 4675249423Sdim return false; 4676249423Sdim 4677249423Sdim HasByrefExtendedLayout = false; 4678249423Sdim if (Ty->isRecordType()) { 4679249423Sdim HasByrefExtendedLayout = true; 4680249423Sdim LifeTime = Qualifiers::OCL_None; 4681198398Srdivacky } 4682249423Sdim else if (getLangOpts().ObjCAutoRefCount) 4683249423Sdim LifeTime = Ty.getObjCLifetime(); 4684249423Sdim // MRR. 4685249423Sdim else if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) 4686249423Sdim LifeTime = Qualifiers::OCL_ExplicitNone; 4687249423Sdim else 4688249423Sdim LifeTime = Qualifiers::OCL_None; 4689249423Sdim return true; 4690198398Srdivacky} 4691198398Srdivacky 4692226633SdimTypedefDecl *ASTContext::getObjCInstanceTypeDecl() { 4693226633Sdim if (!ObjCInstanceTypeDecl) 4694226633Sdim ObjCInstanceTypeDecl = TypedefDecl::Create(*this, 4695226633Sdim getTranslationUnitDecl(), 4696226633Sdim SourceLocation(), 4697226633Sdim SourceLocation(), 4698226633Sdim &Idents.get("instancetype"), 4699226633Sdim getTrivialTypeSourceInfo(getObjCIdType())); 4700226633Sdim return ObjCInstanceTypeDecl; 4701193326Sed} 4702193326Sed 4703193326Sed// This returns true if a type has been typedefed to BOOL: 4704193326Sed// typedef <type> BOOL; 4705193326Sedstatic bool isTypeTypedefedAsBOOL(QualType T) { 4706193326Sed if (const TypedefType *TT = dyn_cast<TypedefType>(T)) 4707193326Sed if (IdentifierInfo *II = TT->getDecl()->getIdentifier()) 4708193326Sed return II->isStr("BOOL"); 4709198092Srdivacky 4710193326Sed return false; 4711193326Sed} 4712193326Sed 4713193326Sed/// getObjCEncodingTypeSize returns size of type for objective-c encoding 4714193326Sed/// purpose. 4715218893SdimCharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const { 4716223017Sdim if (!type->isIncompleteArrayType() && type->isIncompleteType()) 4717223017Sdim return CharUnits::Zero(); 4718223017Sdim 4719202379Srdivacky CharUnits sz = getTypeSizeInChars(type); 4720198092Srdivacky 4721193326Sed // Make all integer and enum types at least as large as an int 4722210299Sed if (sz.isPositive() && type->isIntegralOrEnumerationType()) 4723202379Srdivacky sz = std::max(sz, getTypeSizeInChars(IntTy)); 4724193326Sed // Treat arrays as pointers, since that's how they're passed in. 4725193326Sed else if (type->isArrayType()) 4726202379Srdivacky sz = getTypeSizeInChars(VoidPtrTy); 4727202379Srdivacky return sz; 4728193326Sed} 4729193326Sed 4730202379Srdivackystatic inline 4731202379Srdivackystd::string charUnitsToString(const CharUnits &CU) { 4732202379Srdivacky return llvm::itostr(CU.getQuantity()); 4733202379Srdivacky} 4734202379Srdivacky 4735218893Sdim/// getObjCEncodingForBlock - Return the encoded type for this block 4736199482Srdivacky/// declaration. 4737218893Sdimstd::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { 4738218893Sdim std::string S; 4739218893Sdim 4740199482Srdivacky const BlockDecl *Decl = Expr->getBlockDecl(); 4741199482Srdivacky QualType BlockTy = 4742199482Srdivacky Expr->getType()->getAs<BlockPointerType>()->getPointeeType(); 4743199482Srdivacky // Encode result type. 4744243830Sdim if (getLangOpts().EncodeExtendedBlockSig) 4745243830Sdim getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, 4746243830Sdim BlockTy->getAs<FunctionType>()->getResultType(), 4747243830Sdim S, true /*Extended*/); 4748243830Sdim else 4749243830Sdim getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getResultType(), 4750243830Sdim S); 4751199482Srdivacky // Compute size of all parameters. 4752199482Srdivacky // Start with computing size of a pointer in number of bytes. 4753199482Srdivacky // FIXME: There might(should) be a better way of doing this computation! 4754199482Srdivacky SourceLocation Loc; 4755202379Srdivacky CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); 4756202379Srdivacky CharUnits ParmOffset = PtrSize; 4757207619Srdivacky for (BlockDecl::param_const_iterator PI = Decl->param_begin(), 4758199482Srdivacky E = Decl->param_end(); PI != E; ++PI) { 4759199482Srdivacky QualType PType = (*PI)->getType(); 4760202379Srdivacky CharUnits sz = getObjCEncodingTypeSize(PType); 4761239462Sdim if (sz.isZero()) 4762239462Sdim continue; 4763202379Srdivacky assert (sz.isPositive() && "BlockExpr - Incomplete param type"); 4764199482Srdivacky ParmOffset += sz; 4765199482Srdivacky } 4766199482Srdivacky // Size of the argument frame 4767202379Srdivacky S += charUnitsToString(ParmOffset); 4768199482Srdivacky // Block pointer and offset. 4769199482Srdivacky S += "@?0"; 4770199482Srdivacky 4771199482Srdivacky // Argument types. 4772199482Srdivacky ParmOffset = PtrSize; 4773199482Srdivacky for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E = 4774199482Srdivacky Decl->param_end(); PI != E; ++PI) { 4775199482Srdivacky ParmVarDecl *PVDecl = *PI; 4776199482Srdivacky QualType PType = PVDecl->getOriginalType(); 4777199482Srdivacky if (const ArrayType *AT = 4778199482Srdivacky dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { 4779199482Srdivacky // Use array's original type only if it has known number of 4780199482Srdivacky // elements. 4781199482Srdivacky if (!isa<ConstantArrayType>(AT)) 4782199482Srdivacky PType = PVDecl->getType(); 4783199482Srdivacky } else if (PType->isFunctionType()) 4784199482Srdivacky PType = PVDecl->getType(); 4785243830Sdim if (getLangOpts().EncodeExtendedBlockSig) 4786243830Sdim getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, PType, 4787243830Sdim S, true /*Extended*/); 4788243830Sdim else 4789243830Sdim getObjCEncodingForType(PType, S); 4790202379Srdivacky S += charUnitsToString(ParmOffset); 4791199482Srdivacky ParmOffset += getObjCEncodingTypeSize(PType); 4792199482Srdivacky } 4793218893Sdim 4794218893Sdim return S; 4795199482Srdivacky} 4796199482Srdivacky 4797223017Sdimbool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, 4798218893Sdim std::string& S) { 4799218893Sdim // Encode result type. 4800218893Sdim getObjCEncodingForType(Decl->getResultType(), S); 4801218893Sdim CharUnits ParmOffset; 4802218893Sdim // Compute size of all parameters. 4803218893Sdim for (FunctionDecl::param_const_iterator PI = Decl->param_begin(), 4804218893Sdim E = Decl->param_end(); PI != E; ++PI) { 4805218893Sdim QualType PType = (*PI)->getType(); 4806218893Sdim CharUnits sz = getObjCEncodingTypeSize(PType); 4807223017Sdim if (sz.isZero()) 4808239462Sdim continue; 4809239462Sdim 4810218893Sdim assert (sz.isPositive() && 4811223017Sdim "getObjCEncodingForFunctionDecl - Incomplete param type"); 4812218893Sdim ParmOffset += sz; 4813218893Sdim } 4814218893Sdim S += charUnitsToString(ParmOffset); 4815218893Sdim ParmOffset = CharUnits::Zero(); 4816218893Sdim 4817218893Sdim // Argument types. 4818218893Sdim for (FunctionDecl::param_const_iterator PI = Decl->param_begin(), 4819218893Sdim E = Decl->param_end(); PI != E; ++PI) { 4820218893Sdim ParmVarDecl *PVDecl = *PI; 4821218893Sdim QualType PType = PVDecl->getOriginalType(); 4822218893Sdim if (const ArrayType *AT = 4823218893Sdim dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { 4824218893Sdim // Use array's original type only if it has known number of 4825218893Sdim // elements. 4826218893Sdim if (!isa<ConstantArrayType>(AT)) 4827218893Sdim PType = PVDecl->getType(); 4828218893Sdim } else if (PType->isFunctionType()) 4829218893Sdim PType = PVDecl->getType(); 4830218893Sdim getObjCEncodingForType(PType, S); 4831218893Sdim S += charUnitsToString(ParmOffset); 4832218893Sdim ParmOffset += getObjCEncodingTypeSize(PType); 4833218893Sdim } 4834223017Sdim 4835223017Sdim return false; 4836218893Sdim} 4837218893Sdim 4838234353Sdim/// getObjCEncodingForMethodParameter - Return the encoded type for a single 4839234353Sdim/// method parameter or return type. If Extended, include class names and 4840234353Sdim/// block object types. 4841234353Sdimvoid ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, 4842234353Sdim QualType T, std::string& S, 4843234353Sdim bool Extended) const { 4844234353Sdim // Encode type qualifer, 'in', 'inout', etc. for the parameter. 4845234353Sdim getObjCEncodingForTypeQualifier(QT, S); 4846234353Sdim // Encode parameter type. 4847234353Sdim getObjCEncodingForTypeImpl(T, S, true, true, 0, 4848234353Sdim true /*OutermostType*/, 4849234353Sdim false /*EncodingProperty*/, 4850234353Sdim false /*StructField*/, 4851234353Sdim Extended /*EncodeBlockParameters*/, 4852234353Sdim Extended /*EncodeClassNames*/); 4853234353Sdim} 4854234353Sdim 4855193326Sed/// getObjCEncodingForMethodDecl - Return the encoded type for this method 4856193326Sed/// declaration. 4857223017Sdimbool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, 4858234353Sdim std::string& S, 4859234353Sdim bool Extended) const { 4860193326Sed // FIXME: This is not very efficient. 4861234353Sdim // Encode return type. 4862234353Sdim getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), 4863234353Sdim Decl->getResultType(), S, Extended); 4864193326Sed // Compute size of all parameters. 4865193326Sed // Start with computing size of a pointer in number of bytes. 4866193326Sed // FIXME: There might(should) be a better way of doing this computation! 4867193326Sed SourceLocation Loc; 4868202379Srdivacky CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); 4869193326Sed // The first two arguments (self and _cmd) are pointers; account for 4870193326Sed // their size. 4871202379Srdivacky CharUnits ParmOffset = 2 * PtrSize; 4872226633Sdim for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(), 4873207619Srdivacky E = Decl->sel_param_end(); PI != E; ++PI) { 4874193326Sed QualType PType = (*PI)->getType(); 4875202379Srdivacky CharUnits sz = getObjCEncodingTypeSize(PType); 4876223017Sdim if (sz.isZero()) 4877239462Sdim continue; 4878239462Sdim 4879202379Srdivacky assert (sz.isPositive() && 4880202379Srdivacky "getObjCEncodingForMethodDecl - Incomplete param type"); 4881193326Sed ParmOffset += sz; 4882193326Sed } 4883202379Srdivacky S += charUnitsToString(ParmOffset); 4884193326Sed S += "@0:"; 4885202379Srdivacky S += charUnitsToString(PtrSize); 4886198092Srdivacky 4887193326Sed // Argument types. 4888193326Sed ParmOffset = 2 * PtrSize; 4889226633Sdim for (ObjCMethodDecl::param_const_iterator PI = Decl->param_begin(), 4890207619Srdivacky E = Decl->sel_param_end(); PI != E; ++PI) { 4891226633Sdim const ParmVarDecl *PVDecl = *PI; 4892198092Srdivacky QualType PType = PVDecl->getOriginalType(); 4893193326Sed if (const ArrayType *AT = 4894193326Sed dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { 4895193326Sed // Use array's original type only if it has known number of 4896193326Sed // elements. 4897193326Sed if (!isa<ConstantArrayType>(AT)) 4898193326Sed PType = PVDecl->getType(); 4899193326Sed } else if (PType->isFunctionType()) 4900193326Sed PType = PVDecl->getType(); 4901234353Sdim getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(), 4902234353Sdim PType, S, Extended); 4903202379Srdivacky S += charUnitsToString(ParmOffset); 4904193326Sed ParmOffset += getObjCEncodingTypeSize(PType); 4905193326Sed } 4906223017Sdim 4907223017Sdim return false; 4908193326Sed} 4909193326Sed 4910193326Sed/// getObjCEncodingForPropertyDecl - Return the encoded type for this 4911193326Sed/// property declaration. If non-NULL, Container must be either an 4912193326Sed/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be 4913193326Sed/// NULL when getting encodings for protocol properties. 4914198092Srdivacky/// Property attributes are stored as a comma-delimited C string. The simple 4915198092Srdivacky/// attributes readonly and bycopy are encoded as single characters. The 4916198092Srdivacky/// parametrized attributes, getter=name, setter=name, and ivar=name, are 4917198092Srdivacky/// encoded as single characters, followed by an identifier. Property types 4918198092Srdivacky/// are also encoded as a parametrized attribute. The characters used to encode 4919193326Sed/// these attributes are defined by the following enumeration: 4920193326Sed/// @code 4921193326Sed/// enum PropertyAttributes { 4922193326Sed/// kPropertyReadOnly = 'R', // property is read-only. 4923193326Sed/// kPropertyBycopy = 'C', // property is a copy of the value last assigned 4924193326Sed/// kPropertyByref = '&', // property is a reference to the value last assigned 4925193326Sed/// kPropertyDynamic = 'D', // property is dynamic 4926193326Sed/// kPropertyGetter = 'G', // followed by getter selector name 4927193326Sed/// kPropertySetter = 'S', // followed by setter selector name 4928193326Sed/// kPropertyInstanceVariable = 'V' // followed by instance variable name 4929234353Sdim/// kPropertyType = 'T' // followed by old-style type encoding. 4930193326Sed/// kPropertyWeak = 'W' // 'weak' property 4931193326Sed/// kPropertyStrong = 'P' // property GC'able 4932193326Sed/// kPropertyNonAtomic = 'N' // property non-atomic 4933193326Sed/// }; 4934193326Sed/// @endcode 4935198092Srdivackyvoid ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, 4936193326Sed const Decl *Container, 4937218893Sdim std::string& S) const { 4938193326Sed // Collect information from the property implementation decl(s). 4939193326Sed bool Dynamic = false; 4940193326Sed ObjCPropertyImplDecl *SynthesizePID = 0; 4941193326Sed 4942193326Sed // FIXME: Duplicated code due to poor abstraction. 4943193326Sed if (Container) { 4944198092Srdivacky if (const ObjCCategoryImplDecl *CID = 4945193326Sed dyn_cast<ObjCCategoryImplDecl>(Container)) { 4946193326Sed for (ObjCCategoryImplDecl::propimpl_iterator 4947195341Sed i = CID->propimpl_begin(), e = CID->propimpl_end(); 4948193326Sed i != e; ++i) { 4949193326Sed ObjCPropertyImplDecl *PID = *i; 4950193326Sed if (PID->getPropertyDecl() == PD) { 4951193326Sed if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) { 4952193326Sed Dynamic = true; 4953193326Sed } else { 4954193326Sed SynthesizePID = PID; 4955193326Sed } 4956193326Sed } 4957193326Sed } 4958193326Sed } else { 4959193326Sed const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container); 4960193326Sed for (ObjCCategoryImplDecl::propimpl_iterator 4961195341Sed i = OID->propimpl_begin(), e = OID->propimpl_end(); 4962193326Sed i != e; ++i) { 4963193326Sed ObjCPropertyImplDecl *PID = *i; 4964193326Sed if (PID->getPropertyDecl() == PD) { 4965193326Sed if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) { 4966193326Sed Dynamic = true; 4967193326Sed } else { 4968193326Sed SynthesizePID = PID; 4969193326Sed } 4970193326Sed } 4971198092Srdivacky } 4972193326Sed } 4973193326Sed } 4974193326Sed 4975193326Sed // FIXME: This is not very efficient. 4976193326Sed S = "T"; 4977193326Sed 4978193326Sed // Encode result type. 4979193326Sed // GCC has some special rules regarding encoding of properties which 4980193326Sed // closely resembles encoding of ivars. 4981198092Srdivacky getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0, 4982193326Sed true /* outermost type */, 4983193326Sed true /* encoding for property */); 4984193326Sed 4985193326Sed if (PD->isReadOnly()) { 4986193326Sed S += ",R"; 4987263508Sdim if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) 4988263508Sdim S += ",C"; 4989263508Sdim if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) 4990263508Sdim S += ",&"; 4991193326Sed } else { 4992193326Sed switch (PD->getSetterKind()) { 4993193326Sed case ObjCPropertyDecl::Assign: break; 4994193326Sed case ObjCPropertyDecl::Copy: S += ",C"; break; 4995198092Srdivacky case ObjCPropertyDecl::Retain: S += ",&"; break; 4996226633Sdim case ObjCPropertyDecl::Weak: S += ",W"; break; 4997193326Sed } 4998193326Sed } 4999193326Sed 5000193326Sed // It really isn't clear at all what this means, since properties 5001193326Sed // are "dynamic by default". 5002193326Sed if (Dynamic) 5003193326Sed S += ",D"; 5004193326Sed 5005193326Sed if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) 5006193326Sed S += ",N"; 5007198092Srdivacky 5008193326Sed if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { 5009193326Sed S += ",G"; 5010193326Sed S += PD->getGetterName().getAsString(); 5011193326Sed } 5012193326Sed 5013193326Sed if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { 5014193326Sed S += ",S"; 5015193326Sed S += PD->getSetterName().getAsString(); 5016193326Sed } 5017193326Sed 5018193326Sed if (SynthesizePID) { 5019193326Sed const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl(); 5020193326Sed S += ",V"; 5021193326Sed S += OID->getNameAsString(); 5022193326Sed } 5023193326Sed 5024193326Sed // FIXME: OBJCGC: weak & strong 5025193326Sed} 5026193326Sed 5027193326Sed/// getLegacyIntegralTypeEncoding - 5028198092Srdivacky/// Another legacy compatibility encoding: 32-bit longs are encoded as 5029198092Srdivacky/// 'l' or 'L' , but not always. For typedefs, we need to use 5030193326Sed/// 'i' or 'I' instead if encoding a struct field, or a pointer! 5031193326Sed/// 5032193326Sedvoid ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const { 5033198092Srdivacky if (isa<TypedefType>(PointeeTy.getTypePtr())) { 5034198092Srdivacky if (const BuiltinType *BT = PointeeTy->getAs<BuiltinType>()) { 5035218893Sdim if (BT->getKind() == BuiltinType::ULong && getIntWidth(PointeeTy) == 32) 5036193326Sed PointeeTy = UnsignedIntTy; 5037198092Srdivacky else 5038218893Sdim if (BT->getKind() == BuiltinType::Long && getIntWidth(PointeeTy) == 32) 5039193326Sed PointeeTy = IntTy; 5040193326Sed } 5041193326Sed } 5042193326Sed} 5043193326Sed 5044193326Sedvoid ASTContext::getObjCEncodingForType(QualType T, std::string& S, 5045218893Sdim const FieldDecl *Field) const { 5046193326Sed // We follow the behavior of gcc, expanding structures which are 5047193326Sed // directly pointed to, and expanding embedded structures. Note that 5048193326Sed // these rules are sufficient to prevent recursive encoding of the 5049193326Sed // same type. 5050198092Srdivacky getObjCEncodingForTypeImpl(T, S, true, true, Field, 5051193326Sed true /* outermost type */); 5052193326Sed} 5053193326Sed 5054249423Sdimstatic char getObjCEncodingForPrimitiveKind(const ASTContext *C, 5055249423Sdim BuiltinType::Kind kind) { 5056249423Sdim switch (kind) { 5057210299Sed case BuiltinType::Void: return 'v'; 5058210299Sed case BuiltinType::Bool: return 'B'; 5059210299Sed case BuiltinType::Char_U: 5060210299Sed case BuiltinType::UChar: return 'C'; 5061249423Sdim case BuiltinType::Char16: 5062210299Sed case BuiltinType::UShort: return 'S'; 5063249423Sdim case BuiltinType::Char32: 5064210299Sed case BuiltinType::UInt: return 'I'; 5065210299Sed case BuiltinType::ULong: 5066249423Sdim return C->getTargetInfo().getLongWidth() == 32 ? 'L' : 'Q'; 5067210299Sed case BuiltinType::UInt128: return 'T'; 5068210299Sed case BuiltinType::ULongLong: return 'Q'; 5069210299Sed case BuiltinType::Char_S: 5070210299Sed case BuiltinType::SChar: return 'c'; 5071210299Sed case BuiltinType::Short: return 's'; 5072218893Sdim case BuiltinType::WChar_S: 5073218893Sdim case BuiltinType::WChar_U: 5074210299Sed case BuiltinType::Int: return 'i'; 5075210299Sed case BuiltinType::Long: 5076249423Sdim return C->getTargetInfo().getLongWidth() == 32 ? 'l' : 'q'; 5077210299Sed case BuiltinType::LongLong: return 'q'; 5078210299Sed case BuiltinType::Int128: return 't'; 5079210299Sed case BuiltinType::Float: return 'f'; 5080210299Sed case BuiltinType::Double: return 'd'; 5081218893Sdim case BuiltinType::LongDouble: return 'D'; 5082249423Sdim case BuiltinType::NullPtr: return '*'; // like char* 5083249423Sdim 5084249423Sdim case BuiltinType::Half: 5085249423Sdim // FIXME: potentially need @encodes for these! 5086249423Sdim return ' '; 5087249423Sdim 5088249423Sdim case BuiltinType::ObjCId: 5089249423Sdim case BuiltinType::ObjCClass: 5090249423Sdim case BuiltinType::ObjCSel: 5091249423Sdim llvm_unreachable("@encoding ObjC primitive type"); 5092249423Sdim 5093249423Sdim // OpenCL and placeholder types don't need @encodings. 5094249423Sdim case BuiltinType::OCLImage1d: 5095249423Sdim case BuiltinType::OCLImage1dArray: 5096249423Sdim case BuiltinType::OCLImage1dBuffer: 5097249423Sdim case BuiltinType::OCLImage2d: 5098249423Sdim case BuiltinType::OCLImage2dArray: 5099249423Sdim case BuiltinType::OCLImage3d: 5100249423Sdim case BuiltinType::OCLEvent: 5101249423Sdim case BuiltinType::OCLSampler: 5102249423Sdim case BuiltinType::Dependent: 5103249423Sdim#define BUILTIN_TYPE(KIND, ID) 5104249423Sdim#define PLACEHOLDER_TYPE(KIND, ID) \ 5105249423Sdim case BuiltinType::KIND: 5106249423Sdim#include "clang/AST/BuiltinTypes.def" 5107249423Sdim llvm_unreachable("invalid builtin type for @encode"); 5108210299Sed } 5109249423Sdim llvm_unreachable("invalid BuiltinType::Kind value"); 5110210299Sed} 5111210299Sed 5112226633Sdimstatic char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) { 5113226633Sdim EnumDecl *Enum = ET->getDecl(); 5114226633Sdim 5115226633Sdim // The encoding of an non-fixed enum type is always 'i', regardless of size. 5116226633Sdim if (!Enum->isFixed()) 5117226633Sdim return 'i'; 5118226633Sdim 5119226633Sdim // The encoding of a fixed enum type matches its fixed underlying type. 5120249423Sdim const BuiltinType *BT = Enum->getIntegerType()->castAs<BuiltinType>(); 5121249423Sdim return getObjCEncodingForPrimitiveKind(C, BT->getKind()); 5122226633Sdim} 5123226633Sdim 5124218893Sdimstatic void EncodeBitField(const ASTContext *Ctx, std::string& S, 5125210299Sed QualType T, const FieldDecl *FD) { 5126226633Sdim assert(FD->isBitField() && "not a bitfield - getObjCEncodingForTypeImpl"); 5127210299Sed S += 'b'; 5128210299Sed // The NeXT runtime encodes bit fields as b followed by the number of bits. 5129210299Sed // The GNU runtime requires more information; bitfields are encoded as b, 5130210299Sed // then the offset (in bits) of the first element, then the type of the 5131210299Sed // bitfield, then the size in bits. For example, in this structure: 5132210299Sed // 5133210299Sed // struct 5134210299Sed // { 5135210299Sed // int integer; 5136210299Sed // int flags:2; 5137210299Sed // }; 5138210299Sed // On a 32-bit system, the encoding for flags would be b2 for the NeXT 5139210299Sed // runtime, but b32i2 for the GNU runtime. The reason for this extra 5140210299Sed // information is not especially sensible, but we're stuck with it for 5141210299Sed // compatibility with GCC, although providing it breaks anything that 5142210299Sed // actually uses runtime introspection and wants to work on both runtimes... 5143239462Sdim if (Ctx->getLangOpts().ObjCRuntime.isGNUFamily()) { 5144210299Sed const RecordDecl *RD = FD->getParent(); 5145210299Sed const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD); 5146224145Sdim S += llvm::utostr(RL.getFieldOffset(FD->getFieldIndex())); 5147226633Sdim if (const EnumType *ET = T->getAs<EnumType>()) 5148226633Sdim S += ObjCEncodingForEnumType(Ctx, ET); 5149249423Sdim else { 5150249423Sdim const BuiltinType *BT = T->castAs<BuiltinType>(); 5151249423Sdim S += getObjCEncodingForPrimitiveKind(Ctx, BT->getKind()); 5152249423Sdim } 5153210299Sed } 5154226633Sdim S += llvm::utostr(FD->getBitWidthValue(*Ctx)); 5155193326Sed} 5156193326Sed 5157198398Srdivacky// FIXME: Use SmallString for accumulating string. 5158193326Sedvoid ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, 5159193326Sed bool ExpandPointedToStructures, 5160193326Sed bool ExpandStructures, 5161193326Sed const FieldDecl *FD, 5162193326Sed bool OutermostType, 5163223017Sdim bool EncodingProperty, 5164234353Sdim bool StructField, 5165234353Sdim bool EncodeBlockParameters, 5166249423Sdim bool EncodeClassNames, 5167249423Sdim bool EncodePointerToObjCTypedef) const { 5168249423Sdim CanQualType CT = getCanonicalType(T); 5169249423Sdim switch (CT->getTypeClass()) { 5170249423Sdim case Type::Builtin: 5171249423Sdim case Type::Enum: 5172198092Srdivacky if (FD && FD->isBitField()) 5173210299Sed return EncodeBitField(this, S, T, FD); 5174249423Sdim if (const BuiltinType *BT = dyn_cast<BuiltinType>(CT)) 5175249423Sdim S += getObjCEncodingForPrimitiveKind(this, BT->getKind()); 5176249423Sdim else 5177249423Sdim S += ObjCEncodingForEnumType(this, cast<EnumType>(CT)); 5178198092Srdivacky return; 5179198092Srdivacky 5180249423Sdim case Type::Complex: { 5181249423Sdim const ComplexType *CT = T->castAs<ComplexType>(); 5182193326Sed S += 'j'; 5183198092Srdivacky getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false, 5184193326Sed false); 5185193326Sed return; 5186193326Sed } 5187249423Sdim 5188249423Sdim case Type::Atomic: { 5189249423Sdim const AtomicType *AT = T->castAs<AtomicType>(); 5190249423Sdim S += 'A'; 5191249423Sdim getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, 0, 5192249423Sdim false, false); 5193249423Sdim return; 5194249423Sdim } 5195249423Sdim 5196249423Sdim // encoding for pointer or reference types. 5197249423Sdim case Type::Pointer: 5198249423Sdim case Type::LValueReference: 5199249423Sdim case Type::RValueReference: { 5200249423Sdim QualType PointeeTy; 5201249423Sdim if (isa<PointerType>(CT)) { 5202249423Sdim const PointerType *PT = T->castAs<PointerType>(); 5203249423Sdim if (PT->isObjCSelType()) { 5204249423Sdim S += ':'; 5205249423Sdim return; 5206249423Sdim } 5207249423Sdim PointeeTy = PT->getPointeeType(); 5208249423Sdim } else { 5209249423Sdim PointeeTy = T->castAs<ReferenceType>()->getPointeeType(); 5210199990Srdivacky } 5211249423Sdim 5212193326Sed bool isReadOnly = false; 5213193326Sed // For historical/compatibility reasons, the read-only qualifier of the 5214193326Sed // pointee gets emitted _before_ the '^'. The read-only qualifier of 5215193326Sed // the pointer itself gets ignored, _unless_ we are looking at a typedef! 5216198092Srdivacky // Also, do not emit the 'r' for anything but the outermost type! 5217198092Srdivacky if (isa<TypedefType>(T.getTypePtr())) { 5218193326Sed if (OutermostType && T.isConstQualified()) { 5219193326Sed isReadOnly = true; 5220193326Sed S += 'r'; 5221193326Sed } 5222198092Srdivacky } else if (OutermostType) { 5223193326Sed QualType P = PointeeTy; 5224198092Srdivacky while (P->getAs<PointerType>()) 5225198092Srdivacky P = P->getAs<PointerType>()->getPointeeType(); 5226193326Sed if (P.isConstQualified()) { 5227193326Sed isReadOnly = true; 5228193326Sed S += 'r'; 5229193326Sed } 5230193326Sed } 5231193326Sed if (isReadOnly) { 5232193326Sed // Another legacy compatibility encoding. Some ObjC qualifier and type 5233193326Sed // combinations need to be rearranged. 5234193326Sed // Rewrite "in const" from "nr" to "rn" 5235226633Sdim if (StringRef(S).endswith("nr")) 5236207619Srdivacky S.replace(S.end()-2, S.end(), "rn"); 5237193326Sed } 5238198092Srdivacky 5239193326Sed if (PointeeTy->isCharType()) { 5240193326Sed // char pointer types should be encoded as '*' unless it is a 5241193326Sed // type that has been typedef'd to 'BOOL'. 5242193326Sed if (!isTypeTypedefedAsBOOL(PointeeTy)) { 5243193326Sed S += '*'; 5244193326Sed return; 5245193326Sed } 5246198092Srdivacky } else if (const RecordType *RTy = PointeeTy->getAs<RecordType>()) { 5247198092Srdivacky // GCC binary compat: Need to convert "struct objc_class *" to "#". 5248198092Srdivacky if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) { 5249198092Srdivacky S += '#'; 5250198092Srdivacky return; 5251198092Srdivacky } 5252198092Srdivacky // GCC binary compat: Need to convert "struct objc_object *" to "@". 5253198092Srdivacky if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_object")) { 5254198092Srdivacky S += '@'; 5255198092Srdivacky return; 5256198092Srdivacky } 5257198092Srdivacky // fall through... 5258193326Sed } 5259193326Sed S += '^'; 5260193326Sed getLegacyIntegralTypeEncoding(PointeeTy); 5261193326Sed 5262198092Srdivacky getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures, 5263193326Sed NULL); 5264198092Srdivacky return; 5265198092Srdivacky } 5266249423Sdim 5267249423Sdim case Type::ConstantArray: 5268249423Sdim case Type::IncompleteArray: 5269249423Sdim case Type::VariableArray: { 5270249423Sdim const ArrayType *AT = cast<ArrayType>(CT); 5271249423Sdim 5272223017Sdim if (isa<IncompleteArrayType>(AT) && !StructField) { 5273193326Sed // Incomplete arrays are encoded as a pointer to the array element. 5274193326Sed S += '^'; 5275193326Sed 5276198092Srdivacky getObjCEncodingForTypeImpl(AT->getElementType(), S, 5277193326Sed false, ExpandStructures, FD); 5278193326Sed } else { 5279193326Sed S += '['; 5280198092Srdivacky 5281263508Sdim if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) 5282263508Sdim S += llvm::utostr(CAT->getSize().getZExtValue()); 5283263508Sdim else { 5284193326Sed //Variable length arrays are encoded as a regular array with 0 elements. 5285223017Sdim assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) && 5286223017Sdim "Unknown array type!"); 5287193326Sed S += '0'; 5288193326Sed } 5289198092Srdivacky 5290198092Srdivacky getObjCEncodingForTypeImpl(AT->getElementType(), S, 5291193326Sed false, ExpandStructures, FD); 5292193326Sed S += ']'; 5293193326Sed } 5294198092Srdivacky return; 5295198092Srdivacky } 5296198092Srdivacky 5297249423Sdim case Type::FunctionNoProto: 5298249423Sdim case Type::FunctionProto: 5299193326Sed S += '?'; 5300198092Srdivacky return; 5301198092Srdivacky 5302249423Sdim case Type::Record: { 5303249423Sdim RecordDecl *RDecl = cast<RecordType>(CT)->getDecl(); 5304193326Sed S += RDecl->isUnion() ? '(' : '{'; 5305193326Sed // Anonymous structures print as '?' 5306193326Sed if (const IdentifierInfo *II = RDecl->getIdentifier()) { 5307193326Sed S += II->getName(); 5308208600Srdivacky if (ClassTemplateSpecializationDecl *Spec 5309208600Srdivacky = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) { 5310208600Srdivacky const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 5311249423Sdim llvm::raw_string_ostream OS(S); 5312249423Sdim TemplateSpecializationType::PrintTemplateArgumentList(OS, 5313218893Sdim TemplateArgs.data(), 5314218893Sdim TemplateArgs.size(), 5315226633Sdim (*this).getPrintingPolicy()); 5316208600Srdivacky } 5317193326Sed } else { 5318193326Sed S += '?'; 5319193326Sed } 5320193326Sed if (ExpandStructures) { 5321193326Sed S += '='; 5322223017Sdim if (!RDecl->isUnion()) { 5323223017Sdim getObjCEncodingForStructureImpl(RDecl, S, FD); 5324223017Sdim } else { 5325223017Sdim for (RecordDecl::field_iterator Field = RDecl->field_begin(), 5326223017Sdim FieldEnd = RDecl->field_end(); 5327223017Sdim Field != FieldEnd; ++Field) { 5328223017Sdim if (FD) { 5329223017Sdim S += '"'; 5330223017Sdim S += Field->getNameAsString(); 5331223017Sdim S += '"'; 5332223017Sdim } 5333198092Srdivacky 5334223017Sdim // Special case bit-fields. 5335223017Sdim if (Field->isBitField()) { 5336223017Sdim getObjCEncodingForTypeImpl(Field->getType(), S, false, true, 5337239462Sdim *Field); 5338223017Sdim } else { 5339223017Sdim QualType qt = Field->getType(); 5340223017Sdim getLegacyIntegralTypeEncoding(qt); 5341223017Sdim getObjCEncodingForTypeImpl(qt, S, false, true, 5342223017Sdim FD, /*OutermostType*/false, 5343223017Sdim /*EncodingProperty*/false, 5344223017Sdim /*StructField*/true); 5345223017Sdim } 5346193326Sed } 5347193326Sed } 5348193326Sed } 5349193326Sed S += RDecl->isUnion() ? ')' : '}'; 5350198092Srdivacky return; 5351198092Srdivacky } 5352198092Srdivacky 5353249423Sdim case Type::BlockPointer: { 5354249423Sdim const BlockPointerType *BT = T->castAs<BlockPointerType>(); 5355193326Sed S += "@?"; // Unlike a pointer-to-function, which is "^?". 5356234353Sdim if (EncodeBlockParameters) { 5357249423Sdim const FunctionType *FT = BT->getPointeeType()->castAs<FunctionType>(); 5358234353Sdim 5359234353Sdim S += '<'; 5360234353Sdim // Block return type 5361234353Sdim getObjCEncodingForTypeImpl(FT->getResultType(), S, 5362234353Sdim ExpandPointedToStructures, ExpandStructures, 5363234353Sdim FD, 5364234353Sdim false /* OutermostType */, 5365234353Sdim EncodingProperty, 5366234353Sdim false /* StructField */, 5367234353Sdim EncodeBlockParameters, 5368234353Sdim EncodeClassNames); 5369234353Sdim // Block self 5370234353Sdim S += "@?"; 5371234353Sdim // Block parameters 5372234353Sdim if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { 5373234353Sdim for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), 5374234353Sdim E = FPT->arg_type_end(); I && (I != E); ++I) { 5375234353Sdim getObjCEncodingForTypeImpl(*I, S, 5376234353Sdim ExpandPointedToStructures, 5377234353Sdim ExpandStructures, 5378234353Sdim FD, 5379234353Sdim false /* OutermostType */, 5380234353Sdim EncodingProperty, 5381234353Sdim false /* StructField */, 5382234353Sdim EncodeBlockParameters, 5383234353Sdim EncodeClassNames); 5384234353Sdim } 5385234353Sdim } 5386234353Sdim S += '>'; 5387234353Sdim } 5388198092Srdivacky return; 5389198092Srdivacky } 5390198092Srdivacky 5391249423Sdim case Type::ObjCObject: 5392249423Sdim case Type::ObjCInterface: { 5393249423Sdim // Ignore protocol qualifiers when mangling at this level. 5394249423Sdim T = T->castAs<ObjCObjectType>()->getBaseType(); 5395208600Srdivacky 5396249423Sdim // The assumption seems to be that this assert will succeed 5397249423Sdim // because nested levels will have filtered out 'id' and 'Class'. 5398249423Sdim const ObjCInterfaceType *OIT = T->castAs<ObjCInterfaceType>(); 5399193326Sed // @encode(class_name) 5400198092Srdivacky ObjCInterfaceDecl *OI = OIT->getDecl(); 5401193326Sed S += '{'; 5402193326Sed const IdentifierInfo *II = OI->getIdentifier(); 5403193326Sed S += II->getName(); 5404193326Sed S += '='; 5405226633Sdim SmallVector<const ObjCIvarDecl*, 32> Ivars; 5406212904Sdim DeepCollectObjCIvars(OI, true, Ivars); 5407212904Sdim for (unsigned i = 0, e = Ivars.size(); i != e; ++i) { 5408226633Sdim const FieldDecl *Field = cast<FieldDecl>(Ivars[i]); 5409212904Sdim if (Field->isBitField()) 5410212904Sdim getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field); 5411193326Sed else 5412249423Sdim getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD, 5413249423Sdim false, false, false, false, false, 5414249423Sdim EncodePointerToObjCTypedef); 5415193326Sed } 5416193326Sed S += '}'; 5417198092Srdivacky return; 5418193326Sed } 5419198092Srdivacky 5420249423Sdim case Type::ObjCObjectPointer: { 5421249423Sdim const ObjCObjectPointerType *OPT = T->castAs<ObjCObjectPointerType>(); 5422198092Srdivacky if (OPT->isObjCIdType()) { 5423198092Srdivacky S += '@'; 5424198092Srdivacky return; 5425198092Srdivacky } 5426198092Srdivacky 5427198893Srdivacky if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) { 5428198893Srdivacky // FIXME: Consider if we need to output qualifiers for 'Class<p>'. 5429198893Srdivacky // Since this is a binary compatibility issue, need to consult with runtime 5430198893Srdivacky // folks. Fortunately, this is a *very* obsure construct. 5431198092Srdivacky S += '#'; 5432198092Srdivacky return; 5433198092Srdivacky } 5434198092Srdivacky 5435198092Srdivacky if (OPT->isObjCQualifiedIdType()) { 5436198092Srdivacky getObjCEncodingForTypeImpl(getObjCIdType(), S, 5437198092Srdivacky ExpandPointedToStructures, 5438198092Srdivacky ExpandStructures, FD); 5439234353Sdim if (FD || EncodingProperty || EncodeClassNames) { 5440198092Srdivacky // Note that we do extended encoding of protocol qualifer list 5441198092Srdivacky // Only when doing ivar or property encoding. 5442198092Srdivacky S += '"'; 5443198092Srdivacky for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), 5444198092Srdivacky E = OPT->qual_end(); I != E; ++I) { 5445198092Srdivacky S += '<'; 5446198092Srdivacky S += (*I)->getNameAsString(); 5447198092Srdivacky S += '>'; 5448198092Srdivacky } 5449198092Srdivacky S += '"'; 5450198092Srdivacky } 5451198092Srdivacky return; 5452198092Srdivacky } 5453198092Srdivacky 5454198092Srdivacky QualType PointeeTy = OPT->getPointeeType(); 5455198092Srdivacky if (!EncodingProperty && 5456249423Sdim isa<TypedefType>(PointeeTy.getTypePtr()) && 5457249423Sdim !EncodePointerToObjCTypedef) { 5458198092Srdivacky // Another historical/compatibility reason. 5459198092Srdivacky // We encode the underlying type which comes out as 5460198092Srdivacky // {...}; 5461198092Srdivacky S += '^'; 5462263508Sdim if (FD && OPT->getInterfaceDecl()) { 5463263508Sdim // Prevent recursive encoding of fields in some rare cases. 5464263508Sdim ObjCInterfaceDecl *OI = OPT->getInterfaceDecl(); 5465263508Sdim SmallVector<const ObjCIvarDecl*, 32> Ivars; 5466263508Sdim DeepCollectObjCIvars(OI, true, Ivars); 5467263508Sdim for (unsigned i = 0, e = Ivars.size(); i != e; ++i) { 5468263508Sdim if (cast<FieldDecl>(Ivars[i]) == FD) { 5469263508Sdim S += '{'; 5470263508Sdim S += OI->getIdentifier()->getName(); 5471263508Sdim S += '}'; 5472263508Sdim return; 5473263508Sdim } 5474263508Sdim } 5475263508Sdim } 5476198092Srdivacky getObjCEncodingForTypeImpl(PointeeTy, S, 5477198092Srdivacky false, ExpandPointedToStructures, 5478249423Sdim NULL, 5479249423Sdim false, false, false, false, false, 5480249423Sdim /*EncodePointerToObjCTypedef*/true); 5481198092Srdivacky return; 5482198092Srdivacky } 5483198092Srdivacky 5484198092Srdivacky S += '@'; 5485234353Sdim if (OPT->getInterfaceDecl() && 5486234353Sdim (FD || EncodingProperty || EncodeClassNames)) { 5487198092Srdivacky S += '"'; 5488198893Srdivacky S += OPT->getInterfaceDecl()->getIdentifier()->getName(); 5489198092Srdivacky for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), 5490198092Srdivacky E = OPT->qual_end(); I != E; ++I) { 5491198092Srdivacky S += '<'; 5492198092Srdivacky S += (*I)->getNameAsString(); 5493198092Srdivacky S += '>'; 5494198092Srdivacky } 5495198092Srdivacky S += '"'; 5496198092Srdivacky } 5497198092Srdivacky return; 5498198092Srdivacky } 5499198092Srdivacky 5500208600Srdivacky // gcc just blithely ignores member pointers. 5501249423Sdim // FIXME: we shoul do better than that. 'M' is available. 5502249423Sdim case Type::MemberPointer: 5503208600Srdivacky return; 5504218893Sdim 5505249423Sdim case Type::Vector: 5506249423Sdim case Type::ExtVector: 5507218893Sdim // This matches gcc's encoding, even though technically it is 5508218893Sdim // insufficient. 5509218893Sdim // FIXME. We should do a better job than gcc. 5510218893Sdim return; 5511249423Sdim 5512251662Sdim case Type::Auto: 5513251662Sdim // We could see an undeduced auto type here during error recovery. 5514251662Sdim // Just ignore it. 5515251662Sdim return; 5516251662Sdim 5517249423Sdim#define ABSTRACT_TYPE(KIND, BASE) 5518249423Sdim#define TYPE(KIND, BASE) 5519249423Sdim#define DEPENDENT_TYPE(KIND, BASE) \ 5520249423Sdim case Type::KIND: 5521249423Sdim#define NON_CANONICAL_TYPE(KIND, BASE) \ 5522249423Sdim case Type::KIND: 5523249423Sdim#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(KIND, BASE) \ 5524249423Sdim case Type::KIND: 5525249423Sdim#include "clang/AST/TypeNodes.def" 5526249423Sdim llvm_unreachable("@encode for dependent type!"); 5527218893Sdim } 5528249423Sdim llvm_unreachable("bad type kind!"); 5529193326Sed} 5530193326Sed 5531223017Sdimvoid ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, 5532223017Sdim std::string &S, 5533223017Sdim const FieldDecl *FD, 5534223017Sdim bool includeVBases) const { 5535223017Sdim assert(RDecl && "Expected non-null RecordDecl"); 5536223017Sdim assert(!RDecl->isUnion() && "Should not be called for unions"); 5537223017Sdim if (!RDecl->getDefinition()) 5538223017Sdim return; 5539223017Sdim 5540223017Sdim CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl); 5541223017Sdim std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets; 5542223017Sdim const ASTRecordLayout &layout = getASTRecordLayout(RDecl); 5543223017Sdim 5544223017Sdim if (CXXRec) { 5545223017Sdim for (CXXRecordDecl::base_class_iterator 5546223017Sdim BI = CXXRec->bases_begin(), 5547223017Sdim BE = CXXRec->bases_end(); BI != BE; ++BI) { 5548223017Sdim if (!BI->isVirtual()) { 5549223017Sdim CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl(); 5550224145Sdim if (base->isEmpty()) 5551224145Sdim continue; 5552239462Sdim uint64_t offs = toBits(layout.getBaseClassOffset(base)); 5553223017Sdim FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), 5554223017Sdim std::make_pair(offs, base)); 5555223017Sdim } 5556223017Sdim } 5557223017Sdim } 5558223017Sdim 5559223017Sdim unsigned i = 0; 5560223017Sdim for (RecordDecl::field_iterator Field = RDecl->field_begin(), 5561223017Sdim FieldEnd = RDecl->field_end(); 5562223017Sdim Field != FieldEnd; ++Field, ++i) { 5563223017Sdim uint64_t offs = layout.getFieldOffset(i); 5564223017Sdim FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), 5565223017Sdim std::make_pair(offs, *Field)); 5566223017Sdim } 5567223017Sdim 5568223017Sdim if (CXXRec && includeVBases) { 5569223017Sdim for (CXXRecordDecl::base_class_iterator 5570223017Sdim BI = CXXRec->vbases_begin(), 5571223017Sdim BE = CXXRec->vbases_end(); BI != BE; ++BI) { 5572223017Sdim CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl(); 5573224145Sdim if (base->isEmpty()) 5574224145Sdim continue; 5575239462Sdim uint64_t offs = toBits(layout.getVBaseClassOffset(base)); 5576263508Sdim if (offs >= uint64_t(toBits(layout.getNonVirtualSize())) && 5577263508Sdim FieldOrBaseOffsets.find(offs) == FieldOrBaseOffsets.end()) 5578226633Sdim FieldOrBaseOffsets.insert(FieldOrBaseOffsets.end(), 5579226633Sdim std::make_pair(offs, base)); 5580223017Sdim } 5581223017Sdim } 5582223017Sdim 5583223017Sdim CharUnits size; 5584223017Sdim if (CXXRec) { 5585223017Sdim size = includeVBases ? layout.getSize() : layout.getNonVirtualSize(); 5586223017Sdim } else { 5587223017Sdim size = layout.getSize(); 5588223017Sdim } 5589223017Sdim 5590223017Sdim uint64_t CurOffs = 0; 5591223017Sdim std::multimap<uint64_t, NamedDecl *>::iterator 5592223017Sdim CurLayObj = FieldOrBaseOffsets.begin(); 5593223017Sdim 5594239462Sdim if (CXXRec && CXXRec->isDynamicClass() && 5595239462Sdim (CurLayObj == FieldOrBaseOffsets.end() || CurLayObj->first != 0)) { 5596223017Sdim if (FD) { 5597223017Sdim S += "\"_vptr$"; 5598223017Sdim std::string recname = CXXRec->getNameAsString(); 5599223017Sdim if (recname.empty()) recname = "?"; 5600223017Sdim S += recname; 5601223017Sdim S += '"'; 5602223017Sdim } 5603223017Sdim S += "^^?"; 5604223017Sdim CurOffs += getTypeSize(VoidPtrTy); 5605223017Sdim } 5606223017Sdim 5607223017Sdim if (!RDecl->hasFlexibleArrayMember()) { 5608223017Sdim // Mark the end of the structure. 5609223017Sdim uint64_t offs = toBits(size); 5610223017Sdim FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), 5611223017Sdim std::make_pair(offs, (NamedDecl*)0)); 5612223017Sdim } 5613223017Sdim 5614223017Sdim for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) { 5615223017Sdim assert(CurOffs <= CurLayObj->first); 5616223017Sdim 5617223017Sdim if (CurOffs < CurLayObj->first) { 5618223017Sdim uint64_t padding = CurLayObj->first - CurOffs; 5619223017Sdim // FIXME: There doesn't seem to be a way to indicate in the encoding that 5620223017Sdim // packing/alignment of members is different that normal, in which case 5621223017Sdim // the encoding will be out-of-sync with the real layout. 5622223017Sdim // If the runtime switches to just consider the size of types without 5623223017Sdim // taking into account alignment, we could make padding explicit in the 5624223017Sdim // encoding (e.g. using arrays of chars). The encoding strings would be 5625223017Sdim // longer then though. 5626223017Sdim CurOffs += padding; 5627223017Sdim } 5628223017Sdim 5629223017Sdim NamedDecl *dcl = CurLayObj->second; 5630223017Sdim if (dcl == 0) 5631223017Sdim break; // reached end of structure. 5632223017Sdim 5633223017Sdim if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) { 5634223017Sdim // We expand the bases without their virtual bases since those are going 5635223017Sdim // in the initial structure. Note that this differs from gcc which 5636223017Sdim // expands virtual bases each time one is encountered in the hierarchy, 5637223017Sdim // making the encoding type bigger than it really is. 5638223017Sdim getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false); 5639224145Sdim assert(!base->isEmpty()); 5640224145Sdim CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize()); 5641223017Sdim } else { 5642223017Sdim FieldDecl *field = cast<FieldDecl>(dcl); 5643223017Sdim if (FD) { 5644223017Sdim S += '"'; 5645223017Sdim S += field->getNameAsString(); 5646223017Sdim S += '"'; 5647223017Sdim } 5648223017Sdim 5649223017Sdim if (field->isBitField()) { 5650223017Sdim EncodeBitField(this, S, field->getType(), field); 5651226633Sdim CurOffs += field->getBitWidthValue(*this); 5652223017Sdim } else { 5653223017Sdim QualType qt = field->getType(); 5654223017Sdim getLegacyIntegralTypeEncoding(qt); 5655223017Sdim getObjCEncodingForTypeImpl(qt, S, false, true, FD, 5656223017Sdim /*OutermostType*/false, 5657223017Sdim /*EncodingProperty*/false, 5658223017Sdim /*StructField*/true); 5659223017Sdim CurOffs += getTypeSize(field->getType()); 5660223017Sdim } 5661223017Sdim } 5662223017Sdim } 5663223017Sdim} 5664223017Sdim 5665198092Srdivackyvoid ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, 5666193326Sed std::string& S) const { 5667193326Sed if (QT & Decl::OBJC_TQ_In) 5668193326Sed S += 'n'; 5669193326Sed if (QT & Decl::OBJC_TQ_Inout) 5670193326Sed S += 'N'; 5671193326Sed if (QT & Decl::OBJC_TQ_Out) 5672193326Sed S += 'o'; 5673193326Sed if (QT & Decl::OBJC_TQ_Bycopy) 5674193326Sed S += 'O'; 5675193326Sed if (QT & Decl::OBJC_TQ_Byref) 5676193326Sed S += 'R'; 5677193326Sed if (QT & Decl::OBJC_TQ_Oneway) 5678193326Sed S += 'V'; 5679193326Sed} 5680193326Sed 5681226633SdimTypedefDecl *ASTContext::getObjCIdDecl() const { 5682226633Sdim if (!ObjCIdDecl) { 5683226633Sdim QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0); 5684226633Sdim T = getObjCObjectPointerType(T); 5685226633Sdim TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T); 5686226633Sdim ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 5687226633Sdim getTranslationUnitDecl(), 5688226633Sdim SourceLocation(), SourceLocation(), 5689226633Sdim &Idents.get("id"), IdInfo); 5690226633Sdim } 5691226633Sdim 5692226633Sdim return ObjCIdDecl; 5693193326Sed} 5694193326Sed 5695226633SdimTypedefDecl *ASTContext::getObjCSelDecl() const { 5696226633Sdim if (!ObjCSelDecl) { 5697226633Sdim QualType SelT = getPointerType(ObjCBuiltinSelTy); 5698226633Sdim TypeSourceInfo *SelInfo = getTrivialTypeSourceInfo(SelT); 5699226633Sdim ObjCSelDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 5700226633Sdim getTranslationUnitDecl(), 5701226633Sdim SourceLocation(), SourceLocation(), 5702226633Sdim &Idents.get("SEL"), SelInfo); 5703226633Sdim } 5704226633Sdim return ObjCSelDecl; 5705193326Sed} 5706193326Sed 5707226633SdimTypedefDecl *ASTContext::getObjCClassDecl() const { 5708226633Sdim if (!ObjCClassDecl) { 5709226633Sdim QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0); 5710226633Sdim T = getObjCObjectPointerType(T); 5711226633Sdim TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T); 5712226633Sdim ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 5713226633Sdim getTranslationUnitDecl(), 5714226633Sdim SourceLocation(), SourceLocation(), 5715226633Sdim &Idents.get("Class"), ClassInfo); 5716226633Sdim } 5717226633Sdim 5718226633Sdim return ObjCClassDecl; 5719193326Sed} 5720193326Sed 5721234353SdimObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const { 5722234353Sdim if (!ObjCProtocolClassDecl) { 5723234353Sdim ObjCProtocolClassDecl 5724234353Sdim = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(), 5725234353Sdim SourceLocation(), 5726234353Sdim &Idents.get("Protocol"), 5727234353Sdim /*PrevDecl=*/0, 5728234353Sdim SourceLocation(), true); 5729234353Sdim } 5730234353Sdim 5731234353Sdim return ObjCProtocolClassDecl; 5732234353Sdim} 5733234353Sdim 5734239462Sdim//===----------------------------------------------------------------------===// 5735239462Sdim// __builtin_va_list Construction Functions 5736239462Sdim//===----------------------------------------------------------------------===// 5737239462Sdim 5738239462Sdimstatic TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) { 5739239462Sdim // typedef char* __builtin_va_list; 5740239462Sdim QualType CharPtrType = Context->getPointerType(Context->CharTy); 5741239462Sdim TypeSourceInfo *TInfo 5742239462Sdim = Context->getTrivialTypeSourceInfo(CharPtrType); 5743239462Sdim 5744239462Sdim TypedefDecl *VaListTypeDecl 5745239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5746239462Sdim Context->getTranslationUnitDecl(), 5747239462Sdim SourceLocation(), SourceLocation(), 5748239462Sdim &Context->Idents.get("__builtin_va_list"), 5749239462Sdim TInfo); 5750239462Sdim return VaListTypeDecl; 5751239462Sdim} 5752239462Sdim 5753239462Sdimstatic TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) { 5754239462Sdim // typedef void* __builtin_va_list; 5755239462Sdim QualType VoidPtrType = Context->getPointerType(Context->VoidTy); 5756239462Sdim TypeSourceInfo *TInfo 5757239462Sdim = Context->getTrivialTypeSourceInfo(VoidPtrType); 5758239462Sdim 5759239462Sdim TypedefDecl *VaListTypeDecl 5760239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5761239462Sdim Context->getTranslationUnitDecl(), 5762239462Sdim SourceLocation(), SourceLocation(), 5763239462Sdim &Context->Idents.get("__builtin_va_list"), 5764239462Sdim TInfo); 5765239462Sdim return VaListTypeDecl; 5766239462Sdim} 5767239462Sdim 5768249423Sdimstatic TypedefDecl * 5769249423SdimCreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { 5770249423Sdim RecordDecl *VaListTagDecl; 5771249423Sdim if (Context->getLangOpts().CPlusPlus) { 5772249423Sdim // namespace std { struct __va_list { 5773249423Sdim NamespaceDecl *NS; 5774249423Sdim NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context), 5775249423Sdim Context->getTranslationUnitDecl(), 5776249423Sdim /*Inline*/false, SourceLocation(), 5777249423Sdim SourceLocation(), &Context->Idents.get("std"), 5778249423Sdim /*PrevDecl*/0); 5779249423Sdim 5780249423Sdim VaListTagDecl = CXXRecordDecl::Create(*Context, TTK_Struct, 5781249423Sdim Context->getTranslationUnitDecl(), 5782249423Sdim SourceLocation(), SourceLocation(), 5783249423Sdim &Context->Idents.get("__va_list")); 5784249423Sdim VaListTagDecl->setDeclContext(NS); 5785249423Sdim } else { 5786249423Sdim // struct __va_list 5787249423Sdim VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, 5788249423Sdim Context->getTranslationUnitDecl(), 5789249423Sdim &Context->Idents.get("__va_list")); 5790249423Sdim } 5791249423Sdim 5792249423Sdim VaListTagDecl->startDefinition(); 5793249423Sdim 5794249423Sdim const size_t NumFields = 5; 5795249423Sdim QualType FieldTypes[NumFields]; 5796249423Sdim const char *FieldNames[NumFields]; 5797249423Sdim 5798249423Sdim // void *__stack; 5799249423Sdim FieldTypes[0] = Context->getPointerType(Context->VoidTy); 5800249423Sdim FieldNames[0] = "__stack"; 5801249423Sdim 5802249423Sdim // void *__gr_top; 5803249423Sdim FieldTypes[1] = Context->getPointerType(Context->VoidTy); 5804249423Sdim FieldNames[1] = "__gr_top"; 5805249423Sdim 5806249423Sdim // void *__vr_top; 5807249423Sdim FieldTypes[2] = Context->getPointerType(Context->VoidTy); 5808249423Sdim FieldNames[2] = "__vr_top"; 5809249423Sdim 5810249423Sdim // int __gr_offs; 5811249423Sdim FieldTypes[3] = Context->IntTy; 5812249423Sdim FieldNames[3] = "__gr_offs"; 5813249423Sdim 5814249423Sdim // int __vr_offs; 5815249423Sdim FieldTypes[4] = Context->IntTy; 5816249423Sdim FieldNames[4] = "__vr_offs"; 5817249423Sdim 5818249423Sdim // Create fields 5819249423Sdim for (unsigned i = 0; i < NumFields; ++i) { 5820249423Sdim FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), 5821249423Sdim VaListTagDecl, 5822249423Sdim SourceLocation(), 5823249423Sdim SourceLocation(), 5824249423Sdim &Context->Idents.get(FieldNames[i]), 5825249423Sdim FieldTypes[i], /*TInfo=*/0, 5826249423Sdim /*BitWidth=*/0, 5827249423Sdim /*Mutable=*/false, 5828249423Sdim ICIS_NoInit); 5829249423Sdim Field->setAccess(AS_public); 5830249423Sdim VaListTagDecl->addDecl(Field); 5831249423Sdim } 5832249423Sdim VaListTagDecl->completeDefinition(); 5833249423Sdim QualType VaListTagType = Context->getRecordType(VaListTagDecl); 5834249423Sdim Context->VaListTagTy = VaListTagType; 5835249423Sdim 5836249423Sdim // } __builtin_va_list; 5837249423Sdim TypedefDecl *VaListTypedefDecl 5838249423Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5839249423Sdim Context->getTranslationUnitDecl(), 5840249423Sdim SourceLocation(), SourceLocation(), 5841249423Sdim &Context->Idents.get("__builtin_va_list"), 5842249423Sdim Context->getTrivialTypeSourceInfo(VaListTagType)); 5843249423Sdim 5844249423Sdim return VaListTypedefDecl; 5845249423Sdim} 5846249423Sdim 5847239462Sdimstatic TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { 5848239462Sdim // typedef struct __va_list_tag { 5849239462Sdim RecordDecl *VaListTagDecl; 5850239462Sdim 5851239462Sdim VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, 5852239462Sdim Context->getTranslationUnitDecl(), 5853239462Sdim &Context->Idents.get("__va_list_tag")); 5854239462Sdim VaListTagDecl->startDefinition(); 5855239462Sdim 5856239462Sdim const size_t NumFields = 5; 5857239462Sdim QualType FieldTypes[NumFields]; 5858239462Sdim const char *FieldNames[NumFields]; 5859239462Sdim 5860239462Sdim // unsigned char gpr; 5861239462Sdim FieldTypes[0] = Context->UnsignedCharTy; 5862239462Sdim FieldNames[0] = "gpr"; 5863239462Sdim 5864239462Sdim // unsigned char fpr; 5865239462Sdim FieldTypes[1] = Context->UnsignedCharTy; 5866239462Sdim FieldNames[1] = "fpr"; 5867239462Sdim 5868239462Sdim // unsigned short reserved; 5869239462Sdim FieldTypes[2] = Context->UnsignedShortTy; 5870239462Sdim FieldNames[2] = "reserved"; 5871239462Sdim 5872239462Sdim // void* overflow_arg_area; 5873239462Sdim FieldTypes[3] = Context->getPointerType(Context->VoidTy); 5874239462Sdim FieldNames[3] = "overflow_arg_area"; 5875239462Sdim 5876239462Sdim // void* reg_save_area; 5877239462Sdim FieldTypes[4] = Context->getPointerType(Context->VoidTy); 5878239462Sdim FieldNames[4] = "reg_save_area"; 5879239462Sdim 5880239462Sdim // Create fields 5881239462Sdim for (unsigned i = 0; i < NumFields; ++i) { 5882239462Sdim FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl, 5883239462Sdim SourceLocation(), 5884239462Sdim SourceLocation(), 5885239462Sdim &Context->Idents.get(FieldNames[i]), 5886239462Sdim FieldTypes[i], /*TInfo=*/0, 5887239462Sdim /*BitWidth=*/0, 5888239462Sdim /*Mutable=*/false, 5889239462Sdim ICIS_NoInit); 5890239462Sdim Field->setAccess(AS_public); 5891239462Sdim VaListTagDecl->addDecl(Field); 5892239462Sdim } 5893239462Sdim VaListTagDecl->completeDefinition(); 5894239462Sdim QualType VaListTagType = Context->getRecordType(VaListTagDecl); 5895239462Sdim Context->VaListTagTy = VaListTagType; 5896239462Sdim 5897239462Sdim // } __va_list_tag; 5898239462Sdim TypedefDecl *VaListTagTypedefDecl 5899239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5900239462Sdim Context->getTranslationUnitDecl(), 5901239462Sdim SourceLocation(), SourceLocation(), 5902239462Sdim &Context->Idents.get("__va_list_tag"), 5903239462Sdim Context->getTrivialTypeSourceInfo(VaListTagType)); 5904239462Sdim QualType VaListTagTypedefType = 5905239462Sdim Context->getTypedefType(VaListTagTypedefDecl); 5906239462Sdim 5907239462Sdim // typedef __va_list_tag __builtin_va_list[1]; 5908239462Sdim llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); 5909239462Sdim QualType VaListTagArrayType 5910239462Sdim = Context->getConstantArrayType(VaListTagTypedefType, 5911239462Sdim Size, ArrayType::Normal, 0); 5912239462Sdim TypeSourceInfo *TInfo 5913239462Sdim = Context->getTrivialTypeSourceInfo(VaListTagArrayType); 5914239462Sdim TypedefDecl *VaListTypedefDecl 5915239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5916239462Sdim Context->getTranslationUnitDecl(), 5917239462Sdim SourceLocation(), SourceLocation(), 5918239462Sdim &Context->Idents.get("__builtin_va_list"), 5919239462Sdim TInfo); 5920239462Sdim 5921239462Sdim return VaListTypedefDecl; 5922239462Sdim} 5923239462Sdim 5924239462Sdimstatic TypedefDecl * 5925239462SdimCreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { 5926239462Sdim // typedef struct __va_list_tag { 5927239462Sdim RecordDecl *VaListTagDecl; 5928239462Sdim VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, 5929239462Sdim Context->getTranslationUnitDecl(), 5930239462Sdim &Context->Idents.get("__va_list_tag")); 5931239462Sdim VaListTagDecl->startDefinition(); 5932239462Sdim 5933239462Sdim const size_t NumFields = 4; 5934239462Sdim QualType FieldTypes[NumFields]; 5935239462Sdim const char *FieldNames[NumFields]; 5936239462Sdim 5937239462Sdim // unsigned gp_offset; 5938239462Sdim FieldTypes[0] = Context->UnsignedIntTy; 5939239462Sdim FieldNames[0] = "gp_offset"; 5940239462Sdim 5941239462Sdim // unsigned fp_offset; 5942239462Sdim FieldTypes[1] = Context->UnsignedIntTy; 5943239462Sdim FieldNames[1] = "fp_offset"; 5944239462Sdim 5945239462Sdim // void* overflow_arg_area; 5946239462Sdim FieldTypes[2] = Context->getPointerType(Context->VoidTy); 5947239462Sdim FieldNames[2] = "overflow_arg_area"; 5948239462Sdim 5949239462Sdim // void* reg_save_area; 5950239462Sdim FieldTypes[3] = Context->getPointerType(Context->VoidTy); 5951239462Sdim FieldNames[3] = "reg_save_area"; 5952239462Sdim 5953239462Sdim // Create fields 5954239462Sdim for (unsigned i = 0; i < NumFields; ++i) { 5955239462Sdim FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), 5956239462Sdim VaListTagDecl, 5957239462Sdim SourceLocation(), 5958239462Sdim SourceLocation(), 5959239462Sdim &Context->Idents.get(FieldNames[i]), 5960239462Sdim FieldTypes[i], /*TInfo=*/0, 5961239462Sdim /*BitWidth=*/0, 5962239462Sdim /*Mutable=*/false, 5963239462Sdim ICIS_NoInit); 5964239462Sdim Field->setAccess(AS_public); 5965239462Sdim VaListTagDecl->addDecl(Field); 5966239462Sdim } 5967239462Sdim VaListTagDecl->completeDefinition(); 5968239462Sdim QualType VaListTagType = Context->getRecordType(VaListTagDecl); 5969239462Sdim Context->VaListTagTy = VaListTagType; 5970239462Sdim 5971239462Sdim // } __va_list_tag; 5972239462Sdim TypedefDecl *VaListTagTypedefDecl 5973239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5974239462Sdim Context->getTranslationUnitDecl(), 5975239462Sdim SourceLocation(), SourceLocation(), 5976239462Sdim &Context->Idents.get("__va_list_tag"), 5977239462Sdim Context->getTrivialTypeSourceInfo(VaListTagType)); 5978239462Sdim QualType VaListTagTypedefType = 5979239462Sdim Context->getTypedefType(VaListTagTypedefDecl); 5980239462Sdim 5981239462Sdim // typedef __va_list_tag __builtin_va_list[1]; 5982239462Sdim llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); 5983239462Sdim QualType VaListTagArrayType 5984239462Sdim = Context->getConstantArrayType(VaListTagTypedefType, 5985239462Sdim Size, ArrayType::Normal,0); 5986239462Sdim TypeSourceInfo *TInfo 5987239462Sdim = Context->getTrivialTypeSourceInfo(VaListTagArrayType); 5988239462Sdim TypedefDecl *VaListTypedefDecl 5989239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 5990239462Sdim Context->getTranslationUnitDecl(), 5991239462Sdim SourceLocation(), SourceLocation(), 5992239462Sdim &Context->Idents.get("__builtin_va_list"), 5993239462Sdim TInfo); 5994239462Sdim 5995239462Sdim return VaListTypedefDecl; 5996239462Sdim} 5997239462Sdim 5998239462Sdimstatic TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) { 5999239462Sdim // typedef int __builtin_va_list[4]; 6000239462Sdim llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 4); 6001239462Sdim QualType IntArrayType 6002239462Sdim = Context->getConstantArrayType(Context->IntTy, 6003239462Sdim Size, ArrayType::Normal, 0); 6004239462Sdim TypedefDecl *VaListTypedefDecl 6005239462Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 6006239462Sdim Context->getTranslationUnitDecl(), 6007239462Sdim SourceLocation(), SourceLocation(), 6008239462Sdim &Context->Idents.get("__builtin_va_list"), 6009239462Sdim Context->getTrivialTypeSourceInfo(IntArrayType)); 6010239462Sdim 6011239462Sdim return VaListTypedefDecl; 6012239462Sdim} 6013239462Sdim 6014243830Sdimstatic TypedefDecl * 6015243830SdimCreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { 6016243830Sdim RecordDecl *VaListDecl; 6017243830Sdim if (Context->getLangOpts().CPlusPlus) { 6018243830Sdim // namespace std { struct __va_list { 6019243830Sdim NamespaceDecl *NS; 6020243830Sdim NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context), 6021243830Sdim Context->getTranslationUnitDecl(), 6022243830Sdim /*Inline*/false, SourceLocation(), 6023243830Sdim SourceLocation(), &Context->Idents.get("std"), 6024243830Sdim /*PrevDecl*/0); 6025243830Sdim 6026243830Sdim VaListDecl = CXXRecordDecl::Create(*Context, TTK_Struct, 6027243830Sdim Context->getTranslationUnitDecl(), 6028243830Sdim SourceLocation(), SourceLocation(), 6029243830Sdim &Context->Idents.get("__va_list")); 6030243830Sdim 6031243830Sdim VaListDecl->setDeclContext(NS); 6032243830Sdim 6033243830Sdim } else { 6034243830Sdim // struct __va_list { 6035243830Sdim VaListDecl = CreateRecordDecl(*Context, TTK_Struct, 6036243830Sdim Context->getTranslationUnitDecl(), 6037243830Sdim &Context->Idents.get("__va_list")); 6038243830Sdim } 6039243830Sdim 6040243830Sdim VaListDecl->startDefinition(); 6041243830Sdim 6042243830Sdim // void * __ap; 6043243830Sdim FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), 6044243830Sdim VaListDecl, 6045243830Sdim SourceLocation(), 6046243830Sdim SourceLocation(), 6047243830Sdim &Context->Idents.get("__ap"), 6048243830Sdim Context->getPointerType(Context->VoidTy), 6049243830Sdim /*TInfo=*/0, 6050243830Sdim /*BitWidth=*/0, 6051243830Sdim /*Mutable=*/false, 6052243830Sdim ICIS_NoInit); 6053243830Sdim Field->setAccess(AS_public); 6054243830Sdim VaListDecl->addDecl(Field); 6055243830Sdim 6056243830Sdim // }; 6057243830Sdim VaListDecl->completeDefinition(); 6058243830Sdim 6059243830Sdim // typedef struct __va_list __builtin_va_list; 6060243830Sdim TypeSourceInfo *TInfo 6061243830Sdim = Context->getTrivialTypeSourceInfo(Context->getRecordType(VaListDecl)); 6062243830Sdim 6063243830Sdim TypedefDecl *VaListTypeDecl 6064243830Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 6065243830Sdim Context->getTranslationUnitDecl(), 6066243830Sdim SourceLocation(), SourceLocation(), 6067243830Sdim &Context->Idents.get("__builtin_va_list"), 6068243830Sdim TInfo); 6069243830Sdim 6070243830Sdim return VaListTypeDecl; 6071243830Sdim} 6072243830Sdim 6073251662Sdimstatic TypedefDecl * 6074251662SdimCreateSystemZBuiltinVaListDecl(const ASTContext *Context) { 6075251662Sdim // typedef struct __va_list_tag { 6076251662Sdim RecordDecl *VaListTagDecl; 6077251662Sdim VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, 6078251662Sdim Context->getTranslationUnitDecl(), 6079251662Sdim &Context->Idents.get("__va_list_tag")); 6080251662Sdim VaListTagDecl->startDefinition(); 6081251662Sdim 6082251662Sdim const size_t NumFields = 4; 6083251662Sdim QualType FieldTypes[NumFields]; 6084251662Sdim const char *FieldNames[NumFields]; 6085251662Sdim 6086251662Sdim // long __gpr; 6087251662Sdim FieldTypes[0] = Context->LongTy; 6088251662Sdim FieldNames[0] = "__gpr"; 6089251662Sdim 6090251662Sdim // long __fpr; 6091251662Sdim FieldTypes[1] = Context->LongTy; 6092251662Sdim FieldNames[1] = "__fpr"; 6093251662Sdim 6094251662Sdim // void *__overflow_arg_area; 6095251662Sdim FieldTypes[2] = Context->getPointerType(Context->VoidTy); 6096251662Sdim FieldNames[2] = "__overflow_arg_area"; 6097251662Sdim 6098251662Sdim // void *__reg_save_area; 6099251662Sdim FieldTypes[3] = Context->getPointerType(Context->VoidTy); 6100251662Sdim FieldNames[3] = "__reg_save_area"; 6101251662Sdim 6102251662Sdim // Create fields 6103251662Sdim for (unsigned i = 0; i < NumFields; ++i) { 6104251662Sdim FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context), 6105251662Sdim VaListTagDecl, 6106251662Sdim SourceLocation(), 6107251662Sdim SourceLocation(), 6108251662Sdim &Context->Idents.get(FieldNames[i]), 6109251662Sdim FieldTypes[i], /*TInfo=*/0, 6110251662Sdim /*BitWidth=*/0, 6111251662Sdim /*Mutable=*/false, 6112251662Sdim ICIS_NoInit); 6113251662Sdim Field->setAccess(AS_public); 6114251662Sdim VaListTagDecl->addDecl(Field); 6115251662Sdim } 6116251662Sdim VaListTagDecl->completeDefinition(); 6117251662Sdim QualType VaListTagType = Context->getRecordType(VaListTagDecl); 6118251662Sdim Context->VaListTagTy = VaListTagType; 6119251662Sdim 6120251662Sdim // } __va_list_tag; 6121251662Sdim TypedefDecl *VaListTagTypedefDecl 6122251662Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 6123251662Sdim Context->getTranslationUnitDecl(), 6124251662Sdim SourceLocation(), SourceLocation(), 6125251662Sdim &Context->Idents.get("__va_list_tag"), 6126251662Sdim Context->getTrivialTypeSourceInfo(VaListTagType)); 6127251662Sdim QualType VaListTagTypedefType = 6128251662Sdim Context->getTypedefType(VaListTagTypedefDecl); 6129251662Sdim 6130251662Sdim // typedef __va_list_tag __builtin_va_list[1]; 6131251662Sdim llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); 6132251662Sdim QualType VaListTagArrayType 6133251662Sdim = Context->getConstantArrayType(VaListTagTypedefType, 6134251662Sdim Size, ArrayType::Normal,0); 6135251662Sdim TypeSourceInfo *TInfo 6136251662Sdim = Context->getTrivialTypeSourceInfo(VaListTagArrayType); 6137251662Sdim TypedefDecl *VaListTypedefDecl 6138251662Sdim = TypedefDecl::Create(const_cast<ASTContext &>(*Context), 6139251662Sdim Context->getTranslationUnitDecl(), 6140251662Sdim SourceLocation(), SourceLocation(), 6141251662Sdim &Context->Idents.get("__builtin_va_list"), 6142251662Sdim TInfo); 6143251662Sdim 6144251662Sdim return VaListTypedefDecl; 6145251662Sdim} 6146251662Sdim 6147239462Sdimstatic TypedefDecl *CreateVaListDecl(const ASTContext *Context, 6148239462Sdim TargetInfo::BuiltinVaListKind Kind) { 6149239462Sdim switch (Kind) { 6150239462Sdim case TargetInfo::CharPtrBuiltinVaList: 6151239462Sdim return CreateCharPtrBuiltinVaListDecl(Context); 6152239462Sdim case TargetInfo::VoidPtrBuiltinVaList: 6153239462Sdim return CreateVoidPtrBuiltinVaListDecl(Context); 6154249423Sdim case TargetInfo::AArch64ABIBuiltinVaList: 6155249423Sdim return CreateAArch64ABIBuiltinVaListDecl(Context); 6156239462Sdim case TargetInfo::PowerABIBuiltinVaList: 6157239462Sdim return CreatePowerABIBuiltinVaListDecl(Context); 6158239462Sdim case TargetInfo::X86_64ABIBuiltinVaList: 6159239462Sdim return CreateX86_64ABIBuiltinVaListDecl(Context); 6160239462Sdim case TargetInfo::PNaClABIBuiltinVaList: 6161239462Sdim return CreatePNaClABIBuiltinVaListDecl(Context); 6162243830Sdim case TargetInfo::AAPCSABIBuiltinVaList: 6163243830Sdim return CreateAAPCSABIBuiltinVaListDecl(Context); 6164251662Sdim case TargetInfo::SystemZBuiltinVaList: 6165251662Sdim return CreateSystemZBuiltinVaListDecl(Context); 6166239462Sdim } 6167239462Sdim 6168239462Sdim llvm_unreachable("Unhandled __builtin_va_list type kind"); 6169239462Sdim} 6170239462Sdim 6171239462SdimTypedefDecl *ASTContext::getBuiltinVaListDecl() const { 6172239462Sdim if (!BuiltinVaListDecl) 6173239462Sdim BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind()); 6174239462Sdim 6175239462Sdim return BuiltinVaListDecl; 6176239462Sdim} 6177239462Sdim 6178239462SdimQualType ASTContext::getVaListTagType() const { 6179239462Sdim // Force the creation of VaListTagTy by building the __builtin_va_list 6180239462Sdim // declaration. 6181239462Sdim if (VaListTagTy.isNull()) 6182239462Sdim (void) getBuiltinVaListDecl(); 6183239462Sdim 6184239462Sdim return VaListTagTy; 6185239462Sdim} 6186239462Sdim 6187193326Sedvoid ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { 6188198092Srdivacky assert(ObjCConstantStringType.isNull() && 6189193326Sed "'NSConstantString' type already set!"); 6190198092Srdivacky 6191193326Sed ObjCConstantStringType = getObjCInterfaceType(Decl); 6192193326Sed} 6193193326Sed 6194200583Srdivacky/// \brief Retrieve the template name that corresponds to a non-empty 6195200583Srdivacky/// lookup. 6196218893SdimTemplateName 6197218893SdimASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin, 6198218893Sdim UnresolvedSetIterator End) const { 6199200583Srdivacky unsigned size = End - Begin; 6200200583Srdivacky assert(size > 1 && "set is not overloaded!"); 6201193326Sed 6202200583Srdivacky void *memory = Allocate(sizeof(OverloadedTemplateStorage) + 6203200583Srdivacky size * sizeof(FunctionTemplateDecl*)); 6204200583Srdivacky OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size); 6205200583Srdivacky 6206200583Srdivacky NamedDecl **Storage = OT->getStorage(); 6207202879Srdivacky for (UnresolvedSetIterator I = Begin; I != End; ++I) { 6208200583Srdivacky NamedDecl *D = *I; 6209200583Srdivacky assert(isa<FunctionTemplateDecl>(D) || 6210200583Srdivacky (isa<UsingShadowDecl>(D) && 6211200583Srdivacky isa<FunctionTemplateDecl>(D->getUnderlyingDecl()))); 6212200583Srdivacky *Storage++ = D; 6213193326Sed } 6214193326Sed 6215200583Srdivacky return TemplateName(OT); 6216193326Sed} 6217193326Sed 6218198092Srdivacky/// \brief Retrieve the template name that represents a qualified 6219198092Srdivacky/// template name such as \c std::vector. 6220218893SdimTemplateName 6221218893SdimASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, 6222218893Sdim bool TemplateKeyword, 6223218893Sdim TemplateDecl *Template) const { 6224221345Sdim assert(NNS && "Missing nested-name-specifier in qualified template name"); 6225221345Sdim 6226203955Srdivacky // FIXME: Canonicalization? 6227198092Srdivacky llvm::FoldingSetNodeID ID; 6228198092Srdivacky QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template); 6229198092Srdivacky 6230198092Srdivacky void *InsertPos = 0; 6231198092Srdivacky QualifiedTemplateName *QTN = 6232200583Srdivacky QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); 6233198092Srdivacky if (!QTN) { 6234239462Sdim QTN = new (*this, llvm::alignOf<QualifiedTemplateName>()) 6235239462Sdim QualifiedTemplateName(NNS, TemplateKeyword, Template); 6236198092Srdivacky QualifiedTemplateNames.InsertNode(QTN, InsertPos); 6237198092Srdivacky } 6238198092Srdivacky 6239198092Srdivacky return TemplateName(QTN); 6240198092Srdivacky} 6241198092Srdivacky 6242193326Sed/// \brief Retrieve the template name that represents a dependent 6243193326Sed/// template name such as \c MetaFun::template apply. 6244218893SdimTemplateName 6245218893SdimASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, 6246218893Sdim const IdentifierInfo *Name) const { 6247198092Srdivacky assert((!NNS || NNS->isDependent()) && 6248198092Srdivacky "Nested name specifier must be dependent"); 6249193326Sed 6250193326Sed llvm::FoldingSetNodeID ID; 6251193326Sed DependentTemplateName::Profile(ID, NNS, Name); 6252193326Sed 6253193326Sed void *InsertPos = 0; 6254193326Sed DependentTemplateName *QTN = 6255193326Sed DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); 6256193326Sed 6257193326Sed if (QTN) 6258193326Sed return TemplateName(QTN); 6259193326Sed 6260193326Sed NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); 6261193326Sed if (CanonNNS == NNS) { 6262239462Sdim QTN = new (*this, llvm::alignOf<DependentTemplateName>()) 6263239462Sdim DependentTemplateName(NNS, Name); 6264193326Sed } else { 6265193326Sed TemplateName Canon = getDependentTemplateName(CanonNNS, Name); 6266239462Sdim QTN = new (*this, llvm::alignOf<DependentTemplateName>()) 6267239462Sdim DependentTemplateName(NNS, Name, Canon); 6268203955Srdivacky DependentTemplateName *CheckQTN = 6269203955Srdivacky DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); 6270203955Srdivacky assert(!CheckQTN && "Dependent type name canonicalization broken"); 6271203955Srdivacky (void)CheckQTN; 6272193326Sed } 6273193326Sed 6274193326Sed DependentTemplateNames.InsertNode(QTN, InsertPos); 6275193326Sed return TemplateName(QTN); 6276193326Sed} 6277193326Sed 6278198893Srdivacky/// \brief Retrieve the template name that represents a dependent 6279198893Srdivacky/// template name such as \c MetaFun::template operator+. 6280198893SrdivackyTemplateName 6281198893SrdivackyASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, 6282218893Sdim OverloadedOperatorKind Operator) const { 6283198893Srdivacky assert((!NNS || NNS->isDependent()) && 6284198893Srdivacky "Nested name specifier must be dependent"); 6285198893Srdivacky 6286198893Srdivacky llvm::FoldingSetNodeID ID; 6287198893Srdivacky DependentTemplateName::Profile(ID, NNS, Operator); 6288198893Srdivacky 6289198893Srdivacky void *InsertPos = 0; 6290203955Srdivacky DependentTemplateName *QTN 6291203955Srdivacky = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); 6292198893Srdivacky 6293198893Srdivacky if (QTN) 6294198893Srdivacky return TemplateName(QTN); 6295198893Srdivacky 6296198893Srdivacky NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); 6297198893Srdivacky if (CanonNNS == NNS) { 6298239462Sdim QTN = new (*this, llvm::alignOf<DependentTemplateName>()) 6299239462Sdim DependentTemplateName(NNS, Operator); 6300198893Srdivacky } else { 6301198893Srdivacky TemplateName Canon = getDependentTemplateName(CanonNNS, Operator); 6302239462Sdim QTN = new (*this, llvm::alignOf<DependentTemplateName>()) 6303239462Sdim DependentTemplateName(NNS, Operator, Canon); 6304203955Srdivacky 6305203955Srdivacky DependentTemplateName *CheckQTN 6306203955Srdivacky = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); 6307203955Srdivacky assert(!CheckQTN && "Dependent template name canonicalization broken"); 6308203955Srdivacky (void)CheckQTN; 6309198893Srdivacky } 6310198893Srdivacky 6311198893Srdivacky DependentTemplateNames.InsertNode(QTN, InsertPos); 6312198893Srdivacky return TemplateName(QTN); 6313198893Srdivacky} 6314198893Srdivacky 6315218893SdimTemplateName 6316224145SdimASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, 6317224145Sdim TemplateName replacement) const { 6318224145Sdim llvm::FoldingSetNodeID ID; 6319224145Sdim SubstTemplateTemplateParmStorage::Profile(ID, param, replacement); 6320224145Sdim 6321224145Sdim void *insertPos = 0; 6322224145Sdim SubstTemplateTemplateParmStorage *subst 6323224145Sdim = SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos); 6324224145Sdim 6325224145Sdim if (!subst) { 6326224145Sdim subst = new (*this) SubstTemplateTemplateParmStorage(param, replacement); 6327224145Sdim SubstTemplateTemplateParms.InsertNode(subst, insertPos); 6328224145Sdim } 6329224145Sdim 6330224145Sdim return TemplateName(subst); 6331224145Sdim} 6332224145Sdim 6333224145SdimTemplateName 6334218893SdimASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, 6335218893Sdim const TemplateArgument &ArgPack) const { 6336218893Sdim ASTContext &Self = const_cast<ASTContext &>(*this); 6337218893Sdim llvm::FoldingSetNodeID ID; 6338218893Sdim SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack); 6339218893Sdim 6340218893Sdim void *InsertPos = 0; 6341218893Sdim SubstTemplateTemplateParmPackStorage *Subst 6342218893Sdim = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos); 6343218893Sdim 6344218893Sdim if (!Subst) { 6345224145Sdim Subst = new (*this) SubstTemplateTemplateParmPackStorage(Param, 6346218893Sdim ArgPack.pack_size(), 6347218893Sdim ArgPack.pack_begin()); 6348218893Sdim SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos); 6349218893Sdim } 6350218893Sdim 6351218893Sdim return TemplateName(Subst); 6352218893Sdim} 6353218893Sdim 6354193326Sed/// getFromTargetType - Given one of the integer types provided by 6355193326Sed/// TargetInfo, produce the corresponding type. The unsigned @p Type 6356193326Sed/// is actually a value of type @c TargetInfo::IntType. 6357198893SrdivackyCanQualType ASTContext::getFromTargetType(unsigned Type) const { 6358193326Sed switch (Type) { 6359198893Srdivacky case TargetInfo::NoInt: return CanQualType(); 6360263508Sdim case TargetInfo::SignedChar: return SignedCharTy; 6361263508Sdim case TargetInfo::UnsignedChar: return UnsignedCharTy; 6362193326Sed case TargetInfo::SignedShort: return ShortTy; 6363193326Sed case TargetInfo::UnsignedShort: return UnsignedShortTy; 6364193326Sed case TargetInfo::SignedInt: return IntTy; 6365193326Sed case TargetInfo::UnsignedInt: return UnsignedIntTy; 6366193326Sed case TargetInfo::SignedLong: return LongTy; 6367193326Sed case TargetInfo::UnsignedLong: return UnsignedLongTy; 6368193326Sed case TargetInfo::SignedLongLong: return LongLongTy; 6369193326Sed case TargetInfo::UnsignedLongLong: return UnsignedLongLongTy; 6370193326Sed } 6371193326Sed 6372226633Sdim llvm_unreachable("Unhandled TargetInfo::IntType value"); 6373193326Sed} 6374193326Sed 6375193326Sed//===----------------------------------------------------------------------===// 6376193326Sed// Type Predicates. 6377193326Sed//===----------------------------------------------------------------------===// 6378193326Sed 6379193326Sed/// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's 6380193326Sed/// garbage collection attribute. 6381193326Sed/// 6382218893SdimQualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const { 6383234353Sdim if (getLangOpts().getGC() == LangOptions::NonGC) 6384218893Sdim return Qualifiers::GCNone; 6385218893Sdim 6386234353Sdim assert(getLangOpts().ObjC1); 6387218893Sdim Qualifiers::GC GCAttrs = Ty.getObjCGCAttr(); 6388218893Sdim 6389218893Sdim // Default behaviour under objective-C's gc is for ObjC pointers 6390218893Sdim // (or pointers to them) be treated as though they were declared 6391218893Sdim // as __strong. 6392218893Sdim if (GCAttrs == Qualifiers::GCNone) { 6393218893Sdim if (Ty->isObjCObjectPointerType() || Ty->isBlockPointerType()) 6394218893Sdim return Qualifiers::Strong; 6395218893Sdim else if (Ty->isPointerType()) 6396218893Sdim return getObjCGCAttrKind(Ty->getAs<PointerType>()->getPointeeType()); 6397218893Sdim } else { 6398218893Sdim // It's not valid to set GC attributes on anything that isn't a 6399218893Sdim // pointer. 6400218893Sdim#ifndef NDEBUG 6401218893Sdim QualType CT = Ty->getCanonicalTypeInternal(); 6402218893Sdim while (const ArrayType *AT = dyn_cast<ArrayType>(CT)) 6403218893Sdim CT = AT->getElementType(); 6404218893Sdim assert(CT->isAnyPointerType() || CT->isBlockPointerType()); 6405218893Sdim#endif 6406193326Sed } 6407193326Sed return GCAttrs; 6408193326Sed} 6409193326Sed 6410193326Sed//===----------------------------------------------------------------------===// 6411193326Sed// Type Compatibility Testing 6412193326Sed//===----------------------------------------------------------------------===// 6413193326Sed 6414198092Srdivacky/// areCompatVectorTypes - Return true if the two specified vector types are 6415193326Sed/// compatible. 6416193326Sedstatic bool areCompatVectorTypes(const VectorType *LHS, 6417193326Sed const VectorType *RHS) { 6418198398Srdivacky assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified()); 6419193326Sed return LHS->getElementType() == RHS->getElementType() && 6420193326Sed LHS->getNumElements() == RHS->getNumElements(); 6421193326Sed} 6422193326Sed 6423212904Sdimbool ASTContext::areCompatibleVectorTypes(QualType FirstVec, 6424212904Sdim QualType SecondVec) { 6425212904Sdim assert(FirstVec->isVectorType() && "FirstVec should be a vector type"); 6426212904Sdim assert(SecondVec->isVectorType() && "SecondVec should be a vector type"); 6427212904Sdim 6428212904Sdim if (hasSameUnqualifiedType(FirstVec, SecondVec)) 6429212904Sdim return true; 6430212904Sdim 6431218893Sdim // Treat Neon vector types and most AltiVec vector types as if they are the 6432218893Sdim // equivalent GCC vector types. 6433212904Sdim const VectorType *First = FirstVec->getAs<VectorType>(); 6434212904Sdim const VectorType *Second = SecondVec->getAs<VectorType>(); 6435218893Sdim if (First->getNumElements() == Second->getNumElements() && 6436212904Sdim hasSameType(First->getElementType(), Second->getElementType()) && 6437218893Sdim First->getVectorKind() != VectorType::AltiVecPixel && 6438218893Sdim First->getVectorKind() != VectorType::AltiVecBool && 6439218893Sdim Second->getVectorKind() != VectorType::AltiVecPixel && 6440218893Sdim Second->getVectorKind() != VectorType::AltiVecBool) 6441212904Sdim return true; 6442212904Sdim 6443212904Sdim return false; 6444212904Sdim} 6445212904Sdim 6446198092Srdivacky//===----------------------------------------------------------------------===// 6447198092Srdivacky// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's. 6448198092Srdivacky//===----------------------------------------------------------------------===// 6449198092Srdivacky 6450198092Srdivacky/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the 6451198092Srdivacky/// inheritance hierarchy of 'rProto'. 6452218893Sdimbool 6453218893SdimASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, 6454218893Sdim ObjCProtocolDecl *rProto) const { 6455234353Sdim if (declaresSameEntity(lProto, rProto)) 6456198092Srdivacky return true; 6457198092Srdivacky for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(), 6458198092Srdivacky E = rProto->protocol_end(); PI != E; ++PI) 6459198092Srdivacky if (ProtocolCompatibleWithProtocol(lProto, *PI)) 6460198092Srdivacky return true; 6461198092Srdivacky return false; 6462198092Srdivacky} 6463198092Srdivacky 6464243830Sdim/// ObjCQualifiedClassTypesAreCompatible - compare Class<pr,...> and 6465243830Sdim/// Class<pr1, ...>. 6466212904Sdimbool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs, 6467212904Sdim QualType rhs) { 6468212904Sdim const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>(); 6469212904Sdim const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>(); 6470212904Sdim assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible"); 6471212904Sdim 6472212904Sdim for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), 6473212904Sdim E = lhsQID->qual_end(); I != E; ++I) { 6474212904Sdim bool match = false; 6475212904Sdim ObjCProtocolDecl *lhsProto = *I; 6476212904Sdim for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(), 6477212904Sdim E = rhsOPT->qual_end(); J != E; ++J) { 6478212904Sdim ObjCProtocolDecl *rhsProto = *J; 6479212904Sdim if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) { 6480212904Sdim match = true; 6481212904Sdim break; 6482212904Sdim } 6483212904Sdim } 6484212904Sdim if (!match) 6485212904Sdim return false; 6486212904Sdim } 6487212904Sdim return true; 6488212904Sdim} 6489212904Sdim 6490198092Srdivacky/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an 6491198092Srdivacky/// ObjCQualifiedIDType. 6492198092Srdivackybool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, 6493198092Srdivacky bool compare) { 6494198092Srdivacky // Allow id<P..> and an 'id' or void* type in all cases. 6495198092Srdivacky if (lhs->isVoidPointerType() || 6496198092Srdivacky lhs->isObjCIdType() || lhs->isObjCClassType()) 6497198092Srdivacky return true; 6498198092Srdivacky else if (rhs->isVoidPointerType() || 6499198092Srdivacky rhs->isObjCIdType() || rhs->isObjCClassType()) 6500198092Srdivacky return true; 6501198092Srdivacky 6502198092Srdivacky if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) { 6503198092Srdivacky const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>(); 6504198092Srdivacky 6505198092Srdivacky if (!rhsOPT) return false; 6506198092Srdivacky 6507198092Srdivacky if (rhsOPT->qual_empty()) { 6508198092Srdivacky // If the RHS is a unqualified interface pointer "NSString*", 6509198092Srdivacky // make sure we check the class hierarchy. 6510198092Srdivacky if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) { 6511198092Srdivacky for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), 6512198092Srdivacky E = lhsQID->qual_end(); I != E; ++I) { 6513198092Srdivacky // when comparing an id<P> on lhs with a static type on rhs, 6514198092Srdivacky // see if static class implements all of id's protocols, directly or 6515198092Srdivacky // through its super class and categories. 6516198092Srdivacky if (!rhsID->ClassImplementsProtocol(*I, true)) 6517198092Srdivacky return false; 6518198092Srdivacky } 6519198092Srdivacky } 6520198092Srdivacky // If there are no qualifiers and no interface, we have an 'id'. 6521198092Srdivacky return true; 6522198092Srdivacky } 6523198092Srdivacky // Both the right and left sides have qualifiers. 6524198092Srdivacky for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), 6525198092Srdivacky E = lhsQID->qual_end(); I != E; ++I) { 6526198092Srdivacky ObjCProtocolDecl *lhsProto = *I; 6527198092Srdivacky bool match = false; 6528198092Srdivacky 6529198092Srdivacky // when comparing an id<P> on lhs with a static type on rhs, 6530198092Srdivacky // see if static class implements all of id's protocols, directly or 6531198092Srdivacky // through its super class and categories. 6532198092Srdivacky for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(), 6533198092Srdivacky E = rhsOPT->qual_end(); J != E; ++J) { 6534198092Srdivacky ObjCProtocolDecl *rhsProto = *J; 6535198092Srdivacky if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 6536198092Srdivacky (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { 6537198092Srdivacky match = true; 6538198092Srdivacky break; 6539198092Srdivacky } 6540198092Srdivacky } 6541198092Srdivacky // If the RHS is a qualified interface pointer "NSString<P>*", 6542198092Srdivacky // make sure we check the class hierarchy. 6543198092Srdivacky if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) { 6544198092Srdivacky for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), 6545198092Srdivacky E = lhsQID->qual_end(); I != E; ++I) { 6546198092Srdivacky // when comparing an id<P> on lhs with a static type on rhs, 6547198092Srdivacky // see if static class implements all of id's protocols, directly or 6548198092Srdivacky // through its super class and categories. 6549198092Srdivacky if (rhsID->ClassImplementsProtocol(*I, true)) { 6550198092Srdivacky match = true; 6551198092Srdivacky break; 6552198092Srdivacky } 6553198092Srdivacky } 6554198092Srdivacky } 6555198092Srdivacky if (!match) 6556198092Srdivacky return false; 6557198092Srdivacky } 6558198092Srdivacky 6559198092Srdivacky return true; 6560198092Srdivacky } 6561198092Srdivacky 6562198092Srdivacky const ObjCObjectPointerType *rhsQID = rhs->getAsObjCQualifiedIdType(); 6563198092Srdivacky assert(rhsQID && "One of the LHS/RHS should be id<x>"); 6564198092Srdivacky 6565198092Srdivacky if (const ObjCObjectPointerType *lhsOPT = 6566198092Srdivacky lhs->getAsObjCInterfacePointerType()) { 6567218893Sdim // If both the right and left sides have qualifiers. 6568198092Srdivacky for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(), 6569198092Srdivacky E = lhsOPT->qual_end(); I != E; ++I) { 6570198092Srdivacky ObjCProtocolDecl *lhsProto = *I; 6571198092Srdivacky bool match = false; 6572198092Srdivacky 6573218893Sdim // when comparing an id<P> on rhs with a static type on lhs, 6574198092Srdivacky // see if static class implements all of id's protocols, directly or 6575198092Srdivacky // through its super class and categories. 6576218893Sdim // First, lhs protocols in the qualifier list must be found, direct 6577218893Sdim // or indirect in rhs's qualifier list or it is a mismatch. 6578198092Srdivacky for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), 6579198092Srdivacky E = rhsQID->qual_end(); J != E; ++J) { 6580198092Srdivacky ObjCProtocolDecl *rhsProto = *J; 6581198092Srdivacky if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 6582198092Srdivacky (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { 6583198092Srdivacky match = true; 6584198092Srdivacky break; 6585198092Srdivacky } 6586198092Srdivacky } 6587198092Srdivacky if (!match) 6588198092Srdivacky return false; 6589198092Srdivacky } 6590218893Sdim 6591218893Sdim // Static class's protocols, or its super class or category protocols 6592218893Sdim // must be found, direct or indirect in rhs's qualifier list or it is a mismatch. 6593218893Sdim if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) { 6594218893Sdim llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols; 6595218893Sdim CollectInheritedProtocols(lhsID, LHSInheritedProtocols); 6596218893Sdim // This is rather dubious but matches gcc's behavior. If lhs has 6597218893Sdim // no type qualifier and its class has no static protocol(s) 6598218893Sdim // assume that it is mismatch. 6599218893Sdim if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty()) 6600218893Sdim return false; 6601218893Sdim for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = 6602218893Sdim LHSInheritedProtocols.begin(), 6603218893Sdim E = LHSInheritedProtocols.end(); I != E; ++I) { 6604218893Sdim bool match = false; 6605218893Sdim ObjCProtocolDecl *lhsProto = (*I); 6606218893Sdim for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), 6607218893Sdim E = rhsQID->qual_end(); J != E; ++J) { 6608218893Sdim ObjCProtocolDecl *rhsProto = *J; 6609218893Sdim if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 6610218893Sdim (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { 6611218893Sdim match = true; 6612218893Sdim break; 6613218893Sdim } 6614218893Sdim } 6615218893Sdim if (!match) 6616218893Sdim return false; 6617218893Sdim } 6618218893Sdim } 6619198092Srdivacky return true; 6620198092Srdivacky } 6621198092Srdivacky return false; 6622198092Srdivacky} 6623198092Srdivacky 6624193326Sed/// canAssignObjCInterfaces - Return true if the two interface types are 6625193326Sed/// compatible for assignment from RHS to LHS. This handles validation of any 6626193326Sed/// protocol qualifiers on the LHS or RHS. 6627193326Sed/// 6628198092Srdivackybool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, 6629198092Srdivacky const ObjCObjectPointerType *RHSOPT) { 6630208600Srdivacky const ObjCObjectType* LHS = LHSOPT->getObjectType(); 6631208600Srdivacky const ObjCObjectType* RHS = RHSOPT->getObjectType(); 6632208600Srdivacky 6633198092Srdivacky // If either type represents the built-in 'id' or 'Class' types, return true. 6634208600Srdivacky if (LHS->isObjCUnqualifiedIdOrClass() || 6635208600Srdivacky RHS->isObjCUnqualifiedIdOrClass()) 6636198092Srdivacky return true; 6637198092Srdivacky 6638208600Srdivacky if (LHS->isObjCQualifiedId() || RHS->isObjCQualifiedId()) 6639198092Srdivacky return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0), 6640198092Srdivacky QualType(RHSOPT,0), 6641198092Srdivacky false); 6642212904Sdim 6643212904Sdim if (LHS->isObjCQualifiedClass() && RHS->isObjCQualifiedClass()) 6644212904Sdim return ObjCQualifiedClassTypesAreCompatible(QualType(LHSOPT,0), 6645212904Sdim QualType(RHSOPT,0)); 6646212904Sdim 6647208600Srdivacky // If we have 2 user-defined types, fall into that path. 6648208600Srdivacky if (LHS->getInterface() && RHS->getInterface()) 6649198092Srdivacky return canAssignObjCInterfaces(LHS, RHS); 6650198092Srdivacky 6651198092Srdivacky return false; 6652198092Srdivacky} 6653198092Srdivacky 6654205408Srdivacky/// canAssignObjCInterfacesInBlockPointer - This routine is specifically written 6655221345Sdim/// for providing type-safety for objective-c pointers used to pass/return 6656205408Srdivacky/// arguments in block literals. When passed as arguments, passing 'A*' where 6657205408Srdivacky/// 'id' is expected is not OK. Passing 'Sub *" where 'Super *" is expected is 6658205408Srdivacky/// not OK. For the return type, the opposite is not OK. 6659205408Srdivackybool ASTContext::canAssignObjCInterfacesInBlockPointer( 6660205408Srdivacky const ObjCObjectPointerType *LHSOPT, 6661221345Sdim const ObjCObjectPointerType *RHSOPT, 6662221345Sdim bool BlockReturnType) { 6663207619Srdivacky if (RHSOPT->isObjCBuiltinType() || LHSOPT->isObjCIdType()) 6664205408Srdivacky return true; 6665205408Srdivacky 6666205408Srdivacky if (LHSOPT->isObjCBuiltinType()) { 6667205408Srdivacky return RHSOPT->isObjCBuiltinType() || RHSOPT->isObjCQualifiedIdType(); 6668205408Srdivacky } 6669205408Srdivacky 6670207619Srdivacky if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType()) 6671205408Srdivacky return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0), 6672205408Srdivacky QualType(RHSOPT,0), 6673205408Srdivacky false); 6674205408Srdivacky 6675205408Srdivacky const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType(); 6676205408Srdivacky const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType(); 6677205408Srdivacky if (LHS && RHS) { // We have 2 user-defined types. 6678205408Srdivacky if (LHS != RHS) { 6679205408Srdivacky if (LHS->getDecl()->isSuperClassOf(RHS->getDecl())) 6680221345Sdim return BlockReturnType; 6681205408Srdivacky if (RHS->getDecl()->isSuperClassOf(LHS->getDecl())) 6682221345Sdim return !BlockReturnType; 6683205408Srdivacky } 6684205408Srdivacky else 6685205408Srdivacky return true; 6686205408Srdivacky } 6687205408Srdivacky return false; 6688205408Srdivacky} 6689205408Srdivacky 6690198893Srdivacky/// getIntersectionOfProtocols - This routine finds the intersection of set 6691198893Srdivacky/// of protocols inherited from two distinct objective-c pointer objects. 6692198893Srdivacky/// It is used to build composite qualifier list of the composite type of 6693198893Srdivacky/// the conditional expression involving two objective-c pointer objects. 6694198893Srdivackystatic 6695198893Srdivackyvoid getIntersectionOfProtocols(ASTContext &Context, 6696198893Srdivacky const ObjCObjectPointerType *LHSOPT, 6697198893Srdivacky const ObjCObjectPointerType *RHSOPT, 6698226633Sdim SmallVectorImpl<ObjCProtocolDecl *> &IntersectionOfProtocols) { 6699198893Srdivacky 6700208600Srdivacky const ObjCObjectType* LHS = LHSOPT->getObjectType(); 6701208600Srdivacky const ObjCObjectType* RHS = RHSOPT->getObjectType(); 6702208600Srdivacky assert(LHS->getInterface() && "LHS must have an interface base"); 6703208600Srdivacky assert(RHS->getInterface() && "RHS must have an interface base"); 6704198893Srdivacky 6705198893Srdivacky llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocolSet; 6706198893Srdivacky unsigned LHSNumProtocols = LHS->getNumProtocols(); 6707198893Srdivacky if (LHSNumProtocols > 0) 6708198893Srdivacky InheritedProtocolSet.insert(LHS->qual_begin(), LHS->qual_end()); 6709198893Srdivacky else { 6710203955Srdivacky llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols; 6711208600Srdivacky Context.CollectInheritedProtocols(LHS->getInterface(), 6712208600Srdivacky LHSInheritedProtocols); 6713198893Srdivacky InheritedProtocolSet.insert(LHSInheritedProtocols.begin(), 6714198893Srdivacky LHSInheritedProtocols.end()); 6715198893Srdivacky } 6716198893Srdivacky 6717198893Srdivacky unsigned RHSNumProtocols = RHS->getNumProtocols(); 6718198893Srdivacky if (RHSNumProtocols > 0) { 6719207619Srdivacky ObjCProtocolDecl **RHSProtocols = 6720207619Srdivacky const_cast<ObjCProtocolDecl **>(RHS->qual_begin()); 6721198893Srdivacky for (unsigned i = 0; i < RHSNumProtocols; ++i) 6722198893Srdivacky if (InheritedProtocolSet.count(RHSProtocols[i])) 6723198893Srdivacky IntersectionOfProtocols.push_back(RHSProtocols[i]); 6724226633Sdim } else { 6725203955Srdivacky llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSInheritedProtocols; 6726208600Srdivacky Context.CollectInheritedProtocols(RHS->getInterface(), 6727208600Srdivacky RHSInheritedProtocols); 6728203955Srdivacky for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = 6729203955Srdivacky RHSInheritedProtocols.begin(), 6730203955Srdivacky E = RHSInheritedProtocols.end(); I != E; ++I) 6731203955Srdivacky if (InheritedProtocolSet.count((*I))) 6732203955Srdivacky IntersectionOfProtocols.push_back((*I)); 6733198893Srdivacky } 6734198893Srdivacky} 6735198893Srdivacky 6736198893Srdivacky/// areCommonBaseCompatible - Returns common base class of the two classes if 6737198893Srdivacky/// one found. Note that this is O'2 algorithm. But it will be called as the 6738198893Srdivacky/// last type comparison in a ?-exp of ObjC pointer types before a 6739198893Srdivacky/// warning is issued. So, its invokation is extremely rare. 6740198893SrdivackyQualType ASTContext::areCommonBaseCompatible( 6741208600Srdivacky const ObjCObjectPointerType *Lptr, 6742208600Srdivacky const ObjCObjectPointerType *Rptr) { 6743208600Srdivacky const ObjCObjectType *LHS = Lptr->getObjectType(); 6744208600Srdivacky const ObjCObjectType *RHS = Rptr->getObjectType(); 6745208600Srdivacky const ObjCInterfaceDecl* LDecl = LHS->getInterface(); 6746208600Srdivacky const ObjCInterfaceDecl* RDecl = RHS->getInterface(); 6747234353Sdim if (!LDecl || !RDecl || (declaresSameEntity(LDecl, RDecl))) 6748198893Srdivacky return QualType(); 6749198893Srdivacky 6750221345Sdim do { 6751208600Srdivacky LHS = cast<ObjCInterfaceType>(getObjCInterfaceType(LDecl)); 6752198893Srdivacky if (canAssignObjCInterfaces(LHS, RHS)) { 6753226633Sdim SmallVector<ObjCProtocolDecl *, 8> Protocols; 6754208600Srdivacky getIntersectionOfProtocols(*this, Lptr, Rptr, Protocols); 6755208600Srdivacky 6756208600Srdivacky QualType Result = QualType(LHS, 0); 6757208600Srdivacky if (!Protocols.empty()) 6758208600Srdivacky Result = getObjCObjectType(Result, Protocols.data(), Protocols.size()); 6759208600Srdivacky Result = getObjCObjectPointerType(Result); 6760208600Srdivacky return Result; 6761198893Srdivacky } 6762221345Sdim } while ((LDecl = LDecl->getSuperClass())); 6763198893Srdivacky 6764198893Srdivacky return QualType(); 6765198893Srdivacky} 6766198893Srdivacky 6767208600Srdivackybool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS, 6768208600Srdivacky const ObjCObjectType *RHS) { 6769208600Srdivacky assert(LHS->getInterface() && "LHS is not an interface type"); 6770208600Srdivacky assert(RHS->getInterface() && "RHS is not an interface type"); 6771208600Srdivacky 6772193326Sed // Verify that the base decls are compatible: the RHS must be a subclass of 6773193326Sed // the LHS. 6774208600Srdivacky if (!LHS->getInterface()->isSuperClassOf(RHS->getInterface())) 6775193326Sed return false; 6776198092Srdivacky 6777193326Sed // RHS must have a superset of the protocols in the LHS. If the LHS is not 6778193326Sed // protocol qualified at all, then we are good. 6779198092Srdivacky if (LHS->getNumProtocols() == 0) 6780193326Sed return true; 6781198092Srdivacky 6782221345Sdim // Okay, we know the LHS has protocol qualifiers. If the RHS doesn't, 6783221345Sdim // more detailed analysis is required. 6784221345Sdim if (RHS->getNumProtocols() == 0) { 6785221345Sdim // OK, if LHS is a superclass of RHS *and* 6786221345Sdim // this superclass is assignment compatible with LHS. 6787221345Sdim // false otherwise. 6788221345Sdim bool IsSuperClass = 6789221345Sdim LHS->getInterface()->isSuperClassOf(RHS->getInterface()); 6790221345Sdim if (IsSuperClass) { 6791221345Sdim // OK if conversion of LHS to SuperClass results in narrowing of types 6792221345Sdim // ; i.e., SuperClass may implement at least one of the protocols 6793221345Sdim // in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok. 6794221345Sdim // But not SuperObj<P1,P2,P3> = lhs<P1,P2>. 6795221345Sdim llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols; 6796221345Sdim CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols); 6797221345Sdim // If super class has no protocols, it is not a match. 6798221345Sdim if (SuperClassInheritedProtocols.empty()) 6799221345Sdim return false; 6800221345Sdim 6801221345Sdim for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(), 6802221345Sdim LHSPE = LHS->qual_end(); 6803221345Sdim LHSPI != LHSPE; LHSPI++) { 6804221345Sdim bool SuperImplementsProtocol = false; 6805221345Sdim ObjCProtocolDecl *LHSProto = (*LHSPI); 6806221345Sdim 6807221345Sdim for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = 6808221345Sdim SuperClassInheritedProtocols.begin(), 6809221345Sdim E = SuperClassInheritedProtocols.end(); I != E; ++I) { 6810221345Sdim ObjCProtocolDecl *SuperClassProto = (*I); 6811221345Sdim if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { 6812221345Sdim SuperImplementsProtocol = true; 6813221345Sdim break; 6814221345Sdim } 6815221345Sdim } 6816221345Sdim if (!SuperImplementsProtocol) 6817221345Sdim return false; 6818221345Sdim } 6819221345Sdim return true; 6820221345Sdim } 6821221345Sdim return false; 6822221345Sdim } 6823198092Srdivacky 6824208600Srdivacky for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(), 6825208600Srdivacky LHSPE = LHS->qual_end(); 6826193326Sed LHSPI != LHSPE; LHSPI++) { 6827193326Sed bool RHSImplementsProtocol = false; 6828193326Sed 6829193326Sed // If the RHS doesn't implement the protocol on the left, the types 6830193326Sed // are incompatible. 6831208600Srdivacky for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(), 6832208600Srdivacky RHSPE = RHS->qual_end(); 6833198092Srdivacky RHSPI != RHSPE; RHSPI++) { 6834198092Srdivacky if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) { 6835193326Sed RHSImplementsProtocol = true; 6836198092Srdivacky break; 6837198092Srdivacky } 6838193326Sed } 6839193326Sed // FIXME: For better diagnostics, consider passing back the protocol name. 6840193326Sed if (!RHSImplementsProtocol) 6841193326Sed return false; 6842193326Sed } 6843193326Sed // The RHS implements all protocols listed on the LHS. 6844193326Sed return true; 6845193326Sed} 6846193326Sed 6847193326Sedbool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) { 6848193326Sed // get the "pointed to" types 6849198092Srdivacky const ObjCObjectPointerType *LHSOPT = LHS->getAs<ObjCObjectPointerType>(); 6850198092Srdivacky const ObjCObjectPointerType *RHSOPT = RHS->getAs<ObjCObjectPointerType>(); 6851198092Srdivacky 6852198092Srdivacky if (!LHSOPT || !RHSOPT) 6853193326Sed return false; 6854198092Srdivacky 6855198092Srdivacky return canAssignObjCInterfaces(LHSOPT, RHSOPT) || 6856198092Srdivacky canAssignObjCInterfaces(RHSOPT, LHSOPT); 6857193326Sed} 6858193326Sed 6859212904Sdimbool ASTContext::canBindObjCObjectType(QualType To, QualType From) { 6860212904Sdim return canAssignObjCInterfaces( 6861212904Sdim getObjCObjectPointerType(To)->getAs<ObjCObjectPointerType>(), 6862212904Sdim getObjCObjectPointerType(From)->getAs<ObjCObjectPointerType>()); 6863212904Sdim} 6864212904Sdim 6865198092Srdivacky/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible, 6866193326Sed/// both shall have the identically qualified version of a compatible type. 6867198092Srdivacky/// C99 6.2.7p1: Two types have compatible types if their types are the 6868193326Sed/// same. See 6.7.[2,3,5] for additional rules. 6869212904Sdimbool ASTContext::typesAreCompatible(QualType LHS, QualType RHS, 6870212904Sdim bool CompareUnqualified) { 6871234353Sdim if (getLangOpts().CPlusPlus) 6872203955Srdivacky return hasSameType(LHS, RHS); 6873203955Srdivacky 6874212904Sdim return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull(); 6875193326Sed} 6876193326Sed 6877224145Sdimbool ASTContext::propertyTypesAreCompatible(QualType LHS, QualType RHS) { 6878224145Sdim return typesAreCompatible(LHS, RHS); 6879224145Sdim} 6880224145Sdim 6881205408Srdivackybool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) { 6882205408Srdivacky return !mergeTypes(LHS, RHS, true).isNull(); 6883205408Srdivacky} 6884205408Srdivacky 6885218893Sdim/// mergeTransparentUnionType - if T is a transparent union type and a member 6886218893Sdim/// of T is compatible with SubType, return the merged type, else return 6887218893Sdim/// QualType() 6888218893SdimQualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType, 6889218893Sdim bool OfBlockPointer, 6890218893Sdim bool Unqualified) { 6891218893Sdim if (const RecordType *UT = T->getAsUnionType()) { 6892218893Sdim RecordDecl *UD = UT->getDecl(); 6893218893Sdim if (UD->hasAttr<TransparentUnionAttr>()) { 6894218893Sdim for (RecordDecl::field_iterator it = UD->field_begin(), 6895218893Sdim itend = UD->field_end(); it != itend; ++it) { 6896218893Sdim QualType ET = it->getType().getUnqualifiedType(); 6897218893Sdim QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified); 6898218893Sdim if (!MT.isNull()) 6899218893Sdim return MT; 6900218893Sdim } 6901218893Sdim } 6902218893Sdim } 6903218893Sdim 6904218893Sdim return QualType(); 6905218893Sdim} 6906218893Sdim 6907218893Sdim/// mergeFunctionArgumentTypes - merge two types which appear as function 6908218893Sdim/// argument types 6909218893SdimQualType ASTContext::mergeFunctionArgumentTypes(QualType lhs, QualType rhs, 6910218893Sdim bool OfBlockPointer, 6911218893Sdim bool Unqualified) { 6912218893Sdim // GNU extension: two types are compatible if they appear as a function 6913218893Sdim // argument, one of the types is a transparent union type and the other 6914218893Sdim // type is compatible with a union member 6915218893Sdim QualType lmerge = mergeTransparentUnionType(lhs, rhs, OfBlockPointer, 6916218893Sdim Unqualified); 6917218893Sdim if (!lmerge.isNull()) 6918218893Sdim return lmerge; 6919218893Sdim 6920218893Sdim QualType rmerge = mergeTransparentUnionType(rhs, lhs, OfBlockPointer, 6921218893Sdim Unqualified); 6922218893Sdim if (!rmerge.isNull()) 6923218893Sdim return rmerge; 6924218893Sdim 6925218893Sdim return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified); 6926218893Sdim} 6927218893Sdim 6928205408SrdivackyQualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, 6929212904Sdim bool OfBlockPointer, 6930212904Sdim bool Unqualified) { 6931198092Srdivacky const FunctionType *lbase = lhs->getAs<FunctionType>(); 6932198092Srdivacky const FunctionType *rbase = rhs->getAs<FunctionType>(); 6933193326Sed const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase); 6934193326Sed const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase); 6935193326Sed bool allLTypes = true; 6936193326Sed bool allRTypes = true; 6937193326Sed 6938193326Sed // Check return type 6939205408Srdivacky QualType retType; 6940218893Sdim if (OfBlockPointer) { 6941218893Sdim QualType RHS = rbase->getResultType(); 6942218893Sdim QualType LHS = lbase->getResultType(); 6943218893Sdim bool UnqualifiedResult = Unqualified; 6944218893Sdim if (!UnqualifiedResult) 6945218893Sdim UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers()); 6946221345Sdim retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true); 6947218893Sdim } 6948218893Sdim else 6949218893Sdim retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false, 6950212904Sdim Unqualified); 6951193326Sed if (retType.isNull()) return QualType(); 6952212904Sdim 6953212904Sdim if (Unqualified) 6954212904Sdim retType = retType.getUnqualifiedType(); 6955212904Sdim 6956212904Sdim CanQualType LRetType = getCanonicalType(lbase->getResultType()); 6957212904Sdim CanQualType RRetType = getCanonicalType(rbase->getResultType()); 6958212904Sdim if (Unqualified) { 6959212904Sdim LRetType = LRetType.getUnqualifiedType(); 6960212904Sdim RRetType = RRetType.getUnqualifiedType(); 6961212904Sdim } 6962212904Sdim 6963212904Sdim if (getCanonicalType(retType) != LRetType) 6964193326Sed allLTypes = false; 6965212904Sdim if (getCanonicalType(retType) != RRetType) 6966193326Sed allRTypes = false; 6967218893Sdim 6968198092Srdivacky // FIXME: double check this 6969206084Srdivacky // FIXME: should we error if lbase->getRegParmAttr() != 0 && 6970206084Srdivacky // rbase->getRegParmAttr() != 0 && 6971206084Srdivacky // lbase->getRegParmAttr() != rbase->getRegParmAttr()? 6972206084Srdivacky FunctionType::ExtInfo lbaseInfo = lbase->getExtInfo(); 6973206084Srdivacky FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo(); 6974218893Sdim 6975218893Sdim // Compatible functions must have compatible calling conventions 6976263508Sdim if (lbaseInfo.getCC() != rbaseInfo.getCC()) 6977218893Sdim return QualType(); 6978218893Sdim 6979218893Sdim // Regparm is part of the calling convention. 6980221345Sdim if (lbaseInfo.getHasRegParm() != rbaseInfo.getHasRegParm()) 6981221345Sdim return QualType(); 6982218893Sdim if (lbaseInfo.getRegParm() != rbaseInfo.getRegParm()) 6983218893Sdim return QualType(); 6984218893Sdim 6985224145Sdim if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult()) 6986224145Sdim return QualType(); 6987224145Sdim 6988218893Sdim // FIXME: some uses, e.g. conditional exprs, really want this to be 'both'. 6989206084Srdivacky bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn(); 6990193326Sed 6991249423Sdim if (lbaseInfo.getNoReturn() != NoReturn) 6992249423Sdim allLTypes = false; 6993249423Sdim if (rbaseInfo.getNoReturn() != NoReturn) 6994249423Sdim allRTypes = false; 6995249423Sdim 6996224145Sdim FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn); 6997218893Sdim 6998193326Sed if (lproto && rproto) { // two C99 style function prototypes 6999193326Sed assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && 7000193326Sed "C++ shouldn't be here"); 7001193326Sed unsigned lproto_nargs = lproto->getNumArgs(); 7002193326Sed unsigned rproto_nargs = rproto->getNumArgs(); 7003193326Sed 7004193326Sed // Compatible functions must have the same number of arguments 7005193326Sed if (lproto_nargs != rproto_nargs) 7006193326Sed return QualType(); 7007193326Sed 7008193326Sed // Variadic and non-variadic functions aren't compatible 7009193326Sed if (lproto->isVariadic() != rproto->isVariadic()) 7010193326Sed return QualType(); 7011193326Sed 7012193326Sed if (lproto->getTypeQuals() != rproto->getTypeQuals()) 7013193326Sed return QualType(); 7014193326Sed 7015226633Sdim if (LangOpts.ObjCAutoRefCount && 7016226633Sdim !FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto)) 7017226633Sdim return QualType(); 7018226633Sdim 7019193326Sed // Check argument compatibility 7020226633Sdim SmallVector<QualType, 10> types; 7021193326Sed for (unsigned i = 0; i < lproto_nargs; i++) { 7022193326Sed QualType largtype = lproto->getArgType(i).getUnqualifiedType(); 7023193326Sed QualType rargtype = rproto->getArgType(i).getUnqualifiedType(); 7024218893Sdim QualType argtype = mergeFunctionArgumentTypes(largtype, rargtype, 7025218893Sdim OfBlockPointer, 7026218893Sdim Unqualified); 7027193326Sed if (argtype.isNull()) return QualType(); 7028212904Sdim 7029212904Sdim if (Unqualified) 7030212904Sdim argtype = argtype.getUnqualifiedType(); 7031212904Sdim 7032193326Sed types.push_back(argtype); 7033212904Sdim if (Unqualified) { 7034212904Sdim largtype = largtype.getUnqualifiedType(); 7035212904Sdim rargtype = rargtype.getUnqualifiedType(); 7036212904Sdim } 7037212904Sdim 7038193326Sed if (getCanonicalType(argtype) != getCanonicalType(largtype)) 7039193326Sed allLTypes = false; 7040193326Sed if (getCanonicalType(argtype) != getCanonicalType(rargtype)) 7041193326Sed allRTypes = false; 7042193326Sed } 7043226633Sdim 7044193326Sed if (allLTypes) return lhs; 7045193326Sed if (allRTypes) return rhs; 7046218893Sdim 7047218893Sdim FunctionProtoType::ExtProtoInfo EPI = lproto->getExtProtoInfo(); 7048218893Sdim EPI.ExtInfo = einfo; 7049249423Sdim return getFunctionType(retType, types, EPI); 7050193326Sed } 7051193326Sed 7052193326Sed if (lproto) allRTypes = false; 7053193326Sed if (rproto) allLTypes = false; 7054193326Sed 7055193326Sed const FunctionProtoType *proto = lproto ? lproto : rproto; 7056193326Sed if (proto) { 7057193326Sed assert(!proto->hasExceptionSpec() && "C++ shouldn't be here"); 7058193326Sed if (proto->isVariadic()) return QualType(); 7059193326Sed // Check that the types are compatible with the types that 7060193326Sed // would result from default argument promotions (C99 6.7.5.3p15). 7061193326Sed // The only types actually affected are promotable integer 7062193326Sed // types and floats, which would be passed as a different 7063193326Sed // type depending on whether the prototype is visible. 7064193326Sed unsigned proto_nargs = proto->getNumArgs(); 7065193326Sed for (unsigned i = 0; i < proto_nargs; ++i) { 7066193326Sed QualType argTy = proto->getArgType(i); 7067203955Srdivacky 7068243830Sdim // Look at the converted type of enum types, since that is the type used 7069203955Srdivacky // to pass enum values. 7070243830Sdim if (const EnumType *Enum = argTy->getAs<EnumType>()) { 7071243830Sdim argTy = Enum->getDecl()->getIntegerType(); 7072243830Sdim if (argTy.isNull()) 7073243830Sdim return QualType(); 7074243830Sdim } 7075203955Srdivacky 7076193326Sed if (argTy->isPromotableIntegerType() || 7077193326Sed getCanonicalType(argTy).getUnqualifiedType() == FloatTy) 7078193326Sed return QualType(); 7079193326Sed } 7080193326Sed 7081193326Sed if (allLTypes) return lhs; 7082193326Sed if (allRTypes) return rhs; 7083218893Sdim 7084218893Sdim FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo(); 7085218893Sdim EPI.ExtInfo = einfo; 7086263508Sdim return getFunctionType(retType, proto->getArgTypes(), EPI); 7087193326Sed } 7088193326Sed 7089193326Sed if (allLTypes) return lhs; 7090193326Sed if (allRTypes) return rhs; 7091218893Sdim return getFunctionNoProtoType(retType, einfo); 7092193326Sed} 7093193326Sed 7094249423Sdim/// Given that we have an enum type and a non-enum type, try to merge them. 7095249423Sdimstatic QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET, 7096249423Sdim QualType other, bool isBlockReturnType) { 7097249423Sdim // C99 6.7.2.2p4: Each enumerated type shall be compatible with char, 7098249423Sdim // a signed integer type, or an unsigned integer type. 7099249423Sdim // Compatibility is based on the underlying type, not the promotion 7100249423Sdim // type. 7101249423Sdim QualType underlyingType = ET->getDecl()->getIntegerType(); 7102249423Sdim if (underlyingType.isNull()) return QualType(); 7103249423Sdim if (Context.hasSameType(underlyingType, other)) 7104249423Sdim return other; 7105249423Sdim 7106249423Sdim // In block return types, we're more permissive and accept any 7107249423Sdim // integral type of the same size. 7108249423Sdim if (isBlockReturnType && other->isIntegerType() && 7109249423Sdim Context.getTypeSize(underlyingType) == Context.getTypeSize(other)) 7110249423Sdim return other; 7111249423Sdim 7112249423Sdim return QualType(); 7113249423Sdim} 7114249423Sdim 7115205408SrdivackyQualType ASTContext::mergeTypes(QualType LHS, QualType RHS, 7116212904Sdim bool OfBlockPointer, 7117221345Sdim bool Unqualified, bool BlockReturnType) { 7118193326Sed // C++ [expr]: If an expression initially has the type "reference to T", the 7119193326Sed // type is adjusted to "T" prior to any further analysis, the expression 7120193326Sed // designates the object or function denoted by the reference, and the 7121193326Sed // expression is an lvalue unless the reference is an rvalue reference and 7122193326Sed // the expression is a function call (possibly inside parentheses). 7123203955Srdivacky assert(!LHS->getAs<ReferenceType>() && "LHS is a reference type?"); 7124203955Srdivacky assert(!RHS->getAs<ReferenceType>() && "RHS is a reference type?"); 7125212904Sdim 7126212904Sdim if (Unqualified) { 7127212904Sdim LHS = LHS.getUnqualifiedType(); 7128212904Sdim RHS = RHS.getUnqualifiedType(); 7129212904Sdim } 7130203955Srdivacky 7131193326Sed QualType LHSCan = getCanonicalType(LHS), 7132193326Sed RHSCan = getCanonicalType(RHS); 7133193326Sed 7134193326Sed // If two types are identical, they are compatible. 7135193326Sed if (LHSCan == RHSCan) 7136193326Sed return LHS; 7137193326Sed 7138198092Srdivacky // If the qualifiers are different, the types aren't compatible... mostly. 7139199482Srdivacky Qualifiers LQuals = LHSCan.getLocalQualifiers(); 7140199482Srdivacky Qualifiers RQuals = RHSCan.getLocalQualifiers(); 7141198092Srdivacky if (LQuals != RQuals) { 7142198092Srdivacky // If any of these qualifiers are different, we have a type 7143198092Srdivacky // mismatch. 7144198092Srdivacky if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() || 7145224145Sdim LQuals.getAddressSpace() != RQuals.getAddressSpace() || 7146224145Sdim LQuals.getObjCLifetime() != RQuals.getObjCLifetime()) 7147198092Srdivacky return QualType(); 7148198092Srdivacky 7149198092Srdivacky // Exactly one GC qualifier difference is allowed: __strong is 7150198092Srdivacky // okay if the other type has no GC qualifier but is an Objective 7151198092Srdivacky // C object pointer (i.e. implicitly strong by default). We fix 7152198092Srdivacky // this by pretending that the unqualified type was actually 7153198092Srdivacky // qualified __strong. 7154198092Srdivacky Qualifiers::GC GC_L = LQuals.getObjCGCAttr(); 7155198092Srdivacky Qualifiers::GC GC_R = RQuals.getObjCGCAttr(); 7156198092Srdivacky assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements"); 7157198092Srdivacky 7158198092Srdivacky if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak) 7159198092Srdivacky return QualType(); 7160198092Srdivacky 7161198092Srdivacky if (GC_L == Qualifiers::Strong && RHSCan->isObjCObjectPointerType()) { 7162198092Srdivacky return mergeTypes(LHS, getObjCGCQualType(RHS, Qualifiers::Strong)); 7163198092Srdivacky } 7164198092Srdivacky if (GC_R == Qualifiers::Strong && LHSCan->isObjCObjectPointerType()) { 7165198092Srdivacky return mergeTypes(getObjCGCQualType(LHS, Qualifiers::Strong), RHS); 7166198092Srdivacky } 7167193326Sed return QualType(); 7168198092Srdivacky } 7169193326Sed 7170198092Srdivacky // Okay, qualifiers are equal. 7171198092Srdivacky 7172193326Sed Type::TypeClass LHSClass = LHSCan->getTypeClass(); 7173193326Sed Type::TypeClass RHSClass = RHSCan->getTypeClass(); 7174193326Sed 7175193326Sed // We want to consider the two function types to be the same for these 7176193326Sed // comparisons, just force one to the other. 7177193326Sed if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto; 7178193326Sed if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto; 7179193326Sed 7180193326Sed // Same as above for arrays 7181193326Sed if (LHSClass == Type::VariableArray || LHSClass == Type::IncompleteArray) 7182193326Sed LHSClass = Type::ConstantArray; 7183193326Sed if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray) 7184193326Sed RHSClass = Type::ConstantArray; 7185198092Srdivacky 7186208600Srdivacky // ObjCInterfaces are just specialized ObjCObjects. 7187208600Srdivacky if (LHSClass == Type::ObjCInterface) LHSClass = Type::ObjCObject; 7188208600Srdivacky if (RHSClass == Type::ObjCInterface) RHSClass = Type::ObjCObject; 7189208600Srdivacky 7190193326Sed // Canonicalize ExtVector -> Vector. 7191193326Sed if (LHSClass == Type::ExtVector) LHSClass = Type::Vector; 7192193326Sed if (RHSClass == Type::ExtVector) RHSClass = Type::Vector; 7193193326Sed 7194193326Sed // If the canonical type classes don't match. 7195193326Sed if (LHSClass != RHSClass) { 7196249423Sdim // Note that we only have special rules for turning block enum 7197249423Sdim // returns into block int returns, not vice-versa. 7198198092Srdivacky if (const EnumType* ETy = LHS->getAs<EnumType>()) { 7199249423Sdim return mergeEnumWithInteger(*this, ETy, RHS, false); 7200193326Sed } 7201198092Srdivacky if (const EnumType* ETy = RHS->getAs<EnumType>()) { 7202249423Sdim return mergeEnumWithInteger(*this, ETy, LHS, BlockReturnType); 7203193326Sed } 7204234353Sdim // allow block pointer type to match an 'id' type. 7205234353Sdim if (OfBlockPointer && !BlockReturnType) { 7206234353Sdim if (LHS->isObjCIdType() && RHS->isBlockPointerType()) 7207234353Sdim return LHS; 7208234353Sdim if (RHS->isObjCIdType() && LHS->isBlockPointerType()) 7209234353Sdim return RHS; 7210234353Sdim } 7211234353Sdim 7212193326Sed return QualType(); 7213193326Sed } 7214193326Sed 7215193326Sed // The canonical type classes match. 7216193326Sed switch (LHSClass) { 7217193326Sed#define TYPE(Class, Base) 7218193326Sed#define ABSTRACT_TYPE(Class, Base) 7219204643Srdivacky#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 7220193326Sed#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 7221193326Sed#define DEPENDENT_TYPE(Class, Base) case Type::Class: 7222193326Sed#include "clang/AST/TypeNodes.def" 7223226633Sdim llvm_unreachable("Non-canonical and dependent types shouldn't get here"); 7224193326Sed 7225251662Sdim case Type::Auto: 7226193326Sed case Type::LValueReference: 7227193326Sed case Type::RValueReference: 7228193326Sed case Type::MemberPointer: 7229226633Sdim llvm_unreachable("C++ should never be in mergeTypes"); 7230193326Sed 7231208600Srdivacky case Type::ObjCInterface: 7232193326Sed case Type::IncompleteArray: 7233193326Sed case Type::VariableArray: 7234193326Sed case Type::FunctionProto: 7235193326Sed case Type::ExtVector: 7236226633Sdim llvm_unreachable("Types are eliminated above"); 7237193326Sed 7238193326Sed case Type::Pointer: 7239193326Sed { 7240193326Sed // Merge two pointer types, while trying to preserve typedef info 7241198092Srdivacky QualType LHSPointee = LHS->getAs<PointerType>()->getPointeeType(); 7242198092Srdivacky QualType RHSPointee = RHS->getAs<PointerType>()->getPointeeType(); 7243212904Sdim if (Unqualified) { 7244212904Sdim LHSPointee = LHSPointee.getUnqualifiedType(); 7245212904Sdim RHSPointee = RHSPointee.getUnqualifiedType(); 7246212904Sdim } 7247212904Sdim QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false, 7248212904Sdim Unqualified); 7249193326Sed if (ResultType.isNull()) return QualType(); 7250193326Sed if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) 7251193326Sed return LHS; 7252193326Sed if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) 7253193326Sed return RHS; 7254193326Sed return getPointerType(ResultType); 7255193326Sed } 7256193326Sed case Type::BlockPointer: 7257193326Sed { 7258193326Sed // Merge two block pointer types, while trying to preserve typedef info 7259198092Srdivacky QualType LHSPointee = LHS->getAs<BlockPointerType>()->getPointeeType(); 7260198092Srdivacky QualType RHSPointee = RHS->getAs<BlockPointerType>()->getPointeeType(); 7261212904Sdim if (Unqualified) { 7262212904Sdim LHSPointee = LHSPointee.getUnqualifiedType(); 7263212904Sdim RHSPointee = RHSPointee.getUnqualifiedType(); 7264212904Sdim } 7265212904Sdim QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer, 7266212904Sdim Unqualified); 7267193326Sed if (ResultType.isNull()) return QualType(); 7268193326Sed if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) 7269193326Sed return LHS; 7270193326Sed if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) 7271193326Sed return RHS; 7272193326Sed return getBlockPointerType(ResultType); 7273193326Sed } 7274226633Sdim case Type::Atomic: 7275226633Sdim { 7276226633Sdim // Merge two pointer types, while trying to preserve typedef info 7277226633Sdim QualType LHSValue = LHS->getAs<AtomicType>()->getValueType(); 7278226633Sdim QualType RHSValue = RHS->getAs<AtomicType>()->getValueType(); 7279226633Sdim if (Unqualified) { 7280226633Sdim LHSValue = LHSValue.getUnqualifiedType(); 7281226633Sdim RHSValue = RHSValue.getUnqualifiedType(); 7282226633Sdim } 7283226633Sdim QualType ResultType = mergeTypes(LHSValue, RHSValue, false, 7284226633Sdim Unqualified); 7285226633Sdim if (ResultType.isNull()) return QualType(); 7286226633Sdim if (getCanonicalType(LHSValue) == getCanonicalType(ResultType)) 7287226633Sdim return LHS; 7288226633Sdim if (getCanonicalType(RHSValue) == getCanonicalType(ResultType)) 7289226633Sdim return RHS; 7290226633Sdim return getAtomicType(ResultType); 7291226633Sdim } 7292193326Sed case Type::ConstantArray: 7293193326Sed { 7294193326Sed const ConstantArrayType* LCAT = getAsConstantArrayType(LHS); 7295193326Sed const ConstantArrayType* RCAT = getAsConstantArrayType(RHS); 7296193326Sed if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize()) 7297193326Sed return QualType(); 7298193326Sed 7299193326Sed QualType LHSElem = getAsArrayType(LHS)->getElementType(); 7300193326Sed QualType RHSElem = getAsArrayType(RHS)->getElementType(); 7301212904Sdim if (Unqualified) { 7302212904Sdim LHSElem = LHSElem.getUnqualifiedType(); 7303212904Sdim RHSElem = RHSElem.getUnqualifiedType(); 7304212904Sdim } 7305212904Sdim 7306212904Sdim QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified); 7307193326Sed if (ResultType.isNull()) return QualType(); 7308193326Sed if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) 7309193326Sed return LHS; 7310193326Sed if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) 7311193326Sed return RHS; 7312193326Sed if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(), 7313193326Sed ArrayType::ArraySizeModifier(), 0); 7314193326Sed if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(), 7315193326Sed ArrayType::ArraySizeModifier(), 0); 7316193326Sed const VariableArrayType* LVAT = getAsVariableArrayType(LHS); 7317193326Sed const VariableArrayType* RVAT = getAsVariableArrayType(RHS); 7318193326Sed if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) 7319193326Sed return LHS; 7320193326Sed if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) 7321193326Sed return RHS; 7322193326Sed if (LVAT) { 7323193326Sed // FIXME: This isn't correct! But tricky to implement because 7324193326Sed // the array's size has to be the size of LHS, but the type 7325193326Sed // has to be different. 7326193326Sed return LHS; 7327193326Sed } 7328193326Sed if (RVAT) { 7329193326Sed // FIXME: This isn't correct! But tricky to implement because 7330193326Sed // the array's size has to be the size of RHS, but the type 7331193326Sed // has to be different. 7332193326Sed return RHS; 7333193326Sed } 7334193326Sed if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS; 7335193326Sed if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS; 7336198092Srdivacky return getIncompleteArrayType(ResultType, 7337198092Srdivacky ArrayType::ArraySizeModifier(), 0); 7338193326Sed } 7339193326Sed case Type::FunctionNoProto: 7340212904Sdim return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified); 7341193326Sed case Type::Record: 7342193326Sed case Type::Enum: 7343193326Sed return QualType(); 7344193326Sed case Type::Builtin: 7345193326Sed // Only exactly equal builtin types are compatible, which is tested above. 7346193326Sed return QualType(); 7347193326Sed case Type::Complex: 7348193326Sed // Distinct complex types are incompatible. 7349193326Sed return QualType(); 7350193326Sed case Type::Vector: 7351193326Sed // FIXME: The merged type should be an ExtVector! 7352205219Srdivacky if (areCompatVectorTypes(LHSCan->getAs<VectorType>(), 7353205219Srdivacky RHSCan->getAs<VectorType>())) 7354193326Sed return LHS; 7355193326Sed return QualType(); 7356208600Srdivacky case Type::ObjCObject: { 7357208600Srdivacky // Check if the types are assignment compatible. 7358193326Sed // FIXME: This should be type compatibility, e.g. whether 7359193326Sed // "LHS x; RHS x;" at global scope is legal. 7360208600Srdivacky const ObjCObjectType* LHSIface = LHS->getAs<ObjCObjectType>(); 7361208600Srdivacky const ObjCObjectType* RHSIface = RHS->getAs<ObjCObjectType>(); 7362208600Srdivacky if (canAssignObjCInterfaces(LHSIface, RHSIface)) 7363193326Sed return LHS; 7364193326Sed 7365193326Sed return QualType(); 7366193326Sed } 7367198092Srdivacky case Type::ObjCObjectPointer: { 7368205408Srdivacky if (OfBlockPointer) { 7369205408Srdivacky if (canAssignObjCInterfacesInBlockPointer( 7370205408Srdivacky LHS->getAs<ObjCObjectPointerType>(), 7371221345Sdim RHS->getAs<ObjCObjectPointerType>(), 7372221345Sdim BlockReturnType)) 7373234353Sdim return LHS; 7374205408Srdivacky return QualType(); 7375205408Srdivacky } 7376198092Srdivacky if (canAssignObjCInterfaces(LHS->getAs<ObjCObjectPointerType>(), 7377198092Srdivacky RHS->getAs<ObjCObjectPointerType>())) 7378198092Srdivacky return LHS; 7379198092Srdivacky 7380193326Sed return QualType(); 7381198092Srdivacky } 7382234353Sdim } 7383193326Sed 7384234353Sdim llvm_unreachable("Invalid Type::Class!"); 7385193326Sed} 7386193326Sed 7387226633Sdimbool ASTContext::FunctionTypesMatchOnNSConsumedAttrs( 7388226633Sdim const FunctionProtoType *FromFunctionType, 7389226633Sdim const FunctionProtoType *ToFunctionType) { 7390226633Sdim if (FromFunctionType->hasAnyConsumedArgs() != 7391226633Sdim ToFunctionType->hasAnyConsumedArgs()) 7392226633Sdim return false; 7393226633Sdim FunctionProtoType::ExtProtoInfo FromEPI = 7394226633Sdim FromFunctionType->getExtProtoInfo(); 7395226633Sdim FunctionProtoType::ExtProtoInfo ToEPI = 7396226633Sdim ToFunctionType->getExtProtoInfo(); 7397226633Sdim if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments) 7398226633Sdim for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs(); 7399226633Sdim ArgIdx != NumArgs; ++ArgIdx) { 7400226633Sdim if (FromEPI.ConsumedArguments[ArgIdx] != 7401226633Sdim ToEPI.ConsumedArguments[ArgIdx]) 7402226633Sdim return false; 7403226633Sdim } 7404226633Sdim return true; 7405226633Sdim} 7406226633Sdim 7407208600Srdivacky/// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and 7408208600Srdivacky/// 'RHS' attributes and returns the merged version; including for function 7409208600Srdivacky/// return types. 7410208600SrdivackyQualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) { 7411208600Srdivacky QualType LHSCan = getCanonicalType(LHS), 7412208600Srdivacky RHSCan = getCanonicalType(RHS); 7413208600Srdivacky // If two types are identical, they are compatible. 7414208600Srdivacky if (LHSCan == RHSCan) 7415208600Srdivacky return LHS; 7416208600Srdivacky if (RHSCan->isFunctionType()) { 7417208600Srdivacky if (!LHSCan->isFunctionType()) 7418208600Srdivacky return QualType(); 7419208600Srdivacky QualType OldReturnType = 7420208600Srdivacky cast<FunctionType>(RHSCan.getTypePtr())->getResultType(); 7421208600Srdivacky QualType NewReturnType = 7422208600Srdivacky cast<FunctionType>(LHSCan.getTypePtr())->getResultType(); 7423208600Srdivacky QualType ResReturnType = 7424208600Srdivacky mergeObjCGCQualifiers(NewReturnType, OldReturnType); 7425208600Srdivacky if (ResReturnType.isNull()) 7426208600Srdivacky return QualType(); 7427208600Srdivacky if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) { 7428208600Srdivacky // id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo(); 7429208600Srdivacky // In either case, use OldReturnType to build the new function type. 7430208600Srdivacky const FunctionType *F = LHS->getAs<FunctionType>(); 7431208600Srdivacky if (const FunctionProtoType *FPT = cast<FunctionProtoType>(F)) { 7432218893Sdim FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 7433218893Sdim EPI.ExtInfo = getFunctionExtInfo(LHS); 7434263508Sdim QualType ResultType = 7435263508Sdim getFunctionType(OldReturnType, FPT->getArgTypes(), EPI); 7436208600Srdivacky return ResultType; 7437208600Srdivacky } 7438208600Srdivacky } 7439208600Srdivacky return QualType(); 7440208600Srdivacky } 7441208600Srdivacky 7442208600Srdivacky // If the qualifiers are different, the types can still be merged. 7443208600Srdivacky Qualifiers LQuals = LHSCan.getLocalQualifiers(); 7444208600Srdivacky Qualifiers RQuals = RHSCan.getLocalQualifiers(); 7445208600Srdivacky if (LQuals != RQuals) { 7446208600Srdivacky // If any of these qualifiers are different, we have a type mismatch. 7447208600Srdivacky if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() || 7448208600Srdivacky LQuals.getAddressSpace() != RQuals.getAddressSpace()) 7449208600Srdivacky return QualType(); 7450208600Srdivacky 7451208600Srdivacky // Exactly one GC qualifier difference is allowed: __strong is 7452208600Srdivacky // okay if the other type has no GC qualifier but is an Objective 7453208600Srdivacky // C object pointer (i.e. implicitly strong by default). We fix 7454208600Srdivacky // this by pretending that the unqualified type was actually 7455208600Srdivacky // qualified __strong. 7456208600Srdivacky Qualifiers::GC GC_L = LQuals.getObjCGCAttr(); 7457208600Srdivacky Qualifiers::GC GC_R = RQuals.getObjCGCAttr(); 7458208600Srdivacky assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements"); 7459208600Srdivacky 7460208600Srdivacky if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak) 7461208600Srdivacky return QualType(); 7462208600Srdivacky 7463208600Srdivacky if (GC_L == Qualifiers::Strong) 7464208600Srdivacky return LHS; 7465208600Srdivacky if (GC_R == Qualifiers::Strong) 7466208600Srdivacky return RHS; 7467208600Srdivacky return QualType(); 7468208600Srdivacky } 7469208600Srdivacky 7470208600Srdivacky if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) { 7471208600Srdivacky QualType LHSBaseQT = LHS->getAs<ObjCObjectPointerType>()->getPointeeType(); 7472208600Srdivacky QualType RHSBaseQT = RHS->getAs<ObjCObjectPointerType>()->getPointeeType(); 7473208600Srdivacky QualType ResQT = mergeObjCGCQualifiers(LHSBaseQT, RHSBaseQT); 7474208600Srdivacky if (ResQT == LHSBaseQT) 7475208600Srdivacky return LHS; 7476208600Srdivacky if (ResQT == RHSBaseQT) 7477208600Srdivacky return RHS; 7478208600Srdivacky } 7479208600Srdivacky return QualType(); 7480208600Srdivacky} 7481208600Srdivacky 7482193326Sed//===----------------------------------------------------------------------===// 7483193326Sed// Integer Predicates 7484193326Sed//===----------------------------------------------------------------------===// 7485193326Sed 7486218893Sdimunsigned ASTContext::getIntWidth(QualType T) const { 7487263508Sdim if (const EnumType *ET = T->getAs<EnumType>()) 7488218893Sdim T = ET->getDecl()->getIntegerType(); 7489199482Srdivacky if (T->isBooleanType()) 7490193326Sed return 1; 7491193326Sed // For builtin types, just use the standard type sizing method 7492193326Sed return (unsigned)getTypeSize(T); 7493193326Sed} 7494193326Sed 7495243830SdimQualType ASTContext::getCorrespondingUnsignedType(QualType T) const { 7496212904Sdim assert(T->hasSignedIntegerRepresentation() && "Unexpected type"); 7497198398Srdivacky 7498198398Srdivacky // Turn <4 x signed int> -> <4 x unsigned int> 7499198398Srdivacky if (const VectorType *VTy = T->getAs<VectorType>()) 7500198398Srdivacky return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), 7501218893Sdim VTy->getNumElements(), VTy->getVectorKind()); 7502198398Srdivacky 7503198398Srdivacky // For enums, we return the unsigned version of the base type. 7504198398Srdivacky if (const EnumType *ETy = T->getAs<EnumType>()) 7505193326Sed T = ETy->getDecl()->getIntegerType(); 7506198398Srdivacky 7507198398Srdivacky const BuiltinType *BTy = T->getAs<BuiltinType>(); 7508198398Srdivacky assert(BTy && "Unexpected signed integer type"); 7509193326Sed switch (BTy->getKind()) { 7510193326Sed case BuiltinType::Char_S: 7511193326Sed case BuiltinType::SChar: 7512193326Sed return UnsignedCharTy; 7513193326Sed case BuiltinType::Short: 7514193326Sed return UnsignedShortTy; 7515193326Sed case BuiltinType::Int: 7516193326Sed return UnsignedIntTy; 7517193326Sed case BuiltinType::Long: 7518193326Sed return UnsignedLongTy; 7519193326Sed case BuiltinType::LongLong: 7520193326Sed return UnsignedLongLongTy; 7521193326Sed case BuiltinType::Int128: 7522193326Sed return UnsignedInt128Ty; 7523193326Sed default: 7524226633Sdim llvm_unreachable("Unexpected signed integer type"); 7525193326Sed } 7526193326Sed} 7527193326Sed 7528218893SdimASTMutationListener::~ASTMutationListener() { } 7529194179Sed 7530263508Sdimvoid ASTMutationListener::DeducedReturnType(const FunctionDecl *FD, 7531263508Sdim QualType ReturnType) {} 7532218893Sdim 7533194179Sed//===----------------------------------------------------------------------===// 7534194179Sed// Builtin Type Computation 7535194179Sed//===----------------------------------------------------------------------===// 7536194179Sed 7537194179Sed/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the 7538218893Sdim/// pointer over the consumed characters. This returns the resultant type. If 7539218893Sdim/// AllowTypeModifiers is false then modifier like * are not parsed, just basic 7540218893Sdim/// types. This allows "v2i*" to be parsed as a pointer to a v2i instead of 7541218893Sdim/// a vector of "i*". 7542218893Sdim/// 7543218893Sdim/// RequiresICE is filled in on return to indicate whether the value is required 7544218893Sdim/// to be an Integer Constant Expression. 7545218893Sdimstatic QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, 7546194179Sed ASTContext::GetBuiltinTypeError &Error, 7547218893Sdim bool &RequiresICE, 7548218893Sdim bool AllowTypeModifiers) { 7549194179Sed // Modifiers. 7550194179Sed int HowLong = 0; 7551194179Sed bool Signed = false, Unsigned = false; 7552218893Sdim RequiresICE = false; 7553218893Sdim 7554218893Sdim // Read the prefixed modifiers first. 7555194179Sed bool Done = false; 7556194179Sed while (!Done) { 7557194179Sed switch (*Str++) { 7558198092Srdivacky default: Done = true; --Str; break; 7559218893Sdim case 'I': 7560218893Sdim RequiresICE = true; 7561218893Sdim break; 7562194179Sed case 'S': 7563194179Sed assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!"); 7564194179Sed assert(!Signed && "Can't use 'S' modifier multiple times!"); 7565194179Sed Signed = true; 7566194179Sed break; 7567194179Sed case 'U': 7568194179Sed assert(!Signed && "Can't use both 'S' and 'U' modifiers!"); 7569194179Sed assert(!Unsigned && "Can't use 'S' modifier multiple times!"); 7570194179Sed Unsigned = true; 7571194179Sed break; 7572194179Sed case 'L': 7573194179Sed assert(HowLong <= 2 && "Can't have LLLL modifier"); 7574194179Sed ++HowLong; 7575194179Sed break; 7576194179Sed } 7577194179Sed } 7578194179Sed 7579194179Sed QualType Type; 7580198092Srdivacky 7581194179Sed // Read the base type. 7582194179Sed switch (*Str++) { 7583226633Sdim default: llvm_unreachable("Unknown builtin type letter!"); 7584194179Sed case 'v': 7585194179Sed assert(HowLong == 0 && !Signed && !Unsigned && 7586194179Sed "Bad modifiers used with 'v'!"); 7587194179Sed Type = Context.VoidTy; 7588194179Sed break; 7589263508Sdim case 'h': 7590263508Sdim assert(HowLong == 0 && !Signed && !Unsigned && 7591263508Sdim "Bad modifiers used with 'f'!"); 7592263508Sdim Type = Context.HalfTy; 7593263508Sdim break; 7594194179Sed case 'f': 7595194179Sed assert(HowLong == 0 && !Signed && !Unsigned && 7596194179Sed "Bad modifiers used with 'f'!"); 7597194179Sed Type = Context.FloatTy; 7598194179Sed break; 7599194179Sed case 'd': 7600194179Sed assert(HowLong < 2 && !Signed && !Unsigned && 7601194179Sed "Bad modifiers used with 'd'!"); 7602194179Sed if (HowLong) 7603194179Sed Type = Context.LongDoubleTy; 7604194179Sed else 7605194179Sed Type = Context.DoubleTy; 7606194179Sed break; 7607194179Sed case 's': 7608194179Sed assert(HowLong == 0 && "Bad modifiers used with 's'!"); 7609194179Sed if (Unsigned) 7610194179Sed Type = Context.UnsignedShortTy; 7611194179Sed else 7612194179Sed Type = Context.ShortTy; 7613194179Sed break; 7614194179Sed case 'i': 7615194179Sed if (HowLong == 3) 7616194179Sed Type = Unsigned ? Context.UnsignedInt128Ty : Context.Int128Ty; 7617194179Sed else if (HowLong == 2) 7618194179Sed Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy; 7619194179Sed else if (HowLong == 1) 7620194179Sed Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy; 7621194179Sed else 7622194179Sed Type = Unsigned ? Context.UnsignedIntTy : Context.IntTy; 7623194179Sed break; 7624194179Sed case 'c': 7625194179Sed assert(HowLong == 0 && "Bad modifiers used with 'c'!"); 7626194179Sed if (Signed) 7627194179Sed Type = Context.SignedCharTy; 7628194179Sed else if (Unsigned) 7629194179Sed Type = Context.UnsignedCharTy; 7630194179Sed else 7631194179Sed Type = Context.CharTy; 7632194179Sed break; 7633194179Sed case 'b': // boolean 7634194179Sed assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!"); 7635194179Sed Type = Context.BoolTy; 7636194179Sed break; 7637194179Sed case 'z': // size_t. 7638194179Sed assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'z'!"); 7639194179Sed Type = Context.getSizeType(); 7640194179Sed break; 7641194179Sed case 'F': 7642194179Sed Type = Context.getCFConstantStringType(); 7643194179Sed break; 7644218893Sdim case 'G': 7645218893Sdim Type = Context.getObjCIdType(); 7646218893Sdim break; 7647218893Sdim case 'H': 7648218893Sdim Type = Context.getObjCSelType(); 7649218893Sdim break; 7650249423Sdim case 'M': 7651249423Sdim Type = Context.getObjCSuperType(); 7652249423Sdim break; 7653194179Sed case 'a': 7654194179Sed Type = Context.getBuiltinVaListType(); 7655194179Sed assert(!Type.isNull() && "builtin va list type not initialized!"); 7656194179Sed break; 7657194179Sed case 'A': 7658194179Sed // This is a "reference" to a va_list; however, what exactly 7659194179Sed // this means depends on how va_list is defined. There are two 7660194179Sed // different kinds of va_list: ones passed by value, and ones 7661194179Sed // passed by reference. An example of a by-value va_list is 7662194179Sed // x86, where va_list is a char*. An example of by-ref va_list 7663194179Sed // is x86-64, where va_list is a __va_list_tag[1]. For x86, 7664194179Sed // we want this argument to be a char*&; for x86-64, we want 7665194179Sed // it to be a __va_list_tag*. 7666194179Sed Type = Context.getBuiltinVaListType(); 7667194179Sed assert(!Type.isNull() && "builtin va list type not initialized!"); 7668218893Sdim if (Type->isArrayType()) 7669194179Sed Type = Context.getArrayDecayedType(Type); 7670218893Sdim else 7671194179Sed Type = Context.getLValueReferenceType(Type); 7672194179Sed break; 7673194179Sed case 'V': { 7674194179Sed char *End; 7675194179Sed unsigned NumElements = strtoul(Str, &End, 10); 7676194179Sed assert(End != Str && "Missing vector size"); 7677194179Sed Str = End; 7678198092Srdivacky 7679218893Sdim QualType ElementType = DecodeTypeFromStr(Str, Context, Error, 7680218893Sdim RequiresICE, false); 7681218893Sdim assert(!RequiresICE && "Can't require vector ICE"); 7682218893Sdim 7683218893Sdim // TODO: No way to make AltiVec vectors in builtins yet. 7684210299Sed Type = Context.getVectorType(ElementType, NumElements, 7685218893Sdim VectorType::GenericVector); 7686194179Sed break; 7687194179Sed } 7688239462Sdim case 'E': { 7689239462Sdim char *End; 7690239462Sdim 7691239462Sdim unsigned NumElements = strtoul(Str, &End, 10); 7692239462Sdim assert(End != Str && "Missing vector size"); 7693239462Sdim 7694239462Sdim Str = End; 7695239462Sdim 7696239462Sdim QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE, 7697239462Sdim false); 7698239462Sdim Type = Context.getExtVectorType(ElementType, NumElements); 7699239462Sdim break; 7700239462Sdim } 7701198092Srdivacky case 'X': { 7702218893Sdim QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE, 7703218893Sdim false); 7704218893Sdim assert(!RequiresICE && "Can't require complex ICE"); 7705198092Srdivacky Type = Context.getComplexType(ElementType); 7706198092Srdivacky break; 7707226633Sdim } 7708226633Sdim case 'Y' : { 7709226633Sdim Type = Context.getPointerDiffType(); 7710226633Sdim break; 7711226633Sdim } 7712198092Srdivacky case 'P': 7713198092Srdivacky Type = Context.getFILEType(); 7714198092Srdivacky if (Type.isNull()) { 7715198092Srdivacky Error = ASTContext::GE_Missing_stdio; 7716198092Srdivacky return QualType(); 7717194179Sed } 7718198092Srdivacky break; 7719198092Srdivacky case 'J': 7720198092Srdivacky if (Signed) 7721198092Srdivacky Type = Context.getsigjmp_bufType(); 7722198092Srdivacky else 7723198092Srdivacky Type = Context.getjmp_bufType(); 7724198092Srdivacky 7725198092Srdivacky if (Type.isNull()) { 7726198092Srdivacky Error = ASTContext::GE_Missing_setjmp; 7727194179Sed return QualType(); 7728194179Sed } 7729198092Srdivacky break; 7730227737Sdim case 'K': 7731227737Sdim assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'K'!"); 7732227737Sdim Type = Context.getucontext_tType(); 7733227737Sdim 7734227737Sdim if (Type.isNull()) { 7735227737Sdim Error = ASTContext::GE_Missing_ucontext; 7736227737Sdim return QualType(); 7737227737Sdim } 7738227737Sdim break; 7739243830Sdim case 'p': 7740243830Sdim Type = Context.getProcessIDType(); 7741243830Sdim break; 7742194179Sed } 7743198092Srdivacky 7744218893Sdim // If there are modifiers and if we're allowed to parse them, go for it. 7745218893Sdim Done = !AllowTypeModifiers; 7746194179Sed while (!Done) { 7747205219Srdivacky switch (char c = *Str++) { 7748218893Sdim default: Done = true; --Str; break; 7749218893Sdim case '*': 7750218893Sdim case '&': { 7751218893Sdim // Both pointers and references can have their pointee types 7752218893Sdim // qualified with an address space. 7753218893Sdim char *End; 7754218893Sdim unsigned AddrSpace = strtoul(Str, &End, 10); 7755218893Sdim if (End != Str && AddrSpace != 0) { 7756218893Sdim Type = Context.getAddrSpaceQualType(Type, AddrSpace); 7757218893Sdim Str = End; 7758218893Sdim } 7759218893Sdim if (c == '*') 7760218893Sdim Type = Context.getPointerType(Type); 7761218893Sdim else 7762218893Sdim Type = Context.getLValueReferenceType(Type); 7763218893Sdim break; 7764194179Sed } 7765218893Sdim // FIXME: There's no way to have a built-in with an rvalue ref arg. 7766218893Sdim case 'C': 7767218893Sdim Type = Type.withConst(); 7768218893Sdim break; 7769218893Sdim case 'D': 7770218893Sdim Type = Context.getVolatileType(Type); 7771218893Sdim break; 7772234353Sdim case 'R': 7773234353Sdim Type = Type.withRestrict(); 7774234353Sdim break; 7775218893Sdim } 7776194179Sed } 7777218893Sdim 7778218893Sdim assert((!RequiresICE || Type->isIntegralOrEnumerationType()) && 7779218893Sdim "Integer constant 'I' type must be an integer"); 7780198092Srdivacky 7781194179Sed return Type; 7782194179Sed} 7783194179Sed 7784194179Sed/// GetBuiltinType - Return the type for the specified builtin. 7785218893SdimQualType ASTContext::GetBuiltinType(unsigned Id, 7786218893Sdim GetBuiltinTypeError &Error, 7787218893Sdim unsigned *IntegerConstantArgs) const { 7788218893Sdim const char *TypeStr = BuiltinInfo.GetTypeString(Id); 7789198092Srdivacky 7790226633Sdim SmallVector<QualType, 8> ArgTypes; 7791198092Srdivacky 7792218893Sdim bool RequiresICE = false; 7793194179Sed Error = GE_None; 7794218893Sdim QualType ResType = DecodeTypeFromStr(TypeStr, *this, Error, 7795218893Sdim RequiresICE, true); 7796194179Sed if (Error != GE_None) 7797194179Sed return QualType(); 7798218893Sdim 7799218893Sdim assert(!RequiresICE && "Result of intrinsic cannot be required to be an ICE"); 7800218893Sdim 7801194179Sed while (TypeStr[0] && TypeStr[0] != '.') { 7802218893Sdim QualType Ty = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true); 7803194179Sed if (Error != GE_None) 7804194179Sed return QualType(); 7805194179Sed 7806218893Sdim // If this argument is required to be an IntegerConstantExpression and the 7807218893Sdim // caller cares, fill in the bitmask we return. 7808218893Sdim if (RequiresICE && IntegerConstantArgs) 7809218893Sdim *IntegerConstantArgs |= 1 << ArgTypes.size(); 7810218893Sdim 7811194179Sed // Do array -> pointer decay. The builtin should use the decayed type. 7812194179Sed if (Ty->isArrayType()) 7813194179Sed Ty = getArrayDecayedType(Ty); 7814198092Srdivacky 7815194179Sed ArgTypes.push_back(Ty); 7816194179Sed } 7817194179Sed 7818194179Sed assert((TypeStr[0] != '.' || TypeStr[1] == 0) && 7819194179Sed "'.' should only occur at end of builtin type list!"); 7820194179Sed 7821263508Sdim FunctionType::ExtInfo EI(CC_C); 7822218893Sdim if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true); 7823204643Srdivacky 7824218893Sdim bool Variadic = (TypeStr[0] == '.'); 7825198092Srdivacky 7826218893Sdim // We really shouldn't be making a no-proto type here, especially in C++. 7827218893Sdim if (ArgTypes.empty() && Variadic) 7828218893Sdim return getFunctionNoProtoType(ResType, EI); 7829198092Srdivacky 7830218893Sdim FunctionProtoType::ExtProtoInfo EPI; 7831218893Sdim EPI.ExtInfo = EI; 7832218893Sdim EPI.Variadic = Variadic; 7833198092Srdivacky 7834249423Sdim return getFunctionType(ResType, ArgTypes, EPI); 7835198092Srdivacky} 7836212904Sdim 7837212904SdimGVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) { 7838263508Sdim if (!FD->isExternallyVisible()) 7839263508Sdim return GVA_Internal; 7840263508Sdim 7841212904Sdim GVALinkage External = GVA_StrongExternal; 7842263508Sdim switch (FD->getTemplateSpecializationKind()) { 7843263508Sdim case TSK_Undeclared: 7844263508Sdim case TSK_ExplicitSpecialization: 7845263508Sdim External = GVA_StrongExternal; 7846263508Sdim break; 7847212904Sdim 7848263508Sdim case TSK_ExplicitInstantiationDefinition: 7849263508Sdim return GVA_ExplicitTemplateInstantiation; 7850212904Sdim 7851263508Sdim case TSK_ExplicitInstantiationDeclaration: 7852263508Sdim case TSK_ImplicitInstantiation: 7853263508Sdim External = GVA_TemplateInstantiation; 7854263508Sdim break; 7855212904Sdim } 7856212904Sdim 7857212904Sdim if (!FD->isInlined()) 7858212904Sdim return External; 7859263508Sdim 7860263508Sdim if ((!getLangOpts().CPlusPlus && !getLangOpts().MicrosoftMode) || 7861263508Sdim FD->hasAttr<GNUInlineAttr>()) { 7862212904Sdim // GNU or C99 inline semantics. Determine whether this symbol should be 7863212904Sdim // externally visible. 7864212904Sdim if (FD->isInlineDefinitionExternallyVisible()) 7865212904Sdim return External; 7866212904Sdim 7867212904Sdim // C99 inline semantics, where the symbol is not externally visible. 7868212904Sdim return GVA_C99Inline; 7869212904Sdim } 7870212904Sdim 7871212904Sdim // C++0x [temp.explicit]p9: 7872212904Sdim // [ Note: The intent is that an inline function that is the subject of 7873212904Sdim // an explicit instantiation declaration will still be implicitly 7874212904Sdim // instantiated when used so that the body can be considered for 7875212904Sdim // inlining, but that no out-of-line copy of the inline function would be 7876212904Sdim // generated in the translation unit. -- end note ] 7877212904Sdim if (FD->getTemplateSpecializationKind() 7878212904Sdim == TSK_ExplicitInstantiationDeclaration) 7879212904Sdim return GVA_C99Inline; 7880212904Sdim 7881212904Sdim return GVA_CXXInline; 7882212904Sdim} 7883212904Sdim 7884212904SdimGVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { 7885263508Sdim if (!VD->isExternallyVisible()) 7886263508Sdim return GVA_Internal; 7887212904Sdim 7888263508Sdim switch (VD->getTemplateSpecializationKind()) { 7889263508Sdim case TSK_Undeclared: 7890263508Sdim case TSK_ExplicitSpecialization: 7891263508Sdim return GVA_StrongExternal; 7892212904Sdim 7893263508Sdim case TSK_ExplicitInstantiationDeclaration: 7894263508Sdim llvm_unreachable("Variable should not be instantiated"); 7895263508Sdim // Fall through to treat this like any other instantiation. 7896212904Sdim 7897263508Sdim case TSK_ExplicitInstantiationDefinition: 7898263508Sdim return GVA_ExplicitTemplateInstantiation; 7899212904Sdim 7900263508Sdim case TSK_ImplicitInstantiation: 7901263508Sdim return GVA_TemplateInstantiation; 7902212904Sdim } 7903212904Sdim 7904234353Sdim llvm_unreachable("Invalid Linkage!"); 7905212904Sdim} 7906212904Sdim 7907212904Sdimbool ASTContext::DeclMustBeEmitted(const Decl *D) { 7908212904Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 7909212904Sdim if (!VD->isFileVarDecl()) 7910212904Sdim return false; 7911249423Sdim } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 7912249423Sdim // We never need to emit an uninstantiated function template. 7913249423Sdim if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) 7914249423Sdim return false; 7915249423Sdim } else 7916212904Sdim return false; 7917212904Sdim 7918249423Sdim // If this is a member of a class template, we do not need to emit it. 7919249423Sdim if (D->getDeclContext()->isDependentContext()) 7920249423Sdim return false; 7921249423Sdim 7922212904Sdim // Weak references don't produce any output by themselves. 7923212904Sdim if (D->hasAttr<WeakRefAttr>()) 7924212904Sdim return false; 7925212904Sdim 7926212904Sdim // Aliases and used decls are required. 7927212904Sdim if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>()) 7928212904Sdim return true; 7929212904Sdim 7930212904Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 7931212904Sdim // Forward declarations aren't required. 7932223017Sdim if (!FD->doesThisDeclarationHaveABody()) 7933226633Sdim return FD->doesDeclarationForceExternallyVisibleDefinition(); 7934212904Sdim 7935212904Sdim // Constructors and destructors are required. 7936212904Sdim if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>()) 7937212904Sdim return true; 7938212904Sdim 7939249423Sdim // The key function for a class is required. This rule only comes 7940249423Sdim // into play when inline functions can be key functions, though. 7941249423Sdim if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) { 7942249423Sdim if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { 7943249423Sdim const CXXRecordDecl *RD = MD->getParent(); 7944249423Sdim if (MD->isOutOfLine() && RD->isDynamicClass()) { 7945249423Sdim const CXXMethodDecl *KeyFunc = getCurrentKeyFunction(RD); 7946249423Sdim if (KeyFunc && KeyFunc->getCanonicalDecl() == MD->getCanonicalDecl()) 7947249423Sdim return true; 7948249423Sdim } 7949212904Sdim } 7950212904Sdim } 7951212904Sdim 7952212904Sdim GVALinkage Linkage = GetGVALinkageForFunction(FD); 7953212904Sdim 7954212904Sdim // static, static inline, always_inline, and extern inline functions can 7955212904Sdim // always be deferred. Normal inline functions can be deferred in C99/C++. 7956212904Sdim // Implicit template instantiations can also be deferred in C++. 7957212904Sdim if (Linkage == GVA_Internal || Linkage == GVA_C99Inline || 7958212904Sdim Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) 7959212904Sdim return false; 7960212904Sdim return true; 7961212904Sdim } 7962226633Sdim 7963212904Sdim const VarDecl *VD = cast<VarDecl>(D); 7964212904Sdim assert(VD->isFileVarDecl() && "Expected file scoped var"); 7965212904Sdim 7966212904Sdim if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly) 7967212904Sdim return false; 7968212904Sdim 7969249423Sdim // Variables that can be needed in other TUs are required. 7970249423Sdim GVALinkage L = GetGVALinkageForVariable(VD); 7971249423Sdim if (L != GVA_Internal && L != GVA_TemplateInstantiation) 7972249423Sdim return true; 7973212904Sdim 7974249423Sdim // Variables that have destruction with side-effects are required. 7975249423Sdim if (VD->getType().isDestructedType()) 7976249423Sdim return true; 7977212904Sdim 7978249423Sdim // Variables that have initialization with side-effects are required. 7979249423Sdim if (VD->getInit() && VD->getInit()->HasSideEffects(*this)) 7980249423Sdim return true; 7981212904Sdim 7982249423Sdim return false; 7983212904Sdim} 7984212904Sdim 7985263508SdimCallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, 7986263508Sdim bool IsCXXMethod) const { 7987218893Sdim // Pass through to the C++ ABI object 7988263508Sdim if (IsCXXMethod) 7989263508Sdim return ABI->getDefaultMethodCallConv(IsVariadic); 7990218893Sdim 7991263508Sdim return (LangOpts.MRTD && !IsVariadic) ? CC_X86StdCall : CC_C; 7992239462Sdim} 7993239462Sdim 7994218893Sdimbool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const { 7995218893Sdim // Pass through to the C++ ABI object 7996218893Sdim return ABI->isNearlyEmpty(RD); 7997218893Sdim} 7998218893Sdim 7999218893SdimMangleContext *ASTContext::createMangleContext() { 8000249423Sdim switch (Target->getCXXABI().getKind()) { 8001249423Sdim case TargetCXXABI::GenericAArch64: 8002249423Sdim case TargetCXXABI::GenericItanium: 8003249423Sdim case TargetCXXABI::GenericARM: 8004249423Sdim case TargetCXXABI::iOS: 8005263508Sdim return ItaniumMangleContext::create(*this, getDiagnostics()); 8006249423Sdim case TargetCXXABI::Microsoft: 8007263508Sdim return MicrosoftMangleContext::create(*this, getDiagnostics()); 8008218893Sdim } 8009226633Sdim llvm_unreachable("Unsupported ABI"); 8010218893Sdim} 8011218893Sdim 8012212904SdimCXXABI::~CXXABI() {} 8013221345Sdim 8014221345Sdimsize_t ASTContext::getSideTableAllocatedMemory() const { 8015263508Sdim return ASTRecordLayouts.getMemorySize() + 8016263508Sdim llvm::capacity_in_bytes(ObjCLayouts) + 8017263508Sdim llvm::capacity_in_bytes(KeyFunctions) + 8018263508Sdim llvm::capacity_in_bytes(ObjCImpls) + 8019263508Sdim llvm::capacity_in_bytes(BlockVarCopyInits) + 8020263508Sdim llvm::capacity_in_bytes(DeclAttrs) + 8021263508Sdim llvm::capacity_in_bytes(TemplateOrInstantiation) + 8022263508Sdim llvm::capacity_in_bytes(InstantiatedFromUsingDecl) + 8023263508Sdim llvm::capacity_in_bytes(InstantiatedFromUsingShadowDecl) + 8024263508Sdim llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) + 8025263508Sdim llvm::capacity_in_bytes(OverriddenMethods) + 8026263508Sdim llvm::capacity_in_bytes(Types) + 8027263508Sdim llvm::capacity_in_bytes(VariableArrayTypes) + 8028263508Sdim llvm::capacity_in_bytes(ClassScopeSpecializationPattern); 8029221345Sdim} 8030226633Sdim 8031263508Sdim/// getIntTypeForBitwidth - 8032263508Sdim/// sets integer QualTy according to specified details: 8033263508Sdim/// bitwidth, signed/unsigned. 8034263508Sdim/// Returns empty type if there is no appropriate target types. 8035263508SdimQualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth, 8036263508Sdim unsigned Signed) const { 8037263508Sdim TargetInfo::IntType Ty = getTargetInfo().getIntTypeByWidth(DestWidth, Signed); 8038263508Sdim CanQualType QualTy = getFromTargetType(Ty); 8039263508Sdim if (!QualTy && DestWidth == 128) 8040263508Sdim return Signed ? Int128Ty : UnsignedInt128Ty; 8041263508Sdim return QualTy; 8042263508Sdim} 8043249423Sdim 8044263508Sdim/// getRealTypeForBitwidth - 8045263508Sdim/// sets floating point QualTy according to specified bitwidth. 8046263508Sdim/// Returns empty type if there is no appropriate target types. 8047263508SdimQualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const { 8048263508Sdim TargetInfo::RealType Ty = getTargetInfo().getRealTypeByWidth(DestWidth); 8049263508Sdim switch (Ty) { 8050263508Sdim case TargetInfo::Float: 8051263508Sdim return FloatTy; 8052263508Sdim case TargetInfo::Double: 8053263508Sdim return DoubleTy; 8054263508Sdim case TargetInfo::LongDouble: 8055263508Sdim return LongDoubleTy; 8056263508Sdim case TargetInfo::NoFloat: 8057263508Sdim return QualType(); 8058263508Sdim } 8059263508Sdim 8060263508Sdim llvm_unreachable("Unhandled TargetInfo::RealType value"); 8061249423Sdim} 8062249423Sdim 8063263508Sdimvoid ASTContext::setManglingNumber(const NamedDecl *ND, unsigned Number) { 8064263508Sdim if (Number > 1) 8065263508Sdim MangleNumbers[ND] = Number; 8066249423Sdim} 8067249423Sdim 8068263508Sdimunsigned ASTContext::getManglingNumber(const NamedDecl *ND) const { 8069263508Sdim llvm::DenseMap<const NamedDecl *, unsigned>::const_iterator I = 8070263508Sdim MangleNumbers.find(ND); 8071263508Sdim return I != MangleNumbers.end() ? I->second : 1; 8072234353Sdim} 8073234353Sdim 8074263508SdimMangleNumberingContext & 8075263508SdimASTContext::getManglingNumberContext(const DeclContext *DC) { 8076263508Sdim assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C. 8077263508Sdim MangleNumberingContext *&MCtx = MangleNumberingContexts[DC]; 8078263508Sdim if (!MCtx) 8079263508Sdim MCtx = createMangleNumberingContext(); 8080263508Sdim return *MCtx; 8081263508Sdim} 8082234353Sdim 8083263508SdimMangleNumberingContext *ASTContext::createMangleNumberingContext() const { 8084263508Sdim return ABI->createMangleNumberingContext(); 8085263508Sdim} 8086263508Sdim 8087226633Sdimvoid ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) { 8088226633Sdim ParamIndices[D] = index; 8089226633Sdim} 8090226633Sdim 8091226633Sdimunsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const { 8092226633Sdim ParameterIndexTable::const_iterator I = ParamIndices.find(D); 8093226633Sdim assert(I != ParamIndices.end() && 8094226633Sdim "ParmIndices lacks entry set by ParmVarDecl"); 8095226633Sdim return I->second; 8096226633Sdim} 8097263508Sdim 8098263508SdimAPValue * 8099263508SdimASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, 8100263508Sdim bool MayCreate) { 8101263508Sdim assert(E && E->getStorageDuration() == SD_Static && 8102263508Sdim "don't need to cache the computed value for this temporary"); 8103263508Sdim if (MayCreate) 8104263508Sdim return &MaterializedTemporaryValues[E]; 8105263508Sdim 8106263508Sdim llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I = 8107263508Sdim MaterializedTemporaryValues.find(E); 8108263508Sdim return I == MaterializedTemporaryValues.end() ? 0 : &I->second; 8109263508Sdim} 8110263508Sdim 8111263508Sdimbool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { 8112263508Sdim const llvm::Triple &T = getTargetInfo().getTriple(); 8113263508Sdim if (!T.isOSDarwin()) 8114263508Sdim return false; 8115263508Sdim 8116263508Sdim if (!(T.isiOS() && T.isOSVersionLT(7)) && 8117263508Sdim !(T.isMacOSX() && T.isOSVersionLT(10, 9))) 8118263508Sdim return false; 8119263508Sdim 8120263508Sdim QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); 8121263508Sdim CharUnits sizeChars = getTypeSizeInChars(AtomicTy); 8122263508Sdim uint64_t Size = sizeChars.getQuantity(); 8123263508Sdim CharUnits alignChars = getTypeAlignInChars(AtomicTy); 8124263508Sdim unsigned Align = alignChars.getQuantity(); 8125263508Sdim unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth(); 8126263508Sdim return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits); 8127263508Sdim} 8128263508Sdim 8129263508Sdimnamespace { 8130263508Sdim 8131263508Sdim /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their 8132263508Sdim /// parents as defined by the \c RecursiveASTVisitor. 8133263508Sdim /// 8134263508Sdim /// Note that the relationship described here is purely in terms of AST 8135263508Sdim /// traversal - there are other relationships (for example declaration context) 8136263508Sdim /// in the AST that are better modeled by special matchers. 8137263508Sdim /// 8138263508Sdim /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes. 8139263508Sdim class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> { 8140263508Sdim 8141263508Sdim public: 8142263508Sdim /// \brief Builds and returns the translation unit's parent map. 8143263508Sdim /// 8144263508Sdim /// The caller takes ownership of the returned \c ParentMap. 8145263508Sdim static ASTContext::ParentMap *buildMap(TranslationUnitDecl &TU) { 8146263508Sdim ParentMapASTVisitor Visitor(new ASTContext::ParentMap); 8147263508Sdim Visitor.TraverseDecl(&TU); 8148263508Sdim return Visitor.Parents; 8149263508Sdim } 8150263508Sdim 8151263508Sdim private: 8152263508Sdim typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase; 8153263508Sdim 8154263508Sdim ParentMapASTVisitor(ASTContext::ParentMap *Parents) : Parents(Parents) { 8155263508Sdim } 8156263508Sdim 8157263508Sdim bool shouldVisitTemplateInstantiations() const { 8158263508Sdim return true; 8159263508Sdim } 8160263508Sdim bool shouldVisitImplicitCode() const { 8161263508Sdim return true; 8162263508Sdim } 8163263508Sdim // Disables data recursion. We intercept Traverse* methods in the RAV, which 8164263508Sdim // are not triggered during data recursion. 8165263508Sdim bool shouldUseDataRecursionFor(clang::Stmt *S) const { 8166263508Sdim return false; 8167263508Sdim } 8168263508Sdim 8169263508Sdim template <typename T> 8170263508Sdim bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { 8171263508Sdim if (Node == NULL) 8172263508Sdim return true; 8173263508Sdim if (ParentStack.size() > 0) 8174263508Sdim // FIXME: Currently we add the same parent multiple times, for example 8175263508Sdim // when we visit all subexpressions of template instantiations; this is 8176263508Sdim // suboptimal, bug benign: the only way to visit those is with 8177263508Sdim // hasAncestor / hasParent, and those do not create new matches. 8178263508Sdim // The plan is to enable DynTypedNode to be storable in a map or hash 8179263508Sdim // map. The main problem there is to implement hash functions / 8180263508Sdim // comparison operators for all types that DynTypedNode supports that 8181263508Sdim // do not have pointer identity. 8182263508Sdim (*Parents)[Node].push_back(ParentStack.back()); 8183263508Sdim ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); 8184263508Sdim bool Result = (this ->* traverse) (Node); 8185263508Sdim ParentStack.pop_back(); 8186263508Sdim return Result; 8187263508Sdim } 8188263508Sdim 8189263508Sdim bool TraverseDecl(Decl *DeclNode) { 8190263508Sdim return TraverseNode(DeclNode, &VisitorBase::TraverseDecl); 8191263508Sdim } 8192263508Sdim 8193263508Sdim bool TraverseStmt(Stmt *StmtNode) { 8194263508Sdim return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); 8195263508Sdim } 8196263508Sdim 8197263508Sdim ASTContext::ParentMap *Parents; 8198263508Sdim llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; 8199263508Sdim 8200263508Sdim friend class RecursiveASTVisitor<ParentMapASTVisitor>; 8201263508Sdim }; 8202263508Sdim 8203263508Sdim} // end namespace 8204263508Sdim 8205263508SdimASTContext::ParentVector 8206263508SdimASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { 8207263508Sdim assert(Node.getMemoizationData() && 8208263508Sdim "Invariant broken: only nodes that support memoization may be " 8209263508Sdim "used in the parent map."); 8210263508Sdim if (!AllParents) { 8211263508Sdim // We always need to run over the whole translation unit, as 8212263508Sdim // hasAncestor can escape any subtree. 8213263508Sdim AllParents.reset( 8214263508Sdim ParentMapASTVisitor::buildMap(*getTranslationUnitDecl())); 8215263508Sdim } 8216263508Sdim ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData()); 8217263508Sdim if (I == AllParents->end()) { 8218263508Sdim return ParentVector(); 8219263508Sdim } 8220263508Sdim return I->second; 8221263508Sdim} 8222263508Sdim 8223263508Sdimbool 8224263508SdimASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, 8225263508Sdim const ObjCMethodDecl *MethodImpl) { 8226263508Sdim // No point trying to match an unavailable/deprecated mothod. 8227263508Sdim if (MethodDecl->hasAttr<UnavailableAttr>() 8228263508Sdim || MethodDecl->hasAttr<DeprecatedAttr>()) 8229263508Sdim return false; 8230263508Sdim if (MethodDecl->getObjCDeclQualifier() != 8231263508Sdim MethodImpl->getObjCDeclQualifier()) 8232263508Sdim return false; 8233263508Sdim if (!hasSameType(MethodDecl->getResultType(), 8234263508Sdim MethodImpl->getResultType())) 8235263508Sdim return false; 8236263508Sdim 8237263508Sdim if (MethodDecl->param_size() != MethodImpl->param_size()) 8238263508Sdim return false; 8239263508Sdim 8240263508Sdim for (ObjCMethodDecl::param_const_iterator IM = MethodImpl->param_begin(), 8241263508Sdim IF = MethodDecl->param_begin(), EM = MethodImpl->param_end(), 8242263508Sdim EF = MethodDecl->param_end(); 8243263508Sdim IM != EM && IF != EF; ++IM, ++IF) { 8244263508Sdim const ParmVarDecl *DeclVar = (*IF); 8245263508Sdim const ParmVarDecl *ImplVar = (*IM); 8246263508Sdim if (ImplVar->getObjCDeclQualifier() != DeclVar->getObjCDeclQualifier()) 8247263508Sdim return false; 8248263508Sdim if (!hasSameType(DeclVar->getType(), ImplVar->getType())) 8249263508Sdim return false; 8250263508Sdim } 8251263508Sdim return (MethodDecl->isVariadic() == MethodImpl->isVariadic()); 8252263508Sdim 8253263508Sdim} 8254