[cfe-commits] r126252 - in /cfe/trunk: include/clang/AST/DeclBase.h lib/AST/DeclBase.cpp

John McCall rjmccall at apple.com
Tue Feb 22 14:25:23 PST 2011


Author: rjmccall
Date: Tue Feb 22 16:25:23 2011
New Revision: 126252

URL: http://llvm.org/viewvc/llvm-project?rev=126252&view=rev
Log:
Provide a Decl::getNonClosureContext to look through any "closure" (i.e.
block and, eventually, C++ lambda) contexts.


Modified:
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/DeclBase.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=126252&r1=126251&r2=126252&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Tue Feb 22 16:25:23 2011
@@ -299,6 +299,13 @@
     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 @@
     return cast<Decl>(this)->getASTContext();
   }
 
+  bool isClosure() const {
+    return DeclKind == Decl::Block;
+  }
+
   bool isFunctionOrMethod() const {
     switch (DeclKind) {
     case Decl::Block:

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=126252&r1=126251&r2=126252&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Tue Feb 22 16:25:23 2011
@@ -465,6 +465,22 @@
 #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





More information about the cfe-commits mailing list