Scope.cpp revision ef8225444452a1486bd721f3285301fe84643b00
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;
42ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
43ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                  FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
44ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        0)
45ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
46fb44de956f27875def889482b5393475060392afJohn McCall  } else {
47fb44de956f27875def889482b5393475060392afJohn McCall    Depth = 0;
48fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeDepth = 0;
49fb44de956f27875def889482b5393475060392afJohn McCall    PrototypeIndex = 0;
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    MSLocalManglingParent = FnParent = BlockParent = nullptr;
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    TemplateParamParent = nullptr;
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingNumber = 1;
53fb44de956f27875def889482b5393475060392afJohn McCall  }
54fb44de956f27875def889482b5393475060392afJohn McCall
55fb44de956f27875def889482b5393475060392afJohn McCall  // If this scope is a function or contains breaks/continues, remember it.
56fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & FnScope)            FnParent = this;
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // The MS mangler uses the number of scopes that can hold declarations as
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // part of an external name.
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Flags & (ClassScope | FnScope)) {
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingNumber = getMSLocalManglingNumber();
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MSLocalManglingParent = this;
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
63fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & BreakScope)         BreakParent = this;
64fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & ContinueScope)      ContinueParent = this;
65fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & BlockScope)         BlockParent = this;
66fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & TemplateParamScope) TemplateParamParent = this;
67fb44de956f27875def889482b5393475060392afJohn McCall
68fb44de956f27875def889482b5393475060392afJohn McCall  // If this is a prototype scope, record that.
69fb44de956f27875def889482b5393475060392afJohn McCall  if (flags & FunctionPrototypeScope) PrototypeDepth++;
70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (flags & DeclScope) {
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (flags & FunctionPrototypeScope)
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Prototype scopes are uninteresting.
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((flags & ClassScope) && getParent()->isClassScope())
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Nested class scopes aren't ambiguous.
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ; // Classes inside of namespaces aren't ambiguous.
78ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    else if ((flags & EnumScope))
79ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      ; // Don't increment for enum scopes.
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      incrementMSLocalManglingNumber();
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
83fb44de956f27875def889482b5393475060392afJohn McCall
84fb44de956f27875def889482b5393475060392afJohn McCall  DeclsInScope.clear();
85fb44de956f27875def889482b5393475060392afJohn McCall  UsingDirectives.clear();
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Entity = nullptr;
87fb44de956f27875def889482b5393475060392afJohn McCall  ErrorTrap.reset();
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NRVO.setPointerAndInt(nullptr, 0);
89fb44de956f27875def889482b5393475060392afJohn McCall}
9016f1f717af196b1448258857b2e6dcfe144b39d0James Molloy
9116f1f717af196b1448258857b2e6dcfe144b39d0James Molloybool Scope::containedInPrototypeScope() const {
9216f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  const Scope *S = this;
9316f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  while (S) {
9416f1f717af196b1448258857b2e6dcfe144b39d0James Molloy    if (S->isFunctionPrototypeScope())
9516f1f717af196b1448258857b2e6dcfe144b39d0James Molloy      return true;
9616f1f717af196b1448258857b2e6dcfe144b39d0James Molloy    S = S->getParent();
9716f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  }
9816f1f717af196b1448258857b2e6dcfe144b39d0James Molloy  return false;
9916f1f717af196b1448258857b2e6dcfe144b39d0James Molloy}
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::AddFlags(unsigned FlagsToSet) {
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         "Unsupported scope flags");
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FlagsToSet & BreakScope) {
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Flags & BreakScope) == 0 && "Already set");
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    BreakParent = this;
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FlagsToSet & ContinueScope) {
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Flags & ContinueScope) == 0 && "Already set");
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ContinueParent = this;
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Flags |= FlagsToSet;
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Scope::mergeNRVOIntoParent() {
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (VarDecl *Candidate = NRVO.getPointer()) {
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (isDeclScope(Candidate))
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Candidate->setNRVOVariable(true);
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (getEntity())
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return;
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (NRVO.getInt())
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    getParent()->setNoNRVO();
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  else if (NRVO.getPointer())
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    getParent()->addNRVOCandidate(NRVO.getPointer());
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dump() const { dumpImpl(llvm::errs()); }
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dumpImpl(raw_ostream &OS) const {
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Flags = getFlags();
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool HasFlags = Flags != 0;
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasFlags)
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Flags: ";
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while (Flags) {
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Flags & FnScope) {
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FnScope";
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FnScope;
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & BreakScope) {
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "BreakScope";
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~BreakScope;
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ContinueScope) {
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ContinueScope";
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ContinueScope;
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & DeclScope) {
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "DeclScope";
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~DeclScope;
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ControlScope) {
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ControlScope";
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ControlScope;
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ClassScope) {
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ClassScope";
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ClassScope;
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & BlockScope) {
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "BlockScope";
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~BlockScope;
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & TemplateParamScope) {
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "TemplateParamScope";
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~TemplateParamScope;
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FunctionPrototypeScope) {
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FunctionPrototypeScope";
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FunctionPrototypeScope;
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FunctionDeclarationScope) {
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FunctionDeclarationScope";
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FunctionDeclarationScope;
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & AtCatchScope) {
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "AtCatchScope";
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~AtCatchScope;
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & ObjCMethodScope) {
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "ObjCMethodScope";
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~ObjCMethodScope;
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & SwitchScope) {
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "SwitchScope";
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~SwitchScope;
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & TryScope) {
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "TryScope";
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~TryScope;
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & FnTryCatchScope) {
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "FnTryCatchScope";
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~FnTryCatchScope;
185ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    } else if (Flags & SEHTryScope) {
186ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      OS << "SEHTryScope";
187ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Flags &= ~SEHTryScope;
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else if (Flags & OpenMPDirectiveScope) {
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "OpenMPDirectiveScope";
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Flags &= ~OpenMPDirectiveScope;
191ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    } else if (Flags & OpenMPLoopDirectiveScope) {
192ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      OS << "OpenMPLoopDirectiveScope";
193ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Flags &= ~OpenMPLoopDirectiveScope;
194ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    } else if (Flags & OpenMPSimdDirectiveScope) {
195ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      OS << "OpenMPSimdDirectiveScope";
196ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Flags &= ~OpenMPSimdDirectiveScope;
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Flags)
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << " | ";
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (HasFlags)
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << '\n';
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const Scope *Parent = getParent())
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Parent: (clang::Scope*)" << Parent << '\n';
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << "Depth: " << Depth << '\n';
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const DeclContext *DC = getEntity())
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << "Entity : (clang::DeclContext*)" << DC << '\n';
2126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
2136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (NRVO.getInt())
2146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OS << "NRVO not allowed";
2156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  else if (NRVO.getPointer())
2166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
218