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; 42ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope | 43ef8225444452a1486bd721f3285301fe84643b00Stephen Hines FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) == 44ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 0) 45ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Flags |= parent->getFlags() & OpenMPSimdDirectiveScope; 46fb44de956f27875def889482b5393475060392afJohn McCall } else { 47fb44de956f27875def889482b5393475060392afJohn McCall Depth = 0; 48fb44de956f27875def889482b5393475060392afJohn McCall PrototypeDepth = 0; 49fb44de956f27875def889482b5393475060392afJohn McCall PrototypeIndex = 0; 506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines MSLocalManglingParent = FnParent = BlockParent = nullptr; 516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TemplateParamParent = nullptr; 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingNumber = 1; 53fb44de956f27875def889482b5393475060392afJohn McCall } 54fb44de956f27875def889482b5393475060392afJohn McCall 55fb44de956f27875def889482b5393475060392afJohn McCall // If this scope is a function or contains breaks/continues, remember it. 56fb44de956f27875def889482b5393475060392afJohn McCall if (flags & FnScope) FnParent = this; 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // The MS mangler uses the number of scopes that can hold declarations as 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // part of an external name. 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags & (ClassScope | FnScope)) { 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingNumber = getMSLocalManglingNumber(); 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingParent = this; 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 63fb44de956f27875def889482b5393475060392afJohn McCall if (flags & BreakScope) BreakParent = this; 64fb44de956f27875def889482b5393475060392afJohn McCall if (flags & ContinueScope) ContinueParent = this; 65fb44de956f27875def889482b5393475060392afJohn McCall if (flags & BlockScope) BlockParent = this; 66fb44de956f27875def889482b5393475060392afJohn McCall if (flags & TemplateParamScope) TemplateParamParent = this; 67fb44de956f27875def889482b5393475060392afJohn McCall 68fb44de956f27875def889482b5393475060392afJohn McCall // If this is a prototype scope, record that. 69fb44de956f27875def889482b5393475060392afJohn McCall if (flags & FunctionPrototypeScope) PrototypeDepth++; 70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (flags & DeclScope) { 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (flags & FunctionPrototypeScope) 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Prototype scopes are uninteresting. 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if ((flags & ClassScope) && getParent()->isClassScope()) 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Nested class scopes aren't ambiguous. 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope) 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Classes inside of namespaces aren't ambiguous. 78ef8225444452a1486bd721f3285301fe84643b00Stephen Hines else if ((flags & EnumScope)) 79ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ; // Don't increment for enum scopes. 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines incrementMSLocalManglingNumber(); 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 83fb44de956f27875def889482b5393475060392afJohn McCall 84fb44de956f27875def889482b5393475060392afJohn McCall DeclsInScope.clear(); 85fb44de956f27875def889482b5393475060392afJohn McCall UsingDirectives.clear(); 866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Entity = nullptr; 87fb44de956f27875def889482b5393475060392afJohn McCall ErrorTrap.reset(); 886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NRVO.setPointerAndInt(nullptr, 0); 89fb44de956f27875def889482b5393475060392afJohn McCall} 9016f1f717af196b1448258857b2e6dcfe144b39d0James Molloy 9116f1f717af196b1448258857b2e6dcfe144b39d0James Molloybool Scope::containedInPrototypeScope() const { 9216f1f717af196b1448258857b2e6dcfe144b39d0James Molloy const Scope *S = this; 9316f1f717af196b1448258857b2e6dcfe144b39d0James Molloy while (S) { 9416f1f717af196b1448258857b2e6dcfe144b39d0James Molloy if (S->isFunctionPrototypeScope()) 9516f1f717af196b1448258857b2e6dcfe144b39d0James Molloy return true; 9616f1f717af196b1448258857b2e6dcfe144b39d0James Molloy S = S->getParent(); 9716f1f717af196b1448258857b2e6dcfe144b39d0James Molloy } 9816f1f717af196b1448258857b2e6dcfe144b39d0James Molloy return false; 9916f1f717af196b1448258857b2e6dcfe144b39d0James Molloy} 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::AddFlags(unsigned FlagsToSet) { 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 && 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Unsupported scope flags"); 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FlagsToSet & BreakScope) { 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((Flags & BreakScope) == 0 && "Already set"); 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BreakParent = this; 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FlagsToSet & ContinueScope) { 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((Flags & ContinueScope) == 0 && "Already set"); 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ContinueParent = this; 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags |= FlagsToSet; 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Scope::mergeNRVOIntoParent() { 1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (VarDecl *Candidate = NRVO.getPointer()) { 1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (isDeclScope(Candidate)) 1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Candidate->setNRVOVariable(true); 1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (getEntity()) 1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (NRVO.getInt()) 1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines getParent()->setNoNRVO(); 1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (NRVO.getPointer()) 1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines getParent()->addNRVOCandidate(NRVO.getPointer()); 1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dump() const { dumpImpl(llvm::errs()); } 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dumpImpl(raw_ostream &OS) const { 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Flags = getFlags(); 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasFlags = Flags != 0; 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasFlags) 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Flags: "; 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (Flags) { 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags & FnScope) { 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FnScope"; 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FnScope; 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & BreakScope) { 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "BreakScope"; 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~BreakScope; 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ContinueScope) { 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ContinueScope"; 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ContinueScope; 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & DeclScope) { 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "DeclScope"; 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~DeclScope; 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ControlScope) { 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ControlScope"; 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ControlScope; 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ClassScope) { 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ClassScope"; 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ClassScope; 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & BlockScope) { 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "BlockScope"; 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~BlockScope; 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & TemplateParamScope) { 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "TemplateParamScope"; 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~TemplateParamScope; 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FunctionPrototypeScope) { 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FunctionPrototypeScope"; 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FunctionPrototypeScope; 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FunctionDeclarationScope) { 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FunctionDeclarationScope"; 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FunctionDeclarationScope; 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & AtCatchScope) { 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "AtCatchScope"; 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~AtCatchScope; 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ObjCMethodScope) { 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ObjCMethodScope"; 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ObjCMethodScope; 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & SwitchScope) { 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "SwitchScope"; 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~SwitchScope; 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & TryScope) { 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "TryScope"; 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~TryScope; 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FnTryCatchScope) { 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FnTryCatchScope"; 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FnTryCatchScope; 185ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } else if (Flags & SEHTryScope) { 186ef8225444452a1486bd721f3285301fe84643b00Stephen Hines OS << "SEHTryScope"; 187ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Flags &= ~SEHTryScope; 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & OpenMPDirectiveScope) { 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "OpenMPDirectiveScope"; 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~OpenMPDirectiveScope; 191ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } else if (Flags & OpenMPLoopDirectiveScope) { 192ef8225444452a1486bd721f3285301fe84643b00Stephen Hines OS << "OpenMPLoopDirectiveScope"; 193ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Flags &= ~OpenMPLoopDirectiveScope; 194ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } else if (Flags & OpenMPSimdDirectiveScope) { 195ef8225444452a1486bd721f3285301fe84643b00Stephen Hines OS << "OpenMPSimdDirectiveScope"; 196ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Flags &= ~OpenMPSimdDirectiveScope; 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags) 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " | "; 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasFlags) 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << '\n'; 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const Scope *Parent = getParent()) 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Parent: (clang::Scope*)" << Parent << '\n'; 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Depth: " << Depth << '\n'; 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n'; 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const DeclContext *DC = getEntity()) 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Entity : (clang::DeclContext*)" << DC << '\n'; 2126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (NRVO.getInt()) 2146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OS << "NRVO not allowed"; 2156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (NRVO.getPointer()) 2166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 218