]> granicus.if.org Git - clang/commitdiff
Provide a Decl::getNonClosureContext to look through any "closure" (i.e.
authorJohn McCall <rjmccall@apple.com>
Tue, 22 Feb 2011 22:25:23 +0000 (22:25 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 22 Feb 2011 22:25:23 +0000 (22:25 +0000)
block and, eventually, C++ lambda) contexts.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126252 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclBase.h
lib/AST/DeclBase.cpp

index bf249cea9d5fb0b27d954c4db686f7f6e69c8ad8..b35d134d05345f9ba25f27a0a2cce01ba1c7823d 100644 (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:
index be379d522dd4658233ab8124ef5fd59f6b233151..81df00d6c7e8ac29f5be6be8ea006ad9bd68e263 100644 (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