Scope.cpp revision 651f13cea278ec967336033dd032faef0e9fc2ec
1fb44de956f27875def889482b5393475060392afJohn McCall//===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
2fb44de956f27875def889482b5393475060392afJohn McCall//
3fb44de956f27875def889482b5393475060392afJohn McCall//                     The LLVM Compiler Infrastructure
4fb44de956f27875def889482b5393475060392afJohn McCall//
5fb44de956f27875def889482b5393475060392afJohn McCall// This file is distributed under the University of Illinois Open Source
6fb44de956f27875def889482b5393475060392afJohn McCall// License. See LICENSE.TXT for details.
7fb44de956f27875def889482b5393475060392afJohn McCall//
8fb44de956f27875def889482b5393475060392afJohn McCall//===----------------------------------------------------------------------===//
9fb44de956f27875def889482b5393475060392afJohn McCall//
10fb44de956f27875def889482b5393475060392afJohn McCall// This file implements the Scope class, which is used for recording
11fb44de956f27875def889482b5393475060392afJohn McCall// information about a lexical scope.
12fb44de956f27875def889482b5393475060392afJohn McCall//
13fb44de956f27875def889482b5393475060392afJohn McCall//===----------------------------------------------------------------------===//
14fb44de956f27875def889482b5393475060392afJohn McCall
15fb44de956f27875def889482b5393475060392afJohn McCall#include "clang/Sema/Scope.h"
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_ostream.h"
17fb44de956f27875def889482b5393475060392afJohn McCall
18fb44de956f27875def889482b5393475060392afJohn McCallusing namespace clang;
19fb44de956f27875def889482b5393475060392afJohn McCall
20fb44de956f27875def889482b5393475060392afJohn McCallvoid Scope::Init(Scope *parent, unsigned flags) {
21fb44de956f27875def889482b5393475060392afJohn McCall  AnyParent = parent;
22fb44de956f27875def889482b5393475060392afJohn McCall  Flags = flags;
2385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith
2485b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  if (parent && !(flags & FnScope)) {
2585b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    BreakParent    = parent->BreakParent;
2685b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    ContinueParent = parent->ContinueParent;
2785b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  } else {
2885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // Control scopes do not contain the contents of nested function scopes for
2985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // control flow purposes.
3085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    BreakParent = ContinueParent = 0;
3185b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  }
3285b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith
33fb44de956f27875def889482b5393475060392afJohn McCall  if (parent) {
34fb44de956f27875def889482b5393475060392afJohn McCall    Depth = parent->Depth + 1;
35fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeDepth = parent->PrototypeDepth;
36fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeIndex = 0;
37fb44de956f27875def889482b5393475060392afJohn McCall    FnParent       = parent->FnParent;
38fb44de956f27875def889482b5393475060392afJohn McCall    BlockParent    = parent->BlockParent;
39fb44de956f27875def889482b5393475060392afJohn McCall    TemplateParamParent = parent->TemplateParamParent;
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingParent = parent->MSLocalManglingParent;
41fb44de956f27875def889482b5393475060392afJohn McCall  } else {
42fb44de956f27875def889482b5393475060392afJohn McCall    Depth = 0;
43fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeDepth = 0;
44fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeIndex = 0;
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingParent = FnParent = BlockParent = 0;
46fb44de956f27875def889482b5393475060392afJohn McCall    TemplateParamParent = 0;
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingNumber = 1;
48fb44de956f27875def889482b5393475060392afJohn McCall  }
49fb44de956f27875def889482b5393475060392afJohn McCall
50fb44de956f27875def889482b5393475060392afJohn McCall  // If this scope is a function or contains breaks/continues, remember it.
51fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & FnScope)            FnParent = this;
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // The MS mangler uses the number of scopes that can hold declarations as
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // part of an external name.
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Flags & (ClassScope | FnScope)) {
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingNumber = getMSLocalManglingNumber();
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingParent = this;
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
58fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & BreakScope)         BreakParent = this;
59fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & ContinueScope)      ContinueParent = this;
60fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & BlockScope)         BlockParent = this;
61fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & TemplateParamScope) TemplateParamParent = this;
62fb44de956f27875def889482b5393475060392afJohn McCall
63fb44de956f27875def889482b5393475060392afJohn McCall  // If this is a prototype scope, record that.
64fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & FunctionPrototypeScope) PrototypeDepth++;
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (flags & DeclScope) {
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (flags & FunctionPrototypeScope)
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Prototype scopes are uninteresting.
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((flags & ClassScope) && getParent()->isClassScope())
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Nested class scopes aren't ambiguous.
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Classes inside of namespaces aren't ambiguous.
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      incrementMSLocalManglingNumber();
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
75fb44de956f27875def889482b5393475060392afJohn McCall
76fb44de956f27875def889482b5393475060392afJohn McCall  DeclsInScope.clear();
77fb44de956f27875def889482b5393475060392afJohn McCall  UsingDirectives.clear();
78fb44de956f27875def889482b5393475060392afJohn McCall  Entity = 0;
79fb44de956f27875def889482b5393475060392afJohn McCall  ErrorTrap.reset();
80fb44de956f27875def889482b5393475060392afJohn McCall}
8116f1f717af196b1448258857b2e6dcfe144b39d0James Molloy
8216f1f717af196b1448258857b2e6dcfe144b39d0James Molloybool Scope::containedInPrototypeScope() const {
8316f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  const Scope *S = this;
8416f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  while (S) {
8516f1f717af196b1448258857b2e6dcfe144b39d0James Molloy    if (S->isFunctionPrototypeScope())
8616f1f717af196b1448258857b2e6dcfe144b39d0James Molloy      return true;
8716f1f717af196b1448258857b2e6dcfe144b39d0James Molloy    S = S->getParent();
8816f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  }
8916f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  return false;
9016f1f717af196b1448258857b2e6dcfe144b39d0James Molloy}
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::AddFlags(unsigned FlagsToSet) {
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         "Unsupported scope flags");
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FlagsToSet & BreakScope) {
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Flags & BreakScope) == 0 && "Already set");
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    BreakParent = this;
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FlagsToSet & ContinueScope) {
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Flags & ContinueScope) == 0 && "Already set");
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ContinueParent = this;
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Flags |= FlagsToSet;
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dump() const { dumpImpl(llvm::errs()); }
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dumpImpl(raw_ostream &OS) const {
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Flags = getFlags();
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool HasFlags = Flags != 0;
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasFlags)
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Flags: ";
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while (Flags) {
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Flags & FnScope) {
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FnScope";
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FnScope;
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & BreakScope) {
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "BreakScope";
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~BreakScope;
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ContinueScope) {
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ContinueScope";
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ContinueScope;
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & DeclScope) {
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "DeclScope";
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~DeclScope;
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ControlScope) {
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ControlScope";
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ControlScope;
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ClassScope) {
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ClassScope";
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ClassScope;
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & BlockScope) {
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "BlockScope";
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~BlockScope;
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & TemplateParamScope) {
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "TemplateParamScope";
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~TemplateParamScope;
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FunctionPrototypeScope) {
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FunctionPrototypeScope";
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FunctionPrototypeScope;
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FunctionDeclarationScope) {
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FunctionDeclarationScope";
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FunctionDeclarationScope;
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & AtCatchScope) {
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "AtCatchScope";
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~AtCatchScope;
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ObjCMethodScope) {
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ObjCMethodScope";
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ObjCMethodScope;
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & SwitchScope) {
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "SwitchScope";
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~SwitchScope;
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & TryScope) {
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "TryScope";
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~TryScope;
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FnTryCatchScope) {
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FnTryCatchScope";
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FnTryCatchScope;
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & OpenMPDirectiveScope) {
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "OpenMPDirectiveScope";
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~OpenMPDirectiveScope;
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Flags)
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << " | ";
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasFlags)
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << '\n';
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const Scope *Parent = getParent())
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Parent: (clang::Scope*)" << Parent << '\n';
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << "Depth: " << Depth << '\n';
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const DeclContext *DC = getEntity())
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Entity : (clang::DeclContext*)" << DC << '\n';
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
180