diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/Scope.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/Scope.cpp | 161 |
1 files changed, 157 insertions, 4 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/Scope.cpp b/contrib/llvm/tools/clang/lib/Sema/Scope.cpp index 10f12ce..35e2075 100644 --- a/contrib/llvm/tools/clang/lib/Sema/Scope.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/Scope.cpp @@ -13,6 +13,8 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/Scope.h" +#include "clang/AST/Decl.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; @@ -26,7 +28,7 @@ void Scope::Init(Scope *parent, unsigned flags) { } else { // Control scopes do not contain the contents of nested function scopes for // control flow purposes. - BreakParent = ContinueParent = 0; + BreakParent = ContinueParent = nullptr; } if (parent) { @@ -36,16 +38,35 @@ void Scope::Init(Scope *parent, unsigned flags) { FnParent = parent->FnParent; BlockParent = parent->BlockParent; TemplateParamParent = parent->TemplateParamParent; + MSLocalManglingParent = parent->MSLocalManglingParent; + SEHTryParent = parent->SEHTryParent; + if (parent->Flags & SEHTryScope) + SEHTryParent = parent; + if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope | + FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) == + 0) + Flags |= parent->getFlags() & OpenMPSimdDirectiveScope; } else { Depth = 0; PrototypeDepth = 0; PrototypeIndex = 0; - FnParent = BlockParent = 0; - TemplateParamParent = 0; + SEHTryParent = MSLocalManglingParent = FnParent = BlockParent = nullptr; + TemplateParamParent = nullptr; + MSLocalManglingNumber = 1; } // If this scope is a function or contains breaks/continues, remember it. if (flags & FnScope) FnParent = this; + SEHTryIndexPool = 0; + SEHTryIndex = -1; + if (flags & SEHTryScope) + SEHTryIndex = FnParent ? FnParent->SEHTryIndexPool++ : -1; + // The MS mangler uses the number of scopes that can hold declarations as + // part of an external name. + if (Flags & (ClassScope | FnScope)) { + MSLocalManglingNumber = getMSLocalManglingNumber(); + MSLocalManglingParent = this; + } if (flags & BreakScope) BreakParent = this; if (flags & ContinueScope) ContinueParent = this; if (flags & BlockScope) BlockParent = this; @@ -54,10 +75,24 @@ void Scope::Init(Scope *parent, unsigned flags) { // 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 + incrementMSLocalManglingNumber(); + } + DeclsInScope.clear(); UsingDirectives.clear(); - Entity = 0; + Entity = nullptr; ErrorTrap.reset(); + NRVO.setPointerAndInt(nullptr, 0); } bool Scope::containedInPrototypeScope() const { @@ -69,3 +104,121 @@ bool Scope::containedInPrototypeScope() const { } 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()); +} + +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: "; + + while (Flags) { + if (Flags & FnScope) { + OS << "FnScope"; + Flags &= ~FnScope; + } else if (Flags & BreakScope) { + OS << "BreakScope"; + Flags &= ~BreakScope; + } else if (Flags & ContinueScope) { + OS << "ContinueScope"; + Flags &= ~ContinueScope; + } else if (Flags & DeclScope) { + OS << "DeclScope"; + Flags &= ~DeclScope; + } else if (Flags & ControlScope) { + OS << "ControlScope"; + Flags &= ~ControlScope; + } else if (Flags & ClassScope) { + OS << "ClassScope"; + Flags &= ~ClassScope; + } else if (Flags & BlockScope) { + OS << "BlockScope"; + Flags &= ~BlockScope; + } else if (Flags & TemplateParamScope) { + OS << "TemplateParamScope"; + Flags &= ~TemplateParamScope; + } else if (Flags & FunctionPrototypeScope) { + OS << "FunctionPrototypeScope"; + Flags &= ~FunctionPrototypeScope; + } else if (Flags & FunctionDeclarationScope) { + OS << "FunctionDeclarationScope"; + Flags &= ~FunctionDeclarationScope; + } else if (Flags & AtCatchScope) { + OS << "AtCatchScope"; + Flags &= ~AtCatchScope; + } else if (Flags & ObjCMethodScope) { + OS << "ObjCMethodScope"; + Flags &= ~ObjCMethodScope; + } else if (Flags & SwitchScope) { + OS << "SwitchScope"; + Flags &= ~SwitchScope; + } else if (Flags & TryScope) { + OS << "TryScope"; + Flags &= ~TryScope; + } else if (Flags & FnTryCatchScope) { + OS << "FnTryCatchScope"; + Flags &= ~FnTryCatchScope; + } else if (Flags & SEHTryScope) { + OS << "SEHTryScope"; + Flags &= ~SEHTryScope; + } else if (Flags & OpenMPDirectiveScope) { + OS << "OpenMPDirectiveScope"; + Flags &= ~OpenMPDirectiveScope; + } else if (Flags & OpenMPLoopDirectiveScope) { + OS << "OpenMPLoopDirectiveScope"; + Flags &= ~OpenMPLoopDirectiveScope; + } else if (Flags & OpenMPSimdDirectiveScope) { + OS << "OpenMPSimdDirectiveScope"; + Flags &= ~OpenMPSimdDirectiveScope; + } + + if (Flags) + OS << " | "; + } + if (HasFlags) + OS << '\n'; + + if (const Scope *Parent = getParent()) + OS << "Parent: (clang::Scope*)" << Parent << '\n'; + + OS << "Depth: " << Depth << '\n'; + OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n'; + if (const DeclContext *DC = getEntity()) + OS << "Entity : (clang::DeclContext*)" << DC << '\n'; + + if (NRVO.getInt()) + OS << "NRVO not allowed"; + else if (NRVO.getPointer()) + OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n'; +} |