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