Scope.cpp revision 651f13cea278ec967336033dd032faef0e9fc2ec
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" 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_ostream.h" 17fb44de956f27875def889482b5393475060392afJohn McCall 18fb44de956f27875def889482b5393475060392afJohn McCallusing namespace clang; 19fb44de956f27875def889482b5393475060392afJohn McCall 20fb44de956f27875def889482b5393475060392afJohn McCallvoid Scope::Init(Scope *parent, unsigned flags) { 21fb44de956f27875def889482b5393475060392afJohn McCall AnyParent = parent; 22fb44de956f27875def889482b5393475060392afJohn McCall Flags = flags; 2385b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith 2485b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith if (parent && !(flags & FnScope)) { 2585b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith BreakParent = parent->BreakParent; 2685b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith ContinueParent = parent->ContinueParent; 2785b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith } else { 2885b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith // Control scopes do not contain the contents of nested function scopes for 2985b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith // control flow purposes. 3085b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith BreakParent = ContinueParent = 0; 3185b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith } 3285b29a4c862bb9f41d9739e5dab6436fe6d44ff8Richard Smith 33fb44de956f27875def889482b5393475060392afJohn McCall if (parent) { 34fb44de956f27875def889482b5393475060392afJohn McCall Depth = parent->Depth + 1; 35fb44de956f27875def889482b5393475060392afJohn McCall PrototypeDepth = parent->PrototypeDepth; 36fb44de956f27875def889482b5393475060392afJohn McCall PrototypeIndex = 0; 37fb44de956f27875def889482b5393475060392afJohn McCall FnParent = parent->FnParent; 38fb44de956f27875def889482b5393475060392afJohn McCall BlockParent = parent->BlockParent; 39fb44de956f27875def889482b5393475060392afJohn McCall TemplateParamParent = parent->TemplateParamParent; 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingParent = parent->MSLocalManglingParent; 41fb44de956f27875def889482b5393475060392afJohn McCall } else { 42fb44de956f27875def889482b5393475060392afJohn McCall Depth = 0; 43fb44de956f27875def889482b5393475060392afJohn McCall PrototypeDepth = 0; 44fb44de956f27875def889482b5393475060392afJohn McCall PrototypeIndex = 0; 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingParent = FnParent = BlockParent = 0; 46fb44de956f27875def889482b5393475060392afJohn McCall TemplateParamParent = 0; 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingNumber = 1; 48fb44de956f27875def889482b5393475060392afJohn McCall } 49fb44de956f27875def889482b5393475060392afJohn McCall 50fb44de956f27875def889482b5393475060392afJohn McCall // If this scope is a function or contains breaks/continues, remember it. 51fb44de956f27875def889482b5393475060392afJohn McCall if (flags & FnScope) FnParent = this; 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // The MS mangler uses the number of scopes that can hold declarations as 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // part of an external name. 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags & (ClassScope | FnScope)) { 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingNumber = getMSLocalManglingNumber(); 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSLocalManglingParent = this; 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 58fb44de956f27875def889482b5393475060392afJohn McCall if (flags & BreakScope) BreakParent = this; 59fb44de956f27875def889482b5393475060392afJohn McCall if (flags & ContinueScope) ContinueParent = this; 60fb44de956f27875def889482b5393475060392afJohn McCall if (flags & BlockScope) BlockParent = this; 61fb44de956f27875def889482b5393475060392afJohn McCall if (flags & TemplateParamScope) TemplateParamParent = this; 62fb44de956f27875def889482b5393475060392afJohn McCall 63fb44de956f27875def889482b5393475060392afJohn McCall // If this is a prototype scope, record that. 64fb44de956f27875def889482b5393475060392afJohn McCall if (flags & FunctionPrototypeScope) PrototypeDepth++; 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (flags & DeclScope) { 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (flags & FunctionPrototypeScope) 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Prototype scopes are uninteresting. 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if ((flags & ClassScope) && getParent()->isClassScope()) 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Nested class scopes aren't ambiguous. 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope) 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ; // Classes inside of namespaces aren't ambiguous. 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines incrementMSLocalManglingNumber(); 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 75fb44de956f27875def889482b5393475060392afJohn McCall 76fb44de956f27875def889482b5393475060392afJohn McCall DeclsInScope.clear(); 77fb44de956f27875def889482b5393475060392afJohn McCall UsingDirectives.clear(); 78fb44de956f27875def889482b5393475060392afJohn McCall Entity = 0; 79fb44de956f27875def889482b5393475060392afJohn McCall ErrorTrap.reset(); 80fb44de956f27875def889482b5393475060392afJohn McCall} 8116f1f717af196b1448258857b2e6dcfe144b39d0James Molloy 8216f1f717af196b1448258857b2e6dcfe144b39d0James Molloybool Scope::containedInPrototypeScope() const { 8316f1f717af196b1448258857b2e6dcfe144b39d0James Molloy const Scope *S = this; 8416f1f717af196b1448258857b2e6dcfe144b39d0James Molloy while (S) { 8516f1f717af196b1448258857b2e6dcfe144b39d0James Molloy if (S->isFunctionPrototypeScope()) 8616f1f717af196b1448258857b2e6dcfe144b39d0James Molloy return true; 8716f1f717af196b1448258857b2e6dcfe144b39d0James Molloy S = S->getParent(); 8816f1f717af196b1448258857b2e6dcfe144b39d0James Molloy } 8916f1f717af196b1448258857b2e6dcfe144b39d0James Molloy return false; 9016f1f717af196b1448258857b2e6dcfe144b39d0James Molloy} 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::AddFlags(unsigned FlagsToSet) { 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 && 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Unsupported scope flags"); 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FlagsToSet & BreakScope) { 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((Flags & BreakScope) == 0 && "Already set"); 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BreakParent = this; 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FlagsToSet & ContinueScope) { 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((Flags & ContinueScope) == 0 && "Already set"); 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ContinueParent = this; 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags |= FlagsToSet; 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dump() const { dumpImpl(llvm::errs()); } 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Scope::dumpImpl(raw_ostream &OS) const { 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Flags = getFlags(); 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasFlags = Flags != 0; 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasFlags) 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Flags: "; 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (Flags) { 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags & FnScope) { 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FnScope"; 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FnScope; 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & BreakScope) { 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "BreakScope"; 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~BreakScope; 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ContinueScope) { 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ContinueScope"; 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ContinueScope; 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & DeclScope) { 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "DeclScope"; 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~DeclScope; 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ControlScope) { 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ControlScope"; 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ControlScope; 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ClassScope) { 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ClassScope"; 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ClassScope; 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & BlockScope) { 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "BlockScope"; 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~BlockScope; 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & TemplateParamScope) { 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "TemplateParamScope"; 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~TemplateParamScope; 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FunctionPrototypeScope) { 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FunctionPrototypeScope"; 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FunctionPrototypeScope; 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FunctionDeclarationScope) { 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FunctionDeclarationScope"; 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FunctionDeclarationScope; 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & AtCatchScope) { 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "AtCatchScope"; 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~AtCatchScope; 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & ObjCMethodScope) { 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "ObjCMethodScope"; 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~ObjCMethodScope; 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & SwitchScope) { 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "SwitchScope"; 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~SwitchScope; 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & TryScope) { 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "TryScope"; 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~TryScope; 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & FnTryCatchScope) { 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "FnTryCatchScope"; 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~FnTryCatchScope; 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Flags & OpenMPDirectiveScope) { 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "OpenMPDirectiveScope"; 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Flags &= ~OpenMPDirectiveScope; 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Flags) 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " | "; 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasFlags) 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << '\n'; 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const Scope *Parent = getParent()) 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Parent: (clang::Scope*)" << Parent << '\n'; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Depth: " << Depth << '\n'; 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n'; 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const DeclContext *DC = getEntity()) 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "Entity : (clang::DeclContext*)" << DC << '\n'; 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 180