You've already forked linux-packaging-mono
acceptance-tests
data
debian
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
bdwgc
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
helix-binaries
ikdasm
ikvm
illinker-test-assets
linker
llvm-project
clang
INPUTS
bindings
cmake
docs
examples
include
lib
ARCMigrate
AST
ASTMatchers
Analysis
Basic
CodeGen
CrossTU
Driver
Edit
Format
Frontend
FrontendTool
Headers
Index
Lex
Parse
Rewrite
Sema
AnalysisBasedWarnings.cpp
AttributeList.cpp
CMakeLists.txt
CodeCompleteConsumer.cpp
CoroutineStmtBuilder.h
DeclSpec.cpp
DelayedDiagnostic.cpp
IdentifierResolver.cpp
JumpDiagnostics.cpp
MultiplexExternalSemaSource.cpp
Scope.cpp
ScopeInfo.cpp
Sema.cpp
SemaAccess.cpp
SemaAttr.cpp
SemaCUDA.cpp
SemaCXXScopeSpec.cpp
SemaCast.cpp.REMOVED.git-id
SemaChecking.cpp.REMOVED.git-id
SemaCodeComplete.cpp.REMOVED.git-id
SemaConsumer.cpp
SemaCoroutine.cpp
SemaDecl.cpp.REMOVED.git-id
SemaDeclAttr.cpp.REMOVED.git-id
SemaDeclCXX.cpp.REMOVED.git-id
SemaDeclObjC.cpp.REMOVED.git-id
SemaExceptionSpec.cpp
SemaExpr.cpp.REMOVED.git-id
SemaExprCXX.cpp.REMOVED.git-id
SemaExprMember.cpp
SemaExprObjC.cpp.REMOVED.git-id
SemaFixItUtils.cpp
SemaInit.cpp.REMOVED.git-id
SemaLambda.cpp
SemaLookup.cpp.REMOVED.git-id
SemaObjCProperty.cpp.REMOVED.git-id
SemaOpenMP.cpp.REMOVED.git-id
SemaOverload.cpp.REMOVED.git-id
SemaPseudoObject.cpp
SemaStmt.cpp.REMOVED.git-id
SemaStmtAsm.cpp
SemaStmtAttr.cpp
SemaTemplate.cpp.REMOVED.git-id
SemaTemplateDeduction.cpp.REMOVED.git-id
SemaTemplateInstantiate.cpp.REMOVED.git-id
SemaTemplateInstantiateDecl.cpp.REMOVED.git-id
SemaTemplateVariadic.cpp
SemaType.cpp.REMOVED.git-id
TreeTransform.h.REMOVED.git-id
TypeLocBuilder.cpp
TypeLocBuilder.h
Serialization
StaticAnalyzer
Tooling
CMakeLists.txt
runtime
tools
unittests
utils
www
.arcconfig
.clang-format
.clang-tidy
.gitignore
CMakeLists.txt
CODE_OWNERS.TXT
INSTALL.txt
LICENSE.TXT
ModuleInfo.txt
NOTES.txt
README.txt
clang-tools-extra
compiler-rt
libcxx
libcxxabi
libunwind
lld
lldb
llvm
openmp
polly
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
how-to-bump-roslyn-binaries.md
ikvm-native
llvm
m4
man
mcs
mk
mono
msvc
netcore
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
200 lines
6.2 KiB
C++
200 lines
6.2 KiB
C++
![]() |
//===- Scope.cpp - Lexical scope information --------------------*- C++ -*-===//
|
||
|
//
|
||
|
// The LLVM Compiler Infrastructure
|
||
|
//
|
||
|
// This file is distributed under the University of Illinois Open Source
|
||
|
// License. See LICENSE.TXT for details.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
// This file implements the Scope class, which is used for recording
|
||
|
// information about a lexical scope.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "clang/Sema/Scope.h"
|
||
|
#include "clang/AST/Decl.h"
|
||
|
#include "llvm/Support/raw_ostream.h"
|
||
|
|
||
|
using namespace clang;
|
||
|
|
||
|
void Scope::setFlags(Scope *parent, unsigned flags) {
|
||
|
AnyParent = parent;
|
||
|
Flags = flags;
|
||
|
|
||
|
if (parent && !(flags & FnScope)) {
|
||
|
BreakParent = parent->BreakParent;
|
||
|
ContinueParent = parent->ContinueParent;
|
||
|
} else {
|
||
|
// Control scopes do not contain the contents of nested function scopes for
|
||
|
// control flow purposes.
|
||
|
BreakParent = ContinueParent = nullptr;
|
||
|
}
|
||
|
|
||
|
if (parent) {
|
||
|
Depth = parent->Depth + 1;
|
||
|
PrototypeDepth = parent->PrototypeDepth;
|
||
|
PrototypeIndex = 0;
|
||
|
FnParent = parent->FnParent;
|
||
|
BlockParent = parent->BlockParent;
|
||
|
TemplateParamParent = parent->TemplateParamParent;
|
||
|
MSLastManglingParent = parent->MSLastManglingParent;
|
||
|
MSCurManglingNumber = getMSLastManglingNumber();
|
||
|
if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
|
||
|
FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
|
||
|
0)
|
||
|
Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
|
||
|
} else {
|
||
|
Depth = 0;
|
||
|
PrototypeDepth = 0;
|
||
|
PrototypeIndex = 0;
|
||
|
MSLastManglingParent = FnParent = BlockParent = nullptr;
|
||
|
TemplateParamParent = nullptr;
|
||
|
MSLastManglingNumber = 1;
|
||
|
MSCurManglingNumber = 1;
|
||
|
}
|
||
|
|
||
|
// If this scope is a function or contains breaks/continues, remember it.
|
||
|
if (flags & FnScope) FnParent = this;
|
||
|
// The MS mangler uses the number of scopes that can hold declarations as
|
||
|
// part of an external name.
|
||
|
if (Flags & (ClassScope | FnScope)) {
|
||
|
MSLastManglingNumber = getMSLastManglingNumber();
|
||
|
MSLastManglingParent = this;
|
||
|
MSCurManglingNumber = 1;
|
||
|
}
|
||
|
if (flags & BreakScope) BreakParent = this;
|
||
|
if (flags & ContinueScope) ContinueParent = this;
|
||
|
if (flags & BlockScope) BlockParent = this;
|
||
|
if (flags & TemplateParamScope) TemplateParamParent = this;
|
||
|
|
||
|
// If this is a prototype scope, record that.
|
||
|
if (flags & FunctionPrototypeScope) PrototypeDepth++;
|
||
|
|
||
|
if (flags & DeclScope) {
|
||
|
if (flags & FunctionPrototypeScope)
|
||
|
; // Prototype scopes are uninteresting.
|
||
|
else if ((flags & ClassScope) && getParent()->isClassScope())
|
||
|
; // Nested class scopes aren't ambiguous.
|
||
|
else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
|
||
|
; // Classes inside of namespaces aren't ambiguous.
|
||
|
else if ((flags & EnumScope))
|
||
|
; // Don't increment for enum scopes.
|
||
|
else
|
||
|
incrementMSManglingNumber();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Scope::Init(Scope *parent, unsigned flags) {
|
||
|
setFlags(parent, flags);
|
||
|
|
||
|
DeclsInScope.clear();
|
||
|
UsingDirectives.clear();
|
||
|
Entity = nullptr;
|
||
|
ErrorTrap.reset();
|
||
|
NRVO.setPointerAndInt(nullptr, 0);
|
||
|
}
|
||
|
|
||
|
bool Scope::containedInPrototypeScope() const {
|
||
|
const Scope *S = this;
|
||
|
while (S) {
|
||
|
if (S->isFunctionPrototypeScope())
|
||
|
return true;
|
||
|
S = S->getParent();
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void Scope::AddFlags(unsigned FlagsToSet) {
|
||
|
assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
|
||
|
"Unsupported scope flags");
|
||
|
if (FlagsToSet & BreakScope) {
|
||
|
assert((Flags & BreakScope) == 0 && "Already set");
|
||
|
BreakParent = this;
|
||
|
}
|
||
|
if (FlagsToSet & ContinueScope) {
|
||
|
assert((Flags & ContinueScope) == 0 && "Already set");
|
||
|
ContinueParent = this;
|
||
|
}
|
||
|
Flags |= FlagsToSet;
|
||
|
}
|
||
|
|
||
|
void Scope::mergeNRVOIntoParent() {
|
||
|
if (VarDecl *Candidate = NRVO.getPointer()) {
|
||
|
if (isDeclScope(Candidate))
|
||
|
Candidate->setNRVOVariable(true);
|
||
|
}
|
||
|
|
||
|
if (getEntity())
|
||
|
return;
|
||
|
|
||
|
if (NRVO.getInt())
|
||
|
getParent()->setNoNRVO();
|
||
|
else if (NRVO.getPointer())
|
||
|
getParent()->addNRVOCandidate(NRVO.getPointer());
|
||
|
}
|
||
|
|
||
|
LLVM_DUMP_METHOD void Scope::dump() const { dumpImpl(llvm::errs()); }
|
||
|
|
||
|
void Scope::dumpImpl(raw_ostream &OS) const {
|
||
|
unsigned Flags = getFlags();
|
||
|
bool HasFlags = Flags != 0;
|
||
|
|
||
|
if (HasFlags)
|
||
|
OS << "Flags: ";
|
||
|
|
||
|
std::pair<unsigned, const char *> FlagInfo[] = {
|
||
|
{FnScope, "FnScope"},
|
||
|
{BreakScope, "BreakScope"},
|
||
|
{ContinueScope, "ContinueScope"},
|
||
|
{DeclScope, "DeclScope"},
|
||
|
{ControlScope, "ControlScope"},
|
||
|
{ClassScope, "ClassScope"},
|
||
|
{BlockScope, "BlockScope"},
|
||
|
{TemplateParamScope, "TemplateParamScope"},
|
||
|
{FunctionPrototypeScope, "FunctionPrototypeScope"},
|
||
|
{FunctionDeclarationScope, "FunctionDeclarationScope"},
|
||
|
{AtCatchScope, "AtCatchScope"},
|
||
|
{ObjCMethodScope, "ObjCMethodScope"},
|
||
|
{SwitchScope, "SwitchScope"},
|
||
|
{TryScope, "TryScope"},
|
||
|
{FnTryCatchScope, "FnTryCatchScope"},
|
||
|
{OpenMPDirectiveScope, "OpenMPDirectiveScope"},
|
||
|
{OpenMPLoopDirectiveScope, "OpenMPLoopDirectiveScope"},
|
||
|
{OpenMPSimdDirectiveScope, "OpenMPSimdDirectiveScope"},
|
||
|
{EnumScope, "EnumScope"},
|
||
|
{SEHTryScope, "SEHTryScope"},
|
||
|
{SEHExceptScope, "SEHExceptScope"},
|
||
|
{SEHFilterScope, "SEHFilterScope"},
|
||
|
{CompoundStmtScope, "CompoundStmtScope"},
|
||
|
{ClassInheritanceScope, "ClassInheritanceScope"}};
|
||
|
|
||
|
for (auto Info : FlagInfo) {
|
||
|
if (Flags & Info.first) {
|
||
|
OS << Info.second;
|
||
|
Flags &= ~Info.first;
|
||
|
if (Flags)
|
||
|
OS << " | ";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assert(Flags == 0 && "Unknown scope flags");
|
||
|
|
||
|
if (HasFlags)
|
||
|
OS << '\n';
|
||
|
|
||
|
if (const Scope *Parent = getParent())
|
||
|
OS << "Parent: (clang::Scope*)" << Parent << '\n';
|
||
|
|
||
|
OS << "Depth: " << Depth << '\n';
|
||
|
OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n';
|
||
|
OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n';
|
||
|
if (const DeclContext *DC = getEntity())
|
||
|
OS << "Entity : (clang::DeclContext*)" << DC << '\n';
|
||
|
|
||
|
if (NRVO.getInt())
|
||
|
OS << "NRVO not allowed\n";
|
||
|
else if (NRVO.getPointer())
|
||
|
OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
|
||
|
}
|