clang  10.0.0svn
Scope.cpp
Go to the documentation of this file.
1 //===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Scope class, which is used for recording
10 // information about a lexical scope.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Sema/Scope.h"
15 #include "clang/AST/Decl.h"
16 #include "llvm/Support/raw_ostream.h"
17 
18 using namespace clang;
19 
20 void Scope::setFlags(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 = nullptr;
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  MSLastManglingParent = parent->MSLastManglingParent;
41  MSCurManglingNumber = getMSLastManglingNumber();
42  if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
44  0)
45  Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
46  } else {
47  Depth = 0;
48  PrototypeDepth = 0;
49  PrototypeIndex = 0;
50  MSLastManglingParent = FnParent = BlockParent = nullptr;
51  TemplateParamParent = nullptr;
52  MSLastManglingNumber = 1;
53  MSCurManglingNumber = 1;
54  }
55 
56  // If this scope is a function or contains breaks/continues, remember it.
57  if (flags & FnScope) FnParent = this;
58  // The MS mangler uses the number of scopes that can hold declarations as
59  // part of an external name.
60  if (Flags & (ClassScope | FnScope)) {
61  MSLastManglingNumber = getMSLastManglingNumber();
62  MSLastManglingParent = this;
63  MSCurManglingNumber = 1;
64  }
65  if (flags & BreakScope) BreakParent = this;
66  if (flags & ContinueScope) ContinueParent = this;
67  if (flags & BlockScope) BlockParent = this;
68  if (flags & TemplateParamScope) TemplateParamParent = this;
69 
70  // If this is a prototype scope, record that.
71  if (flags & FunctionPrototypeScope) PrototypeDepth++;
72 
73  if (flags & DeclScope) {
74  if (flags & FunctionPrototypeScope)
75  ; // Prototype scopes are uninteresting.
76  else if ((flags & ClassScope) && getParent()->isClassScope())
77  ; // Nested class scopes aren't ambiguous.
78  else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
79  ; // Classes inside of namespaces aren't ambiguous.
80  else if ((flags & EnumScope))
81  ; // Don't increment for enum scopes.
82  else
84  }
85 }
86 
87 void Scope::Init(Scope *parent, unsigned flags) {
88  setFlags(parent, flags);
89 
90  DeclsInScope.clear();
91  UsingDirectives.clear();
92  Entity = nullptr;
93  ErrorTrap.reset();
94  NRVO.setPointerAndInt(nullptr, 0);
95 }
96 
98  const Scope *S = this;
99  while (S) {
100  if (S->isFunctionPrototypeScope())
101  return true;
102  S = S->getParent();
103  }
104  return false;
105 }
106 
107 void Scope::AddFlags(unsigned FlagsToSet) {
108  assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
109  "Unsupported scope flags");
110  if (FlagsToSet & BreakScope) {
111  assert((Flags & BreakScope) == 0 && "Already set");
112  BreakParent = this;
113  }
114  if (FlagsToSet & ContinueScope) {
115  assert((Flags & ContinueScope) == 0 && "Already set");
116  ContinueParent = this;
117  }
118  Flags |= FlagsToSet;
119 }
120 
122  if (VarDecl *Candidate = NRVO.getPointer()) {
123  if (isDeclScope(Candidate))
124  Candidate->setNRVOVariable(true);
125  }
126 
127  if (getEntity())
128  return;
129 
130  if (NRVO.getInt())
131  getParent()->setNoNRVO();
132  else if (NRVO.getPointer())
133  getParent()->addNRVOCandidate(NRVO.getPointer());
134 }
135 
136 LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); }
137 
138 void Scope::dumpImpl(raw_ostream &OS) const {
139  unsigned Flags = getFlags();
140  bool HasFlags = Flags != 0;
141 
142  if (HasFlags)
143  OS << "Flags: ";
144 
145  std::pair<unsigned, const char *> FlagInfo[] = {
146  {FnScope, "FnScope"},
147  {BreakScope, "BreakScope"},
148  {ContinueScope, "ContinueScope"},
149  {DeclScope, "DeclScope"},
150  {ControlScope, "ControlScope"},
151  {ClassScope, "ClassScope"},
152  {BlockScope, "BlockScope"},
153  {TemplateParamScope, "TemplateParamScope"},
154  {FunctionPrototypeScope, "FunctionPrototypeScope"},
155  {FunctionDeclarationScope, "FunctionDeclarationScope"},
156  {AtCatchScope, "AtCatchScope"},
157  {ObjCMethodScope, "ObjCMethodScope"},
158  {SwitchScope, "SwitchScope"},
159  {TryScope, "TryScope"},
160  {FnTryCatchScope, "FnTryCatchScope"},
161  {OpenMPDirectiveScope, "OpenMPDirectiveScope"},
162  {OpenMPLoopDirectiveScope, "OpenMPLoopDirectiveScope"},
163  {OpenMPSimdDirectiveScope, "OpenMPSimdDirectiveScope"},
164  {EnumScope, "EnumScope"},
165  {SEHTryScope, "SEHTryScope"},
166  {SEHExceptScope, "SEHExceptScope"},
167  {SEHFilterScope, "SEHFilterScope"},
168  {CompoundStmtScope, "CompoundStmtScope"},
169  {ClassInheritanceScope, "ClassInheritanceScope"},
170  {CatchScope, "CatchScope"},
171  };
172 
173  for (auto Info : FlagInfo) {
174  if (Flags & Info.first) {
175  OS << Info.second;
176  Flags &= ~Info.first;
177  if (Flags)
178  OS << " | ";
179  }
180  }
181 
182  assert(Flags == 0 && "Unknown scope flags");
183 
184  if (HasFlags)
185  OS << '\n';
186 
187  if (const Scope *Parent = getParent())
188  OS << "Parent: (clang::Scope*)" << Parent << '\n';
189 
190  OS << "Depth: " << Depth << '\n';
191  OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n';
192  OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n';
193  if (const DeclContext *DC = getEntity())
194  OS << "Entity : (clang::DeclContext*)" << DC << '\n';
195 
196  if (NRVO.getInt())
197  OS << "NRVO not allowed\n";
198  else if (NRVO.getPointer())
199  OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
200 }
void AddFlags(unsigned Flags)
Sets up the specified scope flags and adjusts the scope state variables accordingly.
Definition: Scope.cpp:107
This is the scope of a C++ try statement.
Definition: Scope.h:101
This is a scope that corresponds to the parameters within a function prototype.
Definition: Scope.h:81
bool containedInPrototypeScope() const
containedInPrototypeScope - Return true if this or a parent scope is a FunctionPrototypeScope.
Definition: Scope.cpp:97
This is a while, do, switch, for, etc that can have break statements embedded into it...
Definition: Scope.h:51
This indicates that the scope corresponds to a function, which means that labels are set here...
Definition: Scope.h:47
Represents a variable declaration or definition.
Definition: Decl.h:812
void setNoNRVO()
Definition: Scope.h:483
The controlling scope in a if/switch/while/for statement.
Definition: Scope.h:62
This is a scope that corresponds to a block/closure object.
Definition: Scope.h:71
bool isFunctionPrototypeScope() const
isFunctionPrototypeScope - Return true if this scope is a function prototype scope.
Definition: Scope.h:384
This scope corresponds to an enum.
Definition: Scope.h:118
This is a scope that corresponds to a switch statement.
Definition: Scope.h:98
This is a while, do, for, which can have continue statements embedded into it.
Definition: Scope.h:55
unsigned getMSLastManglingNumber() const
Definition: Scope.h:311
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
void incrementMSManglingNumber()
Definition: Scope.h:297
NodeId Parent
Definition: ASTDiff.cpp:191
unsigned getFlags() const
getFlags - Return the flags for this scope.
Definition: Scope.h:220
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:323
DeclContext * getEntity() const
Definition: Scope.h:327
This is the scope of OpenMP executable directive.
Definition: Scope.h:107
This scope corresponds to an SEH try.
Definition: Scope.h:121
This scope corresponds to an SEH except.
Definition: Scope.h:124
This is a compound statement scope.
Definition: Scope.h:130
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
Definition: Scope.h:340
This is a scope that corresponds to the parameters within a function prototype for a function declara...
Definition: Scope.h:87
unsigned getMSCurManglingNumber() const
Definition: Scope.h:317
This is a scope that corresponds to the Objective-C @catch statement.
Definition: Scope.h:91
void reset()
Set to initial state of "no errors occurred".
Definition: Diagnostic.h:1021
void Init(Scope *parent, unsigned flags)
Init - This is used by the parser to implement scope caching.
Definition: Scope.cpp:87
We are currently in the filter expression of an SEH except block.
Definition: Scope.h:127
The scope of a struct/union/class definition.
Definition: Scope.h:65
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1271
This is the scope of some OpenMP simd directive.
Definition: Scope.h:115
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:228
void addNRVOCandidate(VarDecl *VD)
Definition: Scope.h:472
This is a scope that corresponds to the template parameters of a C++ template.
Definition: Scope.h:77
void dumpImpl(raw_ostream &OS) const
Definition: Scope.cpp:138
void mergeNRVOIntoParent()
Definition: Scope.cpp:121
This is the scope for a function-level C++ try or catch scope.
Definition: Scope.h:104
void dump() const
Definition: Scope.cpp:136
We are between inheritance colon and the real class/struct definition scope.
Definition: Scope.h:133
This is a scope that can contain a declaration.
Definition: Scope.h:59
This is the scope of some OpenMP loop directive.
Definition: Scope.h:110
This is the scope of a C++ catch statement.
Definition: Scope.h:136
This scope corresponds to an Objective-C method body.
Definition: Scope.h:95