r181000 - Correctly emit certain implicit references to 'self' even within

Jordan Rose jordan_rose at apple.com
Fri May 3 09:14:34 PDT 2013


On May 3, 2013, at 0:33 , John McCall <rjmccall at apple.com> 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);
> }
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130503/e9915e8d/attachment.html>


More information about the cfe-commits mailing list