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