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