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