1 //===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Scope class, which is used for recording
11 // information about a lexical scope.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Sema/Scope.h"
16 #include "clang/AST/Decl.h"
17 #include "llvm/Support/raw_ostream.h"
19 using namespace clang;
21 void Scope::setFlags(Scope *parent, unsigned flags) {
25 if (parent && !(flags & FnScope)) {
26 BreakParent = parent->BreakParent;
27 ContinueParent = parent->ContinueParent;
29 // Control scopes do not contain the contents of nested function scopes for
30 // control flow purposes.
31 BreakParent = ContinueParent = nullptr;
35 Depth = parent->Depth + 1;
36 PrototypeDepth = parent->PrototypeDepth;
38 FnParent = parent->FnParent;
39 BlockParent = parent->BlockParent;
40 TemplateParamParent = parent->TemplateParamParent;
41 MSLastManglingParent = parent->MSLastManglingParent;
42 MSCurManglingNumber = getMSLastManglingNumber();
43 if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
44 FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
46 Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
51 MSLastManglingParent = FnParent = BlockParent = nullptr;
52 TemplateParamParent = nullptr;
53 MSLastManglingNumber = 1;
54 MSCurManglingNumber = 1;
57 // If this scope is a function or contains breaks/continues, remember it.
58 if (flags & FnScope) FnParent = this;
59 // The MS mangler uses the number of scopes that can hold declarations as
60 // part of an external name.
61 if (Flags & (ClassScope | FnScope)) {
62 MSLastManglingNumber = getMSLastManglingNumber();
63 MSLastManglingParent = this;
64 MSCurManglingNumber = 1;
66 if (flags & BreakScope) BreakParent = this;
67 if (flags & ContinueScope) ContinueParent = this;
68 if (flags & BlockScope) BlockParent = this;
69 if (flags & TemplateParamScope) TemplateParamParent = this;
71 // If this is a prototype scope, record that.
72 if (flags & FunctionPrototypeScope) PrototypeDepth++;
74 if (flags & DeclScope) {
75 if (flags & FunctionPrototypeScope)
76 ; // Prototype scopes are uninteresting.
77 else if ((flags & ClassScope) && getParent()->isClassScope())
78 ; // Nested class scopes aren't ambiguous.
79 else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
80 ; // Classes inside of namespaces aren't ambiguous.
81 else if ((flags & EnumScope))
82 ; // Don't increment for enum scopes.
84 incrementMSManglingNumber();
88 void Scope::Init(Scope *parent, unsigned flags) {
89 setFlags(parent, flags);
92 UsingDirectives.clear();
95 NRVO.setPointerAndInt(nullptr, 0);
98 bool Scope::containedInPrototypeScope() const {
99 const Scope *S = this;
101 if (S->isFunctionPrototypeScope())
108 void Scope::AddFlags(unsigned FlagsToSet) {
109 assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
110 "Unsupported scope flags");
111 if (FlagsToSet & BreakScope) {
112 assert((Flags & BreakScope) == 0 && "Already set");
115 if (FlagsToSet & ContinueScope) {
116 assert((Flags & ContinueScope) == 0 && "Already set");
117 ContinueParent = this;
122 void Scope::mergeNRVOIntoParent() {
123 if (VarDecl *Candidate = NRVO.getPointer()) {
124 if (isDeclScope(Candidate))
125 Candidate->setNRVOVariable(true);
132 getParent()->setNoNRVO();
133 else if (NRVO.getPointer())
134 getParent()->addNRVOCandidate(NRVO.getPointer());
137 LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); }
139 void Scope::dumpImpl(raw_ostream &OS) const {
140 unsigned Flags = getFlags();
141 bool HasFlags = Flags != 0;
147 if (Flags & FnScope) {
150 } else if (Flags & BreakScope) {
152 Flags &= ~BreakScope;
153 } else if (Flags & ContinueScope) {
154 OS << "ContinueScope";
155 Flags &= ~ContinueScope;
156 } else if (Flags & DeclScope) {
159 } else if (Flags & ControlScope) {
160 OS << "ControlScope";
161 Flags &= ~ControlScope;
162 } else if (Flags & ClassScope) {
164 Flags &= ~ClassScope;
165 } else if (Flags & BlockScope) {
167 Flags &= ~BlockScope;
168 } else if (Flags & TemplateParamScope) {
169 OS << "TemplateParamScope";
170 Flags &= ~TemplateParamScope;
171 } else if (Flags & FunctionPrototypeScope) {
172 OS << "FunctionPrototypeScope";
173 Flags &= ~FunctionPrototypeScope;
174 } else if (Flags & FunctionDeclarationScope) {
175 OS << "FunctionDeclarationScope";
176 Flags &= ~FunctionDeclarationScope;
177 } else if (Flags & AtCatchScope) {
178 OS << "AtCatchScope";
179 Flags &= ~AtCatchScope;
180 } else if (Flags & ObjCMethodScope) {
181 OS << "ObjCMethodScope";
182 Flags &= ~ObjCMethodScope;
183 } else if (Flags & SwitchScope) {
185 Flags &= ~SwitchScope;
186 } else if (Flags & TryScope) {
189 } else if (Flags & FnTryCatchScope) {
190 OS << "FnTryCatchScope";
191 Flags &= ~FnTryCatchScope;
192 } else if (Flags & SEHTryScope) {
194 Flags &= ~SEHTryScope;
195 } else if (Flags & SEHExceptScope) {
196 OS << "SEHExceptScope";
197 Flags &= ~SEHExceptScope;
198 } else if (Flags & OpenMPDirectiveScope) {
199 OS << "OpenMPDirectiveScope";
200 Flags &= ~OpenMPDirectiveScope;
201 } else if (Flags & OpenMPLoopDirectiveScope) {
202 OS << "OpenMPLoopDirectiveScope";
203 Flags &= ~OpenMPLoopDirectiveScope;
204 } else if (Flags & OpenMPSimdDirectiveScope) {
205 OS << "OpenMPSimdDirectiveScope";
206 Flags &= ~OpenMPSimdDirectiveScope;
215 if (const Scope *Parent = getParent())
216 OS << "Parent: (clang::Scope*)" << Parent << '\n';
218 OS << "Depth: " << Depth << '\n';
219 OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n';
220 OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n';
221 if (const DeclContext *DC = getEntity())
222 OS << "Entity : (clang::DeclContext*)" << DC << '\n';
225 OS << "NRVO not allowed\n";
226 else if (NRVO.getPointer())
227 OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';