Scope.cpp revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
1fb44de956f27875def889482b5393475060392afJohn McCall//===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===// 2fb44de956f27875def889482b5393475060392afJohn McCall// 3fb44de956f27875def889482b5393475060392afJohn McCall// The LLVM Compiler Infrastructure 4fb44de956f27875def889482b5393475060392afJohn McCall// 5fb44de956f27875def889482b5393475060392afJohn McCall// This file is distributed under the University of Illinois Open Source 6fb44de956f27875def889482b5393475060392afJohn McCall// License. See LICENSE.TXT for details. 7fb44de956f27875def889482b5393475060392afJohn McCall// 8fb44de956f27875def889482b5393475060392afJohn McCall//===----------------------------------------------------------------------===// 9fb44de956f27875def889482b5393475060392afJohn McCall// 10fb44de956f27875def889482b5393475060392afJohn McCall// This file implements the Scope class, which is used for recording 11fb44de956f27875def889482b5393475060392afJohn McCall// information about a lexical scope. 12fb44de956f27875def889482b5393475060392afJohn McCall// 13fb44de956f27875def889482b5393475060392afJohn McCall//===----------------------------------------------------------------------===// 14fb44de956f27875def889482b5393475060392afJohn McCall 15fb44de956f27875def889482b5393475060392afJohn McCall#include "clang/Sema/Scope.h" 166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/Decl.h" 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_ostream.h" 18fb44de956f27875def889482b5393475060392afJohn McCall 19fb44de956f27875def889482b5393475060392afJohn McCallusing namespace clang; 20fb44de956f27875def889482b5393475060392afJohn McCall 21fb44de956f27875def889482b5393475060392afJohn McCallvoid Scope::Init(Scope *parent, unsigned flags) { 22fb44de956f27875def889482b5393475060392afJohn McCall AnyParent = parent; 23fb44de956f27875def889482b5393475060392afJohn McCall Flags = flags; 2485b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith 2585b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith if (parent && !(flags & FnScope)) { 2685b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith BreakParent = parent->BreakParent; 2785b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith ContinueParent = parent->ContinueParent; 2885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith } else { 2985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith // Control scopes do not contain the contents of nested function scopes for 3085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith // control flow purposes. 316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BreakParent = ContinueParent = nullptr; 3285b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith } 3385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith 34fb44de956f27875def889482b5393475060392afJohn McCall if (parent) { 35fb44de956f27875def889482b5393475060392afJohn McCall Depth = parent->Depth + 1; 36fb44de956f27875def889482b5393475060392afJohn McCall PrototypeDepth = parent->PrototypeDepth; 37fb44de956f27875def889482b5393475060392afJohn McCall PrototypeIndex = 0; 38fb44de956f27875def889482b5393475060392afJohn McCall FnParent = parent->FnParent; 39fb44de956f27875def889482b5393475060392afJohn McCall BlockParent = parent->BlockParent; 40fb44de956f27875def889482b5393475060392afJohn McCall TemplateParamParent = parent->TemplateParamParent; 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingParent = parent->MSLocalManglingParent; 42fb44de956f27875def889482b5393475060392afJohn McCall } else { 43fb44de956f27875def889482b5393475060392afJohn McCall Depth = 0; 44fb44de956f27875def889482b5393475060392afJohn McCall PrototypeDepth = 0; 45fb44de956f27875def889482b5393475060392afJohn McCall PrototypeIndex = 0; 466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines MSLocalManglingParent = FnParent = BlockParent = nullptr; 476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TemplateParamParent = nullptr; 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingNumber = 1; 49fb44de956f27875def889482b5393475060392afJohn McCall } 50fb44de956f27875def889482b5393475060392afJohn McCall 51fb44de956f27875def889482b5393475060392afJohn McCall // If this scope is a function or contains breaks/continues, remember it. 52fb44de956f27875def889482b5393475060392afJohn McCall if (flags & FnScope) FnParent = this; 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // The MS mangler uses the number of scopes that can hold declarations as 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // part of an external name. 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags & (ClassScope | FnScope)) { 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingNumber = getMSLocalManglingNumber(); 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingParent = this; 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 59fb44de956f27875def889482b5393475060392afJohn McCall if (flags & BreakScope) BreakParent = this; 60fb44de956f27875def889482b5393475060392afJohn McCall if (flags & ContinueScope) ContinueParent = this; 61fb44de956f27875def889482b5393475060392afJohn McCall if (flags & BlockScope) BlockParent = this; 62fb44de956f27875def889482b5393475060392afJohn McCall if (flags & TemplateParamScope) TemplateParamParent = this; 63fb44de956f27875def889482b5393475060392afJohn McCall 64fb44de956f27875def889482b5393475060392afJohn McCall // If this is a prototype scope, record that. 65fb44de956f27875def889482b5393475060392afJohn McCall if (flags & FunctionPrototypeScope) PrototypeDepth++; 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (flags & DeclScope) { 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (flags & FunctionPrototypeScope) 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Prototype scopes are uninteresting. 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if ((flags & ClassScope) && getParent()->isClassScope()) 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Nested class scopes aren't ambiguous. 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope) 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Classes inside of namespaces aren't ambiguous. 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines incrementMSLocalManglingNumber(); 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 76fb44de956f27875def889482b5393475060392afJohn McCall 77fb44de956f27875def889482b5393475060392afJohn McCall DeclsInScope.clear(); 78fb44de956f27875def889482b5393475060392afJohn McCall UsingDirectives.clear(); 796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Entity = nullptr; 80fb44de956f27875def889482b5393475060392afJohn McCall ErrorTrap.reset(); 816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NRVO.setPointerAndInt(nullptr, 0); 82fb44de956f27875def889482b5393475060392afJohn McCall} 8316f1f717af196b1448258857b2e6dcfe144b39d0James Molloy 8416f1f717af196b1448258857b2e6dcfe144b39d0James Molloybool Scope::containedInPrototypeScope() const { 8516f1f717af196b1448258857b2e6dcfe144b39d0James Molloy const Scope *S = this; 8616f1f717af196b1448258857b2e6dcfe144b39d0James Molloy while (S) { 8716f1f717af196b1448258857b2e6dcfe144b39d0James Molloy if (S->isFunctionPrototypeScope()) 8816f1f717af196b1448258857b2e6dcfe144b39d0James Molloy return true; 8916f1f717af196b1448258857b2e6dcfe144b39d0James Molloy S = S->getParent(); 9016f1f717af196b1448258857b2e6dcfe144b39d0James Molloy } 9116f1f717af196b1448258857b2e6dcfe144b39d0James Molloy return false; 9216f1f717af196b1448258857b2e6dcfe144b39d0James Molloy} 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::AddFlags(unsigned FlagsToSet) { 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 && 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Unsupported scope flags"); 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FlagsToSet & BreakScope) { 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((Flags & BreakScope) == 0 && "Already set"); 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BreakParent = this; 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FlagsToSet & ContinueScope) { 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((Flags & ContinueScope) == 0 && "Already set"); 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ContinueParent = this; 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags |= FlagsToSet; 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Scope::mergeNRVOIntoParent() { 1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (VarDecl *Candidate = NRVO.getPointer()) { 1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (isDeclScope(Candidate)) 1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Candidate->setNRVOVariable(true); 1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (getEntity()) 1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (NRVO.getInt()) 1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines getParent()->setNoNRVO(); 1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (NRVO.getPointer()) 1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines getParent()->addNRVOCandidate(NRVO.getPointer()); 1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dump() const { dumpImpl(llvm::errs()); } 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dumpImpl(raw_ostream &OS) const { 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Flags = getFlags(); 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasFlags = Flags != 0; 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasFlags) 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Flags: "; 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (Flags) { 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags & FnScope) { 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FnScope"; 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FnScope; 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & BreakScope) { 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "BreakScope"; 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~BreakScope; 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ContinueScope) { 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ContinueScope"; 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ContinueScope; 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & DeclScope) { 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "DeclScope"; 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~DeclScope; 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ControlScope) { 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ControlScope"; 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ControlScope; 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ClassScope) { 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ClassScope"; 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ClassScope; 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & BlockScope) { 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "BlockScope"; 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~BlockScope; 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & TemplateParamScope) { 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "TemplateParamScope"; 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~TemplateParamScope; 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FunctionPrototypeScope) { 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FunctionPrototypeScope"; 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FunctionPrototypeScope; 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FunctionDeclarationScope) { 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FunctionDeclarationScope"; 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FunctionDeclarationScope; 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & AtCatchScope) { 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "AtCatchScope"; 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~AtCatchScope; 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ObjCMethodScope) { 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ObjCMethodScope"; 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ObjCMethodScope; 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & SwitchScope) { 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "SwitchScope"; 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~SwitchScope; 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & TryScope) { 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "TryScope"; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~TryScope; 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FnTryCatchScope) { 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FnTryCatchScope"; 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FnTryCatchScope; 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & OpenMPDirectiveScope) { 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "OpenMPDirectiveScope"; 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~OpenMPDirectiveScope; 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags) 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " | "; 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasFlags) 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << '\n'; 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const Scope *Parent = getParent()) 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Parent: (clang::Scope*)" << Parent << '\n'; 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Depth: " << Depth << '\n'; 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n'; 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const DeclContext *DC = getEntity()) 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Entity : (clang::DeclContext*)" << DC << '\n'; 1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (NRVO.getInt()) 1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OS << "NRVO not allowed"; 1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (NRVO.getPointer()) 2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 202