clang API Documentation
00001 //===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the Scope class, which is used for recording 00011 // information about a lexical scope. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/Sema/Scope.h" 00016 #include "clang/AST/Decl.h" 00017 #include "llvm/Support/raw_ostream.h" 00018 00019 using namespace clang; 00020 00021 void Scope::Init(Scope *parent, unsigned flags) { 00022 AnyParent = parent; 00023 Flags = flags; 00024 00025 if (parent && !(flags & FnScope)) { 00026 BreakParent = parent->BreakParent; 00027 ContinueParent = parent->ContinueParent; 00028 } else { 00029 // Control scopes do not contain the contents of nested function scopes for 00030 // control flow purposes. 00031 BreakParent = ContinueParent = nullptr; 00032 } 00033 00034 if (parent) { 00035 Depth = parent->Depth + 1; 00036 PrototypeDepth = parent->PrototypeDepth; 00037 PrototypeIndex = 0; 00038 FnParent = parent->FnParent; 00039 BlockParent = parent->BlockParent; 00040 TemplateParamParent = parent->TemplateParamParent; 00041 MSLocalManglingParent = parent->MSLocalManglingParent; 00042 if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope | 00043 FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) == 00044 0) 00045 Flags |= parent->getFlags() & OpenMPSimdDirectiveScope; 00046 } else { 00047 Depth = 0; 00048 PrototypeDepth = 0; 00049 PrototypeIndex = 0; 00050 MSLocalManglingParent = FnParent = BlockParent = nullptr; 00051 TemplateParamParent = nullptr; 00052 MSLocalManglingNumber = 1; 00053 } 00054 00055 // If this scope is a function or contains breaks/continues, remember it. 00056 if (flags & FnScope) FnParent = this; 00057 // The MS mangler uses the number of scopes that can hold declarations as 00058 // part of an external name. 00059 if (Flags & (ClassScope | FnScope)) { 00060 MSLocalManglingNumber = getMSLocalManglingNumber(); 00061 MSLocalManglingParent = this; 00062 } 00063 if (flags & BreakScope) BreakParent = this; 00064 if (flags & ContinueScope) ContinueParent = this; 00065 if (flags & BlockScope) BlockParent = this; 00066 if (flags & TemplateParamScope) TemplateParamParent = this; 00067 00068 // If this is a prototype scope, record that. 00069 if (flags & FunctionPrototypeScope) PrototypeDepth++; 00070 00071 if (flags & DeclScope) { 00072 if (flags & FunctionPrototypeScope) 00073 ; // Prototype scopes are uninteresting. 00074 else if ((flags & ClassScope) && getParent()->isClassScope()) 00075 ; // Nested class scopes aren't ambiguous. 00076 else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope) 00077 ; // Classes inside of namespaces aren't ambiguous. 00078 else if ((flags & EnumScope)) 00079 ; // Don't increment for enum scopes. 00080 else 00081 incrementMSLocalManglingNumber(); 00082 } 00083 00084 DeclsInScope.clear(); 00085 UsingDirectives.clear(); 00086 Entity = nullptr; 00087 ErrorTrap.reset(); 00088 NRVO.setPointerAndInt(nullptr, 0); 00089 } 00090 00091 bool Scope::containedInPrototypeScope() const { 00092 const Scope *S = this; 00093 while (S) { 00094 if (S->isFunctionPrototypeScope()) 00095 return true; 00096 S = S->getParent(); 00097 } 00098 return false; 00099 } 00100 00101 void Scope::AddFlags(unsigned FlagsToSet) { 00102 assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 && 00103 "Unsupported scope flags"); 00104 if (FlagsToSet & BreakScope) { 00105 assert((Flags & BreakScope) == 0 && "Already set"); 00106 BreakParent = this; 00107 } 00108 if (FlagsToSet & ContinueScope) { 00109 assert((Flags & ContinueScope) == 0 && "Already set"); 00110 ContinueParent = this; 00111 } 00112 Flags |= FlagsToSet; 00113 } 00114 00115 void Scope::mergeNRVOIntoParent() { 00116 if (VarDecl *Candidate = NRVO.getPointer()) { 00117 if (isDeclScope(Candidate)) 00118 Candidate->setNRVOVariable(true); 00119 } 00120 00121 if (getEntity()) 00122 return; 00123 00124 if (NRVO.getInt()) 00125 getParent()->setNoNRVO(); 00126 else if (NRVO.getPointer()) 00127 getParent()->addNRVOCandidate(NRVO.getPointer()); 00128 } 00129 00130 void Scope::dump() const { dumpImpl(llvm::errs()); } 00131 00132 void Scope::dumpImpl(raw_ostream &OS) const { 00133 unsigned Flags = getFlags(); 00134 bool HasFlags = Flags != 0; 00135 00136 if (HasFlags) 00137 OS << "Flags: "; 00138 00139 while (Flags) { 00140 if (Flags & FnScope) { 00141 OS << "FnScope"; 00142 Flags &= ~FnScope; 00143 } else if (Flags & BreakScope) { 00144 OS << "BreakScope"; 00145 Flags &= ~BreakScope; 00146 } else if (Flags & ContinueScope) { 00147 OS << "ContinueScope"; 00148 Flags &= ~ContinueScope; 00149 } else if (Flags & DeclScope) { 00150 OS << "DeclScope"; 00151 Flags &= ~DeclScope; 00152 } else if (Flags & ControlScope) { 00153 OS << "ControlScope"; 00154 Flags &= ~ControlScope; 00155 } else if (Flags & ClassScope) { 00156 OS << "ClassScope"; 00157 Flags &= ~ClassScope; 00158 } else if (Flags & BlockScope) { 00159 OS << "BlockScope"; 00160 Flags &= ~BlockScope; 00161 } else if (Flags & TemplateParamScope) { 00162 OS << "TemplateParamScope"; 00163 Flags &= ~TemplateParamScope; 00164 } else if (Flags & FunctionPrototypeScope) { 00165 OS << "FunctionPrototypeScope"; 00166 Flags &= ~FunctionPrototypeScope; 00167 } else if (Flags & FunctionDeclarationScope) { 00168 OS << "FunctionDeclarationScope"; 00169 Flags &= ~FunctionDeclarationScope; 00170 } else if (Flags & AtCatchScope) { 00171 OS << "AtCatchScope"; 00172 Flags &= ~AtCatchScope; 00173 } else if (Flags & ObjCMethodScope) { 00174 OS << "ObjCMethodScope"; 00175 Flags &= ~ObjCMethodScope; 00176 } else if (Flags & SwitchScope) { 00177 OS << "SwitchScope"; 00178 Flags &= ~SwitchScope; 00179 } else if (Flags & TryScope) { 00180 OS << "TryScope"; 00181 Flags &= ~TryScope; 00182 } else if (Flags & FnTryCatchScope) { 00183 OS << "FnTryCatchScope"; 00184 Flags &= ~FnTryCatchScope; 00185 } else if (Flags & SEHTryScope) { 00186 OS << "SEHTryScope"; 00187 Flags &= ~SEHTryScope; 00188 } else if (Flags & OpenMPDirectiveScope) { 00189 OS << "OpenMPDirectiveScope"; 00190 Flags &= ~OpenMPDirectiveScope; 00191 } else if (Flags & OpenMPLoopDirectiveScope) { 00192 OS << "OpenMPLoopDirectiveScope"; 00193 Flags &= ~OpenMPLoopDirectiveScope; 00194 } else if (Flags & OpenMPSimdDirectiveScope) { 00195 OS << "OpenMPSimdDirectiveScope"; 00196 Flags &= ~OpenMPSimdDirectiveScope; 00197 } 00198 00199 if (Flags) 00200 OS << " | "; 00201 } 00202 if (HasFlags) 00203 OS << '\n'; 00204 00205 if (const Scope *Parent = getParent()) 00206 OS << "Parent: (clang::Scope*)" << Parent << '\n'; 00207 00208 OS << "Depth: " << Depth << '\n'; 00209 OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n'; 00210 if (const DeclContext *DC = getEntity()) 00211 OS << "Entity : (clang::DeclContext*)" << DC << '\n'; 00212 00213 if (NRVO.getInt()) 00214 OS << "NRVO not allowed"; 00215 else if (NRVO.getPointer()) 00216 OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; 00217 }