mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 17:21:10 +00:00
Move name mangling support from CodeGen to AST. In the
process, perform a number of refactorings: - Move MiscNameMangler member functions to MangleContext - Remove GlobalDecl dependency from MangleContext - Make MangleContext abstract and move Itanium/Microsoft functionality to their own classes/files - Implement ASTContext::createMangleContext and have CodeGen use it No (intended) functionality change. llvm-svn: 123386
This commit is contained in:
parent
018778af3d
commit
0ff0b37627
@ -57,6 +57,7 @@ namespace clang {
|
||||
class CXXRecordDecl;
|
||||
class Decl;
|
||||
class FieldDecl;
|
||||
class MangleContext;
|
||||
class ObjCIvarDecl;
|
||||
class ObjCIvarRefExpr;
|
||||
class ObjCPropertyDecl;
|
||||
@ -1058,6 +1059,8 @@ public:
|
||||
|
||||
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
|
||||
|
||||
MangleContext *createMangleContext();
|
||||
|
||||
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
|
||||
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars)
|
||||
const;
|
||||
|
@ -7,20 +7,15 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements C++ name mangling according to the Itanium C++ ABI,
|
||||
// which is used in GCC 3.2 and newer (and many compilers that are
|
||||
// ABI-compatible with GCC):
|
||||
//
|
||||
// http://www.codesourcery.com/public/cxx-abi/abi.html
|
||||
// Defines the C++ name mangling interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_CODEGEN_MANGLE_H
|
||||
#define LLVM_CLANG_CODEGEN_MANGLE_H
|
||||
#ifndef LLVM_CLANG_AST_MANGLE_H
|
||||
#define LLVM_CLANG_AST_MANGLE_H
|
||||
|
||||
#include "CGCXX.h"
|
||||
#include "GlobalDecl.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
@ -36,8 +31,6 @@ namespace clang {
|
||||
class NamedDecl;
|
||||
class ObjCMethodDecl;
|
||||
class VarDecl;
|
||||
|
||||
namespace CodeGen {
|
||||
struct ThisAdjustment;
|
||||
struct ThunkInfo;
|
||||
|
||||
@ -74,9 +67,6 @@ class MangleContext {
|
||||
ASTContext &Context;
|
||||
Diagnostic &Diags;
|
||||
|
||||
llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
|
||||
unsigned Discriminator;
|
||||
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
|
||||
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
|
||||
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
|
||||
|
||||
@ -91,15 +81,8 @@ public:
|
||||
|
||||
Diagnostic &getDiags() const { return Diags; }
|
||||
|
||||
void startNewFunction() { LocalBlockIds.clear(); }
|
||||
virtual void startNewFunction() { LocalBlockIds.clear(); }
|
||||
|
||||
uint64_t getAnonymousStructId(const TagDecl *TD) {
|
||||
std::pair<llvm::DenseMap<const TagDecl *,
|
||||
uint64_t>::iterator, bool> Result =
|
||||
AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
|
||||
return Result.first->second;
|
||||
}
|
||||
|
||||
unsigned getBlockId(const BlockDecl *BD, bool Local) {
|
||||
llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
|
||||
= Local? LocalBlockIds : GlobalBlockIds;
|
||||
@ -111,69 +94,57 @@ public:
|
||||
/// @name Mangler Entry Points
|
||||
/// @{
|
||||
|
||||
virtual bool shouldMangleDeclName(const NamedDecl *D);
|
||||
virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
|
||||
virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
|
||||
virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &)=0;
|
||||
virtual void mangleThunk(const CXXMethodDecl *MD,
|
||||
const ThunkInfo &Thunk,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||
const ThisAdjustment &ThisAdjustment,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleReferenceTemporary(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXVTable(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXVTT(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||
const CXXRecordDecl *Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
|
||||
virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleBlock(GlobalDecl GD,
|
||||
const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
|
||||
llvm::SmallVectorImpl<char> &) = 0;
|
||||
|
||||
void mangleGlobalBlock(const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res);
|
||||
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
|
||||
const BlockDecl *BD, llvm::SmallVectorImpl<char> &Res);
|
||||
void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
|
||||
const BlockDecl *BD, llvm::SmallVectorImpl<char> &Res);
|
||||
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res);
|
||||
// Do the right thing.
|
||||
void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &Res);
|
||||
|
||||
void mangleObjCMethodName(const ObjCMethodDecl *MD,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
|
||||
// This is pretty lame.
|
||||
void mangleItaniumGuardVariable(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
|
||||
void mangleInitDiscriminator() {
|
||||
Discriminator = 0;
|
||||
}
|
||||
|
||||
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
|
||||
unsigned &discriminator = Uniquifier[ND];
|
||||
if (!discriminator)
|
||||
discriminator = ++Discriminator;
|
||||
if (discriminator == 1)
|
||||
return false;
|
||||
disc = discriminator-2;
|
||||
return true;
|
||||
virtual void mangleItaniumGuardVariable(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &) {
|
||||
assert(0 && "Target does not support mangling guard variables");
|
||||
}
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// MiscNameMangler - Mangles Objective-C method names and blocks.
|
||||
class MiscNameMangler {
|
||||
MangleContext &Context;
|
||||
llvm::raw_svector_ostream Out;
|
||||
|
||||
ASTContext &getASTContext() const { return Context.getASTContext(); }
|
||||
MangleContext *createItaniumMangleContext(ASTContext &Context,
|
||||
Diagnostic &Diags);
|
||||
MangleContext *createMicrosoftMangleContext(ASTContext &Context,
|
||||
Diagnostic &Diags);
|
||||
|
||||
public:
|
||||
MiscNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res);
|
||||
|
||||
llvm::raw_svector_ostream &getStream() { return Out; }
|
||||
|
||||
void mangleBlock(GlobalDecl GD, const BlockDecl *BD);
|
||||
void mangleObjCMethodName(const ObjCMethodDecl *MD);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
126
clang/include/clang/Basic/ABI.h
Normal file
126
clang/include/clang/Basic/ABI.h
Normal file
@ -0,0 +1,126 @@
|
||||
//===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// These enums/classes describe ABI related information about constructors,
|
||||
// destructors and thunks.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_BASIC_ABI_H
|
||||
#define CLANG_BASIC_ABI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// CXXCtorType - C++ constructor types
|
||||
enum CXXCtorType {
|
||||
Ctor_Complete, // Complete object ctor
|
||||
Ctor_Base, // Base object ctor
|
||||
Ctor_CompleteAllocating // Complete object allocating ctor
|
||||
};
|
||||
|
||||
/// CXXDtorType - C++ destructor types
|
||||
enum CXXDtorType {
|
||||
Dtor_Deleting, // Deleting dtor
|
||||
Dtor_Complete, // Complete object dtor
|
||||
Dtor_Base // Base object dtor
|
||||
};
|
||||
|
||||
/// ReturnAdjustment - A return adjustment.
|
||||
struct ReturnAdjustment {
|
||||
/// NonVirtual - The non-virtual adjustment from the derived object to its
|
||||
/// nearest virtual base.
|
||||
int64_t NonVirtual;
|
||||
|
||||
/// VBaseOffsetOffset - The offset (in bytes), relative to the address point
|
||||
/// of the virtual base class offset.
|
||||
int64_t VBaseOffsetOffset;
|
||||
|
||||
ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
|
||||
|
||||
bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
|
||||
|
||||
friend bool operator==(const ReturnAdjustment &LHS,
|
||||
const ReturnAdjustment &RHS) {
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
|
||||
}
|
||||
|
||||
friend bool operator<(const ReturnAdjustment &LHS,
|
||||
const ReturnAdjustment &RHS) {
|
||||
if (LHS.NonVirtual < RHS.NonVirtual)
|
||||
return true;
|
||||
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset;
|
||||
}
|
||||
};
|
||||
|
||||
/// ThisAdjustment - A 'this' pointer adjustment.
|
||||
struct ThisAdjustment {
|
||||
/// NonVirtual - The non-virtual adjustment from the derived object to its
|
||||
/// nearest virtual base.
|
||||
int64_t NonVirtual;
|
||||
|
||||
/// VCallOffsetOffset - The offset (in bytes), relative to the address point,
|
||||
/// of the virtual call offset.
|
||||
int64_t VCallOffsetOffset;
|
||||
|
||||
ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
|
||||
|
||||
bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
|
||||
|
||||
friend bool operator==(const ThisAdjustment &LHS,
|
||||
const ThisAdjustment &RHS) {
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
|
||||
}
|
||||
|
||||
friend bool operator<(const ThisAdjustment &LHS,
|
||||
const ThisAdjustment &RHS) {
|
||||
if (LHS.NonVirtual < RHS.NonVirtual)
|
||||
return true;
|
||||
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VCallOffsetOffset < RHS.VCallOffsetOffset;
|
||||
}
|
||||
};
|
||||
|
||||
/// ThunkInfo - The 'this' pointer adjustment as well as an optional return
|
||||
/// adjustment for a thunk.
|
||||
struct ThunkInfo {
|
||||
/// This - The 'this' pointer adjustment.
|
||||
ThisAdjustment This;
|
||||
|
||||
/// Return - The return adjustment.
|
||||
ReturnAdjustment Return;
|
||||
|
||||
ThunkInfo() { }
|
||||
|
||||
ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
|
||||
: This(This), Return(Return) { }
|
||||
|
||||
friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
|
||||
return LHS.This == RHS.This && LHS.Return == RHS.Return;
|
||||
}
|
||||
|
||||
friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
|
||||
if (LHS.This < RHS.This)
|
||||
return true;
|
||||
|
||||
return LHS.This == RHS.This && LHS.Return < RHS.Return;
|
||||
}
|
||||
|
||||
bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // CLANG_BASIC_ABI_H
|
@ -22,6 +22,7 @@
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/ASTMutationListener.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
@ -5835,4 +5836,16 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {
|
||||
return ABI->isNearlyEmpty(RD);
|
||||
}
|
||||
|
||||
MangleContext *ASTContext::createMangleContext() {
|
||||
switch (Target.getCXXABI()) {
|
||||
case CXXABI_ARM:
|
||||
case CXXABI_Itanium:
|
||||
return createItaniumMangleContext(*this, getDiagnostics());
|
||||
case CXXABI_Microsoft:
|
||||
return createMicrosoftMangleContext(*this, getDiagnostics());
|
||||
}
|
||||
assert(0 && "Unsupported ABI");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CXXABI::~CXXABI() {}
|
||||
|
@ -26,7 +26,10 @@ add_clang_library(clangAST
|
||||
ExprCXX.cpp
|
||||
InheritViz.cpp
|
||||
ItaniumCXXABI.cpp
|
||||
ItaniumMangle.cpp
|
||||
Mangle.cpp
|
||||
MicrosoftCXXABI.cpp
|
||||
MicrosoftMangle.cpp
|
||||
NestedNameSpecifier.cpp
|
||||
ParentMap.cpp
|
||||
RecordLayout.cpp
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
|
||||
//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,18 +14,18 @@
|
||||
// http://www.codesourcery.com/public/cxx-abi/abi.html
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "Mangle.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "CGVTables.h"
|
||||
|
||||
#define MANGLE_CHECKER 0
|
||||
|
||||
@ -34,68 +34,6 @@
|
||||
#endif
|
||||
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
MiscNameMangler::MiscNameMangler(MangleContext &C,
|
||||
llvm::SmallVectorImpl<char> &Res)
|
||||
: Context(C), Out(Res) { }
|
||||
|
||||
void MiscNameMangler::mangleBlock(GlobalDecl GD, const BlockDecl *BD) {
|
||||
// Mangle the context of the block.
|
||||
// FIXME: We currently mimic GCC's mangling scheme, which leaves much to be
|
||||
// desired. Come up with a better mangling scheme.
|
||||
const DeclContext *DC = BD->getDeclContext();
|
||||
while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
if (DC->isFunctionOrMethod()) {
|
||||
Out << "__";
|
||||
if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
|
||||
mangleObjCMethodName(Method);
|
||||
else {
|
||||
const NamedDecl *ND = cast<NamedDecl>(DC);
|
||||
if (IdentifierInfo *II = ND->getIdentifier())
|
||||
Out << II->getName();
|
||||
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND)) {
|
||||
llvm::SmallString<64> Buffer;
|
||||
Context.mangleCXXDtor(D, GD.getDtorType(), Buffer);
|
||||
Out << Buffer;
|
||||
}
|
||||
else if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND)) {
|
||||
llvm::SmallString<64> Buffer;
|
||||
Context.mangleCXXCtor(D, GD.getCtorType(), Buffer);
|
||||
Out << Buffer;
|
||||
}
|
||||
else {
|
||||
// FIXME: We were doing a mangleUnqualifiedName() before, but that's
|
||||
// a private member of a class that will soon itself be private to the
|
||||
// Itanium C++ ABI object. What should we do now? Right now, I'm just
|
||||
// calling the mangleName() method on the MangleContext; is there a
|
||||
// better way?
|
||||
llvm::SmallString<64> Buffer;
|
||||
Context.mangleName(ND, Buffer);
|
||||
Out << Buffer;
|
||||
}
|
||||
}
|
||||
Out << "_block_invoke_" << Context.getBlockId(BD, true);
|
||||
} else {
|
||||
Out << "__block_global_" << Context.getBlockId(BD, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MiscNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
|
||||
llvm::SmallString<64> Name;
|
||||
llvm::raw_svector_ostream OS(Name);
|
||||
|
||||
const ObjCContainerDecl *CD =
|
||||
dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
|
||||
assert (CD && "Missing container decl in GetNameForMethod");
|
||||
OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
|
||||
if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
|
||||
OS << '(' << CID << ')';
|
||||
OS << ' ' << MD->getSelector().getAsString() << ']';
|
||||
|
||||
Out << OS.str().size() << OS.str();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@ -127,9 +65,77 @@ static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
|
||||
|
||||
static const unsigned UnknownArity = ~0U;
|
||||
|
||||
class ItaniumMangleContext : public MangleContext {
|
||||
llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
|
||||
unsigned Discriminator;
|
||||
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
|
||||
|
||||
public:
|
||||
explicit ItaniumMangleContext(ASTContext &Context,
|
||||
Diagnostic &Diags)
|
||||
: MangleContext(Context, Diags) { }
|
||||
|
||||
uint64_t getAnonymousStructId(const TagDecl *TD) {
|
||||
std::pair<llvm::DenseMap<const TagDecl *,
|
||||
uint64_t>::iterator, bool> Result =
|
||||
AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
|
||||
return Result.first->second;
|
||||
}
|
||||
|
||||
void startNewFunction() {
|
||||
MangleContext::startNewFunction();
|
||||
mangleInitDiscriminator();
|
||||
}
|
||||
|
||||
/// @name Mangler Entry Points
|
||||
/// @{
|
||||
|
||||
bool shouldMangleDeclName(const NamedDecl *D);
|
||||
void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
|
||||
void mangleThunk(const CXXMethodDecl *MD,
|
||||
const ThunkInfo &Thunk,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||
const ThisAdjustment &ThisAdjustment,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleReferenceTemporary(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXVTable(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXVTT(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||
const CXXRecordDecl *Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
|
||||
void mangleItaniumGuardVariable(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
|
||||
void mangleInitDiscriminator() {
|
||||
Discriminator = 0;
|
||||
}
|
||||
|
||||
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
|
||||
unsigned &discriminator = Uniquifier[ND];
|
||||
if (!discriminator)
|
||||
discriminator = ++Discriminator;
|
||||
if (discriminator == 1)
|
||||
return false;
|
||||
disc = discriminator-2;
|
||||
return true;
|
||||
}
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// CXXNameMangler - Manage the mangling of a single name.
|
||||
class CXXNameMangler {
|
||||
MangleContext &Context;
|
||||
ItaniumMangleContext &Context;
|
||||
llvm::raw_svector_ostream Out;
|
||||
|
||||
const CXXMethodDecl *Structor;
|
||||
@ -143,13 +149,13 @@ class CXXNameMangler {
|
||||
ASTContext &getASTContext() const { return Context.getASTContext(); }
|
||||
|
||||
public:
|
||||
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res)
|
||||
CXXNameMangler(ItaniumMangleContext &C, llvm::SmallVectorImpl<char> &Res)
|
||||
: Context(C), Out(Res), Structor(0), StructorType(0), SeqID(0) { }
|
||||
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
|
||||
CXXNameMangler(ItaniumMangleContext &C, llvm::SmallVectorImpl<char> &Res,
|
||||
const CXXConstructorDecl *D, CXXCtorType Type)
|
||||
: Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
|
||||
SeqID(0) { }
|
||||
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
|
||||
CXXNameMangler(ItaniumMangleContext &C, llvm::SmallVectorImpl<char> &Res,
|
||||
const CXXDestructorDecl *D, CXXDtorType Type)
|
||||
: Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
|
||||
SeqID(0) { }
|
||||
@ -259,6 +265,7 @@ private:
|
||||
|
||||
void mangleTemplateParameter(unsigned Index);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static bool isInCLinkageSpecification(const Decl *D) {
|
||||
@ -272,7 +279,7 @@ static bool isInCLinkageSpecification(const Decl *D) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
|
||||
bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
|
||||
// In C, functions with no attributes never need to be mangled. Fastpath them.
|
||||
if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
|
||||
return false;
|
||||
@ -896,7 +903,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
|
||||
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
|
||||
manglePrefix(DC->getParent(), NoFunction);
|
||||
llvm::SmallString<64> Name;
|
||||
Context.mangleBlock(GlobalDecl(), Block, Name);
|
||||
Context.mangleBlock(Block, Name);
|
||||
Out << Name.size() << Name;
|
||||
return;
|
||||
}
|
||||
@ -1150,7 +1157,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
|
||||
|
||||
void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
|
||||
llvm::SmallString<64> Buffer;
|
||||
MiscNameMangler(Context, Buffer).mangleObjCMethodName(MD);
|
||||
Context.mangleObjCMethodName(MD, Buffer);
|
||||
Out << Buffer;
|
||||
}
|
||||
|
||||
@ -2470,8 +2477,8 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
|
||||
/// 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.
|
||||
void MangleContext::mangleName(const NamedDecl *D,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleName(const NamedDecl *D,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
|
||||
"Invalid mangleName() call, argument is not a variable or function!");
|
||||
assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
|
||||
@ -2485,27 +2492,23 @@ void MangleContext::mangleName(const NamedDecl *D,
|
||||
return Mangler.mangle(D);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
|
||||
CXXCtorType Type,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
CXXNameMangler Mangler(*this, Res, D, Type);
|
||||
Mangler.mangle(D);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
|
||||
CXXDtorType Type,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
CXXNameMangler Mangler(*this, Res, D, Type);
|
||||
Mangler.mangle(D);
|
||||
}
|
||||
|
||||
void MangleContext::mangleBlock(GlobalDecl GD, const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
MiscNameMangler Mangler(*this, Res);
|
||||
Mangler.mangleBlock(GD, BD);
|
||||
}
|
||||
|
||||
void MangleContext::mangleThunk(const CXXMethodDecl *MD,
|
||||
const ThunkInfo &Thunk,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD,
|
||||
const ThunkInfo &Thunk,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= T <call-offset> <base encoding>
|
||||
// # base is the nominal target function of thunk
|
||||
// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
|
||||
@ -2533,9 +2536,10 @@ void MangleContext::mangleThunk(const CXXMethodDecl *MD,
|
||||
}
|
||||
|
||||
void
|
||||
MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||
const ThisAdjustment &ThisAdjustment,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
|
||||
CXXDtorType Type,
|
||||
const ThisAdjustment &ThisAdjustment,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= T <call-offset> <base encoding>
|
||||
// # base is the nominal target function of thunk
|
||||
|
||||
@ -2551,8 +2555,8 @@ MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||
|
||||
/// mangleGuardVariable - Returns the mangled name for a guard variable
|
||||
/// for the passed in VarDecl.
|
||||
void MangleContext::mangleItaniumGuardVariable(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleItaniumGuardVariable(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= GV <object name> # Guard variable for one-time
|
||||
// # initialization
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
@ -2560,7 +2564,7 @@ void MangleContext::mangleItaniumGuardVariable(const VarDecl *D,
|
||||
Mangler.mangleName(D);
|
||||
}
|
||||
|
||||
void MangleContext::mangleReferenceTemporary(const VarDecl *D,
|
||||
void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// We match the GCC mangling here.
|
||||
// <special-name> ::= GR <object name>
|
||||
@ -2569,25 +2573,26 @@ void MangleContext::mangleReferenceTemporary(const VarDecl *D,
|
||||
Mangler.mangleName(D);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= TV <type> # virtual table
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
Mangler.getStream() << "_ZTV";
|
||||
Mangler.mangleNameOrStandardSubstitution(RD);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= TT <type> # VTT structure
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
Mangler.getStream() << "_ZTT";
|
||||
Mangler.mangleNameOrStandardSubstitution(RD);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||
const CXXRecordDecl *Type,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
|
||||
int64_t Offset,
|
||||
const CXXRecordDecl *Type,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= TC <type> <offset number> _ <base type>
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
Mangler.getStream() << "_ZTC";
|
||||
@ -2597,8 +2602,8 @@ void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||
Mangler.mangleNameOrStandardSubstitution(Type);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXRTTI(QualType Ty,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXRTTI(QualType Ty,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= TI <type> # typeinfo structure
|
||||
assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
@ -2606,10 +2611,15 @@ void MangleContext::mangleCXXRTTI(QualType Ty,
|
||||
Mangler.mangleType(Ty);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCXXRTTIName(QualType Ty,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
void ItaniumMangleContext::mangleCXXRTTIName(QualType Ty,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
Mangler.getStream() << "_ZTS";
|
||||
Mangler.mangleType(Ty);
|
||||
}
|
||||
|
||||
MangleContext *clang::createItaniumMangleContext(ASTContext &Context,
|
||||
Diagnostic &Diags) {
|
||||
return new ItaniumMangleContext(Context, Diags);
|
||||
}
|
132
clang/lib/AST/Mangle.cpp
Normal file
132
clang/lib/AST/Mangle.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements generic name mangling support for blocks and Objective-C.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
#define MANGLE_CHECKER 0
|
||||
|
||||
#if MANGLE_CHECKER
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
using namespace clang;
|
||||
|
||||
// FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
|
||||
// much to be desired. Come up with a better mangling scheme.
|
||||
|
||||
namespace {
|
||||
|
||||
static void mangleFunctionBlock(MangleContext &Context,
|
||||
llvm::StringRef Outer,
|
||||
const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
llvm::raw_svector_ostream Out(Res);
|
||||
Out << "__" << Outer << "_block_invoke_" << Context.getBlockId(BD, true);
|
||||
}
|
||||
|
||||
static void checkMangleDC(const DeclContext *DC, const BlockDecl *BD) {
|
||||
#ifndef NDEBUG
|
||||
const DeclContext *ExpectedDC = BD->getDeclContext();
|
||||
while (isa<BlockDecl>(ExpectedDC) || isa<EnumDecl>(ExpectedDC))
|
||||
ExpectedDC = ExpectedDC->getParent();
|
||||
assert(DC == ExpectedDC && "Given decl context did not match expected!");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MangleContext::mangleGlobalBlock(const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
llvm::raw_svector_ostream Out(Res);
|
||||
Out << "__block_global_" << getBlockId(BD, false);
|
||||
}
|
||||
|
||||
void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
|
||||
CXXCtorType CT, const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
checkMangleDC(CD, BD);
|
||||
llvm::SmallString<64> Buffer;
|
||||
mangleCXXCtor(CD, CT, Buffer);
|
||||
mangleFunctionBlock(*this, Buffer, BD, Res);
|
||||
}
|
||||
|
||||
void MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
|
||||
CXXDtorType DT, const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
checkMangleDC(DD, BD);
|
||||
llvm::SmallString<64> Buffer;
|
||||
mangleCXXDtor(DD, DT, Buffer);
|
||||
mangleFunctionBlock(*this, Buffer, BD, Res);
|
||||
}
|
||||
|
||||
void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
|
||||
checkMangleDC(DC, BD);
|
||||
|
||||
llvm::SmallString<64> Buffer;
|
||||
if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
|
||||
mangleObjCMethodName(Method, Buffer);
|
||||
} else {
|
||||
const NamedDecl *ND = cast<NamedDecl>(DC);
|
||||
if (IdentifierInfo *II = ND->getIdentifier())
|
||||
Buffer = II->getName();
|
||||
else {
|
||||
// FIXME: We were doing a mangleUnqualifiedName() before, but that's
|
||||
// a private member of a class that will soon itself be private to the
|
||||
// Itanium C++ ABI object. What should we do now? Right now, I'm just
|
||||
// calling the mangleName() method on the MangleContext; is there a
|
||||
// better way?
|
||||
mangleName(ND, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
mangleFunctionBlock(*this, Buffer, BD, Res);
|
||||
}
|
||||
|
||||
void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
llvm::SmallString<64> Name;
|
||||
llvm::raw_svector_ostream OS(Name), Out(Res);
|
||||
|
||||
const ObjCContainerDecl *CD =
|
||||
dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
|
||||
assert (CD && "Missing container decl in GetNameForMethod");
|
||||
OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
|
||||
if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
|
||||
OS << '(' << CID << ')';
|
||||
OS << ' ' << MD->getSelector().getAsString() << ']';
|
||||
|
||||
Out << OS.str().size() << OS.str();
|
||||
}
|
||||
|
||||
void MangleContext::mangleBlock(const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
const DeclContext *DC = BD->getDeclContext();
|
||||
while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
if (DC->isFunctionOrMethod())
|
||||
mangleBlock(DC, BD, Res);
|
||||
else
|
||||
mangleGlobalBlock(BD, Res);
|
||||
}
|
1184
clang/lib/AST/MicrosoftMangle.cpp
Normal file
1184
clang/lib/AST/MicrosoftMangle.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -799,7 +799,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const BlockExpr *BExpr,
|
||||
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
|
||||
|
||||
MangleBuffer Name;
|
||||
CGM.getMangledName(GD, Name, BD);
|
||||
CGM.getBlockMangledName(GD, Name, BD);
|
||||
llvm::Function *Fn =
|
||||
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
||||
Name.getString(), &CGM.getModule());
|
||||
|
@ -16,12 +16,12 @@
|
||||
#include "CGCXXABI.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "Mangle.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/Frontend/CodeGenOptions.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
|
@ -1,36 +0,0 @@
|
||||
//===----- CGCXX.h - C++ related code CodeGen declarations ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// These classes wrap the information about a call or function
|
||||
// definition used to handle ABI compliancy.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_CODEGEN_CGCXX_H
|
||||
#define CLANG_CODEGEN_CGCXX_H
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// CXXCtorType - C++ constructor types
|
||||
enum CXXCtorType {
|
||||
Ctor_Complete, // Complete object ctor
|
||||
Ctor_Base, // Base object ctor
|
||||
Ctor_CompleteAllocating // Complete object allocating ctor
|
||||
};
|
||||
|
||||
/// CXXDtorType - C++ destructor types
|
||||
enum CXXDtorType {
|
||||
Dtor_Deleting, // Deleting dtor
|
||||
Dtor_Complete, // Complete object dtor
|
||||
Dtor_Base // Base object dtor
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // CLANG_CODEGEN_CGCXX_H
|
@ -32,18 +32,20 @@ namespace clang {
|
||||
class CXXMethodDecl;
|
||||
class CXXRecordDecl;
|
||||
class FieldDecl;
|
||||
class MangleContext;
|
||||
|
||||
namespace CodeGen {
|
||||
class CodeGenFunction;
|
||||
class CodeGenModule;
|
||||
class MangleContext;
|
||||
|
||||
/// Implements C++ ABI-specific code generation functions.
|
||||
class CGCXXABI {
|
||||
protected:
|
||||
CodeGenModule &CGM;
|
||||
llvm::OwningPtr<MangleContext> MangleCtx;
|
||||
|
||||
CGCXXABI(CodeGenModule &CGM) : CGM(CGM) {}
|
||||
CGCXXABI(CodeGenModule &CGM)
|
||||
: CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {}
|
||||
|
||||
protected:
|
||||
ImplicitParamDecl *&getThisDecl(CodeGenFunction &CGF) {
|
||||
@ -74,7 +76,9 @@ public:
|
||||
virtual ~CGCXXABI();
|
||||
|
||||
/// Gets the mangle context.
|
||||
virtual MangleContext &getMangleContext() = 0;
|
||||
MangleContext &getMangleContext() {
|
||||
return *MangleCtx;
|
||||
}
|
||||
|
||||
/// Find the LLVM type used to represent the given member pointer
|
||||
/// type.
|
||||
|
@ -148,7 +148,7 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
|
||||
const DeclContext *DC = ND->getDeclContext();
|
||||
if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
|
||||
MangleBuffer Name;
|
||||
CGM.getMangledName(GlobalDecl(), Name, BD);
|
||||
CGM.getBlockMangledName(GlobalDecl(), Name, BD);
|
||||
ContextName = Name.getString();
|
||||
}
|
||||
else
|
||||
|
@ -137,6 +137,8 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
|
||||
E = OMD->param_end(); PI != E; ++PI)
|
||||
Args.push_back(std::make_pair(*PI, (*PI)->getType()));
|
||||
|
||||
CurGD = OMD;
|
||||
|
||||
StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart());
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "GlobalDecl.h"
|
||||
|
||||
namespace clang {
|
||||
@ -24,94 +25,6 @@ namespace clang {
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
|
||||
/// ReturnAdjustment - A return adjustment.
|
||||
struct ReturnAdjustment {
|
||||
/// NonVirtual - The non-virtual adjustment from the derived object to its
|
||||
/// nearest virtual base.
|
||||
int64_t NonVirtual;
|
||||
|
||||
/// VBaseOffsetOffset - The offset (in bytes), relative to the address point
|
||||
/// of the virtual base class offset.
|
||||
int64_t VBaseOffsetOffset;
|
||||
|
||||
ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { }
|
||||
|
||||
bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; }
|
||||
|
||||
friend bool operator==(const ReturnAdjustment &LHS,
|
||||
const ReturnAdjustment &RHS) {
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset;
|
||||
}
|
||||
|
||||
friend bool operator<(const ReturnAdjustment &LHS,
|
||||
const ReturnAdjustment &RHS) {
|
||||
if (LHS.NonVirtual < RHS.NonVirtual)
|
||||
return true;
|
||||
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset;
|
||||
}
|
||||
};
|
||||
|
||||
/// ThisAdjustment - A 'this' pointer adjustment.
|
||||
struct ThisAdjustment {
|
||||
/// NonVirtual - The non-virtual adjustment from the derived object to its
|
||||
/// nearest virtual base.
|
||||
int64_t NonVirtual;
|
||||
|
||||
/// VCallOffsetOffset - The offset (in bytes), relative to the address point,
|
||||
/// of the virtual call offset.
|
||||
int64_t VCallOffsetOffset;
|
||||
|
||||
ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { }
|
||||
|
||||
bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; }
|
||||
|
||||
friend bool operator==(const ThisAdjustment &LHS,
|
||||
const ThisAdjustment &RHS) {
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VCallOffsetOffset == RHS.VCallOffsetOffset;
|
||||
}
|
||||
|
||||
friend bool operator<(const ThisAdjustment &LHS,
|
||||
const ThisAdjustment &RHS) {
|
||||
if (LHS.NonVirtual < RHS.NonVirtual)
|
||||
return true;
|
||||
|
||||
return LHS.NonVirtual == RHS.NonVirtual &&
|
||||
LHS.VCallOffsetOffset < RHS.VCallOffsetOffset;
|
||||
}
|
||||
};
|
||||
|
||||
/// ThunkInfo - The 'this' pointer adjustment as well as an optional return
|
||||
/// adjustment for a thunk.
|
||||
struct ThunkInfo {
|
||||
/// This - The 'this' pointer adjustment.
|
||||
ThisAdjustment This;
|
||||
|
||||
/// Return - The return adjustment.
|
||||
ReturnAdjustment Return;
|
||||
|
||||
ThunkInfo() { }
|
||||
|
||||
ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
|
||||
: This(This), Return(Return) { }
|
||||
|
||||
friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
|
||||
return LHS.This == RHS.This && LHS.Return == RHS.Return;
|
||||
}
|
||||
|
||||
friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
|
||||
if (LHS.This < RHS.This)
|
||||
return true;
|
||||
|
||||
return LHS.This == RHS.This && LHS.Return < RHS.Return;
|
||||
}
|
||||
|
||||
bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); }
|
||||
};
|
||||
|
||||
// BaseSubobject - Uniquely identifies a direct or indirect base class.
|
||||
// Stores both the base class decl and the offset from the most derived class to
|
||||
// the base class.
|
||||
|
@ -35,7 +35,6 @@ add_clang_library(clangCodeGen
|
||||
CodeGenTBAA.cpp
|
||||
CodeGenTypes.cpp
|
||||
ItaniumCXXABI.cpp
|
||||
Mangle.cpp
|
||||
MicrosoftCXXABI.cpp
|
||||
ModuleBuilder.cpp
|
||||
TargetInfo.cpp
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@ -26,7 +27,6 @@
|
||||
#include "CGBlocks.h"
|
||||
#include "CGBuilder.h"
|
||||
#include "CGCall.h"
|
||||
#include "CGCXX.h"
|
||||
#include "CGValue.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "CGCall.h"
|
||||
#include "CGCXXABI.h"
|
||||
#include "CGObjCRuntime.h"
|
||||
#include "Mangle.h"
|
||||
#include "TargetInfo.h"
|
||||
#include "clang/Frontend/CodeGenOptions.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
@ -26,6 +25,7 @@
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
@ -275,7 +275,7 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
|
||||
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
|
||||
getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer);
|
||||
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
|
||||
getCXXABI().getMangleContext().mangleBlock(GD, BD, Buffer);
|
||||
getCXXABI().getMangleContext().mangleBlock(BD, Buffer);
|
||||
else
|
||||
getCXXABI().getMangleContext().mangleName(ND, Buffer);
|
||||
|
||||
@ -289,9 +289,18 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
|
||||
return Str;
|
||||
}
|
||||
|
||||
void CodeGenModule::getMangledName(GlobalDecl GD, MangleBuffer &Buffer,
|
||||
const BlockDecl *BD) {
|
||||
getCXXABI().getMangleContext().mangleBlock(GD, BD, Buffer.getBuffer());
|
||||
void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
|
||||
const BlockDecl *BD) {
|
||||
MangleContext &MangleCtx = getCXXABI().getMangleContext();
|
||||
const Decl *D = GD.getDecl();
|
||||
if (D == 0)
|
||||
MangleCtx.mangleGlobalBlock(BD, Buffer.getBuffer());
|
||||
else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
|
||||
MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Buffer.getBuffer());
|
||||
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
|
||||
MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Buffer.getBuffer());
|
||||
else
|
||||
MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Buffer.getBuffer());
|
||||
}
|
||||
|
||||
llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
|
||||
@ -1304,7 +1313,6 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
|
||||
void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
|
||||
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
|
||||
const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD);
|
||||
getCXXABI().getMangleContext().mangleInitDiscriminator();
|
||||
// Get or create the prototype for the function.
|
||||
llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
|
||||
|
||||
|
@ -14,17 +14,17 @@
|
||||
#ifndef CLANG_CODEGEN_CODEGENMODULE_H
|
||||
#define CLANG_CODEGEN_CODEGENMODULE_H
|
||||
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "CGBlocks.h"
|
||||
#include "CGCall.h"
|
||||
#include "CGCXX.h"
|
||||
#include "CGVTables.h"
|
||||
#include "CodeGenTypes.h"
|
||||
#include "GlobalDecl.h"
|
||||
#include "Mangle.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
@ -66,6 +66,7 @@ namespace clang {
|
||||
class Diagnostic;
|
||||
class AnnotateAttr;
|
||||
class CXXDestructorDecl;
|
||||
class MangleBuffer;
|
||||
|
||||
namespace CodeGen {
|
||||
|
||||
@ -74,7 +75,6 @@ namespace CodeGen {
|
||||
class CGCXXABI;
|
||||
class CGDebugInfo;
|
||||
class CGObjCRuntime;
|
||||
class MangleBuffer;
|
||||
|
||||
struct OrderGlobalInits {
|
||||
unsigned int priority;
|
||||
@ -480,7 +480,8 @@ public:
|
||||
unsigned &CallingConv);
|
||||
|
||||
llvm::StringRef getMangledName(GlobalDecl GD);
|
||||
void getMangledName(GlobalDecl GD, MangleBuffer &Buffer, const BlockDecl *BD);
|
||||
void getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
|
||||
const BlockDecl *BD);
|
||||
|
||||
void EmitTentativeDefinition(const VarDecl *D);
|
||||
|
||||
|
@ -16,8 +16,8 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CodeGenTBAA.h"
|
||||
#include "Mangle.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Metadata.h"
|
||||
#include "llvm/Constants.h"
|
||||
|
@ -26,11 +26,11 @@ namespace llvm {
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class LangOptions;
|
||||
class MangleContext;
|
||||
class QualType;
|
||||
class Type;
|
||||
|
||||
namespace CodeGen {
|
||||
class MangleContext;
|
||||
class CGRecordLayout;
|
||||
|
||||
/// CodeGenTBAA - This class organizes the cross-module state that is used
|
||||
|
@ -15,9 +15,9 @@
|
||||
#ifndef CLANG_CODEGEN_GLOBALDECL_H
|
||||
#define CLANG_CODEGEN_GLOBALDECL_H
|
||||
|
||||
#include "CGCXX.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "CGRecordLayout.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "Mangle.h"
|
||||
#include <clang/AST/Mangle.h>
|
||||
#include <clang/AST/Type.h>
|
||||
#include <llvm/Target/TargetData.h>
|
||||
#include <llvm/Value.h>
|
||||
@ -35,7 +35,6 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
|
||||
private:
|
||||
const llvm::IntegerType *PtrDiffTy;
|
||||
protected:
|
||||
CodeGen::MangleContext MangleCtx;
|
||||
bool IsARM;
|
||||
|
||||
// It's a little silly for us to cache this.
|
||||
@ -52,12 +51,7 @@ protected:
|
||||
|
||||
public:
|
||||
ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
|
||||
CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(getContext(), CGM.getDiags()),
|
||||
IsARM(IsARM) { }
|
||||
|
||||
CodeGen::MangleContext &getMangleContext() {
|
||||
return MangleCtx;
|
||||
}
|
||||
CGCXXABI(CGM), PtrDiffTy(0), IsARM(IsARM) { }
|
||||
|
||||
bool isZeroInitializable(const MemberPointerType *MPT);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user