[cfe-commits] r97658 - in /cfe/trunk: lib/CodeGen/Mangle.cpp test/CodeGenCXX/mangle-local-class-names.cpp

Daniel Dunbar daniel at zuster.org
Thu Mar 4 05:34:12 PST 2010


Hi Fariborz,

On Wed, Mar 3, 2010 at 11:41 AM, Fariborz Jahanian <fjahanian at apple.com> wrote:
> Author: fjahanian
> Date: Wed Mar  3 13:41:08 2010
> New Revision: 97658
>
> URL: http://llvm.org/viewvc/llvm-project?rev=97658&view=rev
> Log:
> Implements mangling of local class names to
> fix a code gen crash. This is WIP as not
> all ABI cases are covered (there is a FIXME to
> this effect). Fixes radar 7696748.
>
> Added:
>    cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp
> Modified:
>    cfe/trunk/lib/CodeGen/Mangle.cpp
>
> Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=97658&r1=97657&r2=97658&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
> +++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Mar  3 13:41:08 2010
> @@ -37,7 +37,19 @@
>  using namespace CodeGen;
>
>  namespace {
> -
> +
> +static const DeclContext *GetLocalClassFunctionDeclContext(
> +                                                      const DeclContext *DC) {
> +  if (isa<CXXRecordDecl>(DC)) {
> +    while (!DC->isNamespace() && !DC->isTranslationUnit() &&
> +           !isa<FunctionDecl>(DC))
> +      DC = DC->getParent();
> +    if (isa<FunctionDecl>(DC))
> +      return DC;
> +  }
> +  return 0;
> +}
> +
>  static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
>   assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
>          "Passed in decl is not a ctor or dtor!");
> @@ -53,6 +65,8 @@
>  }
>
>  static const unsigned UnknownArity = ~0U;
> +static unsigned Discriminator = 0;
> +static llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;

Please do not add new static global variables. These belong in a class
somewhere.

They should also be documented, I don't understand the purpose of Discriminator.

>  /// CXXNameMangler - Manage the mangling of a single name.
>  class CXXNameMangler {
> @@ -61,7 +75,7 @@
>
>   const CXXMethodDecl *Structor;
>   unsigned StructorType;
> -
> +
>   llvm::DenseMap<uintptr_t, unsigned> Substitutions;
>
>   ASTContext &getASTContext() const { return Context.getASTContext(); }
> @@ -128,11 +142,12 @@
>   void mangleUnscopedTemplateName(const TemplateDecl *ND);
>   void mangleSourceName(const IdentifierInfo *II);
>   void mangleLocalName(const NamedDecl *ND);
> -  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC);
> +  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
> +                        bool NoFunction=false);

Please document what the NoFunction argument is for.

>   void mangleNestedName(const TemplateDecl *TD,
>                         const TemplateArgument *TemplateArgs,
>                         unsigned NumTemplateArgs);
> -  void manglePrefix(const DeclContext *DC);
> +  void manglePrefix(const DeclContext *DC, bool NoFunction=false);

Ditto.

>   void mangleTemplatePrefix(const TemplateDecl *ND);
>   void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
>   void mangleQualifiers(Qualifiers Quals);
> @@ -342,7 +357,12 @@
>   //         ::= <local-name>
>   //
>   const DeclContext *DC = ND->getDeclContext();
> -
> +
> +  if (GetLocalClassFunctionDeclContext(DC)) {
> +    mangleLocalName(ND);
> +    return;
> +  }
> +
>   // If this is an extern variable declared locally, the relevant DeclContext
>   // is that of the containing namespace, or the translation unit.
>   if (isa<FunctionDecl>(DC) && ND->hasLinkage())
> @@ -603,7 +623,8 @@
>  }
>
>  void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
> -                                      const DeclContext *DC) {
> +                                      const DeclContext *DC,
> +                                      bool NoFunction) {
>   // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
>   //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
>
> @@ -616,8 +637,9 @@
>   if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
>     mangleTemplatePrefix(TD);
>     mangleTemplateArgs(*TemplateArgs);
> -  } else {
> -    manglePrefix(DC);
> +  }
> +  else {

Please write '} else {', in keeping with Clang style.

> +    manglePrefix(DC, NoFunction);
>     mangleUnqualifiedName(ND);
>   }
>
> @@ -640,18 +662,38 @@
>   // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
>   //              := Z <function encoding> E s [<discriminator>]
>   // <discriminator> := _ <non-negative number>
> +  const DeclContext *DC = ND->getDeclContext();
>   Out << 'Z';
>
> -  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ND->getDeclContext()))
> +  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
>     mangleObjCMethodName(MD);
> +  else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
> +    mangleFunctionEncoding(cast<FunctionDecl>(CDC));
> +    Out << 'E';
> +    mangleNestedName(ND, DC, true /*NoFunction*/);
> +
> +    // FIXME. This still does not conform to ABI and does not cover all cases.
> +    unsigned &discriminator = Uniquifier[ND];
> +    if (!discriminator)
> +      discriminator = ++Discriminator;
> +    if (discriminator == 1)
> +      return;
> +    unsigned disc = discriminator-2;
> +    if (disc < 10)
> +      Out << '_' << disc;
> +    else
> +      Out << "__" << disc << '_';

This code is hard to read (it has three distinct variables with
variants of the same name), and should have a comment explaining what
it is trying to do. Does the ABI actually cover the naming of local
variables? I thought not, but if it does please refer to the relevant
sections.

> +
> +    return;
> +  }
>   else
> -    mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
> +    mangleFunctionEncoding(cast<FunctionDecl>(DC));
>
>   Out << 'E';
>   mangleUnqualifiedName(ND);
>  }
>
> -void CXXNameMangler::manglePrefix(const DeclContext *DC) {
> +void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
>   //  <prefix> ::= <prefix> <unqualified-name>
>   //           ::= <template-prefix> <template-args>
>   //           ::= <template-param>
> @@ -672,8 +714,11 @@
>   if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
>     mangleTemplatePrefix(TD);
>     mangleTemplateArgs(*TemplateArgs);
> -  } else {
> -    manglePrefix(DC->getParent());
> +  }
> +  else if(NoFunction && isa<FunctionDecl>(DC))
> +    return;
> +  else {
> +    manglePrefix(DC->getParent(), NoFunction);
>     mangleUnqualifiedName(cast<NamedDecl>(DC));
>   }
>
>
> Added: cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp?rev=97658&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp (added)
> +++ cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp Wed Mar  3 13:41:08 2010
> @@ -0,0 +1,30 @@
> +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
> +
> +// CHECK:  @_ZZ4FUNCvEN4SSSSC1ERKf
> +// CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf
> +
> +void FUNC ()
> +{
> +  {
> +    float IVAR1 ;
> +
> +    struct SSSS
> +    {
> +      float bv;
> +      SSSS( const float& from): bv(from) { }
> +    };
> +
> +    SSSS VAR1(IVAR1);
> +   }
> +
> +   {
> +    float IVAR2 ;
> +
> +    struct SSSS
> +    {
> +     SSSS( const float& from) {}
> +    };
> +
> +    SSSS VAR2(IVAR2);
> +   }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list