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 | 43 FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) == 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. Lambdas have an extra prototype 71 // scope that doesn't add any depth. 72 if (flags & FunctionPrototypeScope && !(flags & LambdaScope)) 73 PrototypeDepth++; 74 75 if (flags & DeclScope) { 76 if (flags & FunctionPrototypeScope) 77 ; // Prototype scopes are uninteresting. 78 else if ((flags & ClassScope) && getParent()->isClassScope()) 79 ; // Nested class scopes aren't ambiguous. 80 else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope) 81 ; // Classes inside of namespaces aren't ambiguous. 82 else if ((flags & EnumScope)) 83 ; // Don't increment for enum scopes. 84 else 85 incrementMSManglingNumber(); 86 } 87 } 88 89 void Scope::Init(Scope *parent, unsigned flags) { 90 setFlags(parent, flags); 91 92 DeclsInScope.clear(); 93 UsingDirectives.clear(); 94 Entity = nullptr; 95 ErrorTrap.reset(); 96 NRVO.setPointerAndInt(nullptr, false); 97 } 98 99 bool Scope::containedInPrototypeScope() const { 100 const Scope *S = this; 101 while (S) { 102 if (S->isFunctionPrototypeScope()) 103 return true; 104 S = S->getParent(); 105 } 106 return false; 107 } 108 109 void Scope::AddFlags(unsigned FlagsToSet) { 110 assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 && 111 "Unsupported scope flags"); 112 if (FlagsToSet & BreakScope) { 113 assert((Flags & BreakScope) == 0 && "Already set"); 114 BreakParent = this; 115 } 116 if (FlagsToSet & ContinueScope) { 117 assert((Flags & ContinueScope) == 0 && "Already set"); 118 ContinueParent = this; 119 } 120 Flags |= FlagsToSet; 121 } 122 123 void Scope::mergeNRVOIntoParent() { 124 if (VarDecl *Candidate = NRVO.getPointer()) { 125 if (isDeclScope(Candidate)) 126 Candidate->setNRVOVariable(true); 127 } 128 129 if (getEntity()) 130 return; 131 132 if (NRVO.getInt()) 133 getParent()->setNoNRVO(); 134 else if (NRVO.getPointer()) 135 getParent()->addNRVOCandidate(NRVO.getPointer()); 136 } 137 138 LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); } 139 140 void Scope::dumpImpl(raw_ostream &OS) const { 141 unsigned Flags = getFlags(); 142 bool HasFlags = Flags != 0; 143 144 if (HasFlags) 145 OS << "Flags: "; 146 147 std::pair<unsigned, const char *> FlagInfo[] = { 148 {FnScope, "FnScope"}, 149 {BreakScope, "BreakScope"}, 150 {ContinueScope, "ContinueScope"}, 151 {DeclScope, "DeclScope"}, 152 {ControlScope, "ControlScope"}, 153 {ClassScope, "ClassScope"}, 154 {BlockScope, "BlockScope"}, 155 {TemplateParamScope, "TemplateParamScope"}, 156 {FunctionPrototypeScope, "FunctionPrototypeScope"}, 157 {FunctionDeclarationScope, "FunctionDeclarationScope"}, 158 {AtCatchScope, "AtCatchScope"}, 159 {ObjCMethodScope, "ObjCMethodScope"}, 160 {SwitchScope, "SwitchScope"}, 161 {TryScope, "TryScope"}, 162 {FnTryCatchScope, "FnTryCatchScope"}, 163 {OpenMPDirectiveScope, "OpenMPDirectiveScope"}, 164 {OpenMPLoopDirectiveScope, "OpenMPLoopDirectiveScope"}, 165 {OpenMPSimdDirectiveScope, "OpenMPSimdDirectiveScope"}, 166 {EnumScope, "EnumScope"}, 167 {SEHTryScope, "SEHTryScope"}, 168 {SEHExceptScope, "SEHExceptScope"}, 169 {SEHFilterScope, "SEHFilterScope"}, 170 {CompoundStmtScope, "CompoundStmtScope"}, 171 {ClassInheritanceScope, "ClassInheritanceScope"}, 172 {CatchScope, "CatchScope"}, 173 }; 174 175 for (auto Info : FlagInfo) { 176 if (Flags & Info.first) { 177 OS << Info.second; 178 Flags &= ~Info.first; 179 if (Flags) 180 OS << " | "; 181 } 182 } 183 184 assert(Flags == 0 && "Unknown scope flags"); 185 186 if (HasFlags) 187 OS << '\n'; 188 189 if (const Scope *Parent = getParent()) 190 OS << "Parent: (clang::Scope*)" << Parent << '\n'; 191 192 OS << "Depth: " << Depth << '\n'; 193 OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n'; 194 OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n'; 195 if (const DeclContext *DC = getEntity()) 196 OS << "Entity : (clang::DeclContext*)" << DC << '\n'; 197 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 } 203