On May 3, 2013, at 0:33 , John McCall <[email protected]> wrote:

> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=181000&r1=180999&r2=181000&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Fri May  3 02:33:41 2013
> @@ -704,21 +704,37 @@ void Decl::CheckAccessDeclContext() cons
> #endif
> }
> 
> -DeclContext *Decl::getNonClosureContext() {
> -  return getDeclContext()->getNonClosureAncestor();
> -}
> +static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
> +static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); 
> }
> 
> -DeclContext *DeclContext::getNonClosureAncestor() {
> -  DeclContext *DC = this;
> +/// Starting at a given context (a Decl or DeclContext), look for a
> +/// code context that is not a closure (a lambda, block, etc.).
> +template <class T> static Decl *getNonClosureContext(T *D) {
> +  if (getKind(D) == Decl::CXXMethod) {
> +    CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
> +    if (MD->getParent()->isLambda() &&
> +        MD->getOverloadedOperator() == OO_Call)
> +      return getNonClosureContext(MD->getParent()->getParent());
> +    return MD;

Can you explain this? I get that lambdas look like CXXMethodDecls, but what's 
wrong with dyn_cast here? I see that other kinds of methods will be caught by 
the FunctionDecl below, but honestly this seems like a silly reason to add 
complexity—not just in the check, but in needing the template and the random 
other free functions to make it work.

Also, checking the overloaded operator is probably ever so slightly cheaper to 
do before checking the parent.

> +  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
> +    return FD;
> +  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
> +    return MD;
> +  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
> +    return getNonClosureContext(BD->getParent());
> +  } else if (CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
> +    return getNonClosureContext(CD->getParent());
> +  } else {
> +    return 0;
> +  }
> +}
> 
> -  // 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().
> -  while (isa<BlockDecl>(DC))
> -    DC = cast<BlockDecl>(DC)->getDeclContext();
> +Decl *Decl::getNonClosureContext() {
> +  return ::getNonClosureContext(this);
> +}
> 
> -  assert(!DC->isClosure());
> -  return DC;
> +Decl *DeclContext::getNonClosureAncestor() {
> +  return ::getNonClosureContext(this);
> }
> 

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to