Scope.cpp 6.9 KB

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