1 //===- 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"
16 #include "llvm/Support/raw_ostream.h"
17 
18 using namespace clang;
19 
20 void Scope::Init(Scope *parent, unsigned flags) {
21   AnyParent = parent;
22   Flags = flags;
23 
24   if (parent && !(flags & FnScope)) {
25     BreakParent    = parent->BreakParent;
26     ContinueParent = parent->ContinueParent;
27   } else {
28     // Control scopes do not contain the contents of nested function scopes for
29     // control flow purposes.
30     BreakParent = ContinueParent = 0;
31   }
32 
33   if (parent) {
34     Depth = parent->Depth + 1;
35     PrototypeDepth = parent->PrototypeDepth;
36     PrototypeIndex = 0;
37     FnParent       = parent->FnParent;
38     BlockParent    = parent->BlockParent;
39     TemplateParamParent = parent->TemplateParamParent;
40     MSLocalManglingParent = parent->MSLocalManglingParent;
41   } else {
42     Depth = 0;
43     PrototypeDepth = 0;
44     PrototypeIndex = 0;
45     MSLocalManglingParent = FnParent = BlockParent = 0;
46     TemplateParamParent = 0;
47     MSLocalManglingNumber = 1;
48   }
49 
50   // If this scope is a function or contains breaks/continues, remember it.
51   if (flags & FnScope)            FnParent = this;
52   // The MS mangler uses the number of scopes that can hold declarations as
53   // part of an external name.
54   if (Flags & (ClassScope | FnScope)) {
55     MSLocalManglingNumber = getMSLocalManglingNumber();
56     MSLocalManglingParent = this;
57   }
58   if (flags & BreakScope)         BreakParent = this;
59   if (flags & ContinueScope)      ContinueParent = this;
60   if (flags & BlockScope)         BlockParent = this;
61   if (flags & TemplateParamScope) TemplateParamParent = this;
62 
63   // If this is a prototype scope, record that.
64   if (flags & FunctionPrototypeScope) PrototypeDepth++;
65   if (flags & DeclScope) {
66     if (flags & FunctionPrototypeScope)
67       ; // Prototype scopes are uninteresting.
68     else if ((flags & ClassScope) && getParent()->isClassScope())
69       ; // Nested class scopes aren't ambiguous.
70     else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
71       ; // Classes inside of namespaces aren't ambiguous.
72     else
73       incrementMSLocalManglingNumber();
74   }
75 
76   DeclsInScope.clear();
77   UsingDirectives.clear();
78   Entity = 0;
79   ErrorTrap.reset();
80 }
81 
82 bool Scope::containedInPrototypeScope() const {
83   const Scope *S = this;
84   while (S) {
85     if (S->isFunctionPrototypeScope())
86       return true;
87     S = S->getParent();
88   }
89   return false;
90 }
91 
92 void Scope::AddFlags(unsigned FlagsToSet) {
93   assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
94          "Unsupported scope flags");
95   if (FlagsToSet & BreakScope) {
96     assert((Flags & BreakScope) == 0 && "Already set");
97     BreakParent = this;
98   }
99   if (FlagsToSet & ContinueScope) {
100     assert((Flags & ContinueScope) == 0 && "Already set");
101     ContinueParent = this;
102   }
103   Flags |= FlagsToSet;
104 }
105 
106 void Scope::dump() const { dumpImpl(llvm::errs()); }
107 
108 void Scope::dumpImpl(raw_ostream &OS) const {
109   unsigned Flags = getFlags();
110   bool HasFlags = Flags != 0;
111 
112   if (HasFlags)
113     OS << "Flags: ";
114 
115   while (Flags) {
116     if (Flags & FnScope) {
117       OS << "FnScope";
118       Flags &= ~FnScope;
119     } else if (Flags & BreakScope) {
120       OS << "BreakScope";
121       Flags &= ~BreakScope;
122     } else if (Flags & ContinueScope) {
123       OS << "ContinueScope";
124       Flags &= ~ContinueScope;
125     } else if (Flags & DeclScope) {
126       OS << "DeclScope";
127       Flags &= ~DeclScope;
128     } else if (Flags & ControlScope) {
129       OS << "ControlScope";
130       Flags &= ~ControlScope;
131     } else if (Flags & ClassScope) {
132       OS << "ClassScope";
133       Flags &= ~ClassScope;
134     } else if (Flags & BlockScope) {
135       OS << "BlockScope";
136       Flags &= ~BlockScope;
137     } else if (Flags & TemplateParamScope) {
138       OS << "TemplateParamScope";
139       Flags &= ~TemplateParamScope;
140     } else if (Flags & FunctionPrototypeScope) {
141       OS << "FunctionPrototypeScope";
142       Flags &= ~FunctionPrototypeScope;
143     } else if (Flags & FunctionDeclarationScope) {
144       OS << "FunctionDeclarationScope";
145       Flags &= ~FunctionDeclarationScope;
146     } else if (Flags & AtCatchScope) {
147       OS << "AtCatchScope";
148       Flags &= ~AtCatchScope;
149     } else if (Flags & ObjCMethodScope) {
150       OS << "ObjCMethodScope";
151       Flags &= ~ObjCMethodScope;
152     } else if (Flags & SwitchScope) {
153       OS << "SwitchScope";
154       Flags &= ~SwitchScope;
155     } else if (Flags & TryScope) {
156       OS << "TryScope";
157       Flags &= ~TryScope;
158     } else if (Flags & FnTryCatchScope) {
159       OS << "FnTryCatchScope";
160       Flags &= ~FnTryCatchScope;
161     } else if (Flags & OpenMPDirectiveScope) {
162       OS << "OpenMPDirectiveScope";
163       Flags &= ~OpenMPDirectiveScope;
164     }
165 
166     if (Flags)
167       OS << " | ";
168   }
169   if (HasFlags)
170     OS << '\n';
171 
172   if (const Scope *Parent = getParent())
173     OS << "Parent: (clang::Scope*)" << Parent << '\n';
174 
175   OS << "Depth: " << Depth << '\n';
176   OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
177   if (const DeclContext *DC = getEntity())
178     OS << "Entity : (clang::DeclContext*)" << DC << '\n';
179 }
180