mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220775 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			159 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // Unified name mangler for assembly backends.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/IR/Mangler.h"
 | |
| #include "llvm/ADT/SmallString.h"
 | |
| #include "llvm/ADT/Twine.h"
 | |
| #include "llvm/IR/DataLayout.h"
 | |
| #include "llvm/IR/DerivedTypes.h"
 | |
| #include "llvm/IR/Function.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| using namespace llvm;
 | |
| 
 | |
| static void getNameWithPrefixx(raw_ostream &OS, const Twine &GVName,
 | |
|                               Mangler::ManglerPrefixTy PrefixTy,
 | |
|                               const DataLayout &DL, char Prefix) {
 | |
|   SmallString<256> TmpData;
 | |
|   StringRef Name = GVName.toStringRef(TmpData);
 | |
|   assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
 | |
| 
 | |
|   // No need to do anything special if the global has the special "do not
 | |
|   // mangle" flag in the name.
 | |
|   if (Name[0] == '\1') {
 | |
|     OS << Name.substr(1);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (PrefixTy == Mangler::Private)
 | |
|     OS << DL.getPrivateGlobalPrefix();
 | |
|   else if (PrefixTy == Mangler::LinkerPrivate)
 | |
|     OS << DL.getLinkerPrivateGlobalPrefix();
 | |
| 
 | |
|   if (Prefix != '\0')
 | |
|     OS << Prefix;
 | |
| 
 | |
|   // If this is a simple string that doesn't need escaping, just append it.
 | |
|   OS << Name;
 | |
| }
 | |
| 
 | |
| void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
 | |
|                                 ManglerPrefixTy PrefixTy) const {
 | |
|   char Prefix = DL->getGlobalPrefix();
 | |
|   return getNameWithPrefixx(OS, GVName, PrefixTy, *DL, Prefix);
 | |
| }
 | |
| 
 | |
| void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
 | |
|                                 const Twine &GVName,
 | |
|                                 ManglerPrefixTy PrefixTy) const {
 | |
|   raw_svector_ostream OS(OutName);
 | |
|   return getNameWithPrefix(OS, GVName, PrefixTy);
 | |
| }
 | |
| 
 | |
| static bool hasByteCountSuffix(CallingConv::ID CC) {
 | |
|   switch (CC) {
 | |
|   case CallingConv::X86_FastCall:
 | |
|   case CallingConv::X86_StdCall:
 | |
|   case CallingConv::X86_VectorCall:
 | |
|     return true;
 | |
|   default:
 | |
|     return false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /// Microsoft fastcall and stdcall functions require a suffix on their name
 | |
| /// indicating the number of words of arguments they take.
 | |
| static void addByteCountSuffix(raw_ostream &OS, const Function *F,
 | |
|                                const DataLayout &TD) {
 | |
|   // Calculate arguments size total.
 | |
|   unsigned ArgWords = 0;
 | |
|   for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
 | |
|        AI != AE; ++AI) {
 | |
|     Type *Ty = AI->getType();
 | |
|     // 'Dereference' type in case of byval or inalloca parameter attribute.
 | |
|     if (AI->hasByValOrInAllocaAttr())
 | |
|       Ty = cast<PointerType>(Ty)->getElementType();
 | |
|     // Size should be aligned to pointer size.
 | |
|     unsigned PtrSize = TD.getPointerSize();
 | |
|     ArgWords += RoundUpToAlignment(TD.getTypeAllocSize(Ty), PtrSize);
 | |
|   }
 | |
| 
 | |
|   OS << '@' << ArgWords;
 | |
| }
 | |
| 
 | |
| void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
 | |
|                                 bool CannotUsePrivateLabel) const {
 | |
|   ManglerPrefixTy PrefixTy = Mangler::Default;
 | |
|   if (GV->hasPrivateLinkage()) {
 | |
|     if (CannotUsePrivateLabel)
 | |
|       PrefixTy = Mangler::LinkerPrivate;
 | |
|     else
 | |
|       PrefixTy = Mangler::Private;
 | |
|   }
 | |
| 
 | |
|   if (!GV->hasName()) {
 | |
|     // Get the ID for the global, assigning a new one if we haven't got one
 | |
|     // already.
 | |
|     unsigned &ID = AnonGlobalIDs[GV];
 | |
|     if (ID == 0)
 | |
|       ID = NextAnonGlobalID++;
 | |
| 
 | |
|     // Must mangle the global into a unique ID.
 | |
|     getNameWithPrefix(OS, "__unnamed_" + Twine(ID), PrefixTy);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   StringRef Name = GV->getName();
 | |
|   char Prefix = DL->getGlobalPrefix();
 | |
| 
 | |
|   // Mangle functions with Microsoft calling conventions specially.  Only do
 | |
|   // this mangling for x86_64 vectorcall and 32-bit x86.
 | |
|   const Function *MSFunc = dyn_cast<Function>(GV);
 | |
|   if (Name.startswith("\01"))
 | |
|     MSFunc = nullptr; // Don't mangle when \01 is present.
 | |
|   CallingConv::ID CC =
 | |
|       MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
 | |
|   if (!DL->hasMicrosoftFastStdCallMangling() &&
 | |
|       CC != CallingConv::X86_VectorCall)
 | |
|     MSFunc = nullptr;
 | |
|   if (MSFunc) {
 | |
|     if (CC == CallingConv::X86_FastCall)
 | |
|       Prefix = '@'; // fastcall functions have an @ prefix instead of _.
 | |
|     else if (CC == CallingConv::X86_VectorCall)
 | |
|       Prefix = '\0'; // vectorcall functions have no prefix.
 | |
|   }
 | |
| 
 | |
|   getNameWithPrefixx(OS, Name, PrefixTy, *DL, Prefix);
 | |
| 
 | |
|   if (!MSFunc)
 | |
|     return;
 | |
| 
 | |
|   // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
 | |
|   // or vectorcall, add it.  These functions have a suffix of @N where N is the
 | |
|   // cumulative byte size of all of the parameters to the function in decimal.
 | |
|   if (CC == CallingConv::X86_VectorCall)
 | |
|     OS << '@'; // vectorcall functions use a double @ suffix.
 | |
|   FunctionType *FT = MSFunc->getFunctionType();
 | |
|   if (hasByteCountSuffix(CC) &&
 | |
|       // "Pure" variadic functions do not receive @0 suffix.
 | |
|       (!FT->isVarArg() || FT->getNumParams() == 0 ||
 | |
|        (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
 | |
|     addByteCountSuffix(OS, MSFunc, *DL);
 | |
| }
 | |
| 
 | |
| void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
 | |
|                                 const GlobalValue *GV,
 | |
|                                 bool CannotUsePrivateLabel) const {
 | |
|   raw_svector_ostream OS(OutName);
 | |
|   getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
 | |
| }
 |