Scope.cpp revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
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"
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/Decl.h"
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_ostream.h"
18fb44de956f27875def889482b5393475060392afJohn McCall
19fb44de956f27875def889482b5393475060392afJohn McCallusing namespace clang;
20fb44de956f27875def889482b5393475060392afJohn McCall
21fb44de956f27875def889482b5393475060392afJohn McCallvoid Scope::Init(Scope *parent, unsigned flags) {
22fb44de956f27875def889482b5393475060392afJohn McCall  AnyParent = parent;
23fb44de956f27875def889482b5393475060392afJohn McCall  Flags = flags;
2485b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith
2585b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  if (parent && !(flags & FnScope)) {
2685b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    BreakParent    = parent->BreakParent;
2785b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    ContinueParent = parent->ContinueParent;
2885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  } else {
2985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // Control scopes do not contain the contents of nested function scopes for
3085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith    // control flow purposes.
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    BreakParent = ContinueParent = nullptr;
3285b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith  }
3385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith
34fb44de956f27875def889482b5393475060392afJohn McCall  if (parent) {
35fb44de956f27875def889482b5393475060392afJohn McCall    Depth = parent->Depth + 1;
36fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeDepth = parent->PrototypeDepth;
37fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeIndex = 0;
38fb44de956f27875def889482b5393475060392afJohn McCall    FnParent       = parent->FnParent;
39fb44de956f27875def889482b5393475060392afJohn McCall    BlockParent    = parent->BlockParent;
40fb44de956f27875def889482b5393475060392afJohn McCall    TemplateParamParent = parent->TemplateParamParent;
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingParent = parent->MSLocalManglingParent;
42fb44de956f27875def889482b5393475060392afJohn McCall  } else {
43fb44de956f27875def889482b5393475060392afJohn McCall    Depth = 0;
44fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeDepth = 0;
45fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeIndex = 0;
466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    MSLocalManglingParent = FnParent = BlockParent = nullptr;
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    TemplateParamParent = nullptr;
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingNumber = 1;
49fb44de956f27875def889482b5393475060392afJohn McCall  }
50fb44de956f27875def889482b5393475060392afJohn McCall
51fb44de956f27875def889482b5393475060392afJohn McCall  // If this scope is a function or contains breaks/continues, remember it.
52fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & FnScope)            FnParent = this;
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // The MS mangler uses the number of scopes that can hold declarations as
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // part of an external name.
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Flags & (ClassScope | FnScope)) {
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingNumber = getMSLocalManglingNumber();
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingParent = this;
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
59fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & BreakScope)         BreakParent = this;
60fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & ContinueScope)      ContinueParent = this;
61fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & BlockScope)         BlockParent = this;
62fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & TemplateParamScope) TemplateParamParent = this;
63fb44de956f27875def889482b5393475060392afJohn McCall
64fb44de956f27875def889482b5393475060392afJohn McCall  // If this is a prototype scope, record that.
65fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & FunctionPrototypeScope) PrototypeDepth++;
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (flags & DeclScope) {
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (flags & FunctionPrototypeScope)
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Prototype scopes are uninteresting.
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((flags & ClassScope) && getParent()->isClassScope())
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Nested class scopes aren't ambiguous.
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Classes inside of namespaces aren't ambiguous.
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      incrementMSLocalManglingNumber();
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
76fb44de956f27875def889482b5393475060392afJohn McCall
77fb44de956f27875def889482b5393475060392afJohn McCall  DeclsInScope.clear();
78fb44de956f27875def889482b5393475060392afJohn McCall  UsingDirectives.clear();
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Entity = nullptr;
80fb44de956f27875def889482b5393475060392afJohn McCall  ErrorTrap.reset();
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NRVO.setPointerAndInt(nullptr, 0);
82fb44de956f27875def889482b5393475060392afJohn McCall}
8316f1f717af196b1448258857b2e6dcfe144b39d0James Molloy
8416f1f717af196b1448258857b2e6dcfe144b39d0James Molloybool Scope::containedInPrototypeScope() const {
8516f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  const Scope *S = this;
8616f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  while (S) {
8716f1f717af196b1448258857b2e6dcfe144b39d0James Molloy    if (S->isFunctionPrototypeScope())
8816f1f717af196b1448258857b2e6dcfe144b39d0James Molloy      return true;
8916f1f717af196b1448258857b2e6dcfe144b39d0James Molloy    S = S->getParent();
9016f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  }
9116f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  return false;
9216f1f717af196b1448258857b2e6dcfe144b39d0James Molloy}
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::AddFlags(unsigned FlagsToSet) {
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         "Unsupported scope flags");
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FlagsToSet & BreakScope) {
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Flags & BreakScope) == 0 && "Already set");
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    BreakParent = this;
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FlagsToSet & ContinueScope) {
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Flags & ContinueScope) == 0 && "Already set");
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ContinueParent = this;
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Flags |= FlagsToSet;
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Scope::mergeNRVOIntoParent() {
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (VarDecl *Candidate = NRVO.getPointer()) {
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (isDeclScope(Candidate))
1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Candidate->setNRVOVariable(true);
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (getEntity())
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return;
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (NRVO.getInt())
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    getParent()->setNoNRVO();
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  else if (NRVO.getPointer())
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    getParent()->addNRVOCandidate(NRVO.getPointer());
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dump() const { dumpImpl(llvm::errs()); }
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dumpImpl(raw_ostream &OS) const {
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Flags = getFlags();
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool HasFlags = Flags != 0;
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasFlags)
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Flags: ";
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while (Flags) {
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Flags & FnScope) {
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FnScope";
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FnScope;
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & BreakScope) {
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "BreakScope";
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~BreakScope;
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ContinueScope) {
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ContinueScope";
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ContinueScope;
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & DeclScope) {
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "DeclScope";
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~DeclScope;
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ControlScope) {
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ControlScope";
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ControlScope;
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ClassScope) {
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ClassScope";
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ClassScope;
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & BlockScope) {
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "BlockScope";
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~BlockScope;
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & TemplateParamScope) {
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "TemplateParamScope";
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~TemplateParamScope;
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FunctionPrototypeScope) {
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FunctionPrototypeScope";
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FunctionPrototypeScope;
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FunctionDeclarationScope) {
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FunctionDeclarationScope";
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FunctionDeclarationScope;
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & AtCatchScope) {
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "AtCatchScope";
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~AtCatchScope;
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ObjCMethodScope) {
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ObjCMethodScope";
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ObjCMethodScope;
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & SwitchScope) {
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "SwitchScope";
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~SwitchScope;
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & TryScope) {
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "TryScope";
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~TryScope;
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FnTryCatchScope) {
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FnTryCatchScope";
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FnTryCatchScope;
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & OpenMPDirectiveScope) {
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "OpenMPDirectiveScope";
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~OpenMPDirectiveScope;
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Flags)
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << " | ";
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasFlags)
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << '\n';
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const Scope *Parent = getParent())
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Parent: (clang::Scope*)" << Parent << '\n';
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << "Depth: " << Depth << '\n';
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const DeclContext *DC = getEntity())
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Entity : (clang::DeclContext*)" << DC << '\n';
1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (NRVO.getInt())
1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OS << "NRVO not allowed";
1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  else if (NRVO.getPointer())
2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
202