xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/Scope.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
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 Scope class, which is used for recording
11f4a2713aSLionel Sambuc // information about a lexical scope.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
16*0a6a1f1dSLionel Sambuc #include "clang/AST/Decl.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/Support/raw_ostream.h"
18f4a2713aSLionel Sambuc 
19f4a2713aSLionel Sambuc using namespace clang;
20f4a2713aSLionel Sambuc 
Init(Scope * parent,unsigned flags)21f4a2713aSLionel Sambuc void Scope::Init(Scope *parent, unsigned flags) {
22f4a2713aSLionel Sambuc   AnyParent = parent;
23f4a2713aSLionel Sambuc   Flags = flags;
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc   if (parent && !(flags & FnScope)) {
26f4a2713aSLionel Sambuc     BreakParent    = parent->BreakParent;
27f4a2713aSLionel Sambuc     ContinueParent = parent->ContinueParent;
28f4a2713aSLionel Sambuc   } else {
29f4a2713aSLionel Sambuc     // Control scopes do not contain the contents of nested function scopes for
30f4a2713aSLionel Sambuc     // control flow purposes.
31*0a6a1f1dSLionel Sambuc     BreakParent = ContinueParent = nullptr;
32f4a2713aSLionel Sambuc   }
33f4a2713aSLionel Sambuc 
34f4a2713aSLionel Sambuc   if (parent) {
35f4a2713aSLionel Sambuc     Depth = parent->Depth + 1;
36f4a2713aSLionel Sambuc     PrototypeDepth = parent->PrototypeDepth;
37f4a2713aSLionel Sambuc     PrototypeIndex = 0;
38f4a2713aSLionel Sambuc     FnParent       = parent->FnParent;
39f4a2713aSLionel Sambuc     BlockParent    = parent->BlockParent;
40f4a2713aSLionel Sambuc     TemplateParamParent = parent->TemplateParamParent;
41*0a6a1f1dSLionel Sambuc     MSLocalManglingParent = parent->MSLocalManglingParent;
42*0a6a1f1dSLionel Sambuc     if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
43*0a6a1f1dSLionel Sambuc                   FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
44*0a6a1f1dSLionel Sambuc         0)
45*0a6a1f1dSLionel Sambuc       Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
46f4a2713aSLionel Sambuc   } else {
47f4a2713aSLionel Sambuc     Depth = 0;
48f4a2713aSLionel Sambuc     PrototypeDepth = 0;
49f4a2713aSLionel Sambuc     PrototypeIndex = 0;
50*0a6a1f1dSLionel Sambuc     MSLocalManglingParent = FnParent = BlockParent = nullptr;
51*0a6a1f1dSLionel Sambuc     TemplateParamParent = nullptr;
52*0a6a1f1dSLionel Sambuc     MSLocalManglingNumber = 1;
53f4a2713aSLionel Sambuc   }
54f4a2713aSLionel Sambuc 
55f4a2713aSLionel Sambuc   // If this scope is a function or contains breaks/continues, remember it.
56f4a2713aSLionel Sambuc   if (flags & FnScope)            FnParent = this;
57*0a6a1f1dSLionel Sambuc   // The MS mangler uses the number of scopes that can hold declarations as
58*0a6a1f1dSLionel Sambuc   // part of an external name.
59*0a6a1f1dSLionel Sambuc   if (Flags & (ClassScope | FnScope)) {
60*0a6a1f1dSLionel Sambuc     MSLocalManglingNumber = getMSLocalManglingNumber();
61*0a6a1f1dSLionel Sambuc     MSLocalManglingParent = this;
62*0a6a1f1dSLionel Sambuc   }
63f4a2713aSLionel Sambuc   if (flags & BreakScope)         BreakParent = this;
64f4a2713aSLionel Sambuc   if (flags & ContinueScope)      ContinueParent = this;
65f4a2713aSLionel Sambuc   if (flags & BlockScope)         BlockParent = this;
66f4a2713aSLionel Sambuc   if (flags & TemplateParamScope) TemplateParamParent = this;
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   // If this is a prototype scope, record that.
69f4a2713aSLionel Sambuc   if (flags & FunctionPrototypeScope) PrototypeDepth++;
70f4a2713aSLionel Sambuc 
71*0a6a1f1dSLionel Sambuc   if (flags & DeclScope) {
72*0a6a1f1dSLionel Sambuc     if (flags & FunctionPrototypeScope)
73*0a6a1f1dSLionel Sambuc       ; // Prototype scopes are uninteresting.
74*0a6a1f1dSLionel Sambuc     else if ((flags & ClassScope) && getParent()->isClassScope())
75*0a6a1f1dSLionel Sambuc       ; // Nested class scopes aren't ambiguous.
76*0a6a1f1dSLionel Sambuc     else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
77*0a6a1f1dSLionel Sambuc       ; // Classes inside of namespaces aren't ambiguous.
78*0a6a1f1dSLionel Sambuc     else if ((flags & EnumScope))
79*0a6a1f1dSLionel Sambuc       ; // Don't increment for enum scopes.
80*0a6a1f1dSLionel Sambuc     else
81*0a6a1f1dSLionel Sambuc       incrementMSLocalManglingNumber();
82*0a6a1f1dSLionel Sambuc   }
83*0a6a1f1dSLionel Sambuc 
84f4a2713aSLionel Sambuc   DeclsInScope.clear();
85f4a2713aSLionel Sambuc   UsingDirectives.clear();
86*0a6a1f1dSLionel Sambuc   Entity = nullptr;
87f4a2713aSLionel Sambuc   ErrorTrap.reset();
88*0a6a1f1dSLionel Sambuc   NRVO.setPointerAndInt(nullptr, 0);
89f4a2713aSLionel Sambuc }
90f4a2713aSLionel Sambuc 
containedInPrototypeScope() const91f4a2713aSLionel Sambuc bool Scope::containedInPrototypeScope() const {
92f4a2713aSLionel Sambuc   const Scope *S = this;
93f4a2713aSLionel Sambuc   while (S) {
94f4a2713aSLionel Sambuc     if (S->isFunctionPrototypeScope())
95f4a2713aSLionel Sambuc       return true;
96f4a2713aSLionel Sambuc     S = S->getParent();
97f4a2713aSLionel Sambuc   }
98f4a2713aSLionel Sambuc   return false;
99f4a2713aSLionel Sambuc }
100*0a6a1f1dSLionel Sambuc 
AddFlags(unsigned FlagsToSet)101*0a6a1f1dSLionel Sambuc void Scope::AddFlags(unsigned FlagsToSet) {
102*0a6a1f1dSLionel Sambuc   assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
103*0a6a1f1dSLionel Sambuc          "Unsupported scope flags");
104*0a6a1f1dSLionel Sambuc   if (FlagsToSet & BreakScope) {
105*0a6a1f1dSLionel Sambuc     assert((Flags & BreakScope) == 0 && "Already set");
106*0a6a1f1dSLionel Sambuc     BreakParent = this;
107*0a6a1f1dSLionel Sambuc   }
108*0a6a1f1dSLionel Sambuc   if (FlagsToSet & ContinueScope) {
109*0a6a1f1dSLionel Sambuc     assert((Flags & ContinueScope) == 0 && "Already set");
110*0a6a1f1dSLionel Sambuc     ContinueParent = this;
111*0a6a1f1dSLionel Sambuc   }
112*0a6a1f1dSLionel Sambuc   Flags |= FlagsToSet;
113*0a6a1f1dSLionel Sambuc }
114*0a6a1f1dSLionel Sambuc 
mergeNRVOIntoParent()115*0a6a1f1dSLionel Sambuc void Scope::mergeNRVOIntoParent() {
116*0a6a1f1dSLionel Sambuc   if (VarDecl *Candidate = NRVO.getPointer()) {
117*0a6a1f1dSLionel Sambuc     if (isDeclScope(Candidate))
118*0a6a1f1dSLionel Sambuc       Candidate->setNRVOVariable(true);
119*0a6a1f1dSLionel Sambuc   }
120*0a6a1f1dSLionel Sambuc 
121*0a6a1f1dSLionel Sambuc   if (getEntity())
122*0a6a1f1dSLionel Sambuc     return;
123*0a6a1f1dSLionel Sambuc 
124*0a6a1f1dSLionel Sambuc   if (NRVO.getInt())
125*0a6a1f1dSLionel Sambuc     getParent()->setNoNRVO();
126*0a6a1f1dSLionel Sambuc   else if (NRVO.getPointer())
127*0a6a1f1dSLionel Sambuc     getParent()->addNRVOCandidate(NRVO.getPointer());
128*0a6a1f1dSLionel Sambuc }
129*0a6a1f1dSLionel Sambuc 
dump() const130*0a6a1f1dSLionel Sambuc void Scope::dump() const { dumpImpl(llvm::errs()); }
131*0a6a1f1dSLionel Sambuc 
dumpImpl(raw_ostream & OS) const132*0a6a1f1dSLionel Sambuc void Scope::dumpImpl(raw_ostream &OS) const {
133*0a6a1f1dSLionel Sambuc   unsigned Flags = getFlags();
134*0a6a1f1dSLionel Sambuc   bool HasFlags = Flags != 0;
135*0a6a1f1dSLionel Sambuc 
136*0a6a1f1dSLionel Sambuc   if (HasFlags)
137*0a6a1f1dSLionel Sambuc     OS << "Flags: ";
138*0a6a1f1dSLionel Sambuc 
139*0a6a1f1dSLionel Sambuc   while (Flags) {
140*0a6a1f1dSLionel Sambuc     if (Flags & FnScope) {
141*0a6a1f1dSLionel Sambuc       OS << "FnScope";
142*0a6a1f1dSLionel Sambuc       Flags &= ~FnScope;
143*0a6a1f1dSLionel Sambuc     } else if (Flags & BreakScope) {
144*0a6a1f1dSLionel Sambuc       OS << "BreakScope";
145*0a6a1f1dSLionel Sambuc       Flags &= ~BreakScope;
146*0a6a1f1dSLionel Sambuc     } else if (Flags & ContinueScope) {
147*0a6a1f1dSLionel Sambuc       OS << "ContinueScope";
148*0a6a1f1dSLionel Sambuc       Flags &= ~ContinueScope;
149*0a6a1f1dSLionel Sambuc     } else if (Flags & DeclScope) {
150*0a6a1f1dSLionel Sambuc       OS << "DeclScope";
151*0a6a1f1dSLionel Sambuc       Flags &= ~DeclScope;
152*0a6a1f1dSLionel Sambuc     } else if (Flags & ControlScope) {
153*0a6a1f1dSLionel Sambuc       OS << "ControlScope";
154*0a6a1f1dSLionel Sambuc       Flags &= ~ControlScope;
155*0a6a1f1dSLionel Sambuc     } else if (Flags & ClassScope) {
156*0a6a1f1dSLionel Sambuc       OS << "ClassScope";
157*0a6a1f1dSLionel Sambuc       Flags &= ~ClassScope;
158*0a6a1f1dSLionel Sambuc     } else if (Flags & BlockScope) {
159*0a6a1f1dSLionel Sambuc       OS << "BlockScope";
160*0a6a1f1dSLionel Sambuc       Flags &= ~BlockScope;
161*0a6a1f1dSLionel Sambuc     } else if (Flags & TemplateParamScope) {
162*0a6a1f1dSLionel Sambuc       OS << "TemplateParamScope";
163*0a6a1f1dSLionel Sambuc       Flags &= ~TemplateParamScope;
164*0a6a1f1dSLionel Sambuc     } else if (Flags & FunctionPrototypeScope) {
165*0a6a1f1dSLionel Sambuc       OS << "FunctionPrototypeScope";
166*0a6a1f1dSLionel Sambuc       Flags &= ~FunctionPrototypeScope;
167*0a6a1f1dSLionel Sambuc     } else if (Flags & FunctionDeclarationScope) {
168*0a6a1f1dSLionel Sambuc       OS << "FunctionDeclarationScope";
169*0a6a1f1dSLionel Sambuc       Flags &= ~FunctionDeclarationScope;
170*0a6a1f1dSLionel Sambuc     } else if (Flags & AtCatchScope) {
171*0a6a1f1dSLionel Sambuc       OS << "AtCatchScope";
172*0a6a1f1dSLionel Sambuc       Flags &= ~AtCatchScope;
173*0a6a1f1dSLionel Sambuc     } else if (Flags & ObjCMethodScope) {
174*0a6a1f1dSLionel Sambuc       OS << "ObjCMethodScope";
175*0a6a1f1dSLionel Sambuc       Flags &= ~ObjCMethodScope;
176*0a6a1f1dSLionel Sambuc     } else if (Flags & SwitchScope) {
177*0a6a1f1dSLionel Sambuc       OS << "SwitchScope";
178*0a6a1f1dSLionel Sambuc       Flags &= ~SwitchScope;
179*0a6a1f1dSLionel Sambuc     } else if (Flags & TryScope) {
180*0a6a1f1dSLionel Sambuc       OS << "TryScope";
181*0a6a1f1dSLionel Sambuc       Flags &= ~TryScope;
182*0a6a1f1dSLionel Sambuc     } else if (Flags & FnTryCatchScope) {
183*0a6a1f1dSLionel Sambuc       OS << "FnTryCatchScope";
184*0a6a1f1dSLionel Sambuc       Flags &= ~FnTryCatchScope;
185*0a6a1f1dSLionel Sambuc     } else if (Flags & SEHTryScope) {
186*0a6a1f1dSLionel Sambuc       OS << "SEHTryScope";
187*0a6a1f1dSLionel Sambuc       Flags &= ~SEHTryScope;
188*0a6a1f1dSLionel Sambuc     } else if (Flags & OpenMPDirectiveScope) {
189*0a6a1f1dSLionel Sambuc       OS << "OpenMPDirectiveScope";
190*0a6a1f1dSLionel Sambuc       Flags &= ~OpenMPDirectiveScope;
191*0a6a1f1dSLionel Sambuc     } else if (Flags & OpenMPLoopDirectiveScope) {
192*0a6a1f1dSLionel Sambuc       OS << "OpenMPLoopDirectiveScope";
193*0a6a1f1dSLionel Sambuc       Flags &= ~OpenMPLoopDirectiveScope;
194*0a6a1f1dSLionel Sambuc     } else if (Flags & OpenMPSimdDirectiveScope) {
195*0a6a1f1dSLionel Sambuc       OS << "OpenMPSimdDirectiveScope";
196*0a6a1f1dSLionel Sambuc       Flags &= ~OpenMPSimdDirectiveScope;
197*0a6a1f1dSLionel Sambuc     }
198*0a6a1f1dSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc     if (Flags)
200*0a6a1f1dSLionel Sambuc       OS << " | ";
201*0a6a1f1dSLionel Sambuc   }
202*0a6a1f1dSLionel Sambuc   if (HasFlags)
203*0a6a1f1dSLionel Sambuc     OS << '\n';
204*0a6a1f1dSLionel Sambuc 
205*0a6a1f1dSLionel Sambuc   if (const Scope *Parent = getParent())
206*0a6a1f1dSLionel Sambuc     OS << "Parent: (clang::Scope*)" << Parent << '\n';
207*0a6a1f1dSLionel Sambuc 
208*0a6a1f1dSLionel Sambuc   OS << "Depth: " << Depth << '\n';
209*0a6a1f1dSLionel Sambuc   OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
210*0a6a1f1dSLionel Sambuc   if (const DeclContext *DC = getEntity())
211*0a6a1f1dSLionel Sambuc     OS << "Entity : (clang::DeclContext*)" << DC << '\n';
212*0a6a1f1dSLionel Sambuc 
213*0a6a1f1dSLionel Sambuc   if (NRVO.getInt())
214*0a6a1f1dSLionel Sambuc     OS << "NRVO not allowed";
215*0a6a1f1dSLionel Sambuc   else if (NRVO.getPointer())
216*0a6a1f1dSLionel Sambuc     OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
217*0a6a1f1dSLionel Sambuc }
218