1*f4a2713aSLionel Sambuc //===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file implements the Decl and DeclContext classes. 11*f4a2713aSLionel Sambuc // 12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc #include "clang/AST/DeclBase.h" 15*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h" 16*f4a2713aSLionel Sambuc #include "clang/AST/ASTMutationListener.h" 17*f4a2713aSLionel Sambuc #include "clang/AST/Attr.h" 18*f4a2713aSLionel Sambuc #include "clang/AST/Decl.h" 19*f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h" 20*f4a2713aSLionel Sambuc #include "clang/AST/DeclContextInternals.h" 21*f4a2713aSLionel Sambuc #include "clang/AST/DeclFriend.h" 22*f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h" 23*f4a2713aSLionel Sambuc #include "clang/AST/DeclOpenMP.h" 24*f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h" 25*f4a2713aSLionel Sambuc #include "clang/AST/DependentDiagnostic.h" 26*f4a2713aSLionel Sambuc #include "clang/AST/ExternalASTSource.h" 27*f4a2713aSLionel Sambuc #include "clang/AST/Stmt.h" 28*f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h" 29*f4a2713aSLionel Sambuc #include "clang/AST/Type.h" 30*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 31*f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h" 32*f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h" 33*f4a2713aSLionel Sambuc #include <algorithm> 34*f4a2713aSLionel Sambuc using namespace clang; 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 37*f4a2713aSLionel Sambuc // Statistics 38*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 39*f4a2713aSLionel Sambuc 40*f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) static int n##DERIVED##s = 0; 41*f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL) 42*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 43*f4a2713aSLionel Sambuc 44*f4a2713aSLionel Sambuc void Decl::updateOutOfDate(IdentifierInfo &II) const { 45*f4a2713aSLionel Sambuc getASTContext().getExternalSource()->updateOutOfDateIdentifier(II); 46*f4a2713aSLionel Sambuc } 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc void *Decl::AllocateDeserializedDecl(const ASTContext &Context, 49*f4a2713aSLionel Sambuc unsigned ID, 50*f4a2713aSLionel Sambuc unsigned Size) { 51*f4a2713aSLionel Sambuc // Allocate an extra 8 bytes worth of storage, which ensures that the 52*f4a2713aSLionel Sambuc // resulting pointer will still be 8-byte aligned. 53*f4a2713aSLionel Sambuc void *Start = Context.Allocate(Size + 8); 54*f4a2713aSLionel Sambuc void *Result = (char*)Start + 8; 55*f4a2713aSLionel Sambuc 56*f4a2713aSLionel Sambuc unsigned *PrefixPtr = (unsigned *)Result - 2; 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc // Zero out the first 4 bytes; this is used to store the owning module ID. 59*f4a2713aSLionel Sambuc PrefixPtr[0] = 0; 60*f4a2713aSLionel Sambuc 61*f4a2713aSLionel Sambuc // Store the global declaration ID in the second 4 bytes. 62*f4a2713aSLionel Sambuc PrefixPtr[1] = ID; 63*f4a2713aSLionel Sambuc 64*f4a2713aSLionel Sambuc return Result; 65*f4a2713aSLionel Sambuc } 66*f4a2713aSLionel Sambuc 67*f4a2713aSLionel Sambuc Module *Decl::getOwningModuleSlow() const { 68*f4a2713aSLionel Sambuc assert(isFromASTFile() && "Not from AST file?"); 69*f4a2713aSLionel Sambuc return getASTContext().getExternalSource()->getModule(getOwningModuleID()); 70*f4a2713aSLionel Sambuc } 71*f4a2713aSLionel Sambuc 72*f4a2713aSLionel Sambuc const char *Decl::getDeclKindName() const { 73*f4a2713aSLionel Sambuc switch (DeclKind) { 74*f4a2713aSLionel Sambuc default: llvm_unreachable("Declaration not in DeclNodes.inc!"); 75*f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) case DERIVED: return #DERIVED; 76*f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL) 77*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 78*f4a2713aSLionel Sambuc } 79*f4a2713aSLionel Sambuc } 80*f4a2713aSLionel Sambuc 81*f4a2713aSLionel Sambuc void Decl::setInvalidDecl(bool Invalid) { 82*f4a2713aSLionel Sambuc InvalidDecl = Invalid; 83*f4a2713aSLionel Sambuc if (Invalid && !isa<ParmVarDecl>(this)) { 84*f4a2713aSLionel Sambuc // Defensive maneuver for ill-formed code: we're likely not to make it to 85*f4a2713aSLionel Sambuc // a point where we set the access specifier, so default it to "public" 86*f4a2713aSLionel Sambuc // to avoid triggering asserts elsewhere in the front end. 87*f4a2713aSLionel Sambuc setAccess(AS_public); 88*f4a2713aSLionel Sambuc } 89*f4a2713aSLionel Sambuc } 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambuc const char *DeclContext::getDeclKindName() const { 92*f4a2713aSLionel Sambuc switch (DeclKind) { 93*f4a2713aSLionel Sambuc default: llvm_unreachable("Declaration context not in DeclNodes.inc!"); 94*f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; 95*f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL) 96*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 97*f4a2713aSLionel Sambuc } 98*f4a2713aSLionel Sambuc } 99*f4a2713aSLionel Sambuc 100*f4a2713aSLionel Sambuc bool Decl::StatisticsEnabled = false; 101*f4a2713aSLionel Sambuc void Decl::EnableStatistics() { 102*f4a2713aSLionel Sambuc StatisticsEnabled = true; 103*f4a2713aSLionel Sambuc } 104*f4a2713aSLionel Sambuc 105*f4a2713aSLionel Sambuc void Decl::PrintStats() { 106*f4a2713aSLionel Sambuc llvm::errs() << "\n*** Decl Stats:\n"; 107*f4a2713aSLionel Sambuc 108*f4a2713aSLionel Sambuc int totalDecls = 0; 109*f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s; 110*f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL) 111*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 112*f4a2713aSLionel Sambuc llvm::errs() << " " << totalDecls << " decls total.\n"; 113*f4a2713aSLionel Sambuc 114*f4a2713aSLionel Sambuc int totalBytes = 0; 115*f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) \ 116*f4a2713aSLionel Sambuc if (n##DERIVED##s > 0) { \ 117*f4a2713aSLionel Sambuc totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \ 118*f4a2713aSLionel Sambuc llvm::errs() << " " << n##DERIVED##s << " " #DERIVED " decls, " \ 119*f4a2713aSLionel Sambuc << sizeof(DERIVED##Decl) << " each (" \ 120*f4a2713aSLionel Sambuc << n##DERIVED##s * sizeof(DERIVED##Decl) \ 121*f4a2713aSLionel Sambuc << " bytes)\n"; \ 122*f4a2713aSLionel Sambuc } 123*f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL) 124*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 125*f4a2713aSLionel Sambuc 126*f4a2713aSLionel Sambuc llvm::errs() << "Total bytes = " << totalBytes << "\n"; 127*f4a2713aSLionel Sambuc } 128*f4a2713aSLionel Sambuc 129*f4a2713aSLionel Sambuc void Decl::add(Kind k) { 130*f4a2713aSLionel Sambuc switch (k) { 131*f4a2713aSLionel Sambuc #define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break; 132*f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL) 133*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 134*f4a2713aSLionel Sambuc } 135*f4a2713aSLionel Sambuc } 136*f4a2713aSLionel Sambuc 137*f4a2713aSLionel Sambuc bool Decl::isTemplateParameterPack() const { 138*f4a2713aSLionel Sambuc if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this)) 139*f4a2713aSLionel Sambuc return TTP->isParameterPack(); 140*f4a2713aSLionel Sambuc if (const NonTypeTemplateParmDecl *NTTP 141*f4a2713aSLionel Sambuc = dyn_cast<NonTypeTemplateParmDecl>(this)) 142*f4a2713aSLionel Sambuc return NTTP->isParameterPack(); 143*f4a2713aSLionel Sambuc if (const TemplateTemplateParmDecl *TTP 144*f4a2713aSLionel Sambuc = dyn_cast<TemplateTemplateParmDecl>(this)) 145*f4a2713aSLionel Sambuc return TTP->isParameterPack(); 146*f4a2713aSLionel Sambuc return false; 147*f4a2713aSLionel Sambuc } 148*f4a2713aSLionel Sambuc 149*f4a2713aSLionel Sambuc bool Decl::isParameterPack() const { 150*f4a2713aSLionel Sambuc if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(this)) 151*f4a2713aSLionel Sambuc return Parm->isParameterPack(); 152*f4a2713aSLionel Sambuc 153*f4a2713aSLionel Sambuc return isTemplateParameterPack(); 154*f4a2713aSLionel Sambuc } 155*f4a2713aSLionel Sambuc 156*f4a2713aSLionel Sambuc bool Decl::isFunctionOrFunctionTemplate() const { 157*f4a2713aSLionel Sambuc if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this)) 158*f4a2713aSLionel Sambuc return UD->getTargetDecl()->isFunctionOrFunctionTemplate(); 159*f4a2713aSLionel Sambuc 160*f4a2713aSLionel Sambuc return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this); 161*f4a2713aSLionel Sambuc } 162*f4a2713aSLionel Sambuc 163*f4a2713aSLionel Sambuc bool Decl::isTemplateDecl() const { 164*f4a2713aSLionel Sambuc return isa<TemplateDecl>(this); 165*f4a2713aSLionel Sambuc } 166*f4a2713aSLionel Sambuc 167*f4a2713aSLionel Sambuc const DeclContext *Decl::getParentFunctionOrMethod() const { 168*f4a2713aSLionel Sambuc for (const DeclContext *DC = getDeclContext(); 169*f4a2713aSLionel Sambuc DC && !DC->isTranslationUnit() && !DC->isNamespace(); 170*f4a2713aSLionel Sambuc DC = DC->getParent()) 171*f4a2713aSLionel Sambuc if (DC->isFunctionOrMethod()) 172*f4a2713aSLionel Sambuc return DC; 173*f4a2713aSLionel Sambuc 174*f4a2713aSLionel Sambuc return 0; 175*f4a2713aSLionel Sambuc } 176*f4a2713aSLionel Sambuc 177*f4a2713aSLionel Sambuc 178*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 179*f4a2713aSLionel Sambuc // PrettyStackTraceDecl Implementation 180*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 181*f4a2713aSLionel Sambuc 182*f4a2713aSLionel Sambuc void PrettyStackTraceDecl::print(raw_ostream &OS) const { 183*f4a2713aSLionel Sambuc SourceLocation TheLoc = Loc; 184*f4a2713aSLionel Sambuc if (TheLoc.isInvalid() && TheDecl) 185*f4a2713aSLionel Sambuc TheLoc = TheDecl->getLocation(); 186*f4a2713aSLionel Sambuc 187*f4a2713aSLionel Sambuc if (TheLoc.isValid()) { 188*f4a2713aSLionel Sambuc TheLoc.print(OS, SM); 189*f4a2713aSLionel Sambuc OS << ": "; 190*f4a2713aSLionel Sambuc } 191*f4a2713aSLionel Sambuc 192*f4a2713aSLionel Sambuc OS << Message; 193*f4a2713aSLionel Sambuc 194*f4a2713aSLionel Sambuc if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl)) { 195*f4a2713aSLionel Sambuc OS << " '"; 196*f4a2713aSLionel Sambuc DN->printQualifiedName(OS); 197*f4a2713aSLionel Sambuc OS << '\''; 198*f4a2713aSLionel Sambuc } 199*f4a2713aSLionel Sambuc OS << '\n'; 200*f4a2713aSLionel Sambuc } 201*f4a2713aSLionel Sambuc 202*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 203*f4a2713aSLionel Sambuc // Decl Implementation 204*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 205*f4a2713aSLionel Sambuc 206*f4a2713aSLionel Sambuc // Out-of-line virtual method providing a home for Decl. 207*f4a2713aSLionel Sambuc Decl::~Decl() { } 208*f4a2713aSLionel Sambuc 209*f4a2713aSLionel Sambuc void Decl::setDeclContext(DeclContext *DC) { 210*f4a2713aSLionel Sambuc DeclCtx = DC; 211*f4a2713aSLionel Sambuc } 212*f4a2713aSLionel Sambuc 213*f4a2713aSLionel Sambuc void Decl::setLexicalDeclContext(DeclContext *DC) { 214*f4a2713aSLionel Sambuc if (DC == getLexicalDeclContext()) 215*f4a2713aSLionel Sambuc return; 216*f4a2713aSLionel Sambuc 217*f4a2713aSLionel Sambuc if (isInSemaDC()) { 218*f4a2713aSLionel Sambuc setDeclContextsImpl(getDeclContext(), DC, getASTContext()); 219*f4a2713aSLionel Sambuc } else { 220*f4a2713aSLionel Sambuc getMultipleDC()->LexicalDC = DC; 221*f4a2713aSLionel Sambuc } 222*f4a2713aSLionel Sambuc } 223*f4a2713aSLionel Sambuc 224*f4a2713aSLionel Sambuc void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, 225*f4a2713aSLionel Sambuc ASTContext &Ctx) { 226*f4a2713aSLionel Sambuc if (SemaDC == LexicalDC) { 227*f4a2713aSLionel Sambuc DeclCtx = SemaDC; 228*f4a2713aSLionel Sambuc } else { 229*f4a2713aSLionel Sambuc Decl::MultipleDC *MDC = new (Ctx) Decl::MultipleDC(); 230*f4a2713aSLionel Sambuc MDC->SemanticDC = SemaDC; 231*f4a2713aSLionel Sambuc MDC->LexicalDC = LexicalDC; 232*f4a2713aSLionel Sambuc DeclCtx = MDC; 233*f4a2713aSLionel Sambuc } 234*f4a2713aSLionel Sambuc } 235*f4a2713aSLionel Sambuc 236*f4a2713aSLionel Sambuc bool Decl::isInAnonymousNamespace() const { 237*f4a2713aSLionel Sambuc const DeclContext *DC = getDeclContext(); 238*f4a2713aSLionel Sambuc do { 239*f4a2713aSLionel Sambuc if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) 240*f4a2713aSLionel Sambuc if (ND->isAnonymousNamespace()) 241*f4a2713aSLionel Sambuc return true; 242*f4a2713aSLionel Sambuc } while ((DC = DC->getParent())); 243*f4a2713aSLionel Sambuc 244*f4a2713aSLionel Sambuc return false; 245*f4a2713aSLionel Sambuc } 246*f4a2713aSLionel Sambuc 247*f4a2713aSLionel Sambuc TranslationUnitDecl *Decl::getTranslationUnitDecl() { 248*f4a2713aSLionel Sambuc if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this)) 249*f4a2713aSLionel Sambuc return TUD; 250*f4a2713aSLionel Sambuc 251*f4a2713aSLionel Sambuc DeclContext *DC = getDeclContext(); 252*f4a2713aSLionel Sambuc assert(DC && "This decl is not contained in a translation unit!"); 253*f4a2713aSLionel Sambuc 254*f4a2713aSLionel Sambuc while (!DC->isTranslationUnit()) { 255*f4a2713aSLionel Sambuc DC = DC->getParent(); 256*f4a2713aSLionel Sambuc assert(DC && "This decl is not contained in a translation unit!"); 257*f4a2713aSLionel Sambuc } 258*f4a2713aSLionel Sambuc 259*f4a2713aSLionel Sambuc return cast<TranslationUnitDecl>(DC); 260*f4a2713aSLionel Sambuc } 261*f4a2713aSLionel Sambuc 262*f4a2713aSLionel Sambuc ASTContext &Decl::getASTContext() const { 263*f4a2713aSLionel Sambuc return getTranslationUnitDecl()->getASTContext(); 264*f4a2713aSLionel Sambuc } 265*f4a2713aSLionel Sambuc 266*f4a2713aSLionel Sambuc ASTMutationListener *Decl::getASTMutationListener() const { 267*f4a2713aSLionel Sambuc return getASTContext().getASTMutationListener(); 268*f4a2713aSLionel Sambuc } 269*f4a2713aSLionel Sambuc 270*f4a2713aSLionel Sambuc unsigned Decl::getMaxAlignment() const { 271*f4a2713aSLionel Sambuc if (!hasAttrs()) 272*f4a2713aSLionel Sambuc return 0; 273*f4a2713aSLionel Sambuc 274*f4a2713aSLionel Sambuc unsigned Align = 0; 275*f4a2713aSLionel Sambuc const AttrVec &V = getAttrs(); 276*f4a2713aSLionel Sambuc ASTContext &Ctx = getASTContext(); 277*f4a2713aSLionel Sambuc specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end()); 278*f4a2713aSLionel Sambuc for (; I != E; ++I) 279*f4a2713aSLionel Sambuc Align = std::max(Align, I->getAlignment(Ctx)); 280*f4a2713aSLionel Sambuc return Align; 281*f4a2713aSLionel Sambuc } 282*f4a2713aSLionel Sambuc 283*f4a2713aSLionel Sambuc bool Decl::isUsed(bool CheckUsedAttr) const { 284*f4a2713aSLionel Sambuc if (Used) 285*f4a2713aSLionel Sambuc return true; 286*f4a2713aSLionel Sambuc 287*f4a2713aSLionel Sambuc // Check for used attribute. 288*f4a2713aSLionel Sambuc if (CheckUsedAttr && hasAttr<UsedAttr>()) 289*f4a2713aSLionel Sambuc return true; 290*f4a2713aSLionel Sambuc 291*f4a2713aSLionel Sambuc return false; 292*f4a2713aSLionel Sambuc } 293*f4a2713aSLionel Sambuc 294*f4a2713aSLionel Sambuc void Decl::markUsed(ASTContext &C) { 295*f4a2713aSLionel Sambuc if (Used) 296*f4a2713aSLionel Sambuc return; 297*f4a2713aSLionel Sambuc 298*f4a2713aSLionel Sambuc if (C.getASTMutationListener()) 299*f4a2713aSLionel Sambuc C.getASTMutationListener()->DeclarationMarkedUsed(this); 300*f4a2713aSLionel Sambuc 301*f4a2713aSLionel Sambuc Used = true; 302*f4a2713aSLionel Sambuc } 303*f4a2713aSLionel Sambuc 304*f4a2713aSLionel Sambuc bool Decl::isReferenced() const { 305*f4a2713aSLionel Sambuc if (Referenced) 306*f4a2713aSLionel Sambuc return true; 307*f4a2713aSLionel Sambuc 308*f4a2713aSLionel Sambuc // Check redeclarations. 309*f4a2713aSLionel Sambuc for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) 310*f4a2713aSLionel Sambuc if (I->Referenced) 311*f4a2713aSLionel Sambuc return true; 312*f4a2713aSLionel Sambuc 313*f4a2713aSLionel Sambuc return false; 314*f4a2713aSLionel Sambuc } 315*f4a2713aSLionel Sambuc 316*f4a2713aSLionel Sambuc /// \brief Determine the availability of the given declaration based on 317*f4a2713aSLionel Sambuc /// the target platform. 318*f4a2713aSLionel Sambuc /// 319*f4a2713aSLionel Sambuc /// When it returns an availability result other than \c AR_Available, 320*f4a2713aSLionel Sambuc /// if the \p Message parameter is non-NULL, it will be set to a 321*f4a2713aSLionel Sambuc /// string describing why the entity is unavailable. 322*f4a2713aSLionel Sambuc /// 323*f4a2713aSLionel Sambuc /// FIXME: Make these strings localizable, since they end up in 324*f4a2713aSLionel Sambuc /// diagnostics. 325*f4a2713aSLionel Sambuc static AvailabilityResult CheckAvailability(ASTContext &Context, 326*f4a2713aSLionel Sambuc const AvailabilityAttr *A, 327*f4a2713aSLionel Sambuc std::string *Message) { 328*f4a2713aSLionel Sambuc StringRef TargetPlatform = Context.getTargetInfo().getPlatformName(); 329*f4a2713aSLionel Sambuc StringRef PrettyPlatformName 330*f4a2713aSLionel Sambuc = AvailabilityAttr::getPrettyPlatformName(TargetPlatform); 331*f4a2713aSLionel Sambuc if (PrettyPlatformName.empty()) 332*f4a2713aSLionel Sambuc PrettyPlatformName = TargetPlatform; 333*f4a2713aSLionel Sambuc 334*f4a2713aSLionel Sambuc VersionTuple TargetMinVersion = Context.getTargetInfo().getPlatformMinVersion(); 335*f4a2713aSLionel Sambuc if (TargetMinVersion.empty()) 336*f4a2713aSLionel Sambuc return AR_Available; 337*f4a2713aSLionel Sambuc 338*f4a2713aSLionel Sambuc // Match the platform name. 339*f4a2713aSLionel Sambuc if (A->getPlatform()->getName() != TargetPlatform) 340*f4a2713aSLionel Sambuc return AR_Available; 341*f4a2713aSLionel Sambuc 342*f4a2713aSLionel Sambuc std::string HintMessage; 343*f4a2713aSLionel Sambuc if (!A->getMessage().empty()) { 344*f4a2713aSLionel Sambuc HintMessage = " - "; 345*f4a2713aSLionel Sambuc HintMessage += A->getMessage(); 346*f4a2713aSLionel Sambuc } 347*f4a2713aSLionel Sambuc 348*f4a2713aSLionel Sambuc // Make sure that this declaration has not been marked 'unavailable'. 349*f4a2713aSLionel Sambuc if (A->getUnavailable()) { 350*f4a2713aSLionel Sambuc if (Message) { 351*f4a2713aSLionel Sambuc Message->clear(); 352*f4a2713aSLionel Sambuc llvm::raw_string_ostream Out(*Message); 353*f4a2713aSLionel Sambuc Out << "not available on " << PrettyPlatformName 354*f4a2713aSLionel Sambuc << HintMessage; 355*f4a2713aSLionel Sambuc } 356*f4a2713aSLionel Sambuc 357*f4a2713aSLionel Sambuc return AR_Unavailable; 358*f4a2713aSLionel Sambuc } 359*f4a2713aSLionel Sambuc 360*f4a2713aSLionel Sambuc // Make sure that this declaration has already been introduced. 361*f4a2713aSLionel Sambuc if (!A->getIntroduced().empty() && 362*f4a2713aSLionel Sambuc TargetMinVersion < A->getIntroduced()) { 363*f4a2713aSLionel Sambuc if (Message) { 364*f4a2713aSLionel Sambuc Message->clear(); 365*f4a2713aSLionel Sambuc llvm::raw_string_ostream Out(*Message); 366*f4a2713aSLionel Sambuc Out << "introduced in " << PrettyPlatformName << ' ' 367*f4a2713aSLionel Sambuc << A->getIntroduced() << HintMessage; 368*f4a2713aSLionel Sambuc } 369*f4a2713aSLionel Sambuc 370*f4a2713aSLionel Sambuc return AR_NotYetIntroduced; 371*f4a2713aSLionel Sambuc } 372*f4a2713aSLionel Sambuc 373*f4a2713aSLionel Sambuc // Make sure that this declaration hasn't been obsoleted. 374*f4a2713aSLionel Sambuc if (!A->getObsoleted().empty() && TargetMinVersion >= A->getObsoleted()) { 375*f4a2713aSLionel Sambuc if (Message) { 376*f4a2713aSLionel Sambuc Message->clear(); 377*f4a2713aSLionel Sambuc llvm::raw_string_ostream Out(*Message); 378*f4a2713aSLionel Sambuc Out << "obsoleted in " << PrettyPlatformName << ' ' 379*f4a2713aSLionel Sambuc << A->getObsoleted() << HintMessage; 380*f4a2713aSLionel Sambuc } 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambuc return AR_Unavailable; 383*f4a2713aSLionel Sambuc } 384*f4a2713aSLionel Sambuc 385*f4a2713aSLionel Sambuc // Make sure that this declaration hasn't been deprecated. 386*f4a2713aSLionel Sambuc if (!A->getDeprecated().empty() && TargetMinVersion >= A->getDeprecated()) { 387*f4a2713aSLionel Sambuc if (Message) { 388*f4a2713aSLionel Sambuc Message->clear(); 389*f4a2713aSLionel Sambuc llvm::raw_string_ostream Out(*Message); 390*f4a2713aSLionel Sambuc Out << "first deprecated in " << PrettyPlatformName << ' ' 391*f4a2713aSLionel Sambuc << A->getDeprecated() << HintMessage; 392*f4a2713aSLionel Sambuc } 393*f4a2713aSLionel Sambuc 394*f4a2713aSLionel Sambuc return AR_Deprecated; 395*f4a2713aSLionel Sambuc } 396*f4a2713aSLionel Sambuc 397*f4a2713aSLionel Sambuc return AR_Available; 398*f4a2713aSLionel Sambuc } 399*f4a2713aSLionel Sambuc 400*f4a2713aSLionel Sambuc AvailabilityResult Decl::getAvailability(std::string *Message) const { 401*f4a2713aSLionel Sambuc AvailabilityResult Result = AR_Available; 402*f4a2713aSLionel Sambuc std::string ResultMessage; 403*f4a2713aSLionel Sambuc 404*f4a2713aSLionel Sambuc for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) { 405*f4a2713aSLionel Sambuc if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) { 406*f4a2713aSLionel Sambuc if (Result >= AR_Deprecated) 407*f4a2713aSLionel Sambuc continue; 408*f4a2713aSLionel Sambuc 409*f4a2713aSLionel Sambuc if (Message) 410*f4a2713aSLionel Sambuc ResultMessage = Deprecated->getMessage(); 411*f4a2713aSLionel Sambuc 412*f4a2713aSLionel Sambuc Result = AR_Deprecated; 413*f4a2713aSLionel Sambuc continue; 414*f4a2713aSLionel Sambuc } 415*f4a2713aSLionel Sambuc 416*f4a2713aSLionel Sambuc if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) { 417*f4a2713aSLionel Sambuc if (Message) 418*f4a2713aSLionel Sambuc *Message = Unavailable->getMessage(); 419*f4a2713aSLionel Sambuc return AR_Unavailable; 420*f4a2713aSLionel Sambuc } 421*f4a2713aSLionel Sambuc 422*f4a2713aSLionel Sambuc if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) { 423*f4a2713aSLionel Sambuc AvailabilityResult AR = CheckAvailability(getASTContext(), Availability, 424*f4a2713aSLionel Sambuc Message); 425*f4a2713aSLionel Sambuc 426*f4a2713aSLionel Sambuc if (AR == AR_Unavailable) 427*f4a2713aSLionel Sambuc return AR_Unavailable; 428*f4a2713aSLionel Sambuc 429*f4a2713aSLionel Sambuc if (AR > Result) { 430*f4a2713aSLionel Sambuc Result = AR; 431*f4a2713aSLionel Sambuc if (Message) 432*f4a2713aSLionel Sambuc ResultMessage.swap(*Message); 433*f4a2713aSLionel Sambuc } 434*f4a2713aSLionel Sambuc continue; 435*f4a2713aSLionel Sambuc } 436*f4a2713aSLionel Sambuc } 437*f4a2713aSLionel Sambuc 438*f4a2713aSLionel Sambuc if (Message) 439*f4a2713aSLionel Sambuc Message->swap(ResultMessage); 440*f4a2713aSLionel Sambuc return Result; 441*f4a2713aSLionel Sambuc } 442*f4a2713aSLionel Sambuc 443*f4a2713aSLionel Sambuc bool Decl::canBeWeakImported(bool &IsDefinition) const { 444*f4a2713aSLionel Sambuc IsDefinition = false; 445*f4a2713aSLionel Sambuc 446*f4a2713aSLionel Sambuc // Variables, if they aren't definitions. 447*f4a2713aSLionel Sambuc if (const VarDecl *Var = dyn_cast<VarDecl>(this)) { 448*f4a2713aSLionel Sambuc if (Var->isThisDeclarationADefinition()) { 449*f4a2713aSLionel Sambuc IsDefinition = true; 450*f4a2713aSLionel Sambuc return false; 451*f4a2713aSLionel Sambuc } 452*f4a2713aSLionel Sambuc return true; 453*f4a2713aSLionel Sambuc 454*f4a2713aSLionel Sambuc // Functions, if they aren't definitions. 455*f4a2713aSLionel Sambuc } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) { 456*f4a2713aSLionel Sambuc if (FD->hasBody()) { 457*f4a2713aSLionel Sambuc IsDefinition = true; 458*f4a2713aSLionel Sambuc return false; 459*f4a2713aSLionel Sambuc } 460*f4a2713aSLionel Sambuc return true; 461*f4a2713aSLionel Sambuc 462*f4a2713aSLionel Sambuc // Objective-C classes, if this is the non-fragile runtime. 463*f4a2713aSLionel Sambuc } else if (isa<ObjCInterfaceDecl>(this) && 464*f4a2713aSLionel Sambuc getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) { 465*f4a2713aSLionel Sambuc return true; 466*f4a2713aSLionel Sambuc 467*f4a2713aSLionel Sambuc // Nothing else. 468*f4a2713aSLionel Sambuc } else { 469*f4a2713aSLionel Sambuc return false; 470*f4a2713aSLionel Sambuc } 471*f4a2713aSLionel Sambuc } 472*f4a2713aSLionel Sambuc 473*f4a2713aSLionel Sambuc bool Decl::isWeakImported() const { 474*f4a2713aSLionel Sambuc bool IsDefinition; 475*f4a2713aSLionel Sambuc if (!canBeWeakImported(IsDefinition)) 476*f4a2713aSLionel Sambuc return false; 477*f4a2713aSLionel Sambuc 478*f4a2713aSLionel Sambuc for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) { 479*f4a2713aSLionel Sambuc if (isa<WeakImportAttr>(*A)) 480*f4a2713aSLionel Sambuc return true; 481*f4a2713aSLionel Sambuc 482*f4a2713aSLionel Sambuc if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) { 483*f4a2713aSLionel Sambuc if (CheckAvailability(getASTContext(), Availability, 0) 484*f4a2713aSLionel Sambuc == AR_NotYetIntroduced) 485*f4a2713aSLionel Sambuc return true; 486*f4a2713aSLionel Sambuc } 487*f4a2713aSLionel Sambuc } 488*f4a2713aSLionel Sambuc 489*f4a2713aSLionel Sambuc return false; 490*f4a2713aSLionel Sambuc } 491*f4a2713aSLionel Sambuc 492*f4a2713aSLionel Sambuc unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { 493*f4a2713aSLionel Sambuc switch (DeclKind) { 494*f4a2713aSLionel Sambuc case Function: 495*f4a2713aSLionel Sambuc case CXXMethod: 496*f4a2713aSLionel Sambuc case CXXConstructor: 497*f4a2713aSLionel Sambuc case CXXDestructor: 498*f4a2713aSLionel Sambuc case CXXConversion: 499*f4a2713aSLionel Sambuc case EnumConstant: 500*f4a2713aSLionel Sambuc case Var: 501*f4a2713aSLionel Sambuc case ImplicitParam: 502*f4a2713aSLionel Sambuc case ParmVar: 503*f4a2713aSLionel Sambuc case NonTypeTemplateParm: 504*f4a2713aSLionel Sambuc case ObjCMethod: 505*f4a2713aSLionel Sambuc case ObjCProperty: 506*f4a2713aSLionel Sambuc case MSProperty: 507*f4a2713aSLionel Sambuc return IDNS_Ordinary; 508*f4a2713aSLionel Sambuc case Label: 509*f4a2713aSLionel Sambuc return IDNS_Label; 510*f4a2713aSLionel Sambuc case IndirectField: 511*f4a2713aSLionel Sambuc return IDNS_Ordinary | IDNS_Member; 512*f4a2713aSLionel Sambuc 513*f4a2713aSLionel Sambuc case ObjCCompatibleAlias: 514*f4a2713aSLionel Sambuc case ObjCInterface: 515*f4a2713aSLionel Sambuc return IDNS_Ordinary | IDNS_Type; 516*f4a2713aSLionel Sambuc 517*f4a2713aSLionel Sambuc case Typedef: 518*f4a2713aSLionel Sambuc case TypeAlias: 519*f4a2713aSLionel Sambuc case TypeAliasTemplate: 520*f4a2713aSLionel Sambuc case UnresolvedUsingTypename: 521*f4a2713aSLionel Sambuc case TemplateTypeParm: 522*f4a2713aSLionel Sambuc return IDNS_Ordinary | IDNS_Type; 523*f4a2713aSLionel Sambuc 524*f4a2713aSLionel Sambuc case UsingShadow: 525*f4a2713aSLionel Sambuc return 0; // we'll actually overwrite this later 526*f4a2713aSLionel Sambuc 527*f4a2713aSLionel Sambuc case UnresolvedUsingValue: 528*f4a2713aSLionel Sambuc return IDNS_Ordinary | IDNS_Using; 529*f4a2713aSLionel Sambuc 530*f4a2713aSLionel Sambuc case Using: 531*f4a2713aSLionel Sambuc return IDNS_Using; 532*f4a2713aSLionel Sambuc 533*f4a2713aSLionel Sambuc case ObjCProtocol: 534*f4a2713aSLionel Sambuc return IDNS_ObjCProtocol; 535*f4a2713aSLionel Sambuc 536*f4a2713aSLionel Sambuc case Field: 537*f4a2713aSLionel Sambuc case ObjCAtDefsField: 538*f4a2713aSLionel Sambuc case ObjCIvar: 539*f4a2713aSLionel Sambuc return IDNS_Member; 540*f4a2713aSLionel Sambuc 541*f4a2713aSLionel Sambuc case Record: 542*f4a2713aSLionel Sambuc case CXXRecord: 543*f4a2713aSLionel Sambuc case Enum: 544*f4a2713aSLionel Sambuc return IDNS_Tag | IDNS_Type; 545*f4a2713aSLionel Sambuc 546*f4a2713aSLionel Sambuc case Namespace: 547*f4a2713aSLionel Sambuc case NamespaceAlias: 548*f4a2713aSLionel Sambuc return IDNS_Namespace; 549*f4a2713aSLionel Sambuc 550*f4a2713aSLionel Sambuc case FunctionTemplate: 551*f4a2713aSLionel Sambuc case VarTemplate: 552*f4a2713aSLionel Sambuc return IDNS_Ordinary; 553*f4a2713aSLionel Sambuc 554*f4a2713aSLionel Sambuc case ClassTemplate: 555*f4a2713aSLionel Sambuc case TemplateTemplateParm: 556*f4a2713aSLionel Sambuc return IDNS_Ordinary | IDNS_Tag | IDNS_Type; 557*f4a2713aSLionel Sambuc 558*f4a2713aSLionel Sambuc // Never have names. 559*f4a2713aSLionel Sambuc case Friend: 560*f4a2713aSLionel Sambuc case FriendTemplate: 561*f4a2713aSLionel Sambuc case AccessSpec: 562*f4a2713aSLionel Sambuc case LinkageSpec: 563*f4a2713aSLionel Sambuc case FileScopeAsm: 564*f4a2713aSLionel Sambuc case StaticAssert: 565*f4a2713aSLionel Sambuc case ObjCPropertyImpl: 566*f4a2713aSLionel Sambuc case Block: 567*f4a2713aSLionel Sambuc case Captured: 568*f4a2713aSLionel Sambuc case TranslationUnit: 569*f4a2713aSLionel Sambuc 570*f4a2713aSLionel Sambuc case UsingDirective: 571*f4a2713aSLionel Sambuc case ClassTemplateSpecialization: 572*f4a2713aSLionel Sambuc case ClassTemplatePartialSpecialization: 573*f4a2713aSLionel Sambuc case ClassScopeFunctionSpecialization: 574*f4a2713aSLionel Sambuc case VarTemplateSpecialization: 575*f4a2713aSLionel Sambuc case VarTemplatePartialSpecialization: 576*f4a2713aSLionel Sambuc case ObjCImplementation: 577*f4a2713aSLionel Sambuc case ObjCCategory: 578*f4a2713aSLionel Sambuc case ObjCCategoryImpl: 579*f4a2713aSLionel Sambuc case Import: 580*f4a2713aSLionel Sambuc case OMPThreadPrivate: 581*f4a2713aSLionel Sambuc case Empty: 582*f4a2713aSLionel Sambuc // Never looked up by name. 583*f4a2713aSLionel Sambuc return 0; 584*f4a2713aSLionel Sambuc } 585*f4a2713aSLionel Sambuc 586*f4a2713aSLionel Sambuc llvm_unreachable("Invalid DeclKind!"); 587*f4a2713aSLionel Sambuc } 588*f4a2713aSLionel Sambuc 589*f4a2713aSLionel Sambuc void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) { 590*f4a2713aSLionel Sambuc assert(!HasAttrs && "Decl already contains attrs."); 591*f4a2713aSLionel Sambuc 592*f4a2713aSLionel Sambuc AttrVec &AttrBlank = Ctx.getDeclAttrs(this); 593*f4a2713aSLionel Sambuc assert(AttrBlank.empty() && "HasAttrs was wrong?"); 594*f4a2713aSLionel Sambuc 595*f4a2713aSLionel Sambuc AttrBlank = attrs; 596*f4a2713aSLionel Sambuc HasAttrs = true; 597*f4a2713aSLionel Sambuc } 598*f4a2713aSLionel Sambuc 599*f4a2713aSLionel Sambuc void Decl::dropAttrs() { 600*f4a2713aSLionel Sambuc if (!HasAttrs) return; 601*f4a2713aSLionel Sambuc 602*f4a2713aSLionel Sambuc HasAttrs = false; 603*f4a2713aSLionel Sambuc getASTContext().eraseDeclAttrs(this); 604*f4a2713aSLionel Sambuc } 605*f4a2713aSLionel Sambuc 606*f4a2713aSLionel Sambuc const AttrVec &Decl::getAttrs() const { 607*f4a2713aSLionel Sambuc assert(HasAttrs && "No attrs to get!"); 608*f4a2713aSLionel Sambuc return getASTContext().getDeclAttrs(this); 609*f4a2713aSLionel Sambuc } 610*f4a2713aSLionel Sambuc 611*f4a2713aSLionel Sambuc Decl *Decl::castFromDeclContext (const DeclContext *D) { 612*f4a2713aSLionel Sambuc Decl::Kind DK = D->getDeclKind(); 613*f4a2713aSLionel Sambuc switch(DK) { 614*f4a2713aSLionel Sambuc #define DECL(NAME, BASE) 615*f4a2713aSLionel Sambuc #define DECL_CONTEXT(NAME) \ 616*f4a2713aSLionel Sambuc case Decl::NAME: \ 617*f4a2713aSLionel Sambuc return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D)); 618*f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME) 619*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 620*f4a2713aSLionel Sambuc default: 621*f4a2713aSLionel Sambuc #define DECL(NAME, BASE) 622*f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME) \ 623*f4a2713aSLionel Sambuc if (DK >= first##NAME && DK <= last##NAME) \ 624*f4a2713aSLionel Sambuc return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D)); 625*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 626*f4a2713aSLionel Sambuc llvm_unreachable("a decl that inherits DeclContext isn't handled"); 627*f4a2713aSLionel Sambuc } 628*f4a2713aSLionel Sambuc } 629*f4a2713aSLionel Sambuc 630*f4a2713aSLionel Sambuc DeclContext *Decl::castToDeclContext(const Decl *D) { 631*f4a2713aSLionel Sambuc Decl::Kind DK = D->getKind(); 632*f4a2713aSLionel Sambuc switch(DK) { 633*f4a2713aSLionel Sambuc #define DECL(NAME, BASE) 634*f4a2713aSLionel Sambuc #define DECL_CONTEXT(NAME) \ 635*f4a2713aSLionel Sambuc case Decl::NAME: \ 636*f4a2713aSLionel Sambuc return static_cast<NAME##Decl*>(const_cast<Decl*>(D)); 637*f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME) 638*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 639*f4a2713aSLionel Sambuc default: 640*f4a2713aSLionel Sambuc #define DECL(NAME, BASE) 641*f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME) \ 642*f4a2713aSLionel Sambuc if (DK >= first##NAME && DK <= last##NAME) \ 643*f4a2713aSLionel Sambuc return static_cast<NAME##Decl*>(const_cast<Decl*>(D)); 644*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 645*f4a2713aSLionel Sambuc llvm_unreachable("a decl that inherits DeclContext isn't handled"); 646*f4a2713aSLionel Sambuc } 647*f4a2713aSLionel Sambuc } 648*f4a2713aSLionel Sambuc 649*f4a2713aSLionel Sambuc SourceLocation Decl::getBodyRBrace() const { 650*f4a2713aSLionel Sambuc // Special handling of FunctionDecl to avoid de-serializing the body from PCH. 651*f4a2713aSLionel Sambuc // FunctionDecl stores EndRangeLoc for this purpose. 652*f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) { 653*f4a2713aSLionel Sambuc const FunctionDecl *Definition; 654*f4a2713aSLionel Sambuc if (FD->hasBody(Definition)) 655*f4a2713aSLionel Sambuc return Definition->getSourceRange().getEnd(); 656*f4a2713aSLionel Sambuc return SourceLocation(); 657*f4a2713aSLionel Sambuc } 658*f4a2713aSLionel Sambuc 659*f4a2713aSLionel Sambuc if (Stmt *Body = getBody()) 660*f4a2713aSLionel Sambuc return Body->getSourceRange().getEnd(); 661*f4a2713aSLionel Sambuc 662*f4a2713aSLionel Sambuc return SourceLocation(); 663*f4a2713aSLionel Sambuc } 664*f4a2713aSLionel Sambuc 665*f4a2713aSLionel Sambuc void Decl::CheckAccessDeclContext() const { 666*f4a2713aSLionel Sambuc #ifndef NDEBUG 667*f4a2713aSLionel Sambuc // Suppress this check if any of the following hold: 668*f4a2713aSLionel Sambuc // 1. this is the translation unit (and thus has no parent) 669*f4a2713aSLionel Sambuc // 2. this is a template parameter (and thus doesn't belong to its context) 670*f4a2713aSLionel Sambuc // 3. this is a non-type template parameter 671*f4a2713aSLionel Sambuc // 4. the context is not a record 672*f4a2713aSLionel Sambuc // 5. it's invalid 673*f4a2713aSLionel Sambuc // 6. it's a C++0x static_assert. 674*f4a2713aSLionel Sambuc if (isa<TranslationUnitDecl>(this) || 675*f4a2713aSLionel Sambuc isa<TemplateTypeParmDecl>(this) || 676*f4a2713aSLionel Sambuc isa<NonTypeTemplateParmDecl>(this) || 677*f4a2713aSLionel Sambuc !isa<CXXRecordDecl>(getDeclContext()) || 678*f4a2713aSLionel Sambuc isInvalidDecl() || 679*f4a2713aSLionel Sambuc isa<StaticAssertDecl>(this) || 680*f4a2713aSLionel Sambuc // FIXME: a ParmVarDecl can have ClassTemplateSpecialization 681*f4a2713aSLionel Sambuc // as DeclContext (?). 682*f4a2713aSLionel Sambuc isa<ParmVarDecl>(this) || 683*f4a2713aSLionel Sambuc // FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have 684*f4a2713aSLionel Sambuc // AS_none as access specifier. 685*f4a2713aSLionel Sambuc isa<CXXRecordDecl>(this) || 686*f4a2713aSLionel Sambuc isa<ClassScopeFunctionSpecializationDecl>(this)) 687*f4a2713aSLionel Sambuc return; 688*f4a2713aSLionel Sambuc 689*f4a2713aSLionel Sambuc assert(Access != AS_none && 690*f4a2713aSLionel Sambuc "Access specifier is AS_none inside a record decl"); 691*f4a2713aSLionel Sambuc #endif 692*f4a2713aSLionel Sambuc } 693*f4a2713aSLionel Sambuc 694*f4a2713aSLionel Sambuc static Decl::Kind getKind(const Decl *D) { return D->getKind(); } 695*f4a2713aSLionel Sambuc static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); } 696*f4a2713aSLionel Sambuc 697*f4a2713aSLionel Sambuc /// Starting at a given context (a Decl or DeclContext), look for a 698*f4a2713aSLionel Sambuc /// code context that is not a closure (a lambda, block, etc.). 699*f4a2713aSLionel Sambuc template <class T> static Decl *getNonClosureContext(T *D) { 700*f4a2713aSLionel Sambuc if (getKind(D) == Decl::CXXMethod) { 701*f4a2713aSLionel Sambuc CXXMethodDecl *MD = cast<CXXMethodDecl>(D); 702*f4a2713aSLionel Sambuc if (MD->getOverloadedOperator() == OO_Call && 703*f4a2713aSLionel Sambuc MD->getParent()->isLambda()) 704*f4a2713aSLionel Sambuc return getNonClosureContext(MD->getParent()->getParent()); 705*f4a2713aSLionel Sambuc return MD; 706*f4a2713aSLionel Sambuc } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 707*f4a2713aSLionel Sambuc return FD; 708*f4a2713aSLionel Sambuc } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 709*f4a2713aSLionel Sambuc return MD; 710*f4a2713aSLionel Sambuc } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 711*f4a2713aSLionel Sambuc return getNonClosureContext(BD->getParent()); 712*f4a2713aSLionel Sambuc } else if (CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) { 713*f4a2713aSLionel Sambuc return getNonClosureContext(CD->getParent()); 714*f4a2713aSLionel Sambuc } else { 715*f4a2713aSLionel Sambuc return 0; 716*f4a2713aSLionel Sambuc } 717*f4a2713aSLionel Sambuc } 718*f4a2713aSLionel Sambuc 719*f4a2713aSLionel Sambuc Decl *Decl::getNonClosureContext() { 720*f4a2713aSLionel Sambuc return ::getNonClosureContext(this); 721*f4a2713aSLionel Sambuc } 722*f4a2713aSLionel Sambuc 723*f4a2713aSLionel Sambuc Decl *DeclContext::getNonClosureAncestor() { 724*f4a2713aSLionel Sambuc return ::getNonClosureContext(this); 725*f4a2713aSLionel Sambuc } 726*f4a2713aSLionel Sambuc 727*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 728*f4a2713aSLionel Sambuc // DeclContext Implementation 729*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 730*f4a2713aSLionel Sambuc 731*f4a2713aSLionel Sambuc bool DeclContext::classof(const Decl *D) { 732*f4a2713aSLionel Sambuc switch (D->getKind()) { 733*f4a2713aSLionel Sambuc #define DECL(NAME, BASE) 734*f4a2713aSLionel Sambuc #define DECL_CONTEXT(NAME) case Decl::NAME: 735*f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME) 736*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 737*f4a2713aSLionel Sambuc return true; 738*f4a2713aSLionel Sambuc default: 739*f4a2713aSLionel Sambuc #define DECL(NAME, BASE) 740*f4a2713aSLionel Sambuc #define DECL_CONTEXT_BASE(NAME) \ 741*f4a2713aSLionel Sambuc if (D->getKind() >= Decl::first##NAME && \ 742*f4a2713aSLionel Sambuc D->getKind() <= Decl::last##NAME) \ 743*f4a2713aSLionel Sambuc return true; 744*f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc" 745*f4a2713aSLionel Sambuc return false; 746*f4a2713aSLionel Sambuc } 747*f4a2713aSLionel Sambuc } 748*f4a2713aSLionel Sambuc 749*f4a2713aSLionel Sambuc DeclContext::~DeclContext() { } 750*f4a2713aSLionel Sambuc 751*f4a2713aSLionel Sambuc /// \brief Find the parent context of this context that will be 752*f4a2713aSLionel Sambuc /// used for unqualified name lookup. 753*f4a2713aSLionel Sambuc /// 754*f4a2713aSLionel Sambuc /// Generally, the parent lookup context is the semantic context. However, for 755*f4a2713aSLionel Sambuc /// a friend function the parent lookup context is the lexical context, which 756*f4a2713aSLionel Sambuc /// is the class in which the friend is declared. 757*f4a2713aSLionel Sambuc DeclContext *DeclContext::getLookupParent() { 758*f4a2713aSLionel Sambuc // FIXME: Find a better way to identify friends 759*f4a2713aSLionel Sambuc if (isa<FunctionDecl>(this)) 760*f4a2713aSLionel Sambuc if (getParent()->getRedeclContext()->isFileContext() && 761*f4a2713aSLionel Sambuc getLexicalParent()->getRedeclContext()->isRecord()) 762*f4a2713aSLionel Sambuc return getLexicalParent(); 763*f4a2713aSLionel Sambuc 764*f4a2713aSLionel Sambuc return getParent(); 765*f4a2713aSLionel Sambuc } 766*f4a2713aSLionel Sambuc 767*f4a2713aSLionel Sambuc bool DeclContext::isInlineNamespace() const { 768*f4a2713aSLionel Sambuc return isNamespace() && 769*f4a2713aSLionel Sambuc cast<NamespaceDecl>(this)->isInline(); 770*f4a2713aSLionel Sambuc } 771*f4a2713aSLionel Sambuc 772*f4a2713aSLionel Sambuc bool DeclContext::isDependentContext() const { 773*f4a2713aSLionel Sambuc if (isFileContext()) 774*f4a2713aSLionel Sambuc return false; 775*f4a2713aSLionel Sambuc 776*f4a2713aSLionel Sambuc if (isa<ClassTemplatePartialSpecializationDecl>(this)) 777*f4a2713aSLionel Sambuc return true; 778*f4a2713aSLionel Sambuc 779*f4a2713aSLionel Sambuc if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) { 780*f4a2713aSLionel Sambuc if (Record->getDescribedClassTemplate()) 781*f4a2713aSLionel Sambuc return true; 782*f4a2713aSLionel Sambuc 783*f4a2713aSLionel Sambuc if (Record->isDependentLambda()) 784*f4a2713aSLionel Sambuc return true; 785*f4a2713aSLionel Sambuc } 786*f4a2713aSLionel Sambuc 787*f4a2713aSLionel Sambuc if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) { 788*f4a2713aSLionel Sambuc if (Function->getDescribedFunctionTemplate()) 789*f4a2713aSLionel Sambuc return true; 790*f4a2713aSLionel Sambuc 791*f4a2713aSLionel Sambuc // Friend function declarations are dependent if their *lexical* 792*f4a2713aSLionel Sambuc // context is dependent. 793*f4a2713aSLionel Sambuc if (cast<Decl>(this)->getFriendObjectKind()) 794*f4a2713aSLionel Sambuc return getLexicalParent()->isDependentContext(); 795*f4a2713aSLionel Sambuc } 796*f4a2713aSLionel Sambuc 797*f4a2713aSLionel Sambuc return getParent() && getParent()->isDependentContext(); 798*f4a2713aSLionel Sambuc } 799*f4a2713aSLionel Sambuc 800*f4a2713aSLionel Sambuc bool DeclContext::isTransparentContext() const { 801*f4a2713aSLionel Sambuc if (DeclKind == Decl::Enum) 802*f4a2713aSLionel Sambuc return !cast<EnumDecl>(this)->isScoped(); 803*f4a2713aSLionel Sambuc else if (DeclKind == Decl::LinkageSpec) 804*f4a2713aSLionel Sambuc return true; 805*f4a2713aSLionel Sambuc 806*f4a2713aSLionel Sambuc return false; 807*f4a2713aSLionel Sambuc } 808*f4a2713aSLionel Sambuc 809*f4a2713aSLionel Sambuc static bool isLinkageSpecContext(const DeclContext *DC, 810*f4a2713aSLionel Sambuc LinkageSpecDecl::LanguageIDs ID) { 811*f4a2713aSLionel Sambuc while (DC->getDeclKind() != Decl::TranslationUnit) { 812*f4a2713aSLionel Sambuc if (DC->getDeclKind() == Decl::LinkageSpec) 813*f4a2713aSLionel Sambuc return cast<LinkageSpecDecl>(DC)->getLanguage() == ID; 814*f4a2713aSLionel Sambuc DC = DC->getParent(); 815*f4a2713aSLionel Sambuc } 816*f4a2713aSLionel Sambuc return false; 817*f4a2713aSLionel Sambuc } 818*f4a2713aSLionel Sambuc 819*f4a2713aSLionel Sambuc bool DeclContext::isExternCContext() const { 820*f4a2713aSLionel Sambuc return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_c); 821*f4a2713aSLionel Sambuc } 822*f4a2713aSLionel Sambuc 823*f4a2713aSLionel Sambuc bool DeclContext::isExternCXXContext() const { 824*f4a2713aSLionel Sambuc return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_cxx); 825*f4a2713aSLionel Sambuc } 826*f4a2713aSLionel Sambuc 827*f4a2713aSLionel Sambuc bool DeclContext::Encloses(const DeclContext *DC) const { 828*f4a2713aSLionel Sambuc if (getPrimaryContext() != this) 829*f4a2713aSLionel Sambuc return getPrimaryContext()->Encloses(DC); 830*f4a2713aSLionel Sambuc 831*f4a2713aSLionel Sambuc for (; DC; DC = DC->getParent()) 832*f4a2713aSLionel Sambuc if (DC->getPrimaryContext() == this) 833*f4a2713aSLionel Sambuc return true; 834*f4a2713aSLionel Sambuc return false; 835*f4a2713aSLionel Sambuc } 836*f4a2713aSLionel Sambuc 837*f4a2713aSLionel Sambuc DeclContext *DeclContext::getPrimaryContext() { 838*f4a2713aSLionel Sambuc switch (DeclKind) { 839*f4a2713aSLionel Sambuc case Decl::TranslationUnit: 840*f4a2713aSLionel Sambuc case Decl::LinkageSpec: 841*f4a2713aSLionel Sambuc case Decl::Block: 842*f4a2713aSLionel Sambuc case Decl::Captured: 843*f4a2713aSLionel Sambuc // There is only one DeclContext for these entities. 844*f4a2713aSLionel Sambuc return this; 845*f4a2713aSLionel Sambuc 846*f4a2713aSLionel Sambuc case Decl::Namespace: 847*f4a2713aSLionel Sambuc // The original namespace is our primary context. 848*f4a2713aSLionel Sambuc return static_cast<NamespaceDecl*>(this)->getOriginalNamespace(); 849*f4a2713aSLionel Sambuc 850*f4a2713aSLionel Sambuc case Decl::ObjCMethod: 851*f4a2713aSLionel Sambuc return this; 852*f4a2713aSLionel Sambuc 853*f4a2713aSLionel Sambuc case Decl::ObjCInterface: 854*f4a2713aSLionel Sambuc if (ObjCInterfaceDecl *Def = cast<ObjCInterfaceDecl>(this)->getDefinition()) 855*f4a2713aSLionel Sambuc return Def; 856*f4a2713aSLionel Sambuc 857*f4a2713aSLionel Sambuc return this; 858*f4a2713aSLionel Sambuc 859*f4a2713aSLionel Sambuc case Decl::ObjCProtocol: 860*f4a2713aSLionel Sambuc if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(this)->getDefinition()) 861*f4a2713aSLionel Sambuc return Def; 862*f4a2713aSLionel Sambuc 863*f4a2713aSLionel Sambuc return this; 864*f4a2713aSLionel Sambuc 865*f4a2713aSLionel Sambuc case Decl::ObjCCategory: 866*f4a2713aSLionel Sambuc return this; 867*f4a2713aSLionel Sambuc 868*f4a2713aSLionel Sambuc case Decl::ObjCImplementation: 869*f4a2713aSLionel Sambuc case Decl::ObjCCategoryImpl: 870*f4a2713aSLionel Sambuc return this; 871*f4a2713aSLionel Sambuc 872*f4a2713aSLionel Sambuc default: 873*f4a2713aSLionel Sambuc if (DeclKind >= Decl::firstTag && DeclKind <= Decl::lastTag) { 874*f4a2713aSLionel Sambuc // If this is a tag type that has a definition or is currently 875*f4a2713aSLionel Sambuc // being defined, that definition is our primary context. 876*f4a2713aSLionel Sambuc TagDecl *Tag = cast<TagDecl>(this); 877*f4a2713aSLionel Sambuc assert(isa<TagType>(Tag->TypeForDecl) || 878*f4a2713aSLionel Sambuc isa<InjectedClassNameType>(Tag->TypeForDecl)); 879*f4a2713aSLionel Sambuc 880*f4a2713aSLionel Sambuc if (TagDecl *Def = Tag->getDefinition()) 881*f4a2713aSLionel Sambuc return Def; 882*f4a2713aSLionel Sambuc 883*f4a2713aSLionel Sambuc if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) { 884*f4a2713aSLionel Sambuc const TagType *TagTy = cast<TagType>(Tag->TypeForDecl); 885*f4a2713aSLionel Sambuc if (TagTy->isBeingDefined()) 886*f4a2713aSLionel Sambuc // FIXME: is it necessarily being defined in the decl 887*f4a2713aSLionel Sambuc // that owns the type? 888*f4a2713aSLionel Sambuc return TagTy->getDecl(); 889*f4a2713aSLionel Sambuc } 890*f4a2713aSLionel Sambuc 891*f4a2713aSLionel Sambuc return Tag; 892*f4a2713aSLionel Sambuc } 893*f4a2713aSLionel Sambuc 894*f4a2713aSLionel Sambuc assert(DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction && 895*f4a2713aSLionel Sambuc "Unknown DeclContext kind"); 896*f4a2713aSLionel Sambuc return this; 897*f4a2713aSLionel Sambuc } 898*f4a2713aSLionel Sambuc } 899*f4a2713aSLionel Sambuc 900*f4a2713aSLionel Sambuc void 901*f4a2713aSLionel Sambuc DeclContext::collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts){ 902*f4a2713aSLionel Sambuc Contexts.clear(); 903*f4a2713aSLionel Sambuc 904*f4a2713aSLionel Sambuc if (DeclKind != Decl::Namespace) { 905*f4a2713aSLionel Sambuc Contexts.push_back(this); 906*f4a2713aSLionel Sambuc return; 907*f4a2713aSLionel Sambuc } 908*f4a2713aSLionel Sambuc 909*f4a2713aSLionel Sambuc NamespaceDecl *Self = static_cast<NamespaceDecl *>(this); 910*f4a2713aSLionel Sambuc for (NamespaceDecl *N = Self->getMostRecentDecl(); N; 911*f4a2713aSLionel Sambuc N = N->getPreviousDecl()) 912*f4a2713aSLionel Sambuc Contexts.push_back(N); 913*f4a2713aSLionel Sambuc 914*f4a2713aSLionel Sambuc std::reverse(Contexts.begin(), Contexts.end()); 915*f4a2713aSLionel Sambuc } 916*f4a2713aSLionel Sambuc 917*f4a2713aSLionel Sambuc std::pair<Decl *, Decl *> 918*f4a2713aSLionel Sambuc DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls, 919*f4a2713aSLionel Sambuc bool FieldsAlreadyLoaded) { 920*f4a2713aSLionel Sambuc // Build up a chain of declarations via the Decl::NextInContextAndBits field. 921*f4a2713aSLionel Sambuc Decl *FirstNewDecl = 0; 922*f4a2713aSLionel Sambuc Decl *PrevDecl = 0; 923*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Decls.size(); I != N; ++I) { 924*f4a2713aSLionel Sambuc if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I])) 925*f4a2713aSLionel Sambuc continue; 926*f4a2713aSLionel Sambuc 927*f4a2713aSLionel Sambuc Decl *D = Decls[I]; 928*f4a2713aSLionel Sambuc if (PrevDecl) 929*f4a2713aSLionel Sambuc PrevDecl->NextInContextAndBits.setPointer(D); 930*f4a2713aSLionel Sambuc else 931*f4a2713aSLionel Sambuc FirstNewDecl = D; 932*f4a2713aSLionel Sambuc 933*f4a2713aSLionel Sambuc PrevDecl = D; 934*f4a2713aSLionel Sambuc } 935*f4a2713aSLionel Sambuc 936*f4a2713aSLionel Sambuc return std::make_pair(FirstNewDecl, PrevDecl); 937*f4a2713aSLionel Sambuc } 938*f4a2713aSLionel Sambuc 939*f4a2713aSLionel Sambuc /// \brief We have just acquired external visible storage, and we already have 940*f4a2713aSLionel Sambuc /// built a lookup map. For every name in the map, pull in the new names from 941*f4a2713aSLionel Sambuc /// the external storage. 942*f4a2713aSLionel Sambuc void DeclContext::reconcileExternalVisibleStorage() { 943*f4a2713aSLionel Sambuc assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer()); 944*f4a2713aSLionel Sambuc NeedToReconcileExternalVisibleStorage = false; 945*f4a2713aSLionel Sambuc 946*f4a2713aSLionel Sambuc StoredDeclsMap &Map = *LookupPtr.getPointer(); 947*f4a2713aSLionel Sambuc for (StoredDeclsMap::iterator I = Map.begin(); I != Map.end(); ++I) 948*f4a2713aSLionel Sambuc I->second.setHasExternalDecls(); 949*f4a2713aSLionel Sambuc } 950*f4a2713aSLionel Sambuc 951*f4a2713aSLionel Sambuc /// \brief Load the declarations within this lexical storage from an 952*f4a2713aSLionel Sambuc /// external source. 953*f4a2713aSLionel Sambuc void 954*f4a2713aSLionel Sambuc DeclContext::LoadLexicalDeclsFromExternalStorage() const { 955*f4a2713aSLionel Sambuc ExternalASTSource *Source = getParentASTContext().getExternalSource(); 956*f4a2713aSLionel Sambuc assert(hasExternalLexicalStorage() && Source && "No external storage?"); 957*f4a2713aSLionel Sambuc 958*f4a2713aSLionel Sambuc // Notify that we have a DeclContext that is initializing. 959*f4a2713aSLionel Sambuc ExternalASTSource::Deserializing ADeclContext(Source); 960*f4a2713aSLionel Sambuc 961*f4a2713aSLionel Sambuc // Load the external declarations, if any. 962*f4a2713aSLionel Sambuc SmallVector<Decl*, 64> Decls; 963*f4a2713aSLionel Sambuc ExternalLexicalStorage = false; 964*f4a2713aSLionel Sambuc switch (Source->FindExternalLexicalDecls(this, Decls)) { 965*f4a2713aSLionel Sambuc case ELR_Success: 966*f4a2713aSLionel Sambuc break; 967*f4a2713aSLionel Sambuc 968*f4a2713aSLionel Sambuc case ELR_Failure: 969*f4a2713aSLionel Sambuc case ELR_AlreadyLoaded: 970*f4a2713aSLionel Sambuc return; 971*f4a2713aSLionel Sambuc } 972*f4a2713aSLionel Sambuc 973*f4a2713aSLionel Sambuc if (Decls.empty()) 974*f4a2713aSLionel Sambuc return; 975*f4a2713aSLionel Sambuc 976*f4a2713aSLionel Sambuc // We may have already loaded just the fields of this record, in which case 977*f4a2713aSLionel Sambuc // we need to ignore them. 978*f4a2713aSLionel Sambuc bool FieldsAlreadyLoaded = false; 979*f4a2713aSLionel Sambuc if (const RecordDecl *RD = dyn_cast<RecordDecl>(this)) 980*f4a2713aSLionel Sambuc FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage; 981*f4a2713aSLionel Sambuc 982*f4a2713aSLionel Sambuc // Splice the newly-read declarations into the beginning of the list 983*f4a2713aSLionel Sambuc // of declarations. 984*f4a2713aSLionel Sambuc Decl *ExternalFirst, *ExternalLast; 985*f4a2713aSLionel Sambuc llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls, 986*f4a2713aSLionel Sambuc FieldsAlreadyLoaded); 987*f4a2713aSLionel Sambuc ExternalLast->NextInContextAndBits.setPointer(FirstDecl); 988*f4a2713aSLionel Sambuc FirstDecl = ExternalFirst; 989*f4a2713aSLionel Sambuc if (!LastDecl) 990*f4a2713aSLionel Sambuc LastDecl = ExternalLast; 991*f4a2713aSLionel Sambuc } 992*f4a2713aSLionel Sambuc 993*f4a2713aSLionel Sambuc DeclContext::lookup_result 994*f4a2713aSLionel Sambuc ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC, 995*f4a2713aSLionel Sambuc DeclarationName Name) { 996*f4a2713aSLionel Sambuc ASTContext &Context = DC->getParentASTContext(); 997*f4a2713aSLionel Sambuc StoredDeclsMap *Map; 998*f4a2713aSLionel Sambuc if (!(Map = DC->LookupPtr.getPointer())) 999*f4a2713aSLionel Sambuc Map = DC->CreateStoredDeclsMap(Context); 1000*f4a2713aSLionel Sambuc 1001*f4a2713aSLionel Sambuc (*Map)[Name].removeExternalDecls(); 1002*f4a2713aSLionel Sambuc 1003*f4a2713aSLionel Sambuc return DeclContext::lookup_result(); 1004*f4a2713aSLionel Sambuc } 1005*f4a2713aSLionel Sambuc 1006*f4a2713aSLionel Sambuc DeclContext::lookup_result 1007*f4a2713aSLionel Sambuc ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, 1008*f4a2713aSLionel Sambuc DeclarationName Name, 1009*f4a2713aSLionel Sambuc ArrayRef<NamedDecl*> Decls) { 1010*f4a2713aSLionel Sambuc ASTContext &Context = DC->getParentASTContext(); 1011*f4a2713aSLionel Sambuc StoredDeclsMap *Map; 1012*f4a2713aSLionel Sambuc if (!(Map = DC->LookupPtr.getPointer())) 1013*f4a2713aSLionel Sambuc Map = DC->CreateStoredDeclsMap(Context); 1014*f4a2713aSLionel Sambuc 1015*f4a2713aSLionel Sambuc StoredDeclsList &List = (*Map)[Name]; 1016*f4a2713aSLionel Sambuc 1017*f4a2713aSLionel Sambuc // Clear out any old external visible declarations, to avoid quadratic 1018*f4a2713aSLionel Sambuc // performance in the redeclaration checks below. 1019*f4a2713aSLionel Sambuc List.removeExternalDecls(); 1020*f4a2713aSLionel Sambuc 1021*f4a2713aSLionel Sambuc if (!List.isNull()) { 1022*f4a2713aSLionel Sambuc // We have both existing declarations and new declarations for this name. 1023*f4a2713aSLionel Sambuc // Some of the declarations may simply replace existing ones. Handle those 1024*f4a2713aSLionel Sambuc // first. 1025*f4a2713aSLionel Sambuc llvm::SmallVector<unsigned, 8> Skip; 1026*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Decls.size(); I != N; ++I) 1027*f4a2713aSLionel Sambuc if (List.HandleRedeclaration(Decls[I])) 1028*f4a2713aSLionel Sambuc Skip.push_back(I); 1029*f4a2713aSLionel Sambuc Skip.push_back(Decls.size()); 1030*f4a2713aSLionel Sambuc 1031*f4a2713aSLionel Sambuc // Add in any new declarations. 1032*f4a2713aSLionel Sambuc unsigned SkipPos = 0; 1033*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Decls.size(); I != N; ++I) { 1034*f4a2713aSLionel Sambuc if (I == Skip[SkipPos]) 1035*f4a2713aSLionel Sambuc ++SkipPos; 1036*f4a2713aSLionel Sambuc else 1037*f4a2713aSLionel Sambuc List.AddSubsequentDecl(Decls[I]); 1038*f4a2713aSLionel Sambuc } 1039*f4a2713aSLionel Sambuc } else { 1040*f4a2713aSLionel Sambuc // Convert the array to a StoredDeclsList. 1041*f4a2713aSLionel Sambuc for (ArrayRef<NamedDecl*>::iterator 1042*f4a2713aSLionel Sambuc I = Decls.begin(), E = Decls.end(); I != E; ++I) { 1043*f4a2713aSLionel Sambuc if (List.isNull()) 1044*f4a2713aSLionel Sambuc List.setOnlyValue(*I); 1045*f4a2713aSLionel Sambuc else 1046*f4a2713aSLionel Sambuc List.AddSubsequentDecl(*I); 1047*f4a2713aSLionel Sambuc } 1048*f4a2713aSLionel Sambuc } 1049*f4a2713aSLionel Sambuc 1050*f4a2713aSLionel Sambuc return List.getLookupResult(); 1051*f4a2713aSLionel Sambuc } 1052*f4a2713aSLionel Sambuc 1053*f4a2713aSLionel Sambuc DeclContext::decl_iterator DeclContext::noload_decls_begin() const { 1054*f4a2713aSLionel Sambuc return decl_iterator(FirstDecl); 1055*f4a2713aSLionel Sambuc } 1056*f4a2713aSLionel Sambuc 1057*f4a2713aSLionel Sambuc DeclContext::decl_iterator DeclContext::decls_begin() const { 1058*f4a2713aSLionel Sambuc if (hasExternalLexicalStorage()) 1059*f4a2713aSLionel Sambuc LoadLexicalDeclsFromExternalStorage(); 1060*f4a2713aSLionel Sambuc 1061*f4a2713aSLionel Sambuc return decl_iterator(FirstDecl); 1062*f4a2713aSLionel Sambuc } 1063*f4a2713aSLionel Sambuc 1064*f4a2713aSLionel Sambuc bool DeclContext::decls_empty() const { 1065*f4a2713aSLionel Sambuc if (hasExternalLexicalStorage()) 1066*f4a2713aSLionel Sambuc LoadLexicalDeclsFromExternalStorage(); 1067*f4a2713aSLionel Sambuc 1068*f4a2713aSLionel Sambuc return !FirstDecl; 1069*f4a2713aSLionel Sambuc } 1070*f4a2713aSLionel Sambuc 1071*f4a2713aSLionel Sambuc bool DeclContext::containsDecl(Decl *D) const { 1072*f4a2713aSLionel Sambuc return (D->getLexicalDeclContext() == this && 1073*f4a2713aSLionel Sambuc (D->NextInContextAndBits.getPointer() || D == LastDecl)); 1074*f4a2713aSLionel Sambuc } 1075*f4a2713aSLionel Sambuc 1076*f4a2713aSLionel Sambuc void DeclContext::removeDecl(Decl *D) { 1077*f4a2713aSLionel Sambuc assert(D->getLexicalDeclContext() == this && 1078*f4a2713aSLionel Sambuc "decl being removed from non-lexical context"); 1079*f4a2713aSLionel Sambuc assert((D->NextInContextAndBits.getPointer() || D == LastDecl) && 1080*f4a2713aSLionel Sambuc "decl is not in decls list"); 1081*f4a2713aSLionel Sambuc 1082*f4a2713aSLionel Sambuc // Remove D from the decl chain. This is O(n) but hopefully rare. 1083*f4a2713aSLionel Sambuc if (D == FirstDecl) { 1084*f4a2713aSLionel Sambuc if (D == LastDecl) 1085*f4a2713aSLionel Sambuc FirstDecl = LastDecl = 0; 1086*f4a2713aSLionel Sambuc else 1087*f4a2713aSLionel Sambuc FirstDecl = D->NextInContextAndBits.getPointer(); 1088*f4a2713aSLionel Sambuc } else { 1089*f4a2713aSLionel Sambuc for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) { 1090*f4a2713aSLionel Sambuc assert(I && "decl not found in linked list"); 1091*f4a2713aSLionel Sambuc if (I->NextInContextAndBits.getPointer() == D) { 1092*f4a2713aSLionel Sambuc I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer()); 1093*f4a2713aSLionel Sambuc if (D == LastDecl) LastDecl = I; 1094*f4a2713aSLionel Sambuc break; 1095*f4a2713aSLionel Sambuc } 1096*f4a2713aSLionel Sambuc } 1097*f4a2713aSLionel Sambuc } 1098*f4a2713aSLionel Sambuc 1099*f4a2713aSLionel Sambuc // Mark that D is no longer in the decl chain. 1100*f4a2713aSLionel Sambuc D->NextInContextAndBits.setPointer(0); 1101*f4a2713aSLionel Sambuc 1102*f4a2713aSLionel Sambuc // Remove D from the lookup table if necessary. 1103*f4a2713aSLionel Sambuc if (isa<NamedDecl>(D)) { 1104*f4a2713aSLionel Sambuc NamedDecl *ND = cast<NamedDecl>(D); 1105*f4a2713aSLionel Sambuc 1106*f4a2713aSLionel Sambuc // Remove only decls that have a name 1107*f4a2713aSLionel Sambuc if (!ND->getDeclName()) return; 1108*f4a2713aSLionel Sambuc 1109*f4a2713aSLionel Sambuc StoredDeclsMap *Map = getPrimaryContext()->LookupPtr.getPointer(); 1110*f4a2713aSLionel Sambuc if (!Map) return; 1111*f4a2713aSLionel Sambuc 1112*f4a2713aSLionel Sambuc StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); 1113*f4a2713aSLionel Sambuc assert(Pos != Map->end() && "no lookup entry for decl"); 1114*f4a2713aSLionel Sambuc if (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND) 1115*f4a2713aSLionel Sambuc Pos->second.remove(ND); 1116*f4a2713aSLionel Sambuc } 1117*f4a2713aSLionel Sambuc } 1118*f4a2713aSLionel Sambuc 1119*f4a2713aSLionel Sambuc void DeclContext::addHiddenDecl(Decl *D) { 1120*f4a2713aSLionel Sambuc assert(D->getLexicalDeclContext() == this && 1121*f4a2713aSLionel Sambuc "Decl inserted into wrong lexical context"); 1122*f4a2713aSLionel Sambuc assert(!D->getNextDeclInContext() && D != LastDecl && 1123*f4a2713aSLionel Sambuc "Decl already inserted into a DeclContext"); 1124*f4a2713aSLionel Sambuc 1125*f4a2713aSLionel Sambuc if (FirstDecl) { 1126*f4a2713aSLionel Sambuc LastDecl->NextInContextAndBits.setPointer(D); 1127*f4a2713aSLionel Sambuc LastDecl = D; 1128*f4a2713aSLionel Sambuc } else { 1129*f4a2713aSLionel Sambuc FirstDecl = LastDecl = D; 1130*f4a2713aSLionel Sambuc } 1131*f4a2713aSLionel Sambuc 1132*f4a2713aSLionel Sambuc // Notify a C++ record declaration that we've added a member, so it can 1133*f4a2713aSLionel Sambuc // update it's class-specific state. 1134*f4a2713aSLionel Sambuc if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) 1135*f4a2713aSLionel Sambuc Record->addedMember(D); 1136*f4a2713aSLionel Sambuc 1137*f4a2713aSLionel Sambuc // If this is a newly-created (not de-serialized) import declaration, wire 1138*f4a2713aSLionel Sambuc // it in to the list of local import declarations. 1139*f4a2713aSLionel Sambuc if (!D->isFromASTFile()) { 1140*f4a2713aSLionel Sambuc if (ImportDecl *Import = dyn_cast<ImportDecl>(D)) 1141*f4a2713aSLionel Sambuc D->getASTContext().addedLocalImportDecl(Import); 1142*f4a2713aSLionel Sambuc } 1143*f4a2713aSLionel Sambuc } 1144*f4a2713aSLionel Sambuc 1145*f4a2713aSLionel Sambuc void DeclContext::addDecl(Decl *D) { 1146*f4a2713aSLionel Sambuc addHiddenDecl(D); 1147*f4a2713aSLionel Sambuc 1148*f4a2713aSLionel Sambuc if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 1149*f4a2713aSLionel Sambuc ND->getDeclContext()->getPrimaryContext()-> 1150*f4a2713aSLionel Sambuc makeDeclVisibleInContextWithFlags(ND, false, true); 1151*f4a2713aSLionel Sambuc } 1152*f4a2713aSLionel Sambuc 1153*f4a2713aSLionel Sambuc void DeclContext::addDeclInternal(Decl *D) { 1154*f4a2713aSLionel Sambuc addHiddenDecl(D); 1155*f4a2713aSLionel Sambuc 1156*f4a2713aSLionel Sambuc if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 1157*f4a2713aSLionel Sambuc ND->getDeclContext()->getPrimaryContext()-> 1158*f4a2713aSLionel Sambuc makeDeclVisibleInContextWithFlags(ND, true, true); 1159*f4a2713aSLionel Sambuc } 1160*f4a2713aSLionel Sambuc 1161*f4a2713aSLionel Sambuc /// shouldBeHidden - Determine whether a declaration which was declared 1162*f4a2713aSLionel Sambuc /// within its semantic context should be invisible to qualified name lookup. 1163*f4a2713aSLionel Sambuc static bool shouldBeHidden(NamedDecl *D) { 1164*f4a2713aSLionel Sambuc // Skip unnamed declarations. 1165*f4a2713aSLionel Sambuc if (!D->getDeclName()) 1166*f4a2713aSLionel Sambuc return true; 1167*f4a2713aSLionel Sambuc 1168*f4a2713aSLionel Sambuc // Skip entities that can't be found by name lookup into a particular 1169*f4a2713aSLionel Sambuc // context. 1170*f4a2713aSLionel Sambuc if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) || 1171*f4a2713aSLionel Sambuc D->isTemplateParameter()) 1172*f4a2713aSLionel Sambuc return true; 1173*f4a2713aSLionel Sambuc 1174*f4a2713aSLionel Sambuc // Skip template specializations. 1175*f4a2713aSLionel Sambuc // FIXME: This feels like a hack. Should DeclarationName support 1176*f4a2713aSLionel Sambuc // template-ids, or is there a better way to keep specializations 1177*f4a2713aSLionel Sambuc // from being visible? 1178*f4a2713aSLionel Sambuc if (isa<ClassTemplateSpecializationDecl>(D)) 1179*f4a2713aSLionel Sambuc return true; 1180*f4a2713aSLionel Sambuc if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 1181*f4a2713aSLionel Sambuc if (FD->isFunctionTemplateSpecialization()) 1182*f4a2713aSLionel Sambuc return true; 1183*f4a2713aSLionel Sambuc 1184*f4a2713aSLionel Sambuc return false; 1185*f4a2713aSLionel Sambuc } 1186*f4a2713aSLionel Sambuc 1187*f4a2713aSLionel Sambuc /// buildLookup - Build the lookup data structure with all of the 1188*f4a2713aSLionel Sambuc /// declarations in this DeclContext (and any other contexts linked 1189*f4a2713aSLionel Sambuc /// to it or transparent contexts nested within it) and return it. 1190*f4a2713aSLionel Sambuc StoredDeclsMap *DeclContext::buildLookup() { 1191*f4a2713aSLionel Sambuc assert(this == getPrimaryContext() && "buildLookup called on non-primary DC"); 1192*f4a2713aSLionel Sambuc 1193*f4a2713aSLionel Sambuc // FIXME: Should we keep going if hasExternalVisibleStorage? 1194*f4a2713aSLionel Sambuc if (!LookupPtr.getInt()) 1195*f4a2713aSLionel Sambuc return LookupPtr.getPointer(); 1196*f4a2713aSLionel Sambuc 1197*f4a2713aSLionel Sambuc SmallVector<DeclContext *, 2> Contexts; 1198*f4a2713aSLionel Sambuc collectAllContexts(Contexts); 1199*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Contexts.size(); I != N; ++I) 1200*f4a2713aSLionel Sambuc buildLookupImpl<&DeclContext::decls_begin, 1201*f4a2713aSLionel Sambuc &DeclContext::decls_end>(Contexts[I]); 1202*f4a2713aSLionel Sambuc 1203*f4a2713aSLionel Sambuc // We no longer have any lazy decls. 1204*f4a2713aSLionel Sambuc LookupPtr.setInt(false); 1205*f4a2713aSLionel Sambuc NeedToReconcileExternalVisibleStorage = false; 1206*f4a2713aSLionel Sambuc return LookupPtr.getPointer(); 1207*f4a2713aSLionel Sambuc } 1208*f4a2713aSLionel Sambuc 1209*f4a2713aSLionel Sambuc /// buildLookupImpl - Build part of the lookup data structure for the 1210*f4a2713aSLionel Sambuc /// declarations contained within DCtx, which will either be this 1211*f4a2713aSLionel Sambuc /// DeclContext, a DeclContext linked to it, or a transparent context 1212*f4a2713aSLionel Sambuc /// nested within it. 1213*f4a2713aSLionel Sambuc template<DeclContext::decl_iterator (DeclContext::*Begin)() const, 1214*f4a2713aSLionel Sambuc DeclContext::decl_iterator (DeclContext::*End)() const> 1215*f4a2713aSLionel Sambuc void DeclContext::buildLookupImpl(DeclContext *DCtx) { 1216*f4a2713aSLionel Sambuc for (decl_iterator I = (DCtx->*Begin)(), E = (DCtx->*End)(); 1217*f4a2713aSLionel Sambuc I != E; ++I) { 1218*f4a2713aSLionel Sambuc Decl *D = *I; 1219*f4a2713aSLionel Sambuc 1220*f4a2713aSLionel Sambuc // Insert this declaration into the lookup structure, but only if 1221*f4a2713aSLionel Sambuc // it's semantically within its decl context. Any other decls which 1222*f4a2713aSLionel Sambuc // should be found in this context are added eagerly. 1223*f4a2713aSLionel Sambuc // 1224*f4a2713aSLionel Sambuc // If it's from an AST file, don't add it now. It'll get handled by 1225*f4a2713aSLionel Sambuc // FindExternalVisibleDeclsByName if needed. Exception: if we're not 1226*f4a2713aSLionel Sambuc // in C++, we do not track external visible decls for the TU, so in 1227*f4a2713aSLionel Sambuc // that case we need to collect them all here. 1228*f4a2713aSLionel Sambuc if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 1229*f4a2713aSLionel Sambuc if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) && 1230*f4a2713aSLionel Sambuc (!ND->isFromASTFile() || 1231*f4a2713aSLionel Sambuc (isTranslationUnit() && 1232*f4a2713aSLionel Sambuc !getParentASTContext().getLangOpts().CPlusPlus))) 1233*f4a2713aSLionel Sambuc makeDeclVisibleInContextImpl(ND, false); 1234*f4a2713aSLionel Sambuc 1235*f4a2713aSLionel Sambuc // If this declaration is itself a transparent declaration context 1236*f4a2713aSLionel Sambuc // or inline namespace, add the members of this declaration of that 1237*f4a2713aSLionel Sambuc // context (recursively). 1238*f4a2713aSLionel Sambuc if (DeclContext *InnerCtx = dyn_cast<DeclContext>(D)) 1239*f4a2713aSLionel Sambuc if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace()) 1240*f4a2713aSLionel Sambuc buildLookupImpl<Begin, End>(InnerCtx); 1241*f4a2713aSLionel Sambuc } 1242*f4a2713aSLionel Sambuc } 1243*f4a2713aSLionel Sambuc 1244*f4a2713aSLionel Sambuc DeclContext::lookup_result 1245*f4a2713aSLionel Sambuc DeclContext::lookup(DeclarationName Name) { 1246*f4a2713aSLionel Sambuc assert(DeclKind != Decl::LinkageSpec && 1247*f4a2713aSLionel Sambuc "Should not perform lookups into linkage specs!"); 1248*f4a2713aSLionel Sambuc 1249*f4a2713aSLionel Sambuc DeclContext *PrimaryContext = getPrimaryContext(); 1250*f4a2713aSLionel Sambuc if (PrimaryContext != this) 1251*f4a2713aSLionel Sambuc return PrimaryContext->lookup(Name); 1252*f4a2713aSLionel Sambuc 1253*f4a2713aSLionel Sambuc if (hasExternalVisibleStorage()) { 1254*f4a2713aSLionel Sambuc StoredDeclsMap *Map = LookupPtr.getPointer(); 1255*f4a2713aSLionel Sambuc if (LookupPtr.getInt()) 1256*f4a2713aSLionel Sambuc Map = buildLookup(); 1257*f4a2713aSLionel Sambuc else if (NeedToReconcileExternalVisibleStorage) 1258*f4a2713aSLionel Sambuc reconcileExternalVisibleStorage(); 1259*f4a2713aSLionel Sambuc 1260*f4a2713aSLionel Sambuc if (!Map) 1261*f4a2713aSLionel Sambuc Map = CreateStoredDeclsMap(getParentASTContext()); 1262*f4a2713aSLionel Sambuc 1263*f4a2713aSLionel Sambuc // If we have a lookup result with no external decls, we are done. 1264*f4a2713aSLionel Sambuc std::pair<StoredDeclsMap::iterator, bool> R = 1265*f4a2713aSLionel Sambuc Map->insert(std::make_pair(Name, StoredDeclsList())); 1266*f4a2713aSLionel Sambuc if (!R.second && !R.first->second.hasExternalDecls()) 1267*f4a2713aSLionel Sambuc return R.first->second.getLookupResult(); 1268*f4a2713aSLionel Sambuc 1269*f4a2713aSLionel Sambuc ExternalASTSource *Source = getParentASTContext().getExternalSource(); 1270*f4a2713aSLionel Sambuc if (Source->FindExternalVisibleDeclsByName(this, Name) || R.second) { 1271*f4a2713aSLionel Sambuc if (StoredDeclsMap *Map = LookupPtr.getPointer()) { 1272*f4a2713aSLionel Sambuc StoredDeclsMap::iterator I = Map->find(Name); 1273*f4a2713aSLionel Sambuc if (I != Map->end()) 1274*f4a2713aSLionel Sambuc return I->second.getLookupResult(); 1275*f4a2713aSLionel Sambuc } 1276*f4a2713aSLionel Sambuc } 1277*f4a2713aSLionel Sambuc 1278*f4a2713aSLionel Sambuc return lookup_result(lookup_iterator(0), lookup_iterator(0)); 1279*f4a2713aSLionel Sambuc } 1280*f4a2713aSLionel Sambuc 1281*f4a2713aSLionel Sambuc StoredDeclsMap *Map = LookupPtr.getPointer(); 1282*f4a2713aSLionel Sambuc if (LookupPtr.getInt()) 1283*f4a2713aSLionel Sambuc Map = buildLookup(); 1284*f4a2713aSLionel Sambuc 1285*f4a2713aSLionel Sambuc if (!Map) 1286*f4a2713aSLionel Sambuc return lookup_result(lookup_iterator(0), lookup_iterator(0)); 1287*f4a2713aSLionel Sambuc 1288*f4a2713aSLionel Sambuc StoredDeclsMap::iterator I = Map->find(Name); 1289*f4a2713aSLionel Sambuc if (I == Map->end()) 1290*f4a2713aSLionel Sambuc return lookup_result(lookup_iterator(0), lookup_iterator(0)); 1291*f4a2713aSLionel Sambuc 1292*f4a2713aSLionel Sambuc return I->second.getLookupResult(); 1293*f4a2713aSLionel Sambuc } 1294*f4a2713aSLionel Sambuc 1295*f4a2713aSLionel Sambuc DeclContext::lookup_result 1296*f4a2713aSLionel Sambuc DeclContext::noload_lookup(DeclarationName Name) { 1297*f4a2713aSLionel Sambuc assert(DeclKind != Decl::LinkageSpec && 1298*f4a2713aSLionel Sambuc "Should not perform lookups into linkage specs!"); 1299*f4a2713aSLionel Sambuc if (!hasExternalVisibleStorage()) 1300*f4a2713aSLionel Sambuc return lookup(Name); 1301*f4a2713aSLionel Sambuc 1302*f4a2713aSLionel Sambuc DeclContext *PrimaryContext = getPrimaryContext(); 1303*f4a2713aSLionel Sambuc if (PrimaryContext != this) 1304*f4a2713aSLionel Sambuc return PrimaryContext->noload_lookup(Name); 1305*f4a2713aSLionel Sambuc 1306*f4a2713aSLionel Sambuc StoredDeclsMap *Map = LookupPtr.getPointer(); 1307*f4a2713aSLionel Sambuc if (LookupPtr.getInt()) { 1308*f4a2713aSLionel Sambuc // Carefully build the lookup map, without deserializing anything. 1309*f4a2713aSLionel Sambuc SmallVector<DeclContext *, 2> Contexts; 1310*f4a2713aSLionel Sambuc collectAllContexts(Contexts); 1311*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Contexts.size(); I != N; ++I) 1312*f4a2713aSLionel Sambuc buildLookupImpl<&DeclContext::noload_decls_begin, 1313*f4a2713aSLionel Sambuc &DeclContext::noload_decls_end>(Contexts[I]); 1314*f4a2713aSLionel Sambuc 1315*f4a2713aSLionel Sambuc // We no longer have any lazy decls. 1316*f4a2713aSLionel Sambuc LookupPtr.setInt(false); 1317*f4a2713aSLionel Sambuc 1318*f4a2713aSLionel Sambuc // There may now be names for which we have local decls but are 1319*f4a2713aSLionel Sambuc // missing the external decls. FIXME: Just set the hasExternalDecls 1320*f4a2713aSLionel Sambuc // flag on those names that have external decls. 1321*f4a2713aSLionel Sambuc NeedToReconcileExternalVisibleStorage = true; 1322*f4a2713aSLionel Sambuc 1323*f4a2713aSLionel Sambuc Map = LookupPtr.getPointer(); 1324*f4a2713aSLionel Sambuc } 1325*f4a2713aSLionel Sambuc 1326*f4a2713aSLionel Sambuc if (!Map) 1327*f4a2713aSLionel Sambuc return lookup_result(lookup_iterator(0), lookup_iterator(0)); 1328*f4a2713aSLionel Sambuc 1329*f4a2713aSLionel Sambuc StoredDeclsMap::iterator I = Map->find(Name); 1330*f4a2713aSLionel Sambuc return I != Map->end() 1331*f4a2713aSLionel Sambuc ? I->second.getLookupResult() 1332*f4a2713aSLionel Sambuc : lookup_result(lookup_iterator(0), lookup_iterator(0)); 1333*f4a2713aSLionel Sambuc } 1334*f4a2713aSLionel Sambuc 1335*f4a2713aSLionel Sambuc void DeclContext::localUncachedLookup(DeclarationName Name, 1336*f4a2713aSLionel Sambuc SmallVectorImpl<NamedDecl *> &Results) { 1337*f4a2713aSLionel Sambuc Results.clear(); 1338*f4a2713aSLionel Sambuc 1339*f4a2713aSLionel Sambuc // If there's no external storage, just perform a normal lookup and copy 1340*f4a2713aSLionel Sambuc // the results. 1341*f4a2713aSLionel Sambuc if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) { 1342*f4a2713aSLionel Sambuc lookup_result LookupResults = lookup(Name); 1343*f4a2713aSLionel Sambuc Results.insert(Results.end(), LookupResults.begin(), LookupResults.end()); 1344*f4a2713aSLionel Sambuc return; 1345*f4a2713aSLionel Sambuc } 1346*f4a2713aSLionel Sambuc 1347*f4a2713aSLionel Sambuc // If we have a lookup table, check there first. Maybe we'll get lucky. 1348*f4a2713aSLionel Sambuc if (Name && !LookupPtr.getInt()) { 1349*f4a2713aSLionel Sambuc if (StoredDeclsMap *Map = LookupPtr.getPointer()) { 1350*f4a2713aSLionel Sambuc StoredDeclsMap::iterator Pos = Map->find(Name); 1351*f4a2713aSLionel Sambuc if (Pos != Map->end()) { 1352*f4a2713aSLionel Sambuc Results.insert(Results.end(), 1353*f4a2713aSLionel Sambuc Pos->second.getLookupResult().begin(), 1354*f4a2713aSLionel Sambuc Pos->second.getLookupResult().end()); 1355*f4a2713aSLionel Sambuc return; 1356*f4a2713aSLionel Sambuc } 1357*f4a2713aSLionel Sambuc } 1358*f4a2713aSLionel Sambuc } 1359*f4a2713aSLionel Sambuc 1360*f4a2713aSLionel Sambuc // Slow case: grovel through the declarations in our chain looking for 1361*f4a2713aSLionel Sambuc // matches. 1362*f4a2713aSLionel Sambuc for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) { 1363*f4a2713aSLionel Sambuc if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 1364*f4a2713aSLionel Sambuc if (ND->getDeclName() == Name) 1365*f4a2713aSLionel Sambuc Results.push_back(ND); 1366*f4a2713aSLionel Sambuc } 1367*f4a2713aSLionel Sambuc } 1368*f4a2713aSLionel Sambuc 1369*f4a2713aSLionel Sambuc DeclContext *DeclContext::getRedeclContext() { 1370*f4a2713aSLionel Sambuc DeclContext *Ctx = this; 1371*f4a2713aSLionel Sambuc // Skip through transparent contexts. 1372*f4a2713aSLionel Sambuc while (Ctx->isTransparentContext()) 1373*f4a2713aSLionel Sambuc Ctx = Ctx->getParent(); 1374*f4a2713aSLionel Sambuc return Ctx; 1375*f4a2713aSLionel Sambuc } 1376*f4a2713aSLionel Sambuc 1377*f4a2713aSLionel Sambuc DeclContext *DeclContext::getEnclosingNamespaceContext() { 1378*f4a2713aSLionel Sambuc DeclContext *Ctx = this; 1379*f4a2713aSLionel Sambuc // Skip through non-namespace, non-translation-unit contexts. 1380*f4a2713aSLionel Sambuc while (!Ctx->isFileContext()) 1381*f4a2713aSLionel Sambuc Ctx = Ctx->getParent(); 1382*f4a2713aSLionel Sambuc return Ctx->getPrimaryContext(); 1383*f4a2713aSLionel Sambuc } 1384*f4a2713aSLionel Sambuc 1385*f4a2713aSLionel Sambuc bool DeclContext::InEnclosingNamespaceSetOf(const DeclContext *O) const { 1386*f4a2713aSLionel Sambuc // For non-file contexts, this is equivalent to Equals. 1387*f4a2713aSLionel Sambuc if (!isFileContext()) 1388*f4a2713aSLionel Sambuc return O->Equals(this); 1389*f4a2713aSLionel Sambuc 1390*f4a2713aSLionel Sambuc do { 1391*f4a2713aSLionel Sambuc if (O->Equals(this)) 1392*f4a2713aSLionel Sambuc return true; 1393*f4a2713aSLionel Sambuc 1394*f4a2713aSLionel Sambuc const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(O); 1395*f4a2713aSLionel Sambuc if (!NS || !NS->isInline()) 1396*f4a2713aSLionel Sambuc break; 1397*f4a2713aSLionel Sambuc O = NS->getParent(); 1398*f4a2713aSLionel Sambuc } while (O); 1399*f4a2713aSLionel Sambuc 1400*f4a2713aSLionel Sambuc return false; 1401*f4a2713aSLionel Sambuc } 1402*f4a2713aSLionel Sambuc 1403*f4a2713aSLionel Sambuc void DeclContext::makeDeclVisibleInContext(NamedDecl *D) { 1404*f4a2713aSLionel Sambuc DeclContext *PrimaryDC = this->getPrimaryContext(); 1405*f4a2713aSLionel Sambuc DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext(); 1406*f4a2713aSLionel Sambuc // If the decl is being added outside of its semantic decl context, we 1407*f4a2713aSLionel Sambuc // need to ensure that we eagerly build the lookup information for it. 1408*f4a2713aSLionel Sambuc PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC); 1409*f4a2713aSLionel Sambuc } 1410*f4a2713aSLionel Sambuc 1411*f4a2713aSLionel Sambuc void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, 1412*f4a2713aSLionel Sambuc bool Recoverable) { 1413*f4a2713aSLionel Sambuc assert(this == getPrimaryContext() && "expected a primary DC"); 1414*f4a2713aSLionel Sambuc 1415*f4a2713aSLionel Sambuc // Skip declarations within functions. 1416*f4a2713aSLionel Sambuc if (isFunctionOrMethod()) 1417*f4a2713aSLionel Sambuc return; 1418*f4a2713aSLionel Sambuc 1419*f4a2713aSLionel Sambuc // Skip declarations which should be invisible to name lookup. 1420*f4a2713aSLionel Sambuc if (shouldBeHidden(D)) 1421*f4a2713aSLionel Sambuc return; 1422*f4a2713aSLionel Sambuc 1423*f4a2713aSLionel Sambuc // If we already have a lookup data structure, perform the insertion into 1424*f4a2713aSLionel Sambuc // it. If we might have externally-stored decls with this name, look them 1425*f4a2713aSLionel Sambuc // up and perform the insertion. If this decl was declared outside its 1426*f4a2713aSLionel Sambuc // semantic context, buildLookup won't add it, so add it now. 1427*f4a2713aSLionel Sambuc // 1428*f4a2713aSLionel Sambuc // FIXME: As a performance hack, don't add such decls into the translation 1429*f4a2713aSLionel Sambuc // unit unless we're in C++, since qualified lookup into the TU is never 1430*f4a2713aSLionel Sambuc // performed. 1431*f4a2713aSLionel Sambuc if (LookupPtr.getPointer() || hasExternalVisibleStorage() || 1432*f4a2713aSLionel Sambuc ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) && 1433*f4a2713aSLionel Sambuc (getParentASTContext().getLangOpts().CPlusPlus || 1434*f4a2713aSLionel Sambuc !isTranslationUnit()))) { 1435*f4a2713aSLionel Sambuc // If we have lazily omitted any decls, they might have the same name as 1436*f4a2713aSLionel Sambuc // the decl which we are adding, so build a full lookup table before adding 1437*f4a2713aSLionel Sambuc // this decl. 1438*f4a2713aSLionel Sambuc buildLookup(); 1439*f4a2713aSLionel Sambuc makeDeclVisibleInContextImpl(D, Internal); 1440*f4a2713aSLionel Sambuc } else { 1441*f4a2713aSLionel Sambuc LookupPtr.setInt(true); 1442*f4a2713aSLionel Sambuc } 1443*f4a2713aSLionel Sambuc 1444*f4a2713aSLionel Sambuc // If we are a transparent context or inline namespace, insert into our 1445*f4a2713aSLionel Sambuc // parent context, too. This operation is recursive. 1446*f4a2713aSLionel Sambuc if (isTransparentContext() || isInlineNamespace()) 1447*f4a2713aSLionel Sambuc getParent()->getPrimaryContext()-> 1448*f4a2713aSLionel Sambuc makeDeclVisibleInContextWithFlags(D, Internal, Recoverable); 1449*f4a2713aSLionel Sambuc 1450*f4a2713aSLionel Sambuc Decl *DCAsDecl = cast<Decl>(this); 1451*f4a2713aSLionel Sambuc // Notify that a decl was made visible unless we are a Tag being defined. 1452*f4a2713aSLionel Sambuc if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined())) 1453*f4a2713aSLionel Sambuc if (ASTMutationListener *L = DCAsDecl->getASTMutationListener()) 1454*f4a2713aSLionel Sambuc L->AddedVisibleDecl(this, D); 1455*f4a2713aSLionel Sambuc } 1456*f4a2713aSLionel Sambuc 1457*f4a2713aSLionel Sambuc void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { 1458*f4a2713aSLionel Sambuc // Find or create the stored declaration map. 1459*f4a2713aSLionel Sambuc StoredDeclsMap *Map = LookupPtr.getPointer(); 1460*f4a2713aSLionel Sambuc if (!Map) { 1461*f4a2713aSLionel Sambuc ASTContext *C = &getParentASTContext(); 1462*f4a2713aSLionel Sambuc Map = CreateStoredDeclsMap(*C); 1463*f4a2713aSLionel Sambuc } 1464*f4a2713aSLionel Sambuc 1465*f4a2713aSLionel Sambuc // If there is an external AST source, load any declarations it knows about 1466*f4a2713aSLionel Sambuc // with this declaration's name. 1467*f4a2713aSLionel Sambuc // If the lookup table contains an entry about this name it means that we 1468*f4a2713aSLionel Sambuc // have already checked the external source. 1469*f4a2713aSLionel Sambuc if (!Internal) 1470*f4a2713aSLionel Sambuc if (ExternalASTSource *Source = getParentASTContext().getExternalSource()) 1471*f4a2713aSLionel Sambuc if (hasExternalVisibleStorage() && 1472*f4a2713aSLionel Sambuc Map->find(D->getDeclName()) == Map->end()) 1473*f4a2713aSLionel Sambuc Source->FindExternalVisibleDeclsByName(this, D->getDeclName()); 1474*f4a2713aSLionel Sambuc 1475*f4a2713aSLionel Sambuc // Insert this declaration into the map. 1476*f4a2713aSLionel Sambuc StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()]; 1477*f4a2713aSLionel Sambuc 1478*f4a2713aSLionel Sambuc if (Internal) { 1479*f4a2713aSLionel Sambuc // If this is being added as part of loading an external declaration, 1480*f4a2713aSLionel Sambuc // this may not be the only external declaration with this name. 1481*f4a2713aSLionel Sambuc // In this case, we never try to replace an existing declaration; we'll 1482*f4a2713aSLionel Sambuc // handle that when we finalize the list of declarations for this name. 1483*f4a2713aSLionel Sambuc DeclNameEntries.setHasExternalDecls(); 1484*f4a2713aSLionel Sambuc DeclNameEntries.AddSubsequentDecl(D); 1485*f4a2713aSLionel Sambuc return; 1486*f4a2713aSLionel Sambuc } 1487*f4a2713aSLionel Sambuc 1488*f4a2713aSLionel Sambuc else if (DeclNameEntries.isNull()) { 1489*f4a2713aSLionel Sambuc DeclNameEntries.setOnlyValue(D); 1490*f4a2713aSLionel Sambuc return; 1491*f4a2713aSLionel Sambuc } 1492*f4a2713aSLionel Sambuc 1493*f4a2713aSLionel Sambuc if (DeclNameEntries.HandleRedeclaration(D)) { 1494*f4a2713aSLionel Sambuc // This declaration has replaced an existing one for which 1495*f4a2713aSLionel Sambuc // declarationReplaces returns true. 1496*f4a2713aSLionel Sambuc return; 1497*f4a2713aSLionel Sambuc } 1498*f4a2713aSLionel Sambuc 1499*f4a2713aSLionel Sambuc // Put this declaration into the appropriate slot. 1500*f4a2713aSLionel Sambuc DeclNameEntries.AddSubsequentDecl(D); 1501*f4a2713aSLionel Sambuc } 1502*f4a2713aSLionel Sambuc 1503*f4a2713aSLionel Sambuc /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within 1504*f4a2713aSLionel Sambuc /// this context. 1505*f4a2713aSLionel Sambuc DeclContext::udir_iterator_range 1506*f4a2713aSLionel Sambuc DeclContext::getUsingDirectives() const { 1507*f4a2713aSLionel Sambuc // FIXME: Use something more efficient than normal lookup for using 1508*f4a2713aSLionel Sambuc // directives. In C++, using directives are looked up more than anything else. 1509*f4a2713aSLionel Sambuc lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); 1510*f4a2713aSLionel Sambuc return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.begin()), 1511*f4a2713aSLionel Sambuc reinterpret_cast<udir_iterator>(Result.end())); 1512*f4a2713aSLionel Sambuc } 1513*f4a2713aSLionel Sambuc 1514*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 1515*f4a2713aSLionel Sambuc // Creation and Destruction of StoredDeclsMaps. // 1516*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 1517*f4a2713aSLionel Sambuc 1518*f4a2713aSLionel Sambuc StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const { 1519*f4a2713aSLionel Sambuc assert(!LookupPtr.getPointer() && "context already has a decls map"); 1520*f4a2713aSLionel Sambuc assert(getPrimaryContext() == this && 1521*f4a2713aSLionel Sambuc "creating decls map on non-primary context"); 1522*f4a2713aSLionel Sambuc 1523*f4a2713aSLionel Sambuc StoredDeclsMap *M; 1524*f4a2713aSLionel Sambuc bool Dependent = isDependentContext(); 1525*f4a2713aSLionel Sambuc if (Dependent) 1526*f4a2713aSLionel Sambuc M = new DependentStoredDeclsMap(); 1527*f4a2713aSLionel Sambuc else 1528*f4a2713aSLionel Sambuc M = new StoredDeclsMap(); 1529*f4a2713aSLionel Sambuc M->Previous = C.LastSDM; 1530*f4a2713aSLionel Sambuc C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent); 1531*f4a2713aSLionel Sambuc LookupPtr.setPointer(M); 1532*f4a2713aSLionel Sambuc return M; 1533*f4a2713aSLionel Sambuc } 1534*f4a2713aSLionel Sambuc 1535*f4a2713aSLionel Sambuc void ASTContext::ReleaseDeclContextMaps() { 1536*f4a2713aSLionel Sambuc // It's okay to delete DependentStoredDeclsMaps via a StoredDeclsMap 1537*f4a2713aSLionel Sambuc // pointer because the subclass doesn't add anything that needs to 1538*f4a2713aSLionel Sambuc // be deleted. 1539*f4a2713aSLionel Sambuc StoredDeclsMap::DestroyAll(LastSDM.getPointer(), LastSDM.getInt()); 1540*f4a2713aSLionel Sambuc } 1541*f4a2713aSLionel Sambuc 1542*f4a2713aSLionel Sambuc void StoredDeclsMap::DestroyAll(StoredDeclsMap *Map, bool Dependent) { 1543*f4a2713aSLionel Sambuc while (Map) { 1544*f4a2713aSLionel Sambuc // Advance the iteration before we invalidate memory. 1545*f4a2713aSLionel Sambuc llvm::PointerIntPair<StoredDeclsMap*,1> Next = Map->Previous; 1546*f4a2713aSLionel Sambuc 1547*f4a2713aSLionel Sambuc if (Dependent) 1548*f4a2713aSLionel Sambuc delete static_cast<DependentStoredDeclsMap*>(Map); 1549*f4a2713aSLionel Sambuc else 1550*f4a2713aSLionel Sambuc delete Map; 1551*f4a2713aSLionel Sambuc 1552*f4a2713aSLionel Sambuc Map = Next.getPointer(); 1553*f4a2713aSLionel Sambuc Dependent = Next.getInt(); 1554*f4a2713aSLionel Sambuc } 1555*f4a2713aSLionel Sambuc } 1556*f4a2713aSLionel Sambuc 1557*f4a2713aSLionel Sambuc DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, 1558*f4a2713aSLionel Sambuc DeclContext *Parent, 1559*f4a2713aSLionel Sambuc const PartialDiagnostic &PDiag) { 1560*f4a2713aSLionel Sambuc assert(Parent->isDependentContext() 1561*f4a2713aSLionel Sambuc && "cannot iterate dependent diagnostics of non-dependent context"); 1562*f4a2713aSLionel Sambuc Parent = Parent->getPrimaryContext(); 1563*f4a2713aSLionel Sambuc if (!Parent->LookupPtr.getPointer()) 1564*f4a2713aSLionel Sambuc Parent->CreateStoredDeclsMap(C); 1565*f4a2713aSLionel Sambuc 1566*f4a2713aSLionel Sambuc DependentStoredDeclsMap *Map 1567*f4a2713aSLionel Sambuc = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr.getPointer()); 1568*f4a2713aSLionel Sambuc 1569*f4a2713aSLionel Sambuc // Allocate the copy of the PartialDiagnostic via the ASTContext's 1570*f4a2713aSLionel Sambuc // BumpPtrAllocator, rather than the ASTContext itself. 1571*f4a2713aSLionel Sambuc PartialDiagnostic::Storage *DiagStorage = 0; 1572*f4a2713aSLionel Sambuc if (PDiag.hasStorage()) 1573*f4a2713aSLionel Sambuc DiagStorage = new (C) PartialDiagnostic::Storage; 1574*f4a2713aSLionel Sambuc 1575*f4a2713aSLionel Sambuc DependentDiagnostic *DD = new (C) DependentDiagnostic(PDiag, DiagStorage); 1576*f4a2713aSLionel Sambuc 1577*f4a2713aSLionel Sambuc // TODO: Maybe we shouldn't reverse the order during insertion. 1578*f4a2713aSLionel Sambuc DD->NextDiagnostic = Map->FirstDiagnostic; 1579*f4a2713aSLionel Sambuc Map->FirstDiagnostic = DD; 1580*f4a2713aSLionel Sambuc 1581*f4a2713aSLionel Sambuc return DD; 1582*f4a2713aSLionel Sambuc } 1583