From b67608fe83cea48f4ea586ebb3ecfbc961596ae3 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 22 Feb 2011 22:25:23 +0000 Subject: [PATCH] Provide a Decl::getNonClosureContext to look through any "closure" (i.e. block and, eventually, C++ lambda) contexts. llvm-svn: 126252 --- clang/include/clang/AST/DeclBase.h | 11 +++++++++++ clang/lib/AST/DeclBase.cpp | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index bf249cea9d5f..b35d134d0534 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -299,6 +299,13 @@ public: return const_cast(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(this)->getNonClosureContext(); + } + TranslationUnitDecl *getTranslationUnitDecl(); const TranslationUnitDecl *getTranslationUnitDecl() const { return const_cast(this)->getTranslationUnitDecl(); @@ -787,6 +794,10 @@ public: return cast(this)->getASTContext(); } + bool isClosure() const { + return DeclKind == Decl::Block; + } + bool isFunctionOrMethod() const { switch (DeclKind) { case Decl::Block: diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index be379d522dd4..81df00d6c7e8 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -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(DC)) { + DC = cast(DC)->getDeclContext(); + continue; + } + } while (false); + + assert(!DC->isClosure()); + return DC; +} //===----------------------------------------------------------------------===// // DeclContext Implementation -- GitLab