diff options
| -rw-r--r-- | clang/include/clang/AST/DeclBase.h | 11 | ||||
| -rw-r--r-- | clang/lib/AST/DeclBase.cpp | 16 | 
2 files changed, 27 insertions, 0 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index bf249cea9d5..b35d134d053 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -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: diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index be379d522dd..81df00d6c7e 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<BlockDecl>(DC)) { +      DC = cast<BlockDecl>(DC)->getDeclContext(); +      continue; +    } +  } while (false); + +  assert(!DC->isClosure()); +  return DC; +}  //===----------------------------------------------------------------------===//  // DeclContext Implementation  | 

