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