mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 00:36:05 +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 CXXRecordDecl;
|
||||||
class Decl;
|
class Decl;
|
||||||
class FieldDecl;
|
class FieldDecl;
|
||||||
|
class MangleContext;
|
||||||
class ObjCIvarDecl;
|
class ObjCIvarDecl;
|
||||||
class ObjCIvarRefExpr;
|
class ObjCIvarRefExpr;
|
||||||
class ObjCPropertyDecl;
|
class ObjCPropertyDecl;
|
||||||
@ -1058,6 +1059,8 @@ public:
|
|||||||
|
|
||||||
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
|
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
|
||||||
|
|
||||||
|
MangleContext *createMangleContext();
|
||||||
|
|
||||||
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
|
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
|
||||||
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars)
|
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars)
|
||||||
const;
|
const;
|
||||||
|
@ -7,20 +7,15 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// Implements C++ name mangling according to the Itanium C++ ABI,
|
// Defines the C++ name mangling interface.
|
||||||
// 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
|
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_CLANG_CODEGEN_MANGLE_H
|
#ifndef LLVM_CLANG_AST_MANGLE_H
|
||||||
#define LLVM_CLANG_CODEGEN_MANGLE_H
|
#define LLVM_CLANG_AST_MANGLE_H
|
||||||
|
|
||||||
#include "CGCXX.h"
|
|
||||||
#include "GlobalDecl.h"
|
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
|
#include "clang/Basic/ABI.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
@ -36,8 +31,6 @@ namespace clang {
|
|||||||
class NamedDecl;
|
class NamedDecl;
|
||||||
class ObjCMethodDecl;
|
class ObjCMethodDecl;
|
||||||
class VarDecl;
|
class VarDecl;
|
||||||
|
|
||||||
namespace CodeGen {
|
|
||||||
struct ThisAdjustment;
|
struct ThisAdjustment;
|
||||||
struct ThunkInfo;
|
struct ThunkInfo;
|
||||||
|
|
||||||
@ -74,9 +67,6 @@ class MangleContext {
|
|||||||
ASTContext &Context;
|
ASTContext &Context;
|
||||||
Diagnostic &Diags;
|
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> GlobalBlockIds;
|
||||||
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
|
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
|
||||||
|
|
||||||
@ -91,15 +81,8 @@ public:
|
|||||||
|
|
||||||
Diagnostic &getDiags() const { return Diags; }
|
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) {
|
unsigned getBlockId(const BlockDecl *BD, bool Local) {
|
||||||
llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
|
llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
|
||||||
= Local? LocalBlockIds : GlobalBlockIds;
|
= Local? LocalBlockIds : GlobalBlockIds;
|
||||||
@ -111,69 +94,57 @@ public:
|
|||||||
/// @name Mangler Entry Points
|
/// @name Mangler Entry Points
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
virtual bool shouldMangleDeclName(const NamedDecl *D);
|
virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
|
||||||
virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
|
virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &)=0;
|
||||||
virtual void mangleThunk(const CXXMethodDecl *MD,
|
virtual void mangleThunk(const CXXMethodDecl *MD,
|
||||||
const ThunkInfo &Thunk,
|
const ThunkInfo &Thunk,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
||||||
const ThisAdjustment &ThisAdjustment,
|
const ThisAdjustment &ThisAdjustment,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleReferenceTemporary(const VarDecl *D,
|
virtual void mangleReferenceTemporary(const VarDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXVTable(const CXXRecordDecl *RD,
|
virtual void mangleCXXVTable(const CXXRecordDecl *RD,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXVTT(const CXXRecordDecl *RD,
|
virtual void mangleCXXVTT(const CXXRecordDecl *RD,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
||||||
const CXXRecordDecl *Type,
|
const CXXRecordDecl *Type,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
|
virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
|
virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) = 0;
|
||||||
void mangleBlock(GlobalDecl GD,
|
|
||||||
const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
|
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.
|
// This is pretty lame.
|
||||||
void mangleItaniumGuardVariable(const VarDecl *D,
|
virtual void mangleItaniumGuardVariable(const VarDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &);
|
llvm::SmallVectorImpl<char> &) {
|
||||||
|
assert(0 && "Target does not support mangling guard variables");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// MiscNameMangler - Mangles Objective-C method names and blocks.
|
MangleContext *createItaniumMangleContext(ASTContext &Context,
|
||||||
class MiscNameMangler {
|
Diagnostic &Diags);
|
||||||
MangleContext &Context;
|
MangleContext *createMicrosoftMangleContext(ASTContext &Context,
|
||||||
llvm::raw_svector_ostream Out;
|
Diagnostic &Diags);
|
||||||
|
|
||||||
ASTContext &getASTContext() const { return Context.getASTContext(); }
|
|
||||||
|
|
||||||
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
|
#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/ExternalASTSource.h"
|
||||||
#include "clang/AST/ASTMutationListener.h"
|
#include "clang/AST/ASTMutationListener.h"
|
||||||
#include "clang/AST/RecordLayout.h"
|
#include "clang/AST/RecordLayout.h"
|
||||||
|
#include "clang/AST/Mangle.h"
|
||||||
#include "clang/Basic/Builtins.h"
|
#include "clang/Basic/Builtins.h"
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
@ -5835,4 +5836,16 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {
|
|||||||
return ABI->isNearlyEmpty(RD);
|
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() {}
|
CXXABI::~CXXABI() {}
|
||||||
|
@ -26,7 +26,10 @@ add_clang_library(clangAST
|
|||||||
ExprCXX.cpp
|
ExprCXX.cpp
|
||||||
InheritViz.cpp
|
InheritViz.cpp
|
||||||
ItaniumCXXABI.cpp
|
ItaniumCXXABI.cpp
|
||||||
|
ItaniumMangle.cpp
|
||||||
|
Mangle.cpp
|
||||||
MicrosoftCXXABI.cpp
|
MicrosoftCXXABI.cpp
|
||||||
|
MicrosoftMangle.cpp
|
||||||
NestedNameSpecifier.cpp
|
NestedNameSpecifier.cpp
|
||||||
ParentMap.cpp
|
ParentMap.cpp
|
||||||
RecordLayout.cpp
|
RecordLayout.cpp
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
|
//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@ -14,18 +14,18 @@
|
|||||||
// http://www.codesourcery.com/public/cxx-abi/abi.html
|
// 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/ASTContext.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
#include "clang/AST/DeclTemplate.h"
|
#include "clang/AST/DeclTemplate.h"
|
||||||
#include "clang/AST/ExprCXX.h"
|
#include "clang/AST/ExprCXX.h"
|
||||||
|
#include "clang/Basic/ABI.h"
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "CGVTables.h"
|
|
||||||
|
|
||||||
#define MANGLE_CHECKER 0
|
#define MANGLE_CHECKER 0
|
||||||
|
|
||||||
@ -34,68 +34,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace clang;
|
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 {
|
namespace {
|
||||||
|
|
||||||
@ -127,9 +65,77 @@ static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
|
|||||||
|
|
||||||
static const unsigned UnknownArity = ~0U;
|
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.
|
/// CXXNameMangler - Manage the mangling of a single name.
|
||||||
class CXXNameMangler {
|
class CXXNameMangler {
|
||||||
MangleContext &Context;
|
ItaniumMangleContext &Context;
|
||||||
llvm::raw_svector_ostream Out;
|
llvm::raw_svector_ostream Out;
|
||||||
|
|
||||||
const CXXMethodDecl *Structor;
|
const CXXMethodDecl *Structor;
|
||||||
@ -143,13 +149,13 @@ class CXXNameMangler {
|
|||||||
ASTContext &getASTContext() const { return Context.getASTContext(); }
|
ASTContext &getASTContext() const { return Context.getASTContext(); }
|
||||||
|
|
||||||
public:
|
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) { }
|
: 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)
|
const CXXConstructorDecl *D, CXXCtorType Type)
|
||||||
: Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
|
: Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
|
||||||
SeqID(0) { }
|
SeqID(0) { }
|
||||||
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
|
CXXNameMangler(ItaniumMangleContext &C, llvm::SmallVectorImpl<char> &Res,
|
||||||
const CXXDestructorDecl *D, CXXDtorType Type)
|
const CXXDestructorDecl *D, CXXDtorType Type)
|
||||||
: Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
|
: Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
|
||||||
SeqID(0) { }
|
SeqID(0) { }
|
||||||
@ -259,6 +265,7 @@ private:
|
|||||||
|
|
||||||
void mangleTemplateParameter(unsigned Index);
|
void mangleTemplateParameter(unsigned Index);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isInCLinkageSpecification(const Decl *D) {
|
static bool isInCLinkageSpecification(const Decl *D) {
|
||||||
@ -272,7 +279,7 @@ static bool isInCLinkageSpecification(const Decl *D) {
|
|||||||
return false;
|
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.
|
// In C, functions with no attributes never need to be mangled. Fastpath them.
|
||||||
if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
|
if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
|
||||||
return false;
|
return false;
|
||||||
@ -896,7 +903,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
|
|||||||
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
|
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
|
||||||
manglePrefix(DC->getParent(), NoFunction);
|
manglePrefix(DC->getParent(), NoFunction);
|
||||||
llvm::SmallString<64> Name;
|
llvm::SmallString<64> Name;
|
||||||
Context.mangleBlock(GlobalDecl(), Block, Name);
|
Context.mangleBlock(Block, Name);
|
||||||
Out << Name.size() << Name;
|
Out << Name.size() << Name;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1150,7 +1157,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
|
|||||||
|
|
||||||
void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
|
void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
|
||||||
llvm::SmallString<64> Buffer;
|
llvm::SmallString<64> Buffer;
|
||||||
MiscNameMangler(Context, Buffer).mangleObjCMethodName(MD);
|
Context.mangleObjCMethodName(MD, Buffer);
|
||||||
Out << 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
|
/// and this routine will return false. In this case, the caller should just
|
||||||
/// emit the identifier of the declaration (\c D->getIdentifier()) as its
|
/// emit the identifier of the declaration (\c D->getIdentifier()) as its
|
||||||
/// name.
|
/// name.
|
||||||
void MangleContext::mangleName(const NamedDecl *D,
|
void ItaniumMangleContext::mangleName(const NamedDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
|
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
|
||||||
"Invalid mangleName() call, argument is not a variable or function!");
|
"Invalid mangleName() call, argument is not a variable or function!");
|
||||||
assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
|
assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
|
||||||
@ -2485,27 +2492,23 @@ void MangleContext::mangleName(const NamedDecl *D,
|
|||||||
return Mangler.mangle(D);
|
return Mangler.mangle(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
|
void ItaniumMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
CXXCtorType Type,
|
||||||
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
CXXNameMangler Mangler(*this, Res, D, Type);
|
CXXNameMangler Mangler(*this, Res, D, Type);
|
||||||
Mangler.mangle(D);
|
Mangler.mangle(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
void ItaniumMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
CXXDtorType Type,
|
||||||
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
CXXNameMangler Mangler(*this, Res, D, Type);
|
CXXNameMangler Mangler(*this, Res, D, Type);
|
||||||
Mangler.mangle(D);
|
Mangler.mangle(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleBlock(GlobalDecl GD, const BlockDecl *BD,
|
void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
const ThunkInfo &Thunk,
|
||||||
MiscNameMangler Mangler(*this, Res);
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
Mangler.mangleBlock(GD, BD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MangleContext::mangleThunk(const CXXMethodDecl *MD,
|
|
||||||
const ThunkInfo &Thunk,
|
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
|
||||||
// <special-name> ::= T <call-offset> <base encoding>
|
// <special-name> ::= T <call-offset> <base encoding>
|
||||||
// # base is the nominal target function of thunk
|
// # base is the nominal target function of thunk
|
||||||
// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
|
// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
|
||||||
@ -2533,9 +2536,10 @@ void MangleContext::mangleThunk(const CXXMethodDecl *MD,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
|
ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
|
||||||
const ThisAdjustment &ThisAdjustment,
|
CXXDtorType Type,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
const ThisAdjustment &ThisAdjustment,
|
||||||
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= T <call-offset> <base encoding>
|
// <special-name> ::= T <call-offset> <base encoding>
|
||||||
// # base is the nominal target function of thunk
|
// # 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
|
/// mangleGuardVariable - Returns the mangled name for a guard variable
|
||||||
/// for the passed in VarDecl.
|
/// for the passed in VarDecl.
|
||||||
void MangleContext::mangleItaniumGuardVariable(const VarDecl *D,
|
void ItaniumMangleContext::mangleItaniumGuardVariable(const VarDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= GV <object name> # Guard variable for one-time
|
// <special-name> ::= GV <object name> # Guard variable for one-time
|
||||||
// # initialization
|
// # initialization
|
||||||
CXXNameMangler Mangler(*this, Res);
|
CXXNameMangler Mangler(*this, Res);
|
||||||
@ -2560,7 +2564,7 @@ void MangleContext::mangleItaniumGuardVariable(const VarDecl *D,
|
|||||||
Mangler.mangleName(D);
|
Mangler.mangleName(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleReferenceTemporary(const VarDecl *D,
|
void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// We match the GCC mangling here.
|
// We match the GCC mangling here.
|
||||||
// <special-name> ::= GR <object name>
|
// <special-name> ::= GR <object name>
|
||||||
@ -2569,25 +2573,26 @@ void MangleContext::mangleReferenceTemporary(const VarDecl *D,
|
|||||||
Mangler.mangleName(D);
|
Mangler.mangleName(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
|
void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= TV <type> # virtual table
|
// <special-name> ::= TV <type> # virtual table
|
||||||
CXXNameMangler Mangler(*this, Res);
|
CXXNameMangler Mangler(*this, Res);
|
||||||
Mangler.getStream() << "_ZTV";
|
Mangler.getStream() << "_ZTV";
|
||||||
Mangler.mangleNameOrStandardSubstitution(RD);
|
Mangler.mangleNameOrStandardSubstitution(RD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
|
void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= TT <type> # VTT structure
|
// <special-name> ::= TT <type> # VTT structure
|
||||||
CXXNameMangler Mangler(*this, Res);
|
CXXNameMangler Mangler(*this, Res);
|
||||||
Mangler.getStream() << "_ZTT";
|
Mangler.getStream() << "_ZTT";
|
||||||
Mangler.mangleNameOrStandardSubstitution(RD);
|
Mangler.mangleNameOrStandardSubstitution(RD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
|
||||||
const CXXRecordDecl *Type,
|
int64_t Offset,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
const CXXRecordDecl *Type,
|
||||||
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= TC <type> <offset number> _ <base type>
|
// <special-name> ::= TC <type> <offset number> _ <base type>
|
||||||
CXXNameMangler Mangler(*this, Res);
|
CXXNameMangler Mangler(*this, Res);
|
||||||
Mangler.getStream() << "_ZTC";
|
Mangler.getStream() << "_ZTC";
|
||||||
@ -2597,8 +2602,8 @@ void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
|
|||||||
Mangler.mangleNameOrStandardSubstitution(Type);
|
Mangler.mangleNameOrStandardSubstitution(Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXRTTI(QualType Ty,
|
void ItaniumMangleContext::mangleCXXRTTI(QualType Ty,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= TI <type> # typeinfo structure
|
// <special-name> ::= TI <type> # typeinfo structure
|
||||||
assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");
|
assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");
|
||||||
CXXNameMangler Mangler(*this, Res);
|
CXXNameMangler Mangler(*this, Res);
|
||||||
@ -2606,10 +2611,15 @@ void MangleContext::mangleCXXRTTI(QualType Ty,
|
|||||||
Mangler.mangleType(Ty);
|
Mangler.mangleType(Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleContext::mangleCXXRTTIName(QualType Ty,
|
void ItaniumMangleContext::mangleCXXRTTIName(QualType Ty,
|
||||||
llvm::SmallVectorImpl<char> &Res) {
|
llvm::SmallVectorImpl<char> &Res) {
|
||||||
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
|
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
|
||||||
CXXNameMangler Mangler(*this, Res);
|
CXXNameMangler Mangler(*this, Res);
|
||||||
Mangler.getStream() << "_ZTS";
|
Mangler.getStream() << "_ZTS";
|
||||||
Mangler.mangleType(Ty);
|
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);
|
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
|
||||||
|
|
||||||
MangleBuffer Name;
|
MangleBuffer Name;
|
||||||
CGM.getMangledName(GD, Name, BD);
|
CGM.getBlockMangledName(GD, Name, BD);
|
||||||
llvm::Function *Fn =
|
llvm::Function *Fn =
|
||||||
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
||||||
Name.getString(), &CGM.getModule());
|
Name.getString(), &CGM.getModule());
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
#include "CGCXXABI.h"
|
#include "CGCXXABI.h"
|
||||||
#include "CodeGenFunction.h"
|
#include "CodeGenFunction.h"
|
||||||
#include "CodeGenModule.h"
|
#include "CodeGenModule.h"
|
||||||
#include "Mangle.h"
|
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/AST/RecordLayout.h"
|
#include "clang/AST/RecordLayout.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
|
#include "clang/AST/Mangle.h"
|
||||||
#include "clang/AST/StmtCXX.h"
|
#include "clang/AST/StmtCXX.h"
|
||||||
#include "clang/Frontend/CodeGenOptions.h"
|
#include "clang/Frontend/CodeGenOptions.h"
|
||||||
#include "llvm/ADT/StringExtras.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 CXXMethodDecl;
|
||||||
class CXXRecordDecl;
|
class CXXRecordDecl;
|
||||||
class FieldDecl;
|
class FieldDecl;
|
||||||
|
class MangleContext;
|
||||||
|
|
||||||
namespace CodeGen {
|
namespace CodeGen {
|
||||||
class CodeGenFunction;
|
class CodeGenFunction;
|
||||||
class CodeGenModule;
|
class CodeGenModule;
|
||||||
class MangleContext;
|
|
||||||
|
|
||||||
/// Implements C++ ABI-specific code generation functions.
|
/// Implements C++ ABI-specific code generation functions.
|
||||||
class CGCXXABI {
|
class CGCXXABI {
|
||||||
protected:
|
protected:
|
||||||
CodeGenModule &CGM;
|
CodeGenModule &CGM;
|
||||||
|
llvm::OwningPtr<MangleContext> MangleCtx;
|
||||||
|
|
||||||
CGCXXABI(CodeGenModule &CGM) : CGM(CGM) {}
|
CGCXXABI(CodeGenModule &CGM)
|
||||||
|
: CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ImplicitParamDecl *&getThisDecl(CodeGenFunction &CGF) {
|
ImplicitParamDecl *&getThisDecl(CodeGenFunction &CGF) {
|
||||||
@ -74,7 +76,9 @@ public:
|
|||||||
virtual ~CGCXXABI();
|
virtual ~CGCXXABI();
|
||||||
|
|
||||||
/// Gets the mangle context.
|
/// Gets the mangle context.
|
||||||
virtual MangleContext &getMangleContext() = 0;
|
MangleContext &getMangleContext() {
|
||||||
|
return *MangleCtx;
|
||||||
|
}
|
||||||
|
|
||||||
/// Find the LLVM type used to represent the given member pointer
|
/// Find the LLVM type used to represent the given member pointer
|
||||||
/// type.
|
/// type.
|
||||||
|
@ -148,7 +148,7 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
|
|||||||
const DeclContext *DC = ND->getDeclContext();
|
const DeclContext *DC = ND->getDeclContext();
|
||||||
if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
|
if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
|
||||||
MangleBuffer Name;
|
MangleBuffer Name;
|
||||||
CGM.getMangledName(GlobalDecl(), Name, BD);
|
CGM.getBlockMangledName(GlobalDecl(), Name, BD);
|
||||||
ContextName = Name.getString();
|
ContextName = Name.getString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -137,6 +137,8 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
|
|||||||
E = OMD->param_end(); PI != E; ++PI)
|
E = OMD->param_end(); PI != E; ++PI)
|
||||||
Args.push_back(std::make_pair(*PI, (*PI)->getType()));
|
Args.push_back(std::make_pair(*PI, (*PI)->getType()));
|
||||||
|
|
||||||
|
CurGD = OMD;
|
||||||
|
|
||||||
StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart());
|
StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
|
#include "clang/Basic/ABI.h"
|
||||||
#include "GlobalDecl.h"
|
#include "GlobalDecl.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
@ -24,94 +25,6 @@ namespace clang {
|
|||||||
namespace CodeGen {
|
namespace CodeGen {
|
||||||
class CodeGenModule;
|
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.
|
// BaseSubobject - Uniquely identifies a direct or indirect base class.
|
||||||
// Stores both the base class decl and the offset from the most derived class to
|
// Stores both the base class decl and the offset from the most derived class to
|
||||||
// the base class.
|
// the base class.
|
||||||
|
@ -35,7 +35,6 @@ add_clang_library(clangCodeGen
|
|||||||
CodeGenTBAA.cpp
|
CodeGenTBAA.cpp
|
||||||
CodeGenTypes.cpp
|
CodeGenTypes.cpp
|
||||||
ItaniumCXXABI.cpp
|
ItaniumCXXABI.cpp
|
||||||
Mangle.cpp
|
|
||||||
MicrosoftCXXABI.cpp
|
MicrosoftCXXABI.cpp
|
||||||
ModuleBuilder.cpp
|
ModuleBuilder.cpp
|
||||||
TargetInfo.cpp
|
TargetInfo.cpp
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "clang/AST/ExprCXX.h"
|
#include "clang/AST/ExprCXX.h"
|
||||||
#include "clang/AST/ExprObjC.h"
|
#include "clang/AST/ExprObjC.h"
|
||||||
#include "clang/AST/CharUnits.h"
|
#include "clang/AST/CharUnits.h"
|
||||||
|
#include "clang/Basic/ABI.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
@ -26,7 +27,6 @@
|
|||||||
#include "CGBlocks.h"
|
#include "CGBlocks.h"
|
||||||
#include "CGBuilder.h"
|
#include "CGBuilder.h"
|
||||||
#include "CGCall.h"
|
#include "CGCall.h"
|
||||||
#include "CGCXX.h"
|
|
||||||
#include "CGValue.h"
|
#include "CGValue.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "CGCall.h"
|
#include "CGCall.h"
|
||||||
#include "CGCXXABI.h"
|
#include "CGCXXABI.h"
|
||||||
#include "CGObjCRuntime.h"
|
#include "CGObjCRuntime.h"
|
||||||
#include "Mangle.h"
|
|
||||||
#include "TargetInfo.h"
|
#include "TargetInfo.h"
|
||||||
#include "clang/Frontend/CodeGenOptions.h"
|
#include "clang/Frontend/CodeGenOptions.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
@ -26,6 +25,7 @@
|
|||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
#include "clang/AST/DeclTemplate.h"
|
#include "clang/AST/DeclTemplate.h"
|
||||||
|
#include "clang/AST/Mangle.h"
|
||||||
#include "clang/AST/RecordLayout.h"
|
#include "clang/AST/RecordLayout.h"
|
||||||
#include "clang/Basic/Builtins.h"
|
#include "clang/Basic/Builtins.h"
|
||||||
#include "clang/Basic/Diagnostic.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))
|
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
|
||||||
getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer);
|
getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer);
|
||||||
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
|
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
|
||||||
getCXXABI().getMangleContext().mangleBlock(GD, BD, Buffer);
|
getCXXABI().getMangleContext().mangleBlock(BD, Buffer);
|
||||||
else
|
else
|
||||||
getCXXABI().getMangleContext().mangleName(ND, Buffer);
|
getCXXABI().getMangleContext().mangleName(ND, Buffer);
|
||||||
|
|
||||||
@ -289,9 +289,18 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
|
|||||||
return Str;
|
return Str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::getMangledName(GlobalDecl GD, MangleBuffer &Buffer,
|
void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
|
||||||
const BlockDecl *BD) {
|
const BlockDecl *BD) {
|
||||||
getCXXABI().getMangleContext().mangleBlock(GD, BD, Buffer.getBuffer());
|
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) {
|
llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
|
||||||
@ -1304,7 +1313,6 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
|
|||||||
void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
|
void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
|
||||||
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
|
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
|
||||||
const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD);
|
const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD);
|
||||||
getCXXABI().getMangleContext().mangleInitDiscriminator();
|
|
||||||
// Get or create the prototype for the function.
|
// Get or create the prototype for the function.
|
||||||
llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
|
llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
|
||||||
|
|
||||||
|
@ -14,17 +14,17 @@
|
|||||||
#ifndef CLANG_CODEGEN_CODEGENMODULE_H
|
#ifndef CLANG_CODEGEN_CODEGENMODULE_H
|
||||||
#define CLANG_CODEGEN_CODEGENMODULE_H
|
#define CLANG_CODEGEN_CODEGENMODULE_H
|
||||||
|
|
||||||
|
#include "clang/Basic/ABI.h"
|
||||||
#include "clang/Basic/LangOptions.h"
|
#include "clang/Basic/LangOptions.h"
|
||||||
#include "clang/AST/Attr.h"
|
#include "clang/AST/Attr.h"
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
|
#include "clang/AST/Mangle.h"
|
||||||
#include "CGBlocks.h"
|
#include "CGBlocks.h"
|
||||||
#include "CGCall.h"
|
#include "CGCall.h"
|
||||||
#include "CGCXX.h"
|
|
||||||
#include "CGVTables.h"
|
#include "CGVTables.h"
|
||||||
#include "CodeGenTypes.h"
|
#include "CodeGenTypes.h"
|
||||||
#include "GlobalDecl.h"
|
#include "GlobalDecl.h"
|
||||||
#include "Mangle.h"
|
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
@ -66,6 +66,7 @@ namespace clang {
|
|||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
class AnnotateAttr;
|
class AnnotateAttr;
|
||||||
class CXXDestructorDecl;
|
class CXXDestructorDecl;
|
||||||
|
class MangleBuffer;
|
||||||
|
|
||||||
namespace CodeGen {
|
namespace CodeGen {
|
||||||
|
|
||||||
@ -74,7 +75,6 @@ namespace CodeGen {
|
|||||||
class CGCXXABI;
|
class CGCXXABI;
|
||||||
class CGDebugInfo;
|
class CGDebugInfo;
|
||||||
class CGObjCRuntime;
|
class CGObjCRuntime;
|
||||||
class MangleBuffer;
|
|
||||||
|
|
||||||
struct OrderGlobalInits {
|
struct OrderGlobalInits {
|
||||||
unsigned int priority;
|
unsigned int priority;
|
||||||
@ -480,7 +480,8 @@ public:
|
|||||||
unsigned &CallingConv);
|
unsigned &CallingConv);
|
||||||
|
|
||||||
llvm::StringRef getMangledName(GlobalDecl GD);
|
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);
|
void EmitTentativeDefinition(const VarDecl *D);
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "CodeGenTBAA.h"
|
#include "CodeGenTBAA.h"
|
||||||
#include "Mangle.h"
|
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
|
#include "clang/AST/Mangle.h"
|
||||||
#include "llvm/LLVMContext.h"
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Metadata.h"
|
#include "llvm/Metadata.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
|
@ -26,11 +26,11 @@ namespace llvm {
|
|||||||
namespace clang {
|
namespace clang {
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
class LangOptions;
|
class LangOptions;
|
||||||
|
class MangleContext;
|
||||||
class QualType;
|
class QualType;
|
||||||
class Type;
|
class Type;
|
||||||
|
|
||||||
namespace CodeGen {
|
namespace CodeGen {
|
||||||
class MangleContext;
|
|
||||||
class CGRecordLayout;
|
class CGRecordLayout;
|
||||||
|
|
||||||
/// CodeGenTBAA - This class organizes the cross-module state that is used
|
/// CodeGenTBAA - This class organizes the cross-module state that is used
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
#ifndef CLANG_CODEGEN_GLOBALDECL_H
|
#ifndef CLANG_CODEGEN_GLOBALDECL_H
|
||||||
#define CLANG_CODEGEN_GLOBALDECL_H
|
#define CLANG_CODEGEN_GLOBALDECL_H
|
||||||
|
|
||||||
#include "CGCXX.h"
|
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
|
#include "clang/Basic/ABI.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "CGRecordLayout.h"
|
#include "CGRecordLayout.h"
|
||||||
#include "CodeGenFunction.h"
|
#include "CodeGenFunction.h"
|
||||||
#include "CodeGenModule.h"
|
#include "CodeGenModule.h"
|
||||||
#include "Mangle.h"
|
#include <clang/AST/Mangle.h>
|
||||||
#include <clang/AST/Type.h>
|
#include <clang/AST/Type.h>
|
||||||
#include <llvm/Target/TargetData.h>
|
#include <llvm/Target/TargetData.h>
|
||||||
#include <llvm/Value.h>
|
#include <llvm/Value.h>
|
||||||
@ -35,7 +35,6 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
|
|||||||
private:
|
private:
|
||||||
const llvm::IntegerType *PtrDiffTy;
|
const llvm::IntegerType *PtrDiffTy;
|
||||||
protected:
|
protected:
|
||||||
CodeGen::MangleContext MangleCtx;
|
|
||||||
bool IsARM;
|
bool IsARM;
|
||||||
|
|
||||||
// It's a little silly for us to cache this.
|
// It's a little silly for us to cache this.
|
||||||
@ -52,12 +51,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
|
ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
|
||||||
CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(getContext(), CGM.getDiags()),
|
CGCXXABI(CGM), PtrDiffTy(0), IsARM(IsARM) { }
|
||||||
IsARM(IsARM) { }
|
|
||||||
|
|
||||||
CodeGen::MangleContext &getMangleContext() {
|
|
||||||
return MangleCtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isZeroInitializable(const MemberPointerType *MPT);
|
bool isZeroInitializable(const MemberPointerType *MPT);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user