]> granicus.if.org Git - clang/commitdiff
Add mangling for thunks.
authorMike Stump <mrs@apple.com>
Wed, 2 Sep 2009 00:25:38 +0000 (00:25 +0000)
committerMike Stump <mrs@apple.com>
Wed, 2 Sep 2009 00:25:38 +0000 (00:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80743 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Mangle.cpp
lib/CodeGen/Mangle.h

index 71b84e70013c7defad35913b437de375cb6162dc..c5014d3ff7cbc53fc0b068f2b0d5d1961ae2b9e0 100644 (file)
@@ -39,6 +39,8 @@ namespace {
       : Context(C), Out(os), Structor(0), StructorType(0) { }
 
     bool mangle(const NamedDecl *D);
+    void mangleThunkName(const NamedDecl *ND, bool Virtual, int64_t nv,
+                         int64_t v);
     void mangleGuardVariable(const VarDecl *D);
     
     void mangleCXXVtable(QualType Type);
@@ -87,8 +89,8 @@ static bool isInCLinkageSpecification(const Decl *D) {
 }
 
 bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
-  // Clang's "overloadable" attribute extension to C/C++ implies
-  // name mangling (always).
+  // Clang's "overloadable" attribute extension to C/C++ implies name mangling
+  // (always).
   if (!FD->hasAttr<OverloadableAttr>()) {
     // C functions are not mangled, and "main" is never mangled.
     if (!Context.getLangOptions().CPlusPlus || FD->isMain(Context))
@@ -111,8 +113,8 @@ bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
 }
 
 bool CXXNameMangler::mangle(const NamedDecl *D) {
-  // Any decl can be declared with __asm("foo") on it, and this takes
-  // precedence over all other naming in the .o file.
+  // Any decl can be declared with __asm("foo") on it, and this takes precedence
+  // over all other naming in the .o file.
   if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
     // If we have an asm name, then we use it as the mangling.
     Out << '\01';  // LLVM IR Marker for __asm("foo")
@@ -185,9 +187,9 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
   // <encoding> ::= <function name> <bare-function-type>
   mangleName(FD);
   
-  // Whether the mangling of a function type includes the return type depends 
-  // on the context and the nature of the function. The rules for deciding 
-  // whether the return type is included are:
+  // Whether the mangling of a function type includes the return type depends on
+  // the context and the nature of the function. The rules for deciding whether
+  // the return type is included are:
   // 
   //   1. Template functions (names or types) have return types encoded, with
   //   the exceptions listed below.
@@ -196,8 +198,8 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
   //   exceptions listed below.
   //   3. Non-template function names do not have return types encoded.
   //
-  // The exceptions mentioned in (1) and (2) above, for which the return 
-  // type is never included, are
+  // The exceptions mentioned in (1) and (2) above, for which the return type is
+  // never included, are
   //   1. Constructors.
   //   2. Destructors.
   //   3. Conversion operator functions, e.g. operator int.
@@ -236,6 +238,40 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
     mangleNestedName(ND);
 }
 
+void CXXNameMangler::mangleThunkName(const NamedDecl *D, bool Virtual,
+                                     int64_t nv, int64_t v) {
+  //  <special-name> ::= T <call-offset> <base encoding>
+  //                      # base is the nominal target function of thunk
+  //  <call-offset>  ::= h <nv-offset> _
+  //                 ::= v <v-offset> _
+  //  <nv-offset>    ::= <offset number>        # non-virtual base override
+  //  <v-offset>     ::= <offset nubmer> _ <virtual offset number>
+  //                      # virtual base override, with vcall offset
+  if (!Virtual) {
+    Out << "_Th";
+    if (nv < 0) {
+      Out << "n";
+      nv = -nv;
+    }
+    Out << nv;
+  } else {
+    Out << "_Tv";
+    if (nv < 0) {
+      Out << "n";
+      nv = -nv;
+    }
+    Out << nv;
+    Out << "_";
+    if (v < 0) {
+      Out << "n";
+      v = -v;
+    }
+    Out << v;
+  }
+  Out << "_";
+  mangleName(D);
+}
+
 void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
   //  <unqualified-name> ::= <operator-name>
   //                     ::= <ctor-dtor-name>  
@@ -254,8 +290,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
 
   case DeclarationName::CXXConstructorName:
     if (ND == Structor)
-      // If the named decl is the C++ constructor we're mangling, use the 
-      // type we were given.
+      // If the named decl is the C++ constructor we're mangling, use the type
+      // we were given.
       mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
     else
       // Otherwise, use the complete constructor name. This is relevant if a
@@ -265,8 +301,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
 
   case DeclarationName::CXXDestructorName:
     if (ND == Structor)
-      // If the named decl is the C++ destructor we're mangling, use the 
-      // type we were given.
+      // If the named decl is the C++ destructor we're mangling, use the type we
+      // were given.
       mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
     else
       // Otherwise, use the complete destructor name. This is relevant if a
@@ -637,8 +673,7 @@ void CXXNameMangler::mangleType(const TagType *T) {
   else
     mangleName(T->getDecl());
   
-  // If this is a class template specialization, mangle the template
-  // arguments.
+  // If this is a class template specialization, mangle the template arguments.
   if (ClassTemplateSpecializationDecl *Spec 
       = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
     mangleTemplateArgumentList(Spec->getTemplateArgs());
@@ -773,14 +808,14 @@ void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
 }
 
 namespace clang {
-  /// \brief Mangles the name of the declaration D and emits that name
-  /// to the given output stream.
+  /// \brief Mangles the name of the declaration D and emits that name to the
+  /// given output stream.
   ///
-  /// If the declaration D requires a mangled name, this routine will
-  /// emit that mangled name to \p os and return true. Otherwise, \p
-  /// os will be unchanged and this routine will return false. In this
-  /// case, the caller should just emit the identifier of the declaration
-  /// (\c D->getIdentifier()) as its name.
+  /// If the declaration D requires a mangled name, this routine will emit that
+  /// mangled name to \p os and return true. Otherwise, \p os will be unchanged
+  /// and this routine will return false. In this case, the caller should just
+  /// emit the identifier of the declaration (\c D->getIdentifier()) as its
+  /// name.
   bool mangleName(const NamedDecl *D, ASTContext &Context, 
                   llvm::raw_ostream &os) {
     assert(!isa<CXXConstructorDecl>(D) &&
@@ -796,6 +831,21 @@ namespace clang {
     return true;
   }
   
+  /// \brief Mangles the a thunk with the offset n for the declaration D and
+  /// emits that name to the given output stream.
+  void mangleThunkName(const NamedDecl *D, bool Virtual, int64_t nv,
+                       int64_t v, ASTContext &Context, llvm::raw_ostream &os) {
+    // FIXME: Hum, we might have to thunk these, fix.
+    assert(!isa<CXXConstructorDecl>(D) &&
+           "Use mangleCXXCtor for constructor decls!");
+    assert(!isa<CXXDestructorDecl>(D) &&
+           "Use mangleCXXDtor for destructor decls!");
+    
+    CXXNameMangler Mangler(Context, os);
+    Mangler.mangleThunkName(D, Virtual, nv, v);
+    os.flush();
+  }
+  
   /// mangleGuardVariable - Returns the mangled name for a guard variable
   /// for the passed in VarDecl.
   void mangleGuardVariable(const VarDecl *D, ASTContext &Context,
index 8f0a32da8850e3771ad734563151a54ad6342142..a2fba4e6696b9265971d42d8e78b7fda60d386dc 100644 (file)
@@ -34,6 +34,8 @@ namespace clang {
   
   bool mangleName(const NamedDecl *D, ASTContext &Context, 
                   llvm::raw_ostream &os);
+  void mangleThunkName(const NamedDecl *D, bool Virtual, int64_t n,
+                       int64_t vn, ASTContext &Context, llvm::raw_ostream &os);
   void mangleGuardVariable(const VarDecl *D, ASTContext &Context,
                            llvm::raw_ostream &os);
   void mangleCXXVtable(QualType T, ASTContext &Context, llvm::raw_ostream &os);