blob: eeb2e01781e53c3082e94bbc35ff752249e4d212 [file] [log] [blame]
John McCall8fb0d9d2011-05-01 22:35:37 +00001//===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Scope class, which is used for recording
11// information about a lexical scope.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Sema/Scope.h"
Nick Lewyckyd78f92f2014-05-03 00:41:18 +000016#include "clang/AST/Decl.h"
David Majnemer2206bf52014-03-05 08:57:59 +000017#include "llvm/Support/raw_ostream.h"
John McCall8fb0d9d2011-05-01 22:35:37 +000018
19using namespace clang;
20
21void Scope::Init(Scope *parent, unsigned flags) {
22 AnyParent = parent;
23 Flags = flags;
Richard Smith1002d102012-02-17 01:35:32 +000024
25 if (parent && !(flags & FnScope)) {
26 BreakParent = parent->BreakParent;
27 ContinueParent = parent->ContinueParent;
28 } else {
29 // Control scopes do not contain the contents of nested function scopes for
30 // control flow purposes.
Craig Topperc3ec1492014-05-26 06:22:03 +000031 BreakParent = ContinueParent = nullptr;
Richard Smith1002d102012-02-17 01:35:32 +000032 }
33
John McCall8fb0d9d2011-05-01 22:35:37 +000034 if (parent) {
35 Depth = parent->Depth + 1;
36 PrototypeDepth = parent->PrototypeDepth;
37 PrototypeIndex = 0;
38 FnParent = parent->FnParent;
John McCall8fb0d9d2011-05-01 22:35:37 +000039 BlockParent = parent->BlockParent;
40 TemplateParamParent = parent->TemplateParamParent;
David Majnemer2206bf52014-03-05 08:57:59 +000041 MSLocalManglingParent = parent->MSLocalManglingParent;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +000042 if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
43 FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
44 0)
45 Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
John McCall8fb0d9d2011-05-01 22:35:37 +000046 } else {
47 Depth = 0;
48 PrototypeDepth = 0;
49 PrototypeIndex = 0;
Warren Huntf6be4cb2014-07-25 20:52:51 +000050 MSLocalManglingParent = FnParent = BlockParent = nullptr;
Craig Topperc3ec1492014-05-26 06:22:03 +000051 TemplateParamParent = nullptr;
David Majnemer2206bf52014-03-05 08:57:59 +000052 MSLocalManglingNumber = 1;
John McCall8fb0d9d2011-05-01 22:35:37 +000053 }
54
55 // If this scope is a function or contains breaks/continues, remember it.
56 if (flags & FnScope) FnParent = this;
David Majnemer2206bf52014-03-05 08:57:59 +000057 // The MS mangler uses the number of scopes that can hold declarations as
58 // part of an external name.
59 if (Flags & (ClassScope | FnScope)) {
60 MSLocalManglingNumber = getMSLocalManglingNumber();
61 MSLocalManglingParent = this;
62 }
John McCall8fb0d9d2011-05-01 22:35:37 +000063 if (flags & BreakScope) BreakParent = this;
64 if (flags & ContinueScope) ContinueParent = this;
John McCall8fb0d9d2011-05-01 22:35:37 +000065 if (flags & BlockScope) BlockParent = this;
66 if (flags & TemplateParamScope) TemplateParamParent = this;
67
68 // If this is a prototype scope, record that.
69 if (flags & FunctionPrototypeScope) PrototypeDepth++;
Hans Wennborgfe781452014-06-17 00:00:18 +000070
David Majnemer2206bf52014-03-05 08:57:59 +000071 if (flags & DeclScope) {
72 if (flags & FunctionPrototypeScope)
73 ; // Prototype scopes are uninteresting.
74 else if ((flags & ClassScope) && getParent()->isClassScope())
75 ; // Nested class scopes aren't ambiguous.
76 else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
77 ; // Classes inside of namespaces aren't ambiguous.
Hans Wennborgfe781452014-06-17 00:00:18 +000078 else if ((flags & EnumScope))
79 ; // Don't increment for enum scopes.
David Majnemer2206bf52014-03-05 08:57:59 +000080 else
81 incrementMSLocalManglingNumber();
82 }
John McCall8fb0d9d2011-05-01 22:35:37 +000083
84 DeclsInScope.clear();
85 UsingDirectives.clear();
Craig Topperc3ec1492014-05-26 06:22:03 +000086 Entity = nullptr;
John McCall8fb0d9d2011-05-01 22:35:37 +000087 ErrorTrap.reset();
Nick Lewyckyd78f92f2014-05-03 00:41:18 +000088 NRVO.setPointerAndInt(nullptr, 0);
John McCall8fb0d9d2011-05-01 22:35:37 +000089}
James Molloy6f8780b2012-02-29 10:24:19 +000090
91bool Scope::containedInPrototypeScope() const {
92 const Scope *S = this;
93 while (S) {
94 if (S->isFunctionPrototypeScope())
95 return true;
96 S = S->getParent();
97 }
98 return false;
99}
Serge Pavlov09f99242014-01-23 15:05:00 +0000100
101void Scope::AddFlags(unsigned FlagsToSet) {
102 assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
103 "Unsupported scope flags");
104 if (FlagsToSet & BreakScope) {
105 assert((Flags & BreakScope) == 0 && "Already set");
106 BreakParent = this;
107 }
108 if (FlagsToSet & ContinueScope) {
109 assert((Flags & ContinueScope) == 0 && "Already set");
110 ContinueParent = this;
111 }
112 Flags |= FlagsToSet;
113}
114
Nick Lewyckyd78f92f2014-05-03 00:41:18 +0000115void Scope::mergeNRVOIntoParent() {
116 if (VarDecl *Candidate = NRVO.getPointer()) {
117 if (isDeclScope(Candidate))
118 Candidate->setNRVOVariable(true);
119 }
120
121 if (getEntity())
122 return;
123
124 if (NRVO.getInt())
125 getParent()->setNoNRVO();
126 else if (NRVO.getPointer())
127 getParent()->addNRVOCandidate(NRVO.getPointer());
128}
129
David Majnemer2206bf52014-03-05 08:57:59 +0000130void Scope::dump() const { dumpImpl(llvm::errs()); }
131
132void Scope::dumpImpl(raw_ostream &OS) const {
133 unsigned Flags = getFlags();
134 bool HasFlags = Flags != 0;
135
136 if (HasFlags)
137 OS << "Flags: ";
138
139 while (Flags) {
140 if (Flags & FnScope) {
141 OS << "FnScope";
142 Flags &= ~FnScope;
143 } else if (Flags & BreakScope) {
144 OS << "BreakScope";
145 Flags &= ~BreakScope;
146 } else if (Flags & ContinueScope) {
147 OS << "ContinueScope";
148 Flags &= ~ContinueScope;
149 } else if (Flags & DeclScope) {
150 OS << "DeclScope";
151 Flags &= ~DeclScope;
152 } else if (Flags & ControlScope) {
153 OS << "ControlScope";
154 Flags &= ~ControlScope;
155 } else if (Flags & ClassScope) {
156 OS << "ClassScope";
157 Flags &= ~ClassScope;
158 } else if (Flags & BlockScope) {
159 OS << "BlockScope";
160 Flags &= ~BlockScope;
161 } else if (Flags & TemplateParamScope) {
162 OS << "TemplateParamScope";
163 Flags &= ~TemplateParamScope;
164 } else if (Flags & FunctionPrototypeScope) {
165 OS << "FunctionPrototypeScope";
166 Flags &= ~FunctionPrototypeScope;
167 } else if (Flags & FunctionDeclarationScope) {
168 OS << "FunctionDeclarationScope";
169 Flags &= ~FunctionDeclarationScope;
170 } else if (Flags & AtCatchScope) {
171 OS << "AtCatchScope";
172 Flags &= ~AtCatchScope;
173 } else if (Flags & ObjCMethodScope) {
174 OS << "ObjCMethodScope";
175 Flags &= ~ObjCMethodScope;
176 } else if (Flags & SwitchScope) {
177 OS << "SwitchScope";
178 Flags &= ~SwitchScope;
179 } else if (Flags & TryScope) {
180 OS << "TryScope";
181 Flags &= ~TryScope;
182 } else if (Flags & FnTryCatchScope) {
183 OS << "FnTryCatchScope";
184 Flags &= ~FnTryCatchScope;
Nico Webereb61d4d2014-07-06 22:53:19 +0000185 } else if (Flags & SEHTryScope) {
186 OS << "SEHTryScope";
187 Flags &= ~SEHTryScope;
Reid Kleckner1d59f992015-01-22 01:36:17 +0000188 } else if (Flags & SEHExceptScope) {
189 OS << "SEHExceptScope";
190 Flags &= ~SEHExceptScope;
David Majnemer2206bf52014-03-05 08:57:59 +0000191 } else if (Flags & OpenMPDirectiveScope) {
192 OS << "OpenMPDirectiveScope";
193 Flags &= ~OpenMPDirectiveScope;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +0000194 } else if (Flags & OpenMPLoopDirectiveScope) {
195 OS << "OpenMPLoopDirectiveScope";
196 Flags &= ~OpenMPLoopDirectiveScope;
197 } else if (Flags & OpenMPSimdDirectiveScope) {
198 OS << "OpenMPSimdDirectiveScope";
199 Flags &= ~OpenMPSimdDirectiveScope;
David Majnemer2206bf52014-03-05 08:57:59 +0000200 }
201
202 if (Flags)
203 OS << " | ";
204 }
205 if (HasFlags)
206 OS << '\n';
207
208 if (const Scope *Parent = getParent())
209 OS << "Parent: (clang::Scope*)" << Parent << '\n';
210
211 OS << "Depth: " << Depth << '\n';
212 OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
213 if (const DeclContext *DC = getEntity())
214 OS << "Entity : (clang::DeclContext*)" << DC << '\n';
Nick Lewyckyd78f92f2014-05-03 00:41:18 +0000215
216 if (NRVO.getInt())
217 OS << "NRVO not allowed";
218 else if (NRVO.getPointer())
219 OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
David Majnemer2206bf52014-03-05 08:57:59 +0000220}