14967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===- CodegenNameGenerator.cpp - Codegen name generation -----------------===// 24967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 34967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// The LLVM Compiler Infrastructure 44967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 54967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 64967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// License. See LICENSE.TXT for details. 74967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 84967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===----------------------------------------------------------------------===// 94967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Determines the name that the symbol will get for code generation. 114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// 124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===----------------------------------------------------------------------===// 134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Index/CodegenNameGenerator.h" 154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/ASTContext.h" 164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/DeclCXX.h" 174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/DeclObjC.h" 184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/Mangle.h" 194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/VTableBuilder.h" 204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Basic/TargetInfo.h" 214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/IR/DataLayout.h" 224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/IR/Mangler.h" 234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace clang; 264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace clang::index; 274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstruct CodegenNameGenerator::Implementation { 294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::unique_ptr<MangleContext> MC; 304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::DataLayout DL; 314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Implementation(ASTContext &Ctx) 334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar : MC(Ctx.createMangleContext()), 344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar DL(Ctx.getTargetInfo().getDataLayout()) {} 354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool writeName(const Decl *D, raw_ostream &OS) { 374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // First apply frontend mangling. 384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SmallString<128> FrontendBuf; 394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::raw_svector_ostream FrontendBufOS(FrontendBuf); 404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (auto *FD = dyn_cast<FunctionDecl>(D)) { 414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (FD->isDependentContext()) 424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (writeFuncOrVarName(FD, FrontendBufOS)) 444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (auto *VD = dyn_cast<VarDecl>(D)) { 464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (writeFuncOrVarName(VD, FrontendBufOS)) 474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) { 494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleObjCMethodNameWithoutSize(MD, OS); 504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) { 524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar writeObjCClassName(ID, FrontendBufOS); 534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Now apply backend mangling. 584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL); 594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string getName(const Decl *D) { 634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string Name; 644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar { 654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::raw_string_ostream OS(Name); 664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar writeName(D, OS); 674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Name; 694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::vector<std::string> getAllManglings(const Decl *D) { 724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D))) 734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return {}; 744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const NamedDecl *ND = cast<NamedDecl>(D); 764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ASTContext &Ctx = ND->getASTContext(); 784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::unique_ptr<MangleContext> M(Ctx.createMangleContext()); 794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::vector<std::string> Manglings; 814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { 834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, 844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar /*IsCSSMethod=*/true); 854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv(); 864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return CC == DefaultCC; 874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar }; 884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) { 904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledStructor(CD, Ctor_Base)); 914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) 934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!CD->getParent()->isAbstract()) 944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete)); 954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) 974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor()) 984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) 994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure)); 1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) { 1014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledStructor(DD, Dtor_Base)); 1024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { 1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete)); 1044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (DD->isVirtual()) 1054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting)); 1064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) { 1084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getName(ND)); 1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (MD->isVirtual()) 1104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) 1114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (const auto &T : *TIV) 1124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Manglings.emplace_back(getMangledThunk(MD, T)); 1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Manglings; 1164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate: 1194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) { 1204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (MC->shouldMangleDeclName(D)) { 1214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D)) 1224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleCXXCtor(CtorD, Ctor_Complete, OS); 1234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D)) 1244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleCXXDtor(DtorD, Dtor_Complete, OS); 1254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar else 1264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleName(D, OS); 1274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 1284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } else { 1294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar IdentifierInfo *II = D->getIdentifier(); 1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!II) 1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 1324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar OS << II->getName(); 1334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 1344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) { 1384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar OS << getClassSymbolPrefix(); 1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar OS << D->getObjCRuntimeNameAsString(); 1404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar static StringRef getClassSymbolPrefix() { 1434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return "OBJC_CLASS_$_"; 1444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) { 1474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string FrontendBuf; 1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::raw_string_ostream FOS(FrontendBuf); 1494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) 1514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS); 1524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) 1534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS); 1544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string BackendBuf; 1564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::raw_string_ostream BOS(BackendBuf); 1574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); 1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return BOS.str(); 1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) { 1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string FrontendBuf; 1654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::raw_string_ostream FOS(FrontendBuf); 1664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MC->mangleThunk(MD, T, FOS); 1684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar std::string BackendBuf; 1704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::raw_string_ostream BOS(BackendBuf); 1714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); 1734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return BOS.str(); 1754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}; 1774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1784967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCodegenNameGenerator::CodegenNameGenerator(ASTContext &Ctx) 1794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar : Impl(new Implementation(Ctx)) { 1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1824967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarCodegenNameGenerator::~CodegenNameGenerator() { 1834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool CodegenNameGenerator::writeName(const Decl *D, raw_ostream &OS) { 1864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Impl->writeName(D, OS); 1874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstd::string CodegenNameGenerator::getName(const Decl *D) { 1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Impl->getName(D); 1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstd::vector<std::string> CodegenNameGenerator::getAllManglings(const Decl *D) { 1944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Impl->getAllManglings(D); 1954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 196