1221339Sdim//===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===// 2221339Sdim// 3221339Sdim// The LLVM Compiler Infrastructure 4221339Sdim// 5221339Sdim// This file is distributed under the University of Illinois Open Source 6221339Sdim// License. See LICENSE.TXT for details. 7221339Sdim// 8221339Sdim//===----------------------------------------------------------------------===// 9221339Sdim// 10221339Sdim// This file implements the Scope class, which is used for recording 11221339Sdim// information about a lexical scope. 12221339Sdim// 13221339Sdim//===----------------------------------------------------------------------===// 14221339Sdim 15221339Sdim#include "clang/Sema/Scope.h" 16276479Sdim#include "clang/AST/Decl.h" 17276479Sdim#include "llvm/Support/raw_ostream.h" 18221339Sdim 19221339Sdimusing namespace clang; 20221339Sdim 21221339Sdimvoid Scope::Init(Scope *parent, unsigned flags) { 22221339Sdim AnyParent = parent; 23221339Sdim Flags = flags; 24234353Sdim 25234353Sdim if (parent && !(flags & FnScope)) { 26234353Sdim BreakParent = parent->BreakParent; 27234353Sdim ContinueParent = parent->ContinueParent; 28234353Sdim } else { 29234353Sdim // Control scopes do not contain the contents of nested function scopes for 30234353Sdim // control flow purposes. 31276479Sdim BreakParent = ContinueParent = nullptr; 32234353Sdim } 33234353Sdim 34221339Sdim if (parent) { 35221339Sdim Depth = parent->Depth + 1; 36221339Sdim PrototypeDepth = parent->PrototypeDepth; 37221339Sdim PrototypeIndex = 0; 38221339Sdim FnParent = parent->FnParent; 39221339Sdim BlockParent = parent->BlockParent; 40221339Sdim TemplateParamParent = parent->TemplateParamParent; 41288943Sdim MSLastManglingParent = parent->MSLastManglingParent; 42288943Sdim MSCurManglingNumber = getMSLastManglingNumber(); 43276479Sdim if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope | 44276479Sdim FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) == 45276479Sdim 0) 46276479Sdim Flags |= parent->getFlags() & OpenMPSimdDirectiveScope; 47221339Sdim } else { 48221339Sdim Depth = 0; 49221339Sdim PrototypeDepth = 0; 50221339Sdim PrototypeIndex = 0; 51288943Sdim MSLastManglingParent = FnParent = BlockParent = nullptr; 52276479Sdim TemplateParamParent = nullptr; 53288943Sdim MSLastManglingNumber = 1; 54288943Sdim MSCurManglingNumber = 1; 55221339Sdim } 56221339Sdim 57221339Sdim // If this scope is a function or contains breaks/continues, remember it. 58221339Sdim if (flags & FnScope) FnParent = this; 59276479Sdim // The MS mangler uses the number of scopes that can hold declarations as 60276479Sdim // part of an external name. 61276479Sdim if (Flags & (ClassScope | FnScope)) { 62288943Sdim MSLastManglingNumber = getMSLastManglingNumber(); 63288943Sdim MSLastManglingParent = this; 64288943Sdim MSCurManglingNumber = 1; 65276479Sdim } 66221339Sdim if (flags & BreakScope) BreakParent = this; 67221339Sdim if (flags & ContinueScope) ContinueParent = this; 68221339Sdim if (flags & BlockScope) BlockParent = this; 69221339Sdim if (flags & TemplateParamScope) TemplateParamParent = this; 70221339Sdim 71221339Sdim // If this is a prototype scope, record that. 72221339Sdim if (flags & FunctionPrototypeScope) PrototypeDepth++; 73221339Sdim 74276479Sdim if (flags & DeclScope) { 75276479Sdim if (flags & FunctionPrototypeScope) 76276479Sdim ; // Prototype scopes are uninteresting. 77276479Sdim else if ((flags & ClassScope) && getParent()->isClassScope()) 78276479Sdim ; // Nested class scopes aren't ambiguous. 79276479Sdim else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope) 80276479Sdim ; // Classes inside of namespaces aren't ambiguous. 81276479Sdim else if ((flags & EnumScope)) 82276479Sdim ; // Don't increment for enum scopes. 83276479Sdim else 84288943Sdim incrementMSManglingNumber(); 85276479Sdim } 86276479Sdim 87221339Sdim DeclsInScope.clear(); 88221339Sdim UsingDirectives.clear(); 89276479Sdim Entity = nullptr; 90221339Sdim ErrorTrap.reset(); 91276479Sdim NRVO.setPointerAndInt(nullptr, 0); 92221339Sdim} 93234353Sdim 94234353Sdimbool Scope::containedInPrototypeScope() const { 95234353Sdim const Scope *S = this; 96234353Sdim while (S) { 97234353Sdim if (S->isFunctionPrototypeScope()) 98234353Sdim return true; 99234353Sdim S = S->getParent(); 100234353Sdim } 101234353Sdim return false; 102234353Sdim} 103276479Sdim 104276479Sdimvoid Scope::AddFlags(unsigned FlagsToSet) { 105276479Sdim assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 && 106276479Sdim "Unsupported scope flags"); 107276479Sdim if (FlagsToSet & BreakScope) { 108276479Sdim assert((Flags & BreakScope) == 0 && "Already set"); 109276479Sdim BreakParent = this; 110276479Sdim } 111276479Sdim if (FlagsToSet & ContinueScope) { 112276479Sdim assert((Flags & ContinueScope) == 0 && "Already set"); 113276479Sdim ContinueParent = this; 114276479Sdim } 115276479Sdim Flags |= FlagsToSet; 116276479Sdim} 117276479Sdim 118276479Sdimvoid Scope::mergeNRVOIntoParent() { 119276479Sdim if (VarDecl *Candidate = NRVO.getPointer()) { 120276479Sdim if (isDeclScope(Candidate)) 121276479Sdim Candidate->setNRVOVariable(true); 122276479Sdim } 123276479Sdim 124276479Sdim if (getEntity()) 125276479Sdim return; 126276479Sdim 127276479Sdim if (NRVO.getInt()) 128276479Sdim getParent()->setNoNRVO(); 129276479Sdim else if (NRVO.getPointer()) 130276479Sdim getParent()->addNRVOCandidate(NRVO.getPointer()); 131276479Sdim} 132276479Sdim 133276479Sdimvoid Scope::dump() const { dumpImpl(llvm::errs()); } 134276479Sdim 135276479Sdimvoid Scope::dumpImpl(raw_ostream &OS) const { 136276479Sdim unsigned Flags = getFlags(); 137276479Sdim bool HasFlags = Flags != 0; 138276479Sdim 139276479Sdim if (HasFlags) 140276479Sdim OS << "Flags: "; 141276479Sdim 142276479Sdim while (Flags) { 143276479Sdim if (Flags & FnScope) { 144276479Sdim OS << "FnScope"; 145276479Sdim Flags &= ~FnScope; 146276479Sdim } else if (Flags & BreakScope) { 147276479Sdim OS << "BreakScope"; 148276479Sdim Flags &= ~BreakScope; 149276479Sdim } else if (Flags & ContinueScope) { 150276479Sdim OS << "ContinueScope"; 151276479Sdim Flags &= ~ContinueScope; 152276479Sdim } else if (Flags & DeclScope) { 153276479Sdim OS << "DeclScope"; 154276479Sdim Flags &= ~DeclScope; 155276479Sdim } else if (Flags & ControlScope) { 156276479Sdim OS << "ControlScope"; 157276479Sdim Flags &= ~ControlScope; 158276479Sdim } else if (Flags & ClassScope) { 159276479Sdim OS << "ClassScope"; 160276479Sdim Flags &= ~ClassScope; 161276479Sdim } else if (Flags & BlockScope) { 162276479Sdim OS << "BlockScope"; 163276479Sdim Flags &= ~BlockScope; 164276479Sdim } else if (Flags & TemplateParamScope) { 165276479Sdim OS << "TemplateParamScope"; 166276479Sdim Flags &= ~TemplateParamScope; 167276479Sdim } else if (Flags & FunctionPrototypeScope) { 168276479Sdim OS << "FunctionPrototypeScope"; 169276479Sdim Flags &= ~FunctionPrototypeScope; 170276479Sdim } else if (Flags & FunctionDeclarationScope) { 171276479Sdim OS << "FunctionDeclarationScope"; 172276479Sdim Flags &= ~FunctionDeclarationScope; 173276479Sdim } else if (Flags & AtCatchScope) { 174276479Sdim OS << "AtCatchScope"; 175276479Sdim Flags &= ~AtCatchScope; 176276479Sdim } else if (Flags & ObjCMethodScope) { 177276479Sdim OS << "ObjCMethodScope"; 178276479Sdim Flags &= ~ObjCMethodScope; 179276479Sdim } else if (Flags & SwitchScope) { 180276479Sdim OS << "SwitchScope"; 181276479Sdim Flags &= ~SwitchScope; 182276479Sdim } else if (Flags & TryScope) { 183276479Sdim OS << "TryScope"; 184276479Sdim Flags &= ~TryScope; 185276479Sdim } else if (Flags & FnTryCatchScope) { 186276479Sdim OS << "FnTryCatchScope"; 187276479Sdim Flags &= ~FnTryCatchScope; 188276479Sdim } else if (Flags & SEHTryScope) { 189276479Sdim OS << "SEHTryScope"; 190276479Sdim Flags &= ~SEHTryScope; 191288943Sdim } else if (Flags & SEHExceptScope) { 192288943Sdim OS << "SEHExceptScope"; 193288943Sdim Flags &= ~SEHExceptScope; 194276479Sdim } else if (Flags & OpenMPDirectiveScope) { 195276479Sdim OS << "OpenMPDirectiveScope"; 196276479Sdim Flags &= ~OpenMPDirectiveScope; 197276479Sdim } else if (Flags & OpenMPLoopDirectiveScope) { 198276479Sdim OS << "OpenMPLoopDirectiveScope"; 199276479Sdim Flags &= ~OpenMPLoopDirectiveScope; 200276479Sdim } else if (Flags & OpenMPSimdDirectiveScope) { 201276479Sdim OS << "OpenMPSimdDirectiveScope"; 202276479Sdim Flags &= ~OpenMPSimdDirectiveScope; 203276479Sdim } 204276479Sdim 205276479Sdim if (Flags) 206276479Sdim OS << " | "; 207276479Sdim } 208276479Sdim if (HasFlags) 209276479Sdim OS << '\n'; 210276479Sdim 211276479Sdim if (const Scope *Parent = getParent()) 212276479Sdim OS << "Parent: (clang::Scope*)" << Parent << '\n'; 213276479Sdim 214276479Sdim OS << "Depth: " << Depth << '\n'; 215288943Sdim OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n'; 216288943Sdim OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n'; 217276479Sdim if (const DeclContext *DC = getEntity()) 218276479Sdim OS << "Entity : (clang::DeclContext*)" << DC << '\n'; 219276479Sdim 220276479Sdim if (NRVO.getInt()) 221288943Sdim OS << "NRVO not allowed\n"; 222276479Sdim else if (NRVO.getPointer()) 223276479Sdim OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; 224276479Sdim} 225