Scope.cpp 6.2 KB

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