Provide a Decl::getNonClosureContext to look through any "closure" (i.e.

block and, eventually, C++ lambda) contexts.

llvm-svn: 126252
This commit is contained in:
John McCall 2011-02-22 22:25:23 +00:00
parent 2d1f4be47a
commit b67608fe83
2 changed files with 27 additions and 0 deletions

View File

@ -299,6 +299,13 @@ public:
return const_cast<Decl*>(this)->getDeclContext();
}
/// Finds the innermost non-closure context of this declaration.
/// That is, walk out the DeclContext chain, skipping any blocks.
DeclContext *getNonClosureContext();
const DeclContext *getNonClosureContext() const {
return const_cast<Decl*>(this)->getNonClosureContext();
}
TranslationUnitDecl *getTranslationUnitDecl();
const TranslationUnitDecl *getTranslationUnitDecl() const {
return const_cast<Decl*>(this)->getTranslationUnitDecl();
@ -787,6 +794,10 @@ public:
return cast<Decl>(this)->getASTContext();
}
bool isClosure() const {
return DeclKind == Decl::Block;
}
bool isFunctionOrMethod() const {
switch (DeclKind) {
case Decl::Block:

View File

@ -465,6 +465,22 @@ void Decl::CheckAccessDeclContext() const {
#endif
}
DeclContext *Decl::getNonClosureContext() {
DeclContext *DC = getDeclContext();
// This is basically "while (DC->isClosure()) DC = DC->getParent();"
// except that it's significantly more efficient to cast to a known
// decl type and call getDeclContext() than to call getParent().
do {
if (isa<BlockDecl>(DC)) {
DC = cast<BlockDecl>(DC)->getDeclContext();
continue;
}
} while (false);
assert(!DC->isClosure());
return DC;
}
//===----------------------------------------------------------------------===//
// DeclContext Implementation