mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 18:20:38 +00:00
Change CodeGenModule to rely on the Module's symbol table instead of
shadowing it in the GlobalDeclMap. Eliminates the string-uniquing requirement for mangled names, which should help C++ codegen times a little. Forces us to do string lookups instead of pointer lookups, which might hurt codegen times a little across the board. We'll see how it plays out. Removing the string-uniquing requirement implicitly fixes any bugs like PR6635 which arose from the fact that we had multiple uniquing tables for different kinds of identifiers. llvm-svn: 99012
This commit is contained in:
parent
3e2bb702db
commit
7ec5043c2c
@ -165,19 +165,21 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
||||
new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
|
||||
|
||||
// Switch any previous uses to the alias.
|
||||
const char *MangledName = getMangledName(AliasDecl);
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
MangleBuffer MangledName;
|
||||
getMangledName(MangledName, AliasDecl);
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
|
||||
if (Entry) {
|
||||
assert(Entry->isDeclaration() && "definition already exists for alias");
|
||||
assert(Entry->getType() == AliasType &&
|
||||
"declaration exists with different type");
|
||||
Alias->takeName(Entry);
|
||||
Entry->replaceAllUsesWith(Alias);
|
||||
Entry->eraseFromParent();
|
||||
} else {
|
||||
Alias->setName(MangledName.getString());
|
||||
}
|
||||
Entry = Alias;
|
||||
|
||||
// Finally, set up the alias with its proper name and attributes.
|
||||
Alias->setName(MangledName);
|
||||
SetCommonAttributes(AliasDecl.getDecl(), Alias);
|
||||
|
||||
return false;
|
||||
@ -214,8 +216,9 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
|
||||
llvm::GlobalValue *
|
||||
CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
|
||||
CXXCtorType Type) {
|
||||
const char *Name = getMangledCXXCtorName(D, Type);
|
||||
if (llvm::GlobalValue *V = GlobalDeclMap[Name])
|
||||
MangleBuffer Name;
|
||||
getMangledCXXCtorName(Name, D, Type);
|
||||
if (llvm::GlobalValue *V = GetGlobalValue(Name))
|
||||
return V;
|
||||
|
||||
const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>();
|
||||
@ -226,13 +229,10 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
|
||||
GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
|
||||
}
|
||||
|
||||
const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
|
||||
CXXCtorType Type) {
|
||||
llvm::SmallString<256> Name;
|
||||
getMangleContext().mangleCXXCtor(D, Type, Name);
|
||||
|
||||
Name += '\0';
|
||||
return UniqueMangledName(Name.begin(), Name.end());
|
||||
void CodeGenModule::getMangledCXXCtorName(MangleBuffer &Name,
|
||||
const CXXConstructorDecl *D,
|
||||
CXXCtorType Type) {
|
||||
getMangleContext().mangleCXXCtor(D, Type, Name.getBuffer());
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
|
||||
@ -279,8 +279,9 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
|
||||
llvm::GlobalValue *
|
||||
CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
|
||||
CXXDtorType Type) {
|
||||
const char *Name = getMangledCXXDtorName(D, Type);
|
||||
if (llvm::GlobalValue *V = GlobalDeclMap[Name])
|
||||
MangleBuffer Name;
|
||||
getMangledCXXDtorName(Name, D, Type);
|
||||
if (llvm::GlobalValue *V = GetGlobalValue(Name))
|
||||
return V;
|
||||
|
||||
const llvm::FunctionType *FTy =
|
||||
@ -290,13 +291,10 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
|
||||
GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
|
||||
}
|
||||
|
||||
const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
|
||||
CXXDtorType Type) {
|
||||
llvm::SmallString<256> Name;
|
||||
getMangleContext().mangleCXXDtor(D, Type, Name);
|
||||
|
||||
Name += '\0';
|
||||
return UniqueMangledName(Name.begin(), Name.end());
|
||||
void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name,
|
||||
const CXXDestructorDecl *D,
|
||||
CXXDtorType Type) {
|
||||
getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer());
|
||||
}
|
||||
|
||||
llvm::Constant *
|
||||
@ -470,12 +468,10 @@ CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
|
||||
OutName);
|
||||
else
|
||||
getMangleContext().mangleThunk(MD, ThisAdjustment, OutName);
|
||||
OutName += '\0';
|
||||
const char* Name = UniqueMangledName(OutName.begin(), OutName.end());
|
||||
|
||||
// Get function for mangled name
|
||||
const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD);
|
||||
return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
|
||||
return GetOrCreateLLVMFunction(OutName, Ty, GlobalDecl());
|
||||
}
|
||||
|
||||
llvm::Constant *
|
||||
@ -484,10 +480,8 @@ CodeGenModule::GetAddrOfCovariantThunk(GlobalDecl GD,
|
||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
||||
|
||||
// Compute mangled name
|
||||
llvm::SmallString<256> OutName;
|
||||
getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName);
|
||||
OutName += '\0';
|
||||
const char* Name = UniqueMangledName(OutName.begin(), OutName.end());
|
||||
llvm::SmallString<256> Name;
|
||||
getMangleContext().mangleCovariantThunk(MD, Adjustment, Name);
|
||||
|
||||
// Get function for mangled name
|
||||
const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD);
|
||||
@ -528,9 +522,6 @@ void CodeGenModule::BuildThunksForVirtual(GlobalDecl GD) {
|
||||
llvm::Constant *SubExpr =
|
||||
cast<llvm::ConstantExpr>(FnConst)->getOperand(0);
|
||||
llvm::Function *OldFn = cast<llvm::Function>(SubExpr);
|
||||
std::string Name = OldFn->getNameStr();
|
||||
GlobalDeclMap.erase(UniqueMangledName(Name.data(),
|
||||
Name.data() + Name.size() + 1));
|
||||
llvm::Constant *NewFnConst;
|
||||
if (!ReturnAdjustment.isEmpty())
|
||||
NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj);
|
||||
|
@ -569,13 +569,13 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
|
||||
isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
|
||||
|
||||
llvm::StringRef MethodName = getFunctionName(Method);
|
||||
llvm::StringRef MethodLinkageName;
|
||||
llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);
|
||||
|
||||
// Since a single ctor/dtor corresponds to multiple functions, it doesn't
|
||||
// make sense to give a single ctor/dtor a linkage name.
|
||||
MangleBuffer MethodLinkageName;
|
||||
if (!IsCtorOrDtor)
|
||||
MethodLinkageName = CGM.getMangledName(Method);
|
||||
CGM.getMangledName(MethodLinkageName, Method);
|
||||
|
||||
SourceManager &SM = CGM.getContext().getSourceManager();
|
||||
|
||||
@ -1307,7 +1307,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
|
||||
CGBuilderTy &Builder) {
|
||||
|
||||
llvm::StringRef Name;
|
||||
llvm::StringRef LinkageName;
|
||||
MangleBuffer LinkageName;
|
||||
|
||||
const Decl *D = GD.getDecl();
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
@ -1326,11 +1326,11 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
|
||||
if (!Name.empty() && Name[0] == '\01')
|
||||
Name = Name.substr(1);
|
||||
// Use mangled name as linkage name for c/c++ functions.
|
||||
LinkageName = CGM.getMangledName(GD);
|
||||
CGM.getMangledName(LinkageName, GD);
|
||||
} else {
|
||||
// Use llvm function name as linkage name.
|
||||
Name = Fn->getName();
|
||||
LinkageName = Name;
|
||||
LinkageName.setString(Name);
|
||||
if (!Name.empty() && Name[0] == '\01')
|
||||
Name = Name.substr(1);
|
||||
}
|
||||
|
@ -103,13 +103,18 @@ void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
|
||||
static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
|
||||
const char *Separator) {
|
||||
CodeGenModule &CGM = CGF.CGM;
|
||||
if (CGF.getContext().getLangOptions().CPlusPlus)
|
||||
return CGM.getMangledName(&D);
|
||||
if (CGF.getContext().getLangOptions().CPlusPlus) {
|
||||
MangleBuffer Name;
|
||||
CGM.getMangledName(Name, &D);
|
||||
return Name.getString().str();
|
||||
}
|
||||
|
||||
std::string ContextName;
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl))
|
||||
ContextName = CGM.getMangledName(FD);
|
||||
else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
|
||||
MangleBuffer Name;
|
||||
CGM.getMangledName(Name, FD);
|
||||
ContextName = Name.getString().str();
|
||||
} else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
|
||||
ContextName = CGF.CurFn->getName();
|
||||
else
|
||||
// FIXME: What about in a block??
|
||||
|
@ -163,15 +163,15 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
|
||||
}
|
||||
}
|
||||
|
||||
const char *CodeGenModule::getMangledName(const GlobalDecl &GD) {
|
||||
void CodeGenModule::getMangledName(MangleBuffer &Buffer, GlobalDecl GD) {
|
||||
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
|
||||
|
||||
if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
|
||||
return getMangledCXXCtorName(D, GD.getCtorType());
|
||||
return getMangledCXXCtorName(Buffer, D, GD.getCtorType());
|
||||
if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
|
||||
return getMangledCXXDtorName(D, GD.getDtorType());
|
||||
return getMangledCXXDtorName(Buffer, D, GD.getDtorType());
|
||||
|
||||
return getMangledName(ND);
|
||||
return getMangledName(Buffer, ND);
|
||||
}
|
||||
|
||||
/// \brief Retrieves the mangled name for the given declaration.
|
||||
@ -180,23 +180,19 @@ const char *CodeGenModule::getMangledName(const GlobalDecl &GD) {
|
||||
/// const char* containing the mangled name. Otherwise, returns
|
||||
/// the unmangled name.
|
||||
///
|
||||
const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
|
||||
void CodeGenModule::getMangledName(MangleBuffer &Buffer,
|
||||
const NamedDecl *ND) {
|
||||
if (!getMangleContext().shouldMangleDeclName(ND)) {
|
||||
assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
|
||||
return ND->getNameAsCString();
|
||||
Buffer.setString(ND->getNameAsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::SmallString<256> Name;
|
||||
getMangleContext().mangleName(ND, Name);
|
||||
Name += '\0';
|
||||
return UniqueMangledName(Name.begin(), Name.end());
|
||||
getMangleContext().mangleName(ND, Buffer.getBuffer());
|
||||
}
|
||||
|
||||
const char *CodeGenModule::UniqueMangledName(const char *NameStart,
|
||||
const char *NameEnd) {
|
||||
assert(*(NameEnd - 1) == '\0' && "Mangled name must be null terminated!");
|
||||
|
||||
return MangledNames.GetOrCreateValue(NameStart, NameEnd).getKeyData();
|
||||
llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
|
||||
return getModule().getNamedValue(Name);
|
||||
}
|
||||
|
||||
/// AddGlobalCtor - Add a function to the list that will be called before
|
||||
@ -505,11 +501,12 @@ void CodeGenModule::EmitDeferred() {
|
||||
GlobalDecl D = DeferredDeclsToEmit.back();
|
||||
DeferredDeclsToEmit.pop_back();
|
||||
|
||||
// The mangled name for the decl must have been emitted in GlobalDeclMap.
|
||||
// Look it up to see if it was defined with a stronger definition (e.g. an
|
||||
// extern inline function with a strong function redefinition). If so,
|
||||
// just ignore the deferred decl.
|
||||
llvm::GlobalValue *CGRef = GlobalDeclMap[getMangledName(D)];
|
||||
MangleBuffer Name;
|
||||
getMangledName(Name, D);
|
||||
llvm::GlobalValue *CGRef = GetGlobalValue(Name);
|
||||
assert(CGRef && "Deferred decl wasn't referenced?");
|
||||
|
||||
if (!CGRef->isDeclaration())
|
||||
@ -644,18 +641,14 @@ llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
|
||||
|
||||
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType());
|
||||
|
||||
// Unique the name through the identifier table.
|
||||
const char *AliaseeName =
|
||||
getContext().Idents.get(AA->getAliasee()).getNameStart();
|
||||
|
||||
// See if there is already something with the target's name in the module.
|
||||
llvm::GlobalValue *Entry = GlobalDeclMap[AliaseeName];
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(AA->getAliasee());
|
||||
|
||||
llvm::Constant *Aliasee;
|
||||
if (isa<llvm::FunctionType>(DeclTy))
|
||||
Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
|
||||
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
|
||||
else
|
||||
Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
|
||||
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
|
||||
llvm::PointerType::getUnqual(DeclTy), 0);
|
||||
if (!Entry) {
|
||||
llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
|
||||
@ -676,7 +669,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
|
||||
// If this is an alias definition (which otherwise looks like a declaration)
|
||||
// emit it now.
|
||||
if (Global->hasAttr<AliasAttr>())
|
||||
return EmitAliasDefinition(Global);
|
||||
return EmitAliasDefinition(GD);
|
||||
|
||||
// Ignore declarations, they will be emitted on their first use.
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
|
||||
@ -696,8 +689,9 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
|
||||
if (MayDeferGeneration(Global)) {
|
||||
// If the value has already been used, add it directly to the
|
||||
// DeferredDeclsToEmit list.
|
||||
const char *MangledName = getMangledName(GD);
|
||||
if (GlobalDeclMap.count(MangledName))
|
||||
MangleBuffer MangledName;
|
||||
getMangledName(MangledName, GD);
|
||||
if (GetGlobalValue(MangledName))
|
||||
DeferredDeclsToEmit.push_back(GD);
|
||||
else {
|
||||
// Otherwise, remember that we saw a deferred decl with this name. The
|
||||
@ -753,11 +747,12 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
///
|
||||
/// If D is non-null, it specifies a decl that correspond to this. This is used
|
||||
/// to set the attributes on the function when it is first created.
|
||||
llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
|
||||
const llvm::Type *Ty,
|
||||
GlobalDecl D) {
|
||||
llvm::Constant *
|
||||
CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName,
|
||||
const llvm::Type *Ty,
|
||||
GlobalDecl D) {
|
||||
// Lookup the entry, lazily creating it if necessary.
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
|
||||
if (Entry) {
|
||||
if (WeakRefReferences.count(Entry)) {
|
||||
const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl());
|
||||
@ -786,17 +781,15 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
|
||||
}
|
||||
llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
|
||||
llvm::Function::ExternalLinkage,
|
||||
"", &getModule());
|
||||
F->setName(MangledName);
|
||||
MangledName, &getModule());
|
||||
assert(F->getName() == MangledName && "name was uniqued!");
|
||||
if (D.getDecl())
|
||||
SetFunctionAttributes(D, F, IsIncompleteFunction);
|
||||
Entry = F;
|
||||
|
||||
// This is the first use or definition of a mangled name. If there is a
|
||||
// deferred decl with this name, remember that we need to emit it at the end
|
||||
// of the file.
|
||||
llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
|
||||
DeferredDecls.find(MangledName);
|
||||
llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
|
||||
if (DDI != DeferredDecls.end()) {
|
||||
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
|
||||
// list, and remove it from DeferredDecls (since we don't need it anymore).
|
||||
@ -839,16 +832,16 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
|
||||
// If there was no specific requested type, just convert it now.
|
||||
if (!Ty)
|
||||
Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
|
||||
return GetOrCreateLLVMFunction(getMangledName(GD), Ty, GD);
|
||||
MangleBuffer MangledName;
|
||||
getMangledName(MangledName, GD);
|
||||
return GetOrCreateLLVMFunction(MangledName, Ty, GD);
|
||||
}
|
||||
|
||||
/// CreateRuntimeFunction - Create a new runtime function with the specified
|
||||
/// type and name.
|
||||
llvm::Constant *
|
||||
CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
|
||||
const char *Name) {
|
||||
// Convert Name to be a uniqued string from the IdentifierInfo table.
|
||||
Name = getContext().Idents.get(Name).getNameStart();
|
||||
llvm::StringRef Name) {
|
||||
return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());
|
||||
}
|
||||
|
||||
@ -870,11 +863,12 @@ static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) {
|
||||
///
|
||||
/// If D is non-null, it specifies a decl that correspond to this. This is used
|
||||
/// to set the attributes on the global when it is first created.
|
||||
llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
const llvm::PointerType*Ty,
|
||||
const VarDecl *D) {
|
||||
llvm::Constant *
|
||||
CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
|
||||
const llvm::PointerType *Ty,
|
||||
const VarDecl *D) {
|
||||
// Lookup the entry, lazily creating it if necessary.
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
|
||||
if (Entry) {
|
||||
if (WeakRefReferences.count(Entry)) {
|
||||
if (D && !D->hasAttr<WeakAttr>())
|
||||
@ -893,8 +887,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
// This is the first use or definition of a mangled name. If there is a
|
||||
// deferred decl with this name, remember that we need to emit it at the end
|
||||
// of the file.
|
||||
llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
|
||||
DeferredDecls.find(MangledName);
|
||||
llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
|
||||
if (DDI != DeferredDecls.end()) {
|
||||
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
|
||||
// list, and remove it from DeferredDecls (since we don't need it anymore).
|
||||
@ -905,9 +898,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
llvm::GlobalVariable *GV =
|
||||
new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0, "", 0,
|
||||
0, MangledName, 0,
|
||||
false, Ty->getAddressSpace());
|
||||
GV->setName(MangledName);
|
||||
|
||||
// Handle things which are present even on external declarations.
|
||||
if (D) {
|
||||
@ -926,7 +918,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
GV->setThreadLocal(D->isThreadSpecified());
|
||||
}
|
||||
|
||||
return Entry = GV;
|
||||
return GV;
|
||||
}
|
||||
|
||||
|
||||
@ -943,16 +935,17 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
|
||||
|
||||
const llvm::PointerType *PTy =
|
||||
llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
|
||||
return GetOrCreateLLVMGlobal(getMangledName(D), PTy, D);
|
||||
|
||||
MangleBuffer MangledName;
|
||||
getMangledName(MangledName, D);
|
||||
return GetOrCreateLLVMGlobal(MangledName, PTy, D);
|
||||
}
|
||||
|
||||
/// CreateRuntimeVariable - Create a new runtime global variable with the
|
||||
/// specified type and name.
|
||||
llvm::Constant *
|
||||
CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
|
||||
const char *Name) {
|
||||
// Convert Name to be a uniqued string from the IdentifierInfo table.
|
||||
Name = getContext().Idents.get(Name).getNameStart();
|
||||
llvm::StringRef Name) {
|
||||
return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0);
|
||||
}
|
||||
|
||||
@ -963,8 +956,9 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
|
||||
// If we have not seen a reference to this variable yet, place it
|
||||
// into the deferred declarations table to be emitted if needed
|
||||
// later.
|
||||
const char *MangledName = getMangledName(D);
|
||||
if (GlobalDeclMap.count(MangledName) == 0) {
|
||||
MangleBuffer MangledName;
|
||||
getMangledName(MangledName, D);
|
||||
if (!GetGlobalValue(MangledName)) {
|
||||
DeferredDecls[MangledName] = D;
|
||||
return;
|
||||
}
|
||||
@ -1133,12 +1127,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
||||
GV->getType()->getElementType() != InitType ||
|
||||
GV->getType()->getAddressSpace() != ASTTy.getAddressSpace()) {
|
||||
|
||||
// Remove the old entry from GlobalDeclMap so that we'll create a new one.
|
||||
GlobalDeclMap.erase(getMangledName(D));
|
||||
// Move the old entry aside so that we'll create a new one.
|
||||
Entry->setName(llvm::StringRef());
|
||||
|
||||
// Make a new global with the correct type, this is now guaranteed to work.
|
||||
GV = cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, InitType));
|
||||
GV->takeName(cast<llvm::GlobalValue>(Entry));
|
||||
|
||||
// Replace all uses of the old global with the new global
|
||||
llvm::Constant *NewPtrForOldDecl =
|
||||
@ -1296,11 +1289,10 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
|
||||
//
|
||||
// This happens if there is a prototype for a function
|
||||
// (e.g. "int f()") and then a definition of a different type
|
||||
// (e.g. "int f(int x)"). Start by making a new function of the
|
||||
// correct type, RAUW, then steal the name.
|
||||
GlobalDeclMap.erase(getMangledName(D));
|
||||
// (e.g. "int f(int x)"). Move the old function aside so that it
|
||||
// doesn't interfere with GetAddrOfFunction.
|
||||
OldFn->setName(llvm::StringRef());
|
||||
llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
|
||||
NewFn->takeName(OldFn);
|
||||
|
||||
// If this is an implementation of a function without a prototype, try to
|
||||
// replace any existing uses of the function (which may be calls) with uses
|
||||
@ -1336,23 +1328,29 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
|
||||
AddGlobalDtor(Fn, DA->getPriority());
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
|
||||
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
||||
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
|
||||
const AliasAttr *AA = D->getAttr<AliasAttr>();
|
||||
assert(AA && "Not an alias?");
|
||||
|
||||
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
|
||||
MangleBuffer MangledName;
|
||||
getMangledName(MangledName, GD);
|
||||
|
||||
// Unique the name through the identifier table.
|
||||
const char *AliaseeName =
|
||||
getContext().Idents.get(AA->getAliasee()).getNameStart();
|
||||
// If there is a definition in the module, then it wins over the alias.
|
||||
// This is dubious, but allow it to be safe. Just ignore the alias.
|
||||
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
|
||||
if (Entry && !Entry->isDeclaration())
|
||||
return;
|
||||
|
||||
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
|
||||
|
||||
// Create a reference to the named value. This ensures that it is emitted
|
||||
// if a deferred decl.
|
||||
llvm::Constant *Aliasee;
|
||||
if (isa<llvm::FunctionType>(DeclTy))
|
||||
Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
|
||||
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
|
||||
else
|
||||
Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
|
||||
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
|
||||
llvm::PointerType::getUnqual(DeclTy), 0);
|
||||
|
||||
// Create the new alias itself, but don't set a name yet.
|
||||
@ -1361,18 +1359,9 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
|
||||
llvm::Function::ExternalLinkage,
|
||||
"", Aliasee, &getModule());
|
||||
|
||||
// See if there is already something with the alias' name in the module.
|
||||
const char *MangledName = getMangledName(D);
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
|
||||
if (Entry && !Entry->isDeclaration()) {
|
||||
// If there is a definition in the module, then it wins over the alias.
|
||||
// This is dubious, but allow it to be safe. Just ignore the alias.
|
||||
GA->eraseFromParent();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Entry) {
|
||||
assert(Entry->isDeclaration());
|
||||
|
||||
// If there is a declaration in the module, then we had an extern followed
|
||||
// by the alias, as in:
|
||||
// extern int test6();
|
||||
@ -1380,16 +1369,15 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
|
||||
// int test6() __attribute__((alias("test7")));
|
||||
//
|
||||
// Remove it and replace uses of it with the alias.
|
||||
GA->takeName(Entry);
|
||||
|
||||
Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
|
||||
Entry->getType()));
|
||||
Entry->eraseFromParent();
|
||||
} else {
|
||||
GA->setName(MangledName.getString());
|
||||
}
|
||||
|
||||
// Now we know that there is no conflict, set the name.
|
||||
Entry = GA;
|
||||
GA->setName(MangledName);
|
||||
|
||||
// Set attributes which are particular to an alias; this is a
|
||||
// specialization of the attributes which may be set on a global
|
||||
// variable/function.
|
||||
@ -1426,8 +1414,6 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
|
||||
const llvm::FunctionType *Ty =
|
||||
cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
|
||||
|
||||
// Unique the name through the identifier table.
|
||||
Name = getContext().Idents.get(Name).getNameStart();
|
||||
return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace CodeGen {
|
||||
class CodeGenFunction;
|
||||
class CGDebugInfo;
|
||||
class CGObjCRuntime;
|
||||
|
||||
class MangleBuffer;
|
||||
|
||||
/// CodeGenModule - This class organizes the cross-function state that is used
|
||||
/// while generating LLVM code.
|
||||
@ -103,38 +103,16 @@ class CodeGenModule : public BlockModule {
|
||||
llvm::Function *MemMoveFn;
|
||||
llvm::Function *MemSetFn;
|
||||
|
||||
/// GlobalDeclMap - Mapping of decl names (represented as unique
|
||||
/// character pointers from either the identifier table or the set
|
||||
/// of mangled names) to global variables we have already
|
||||
/// emitted. Note that the entries in this map are the actual
|
||||
/// globals and therefore may not be of the same type as the decl,
|
||||
/// they should be bitcasted on retrieval. Also note that the
|
||||
/// globals are keyed on their source mangled name, not the global name
|
||||
/// (which may change with attributes such as asm-labels). The key
|
||||
/// to this map should be generated using getMangledName().
|
||||
///
|
||||
/// Note that this map always lines up exactly with the contents of the LLVM
|
||||
/// IR symbol table, but this is quicker to query since it is doing uniqued
|
||||
/// pointer lookups instead of full string lookups.
|
||||
llvm::DenseMap<const char*, llvm::GlobalValue*> GlobalDeclMap;
|
||||
|
||||
// WeakRefReferences - A set of references that have only been seen via
|
||||
// a weakref so far. This is used to remove the weak of the reference if we ever
|
||||
// see a direct reference or a definition.
|
||||
llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
|
||||
|
||||
/// \brief Contains the strings used for mangled names.
|
||||
///
|
||||
/// FIXME: Eventually, this should map from the semantic/canonical
|
||||
/// declaration for each global entity to its mangled name (if it
|
||||
/// has one).
|
||||
llvm::StringSet<> MangledNames;
|
||||
|
||||
/// DeferredDecls - This contains all the decls which have definitions but
|
||||
/// which are deferred for emission and therefore should only be output if
|
||||
/// they are actually used. If a decl is in this, then it is known to have
|
||||
/// not been referenced yet. The key to this map is a uniqued mangled name.
|
||||
llvm::DenseMap<const char*, GlobalDecl> DeferredDecls;
|
||||
/// not been referenced yet.
|
||||
llvm::StringMap<GlobalDecl> DeferredDecls;
|
||||
|
||||
/// DeferredDeclsToEmit - This is a list of deferred decls which we have seen
|
||||
/// that *are* actually referenced. These get code generated when the module
|
||||
@ -346,11 +324,11 @@ public:
|
||||
/// CreateRuntimeFunction - Create a new runtime function with the specified
|
||||
/// type and name.
|
||||
llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty,
|
||||
const char *Name);
|
||||
llvm::StringRef Name);
|
||||
/// CreateRuntimeVariable - Create a new runtime global variable with the
|
||||
/// specified type and name.
|
||||
llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty,
|
||||
const char *Name);
|
||||
llvm::StringRef Name);
|
||||
|
||||
void UpdateCompletedType(const TagDecl *TD) {
|
||||
// Make sure that this type is translated.
|
||||
@ -422,13 +400,14 @@ public:
|
||||
AttributeListType &PAL,
|
||||
unsigned &CallingConv);
|
||||
|
||||
const char *getMangledName(const GlobalDecl &D);
|
||||
|
||||
const char *getMangledName(const NamedDecl *ND);
|
||||
const char *getMangledCXXCtorName(const CXXConstructorDecl *D,
|
||||
CXXCtorType Type);
|
||||
const char *getMangledCXXDtorName(const CXXDestructorDecl *D,
|
||||
CXXDtorType Type);
|
||||
void getMangledName(MangleBuffer &Buffer, GlobalDecl D);
|
||||
void getMangledName(MangleBuffer &Buffer, const NamedDecl *ND);
|
||||
void getMangledCXXCtorName(MangleBuffer &Buffer,
|
||||
const CXXConstructorDecl *D,
|
||||
CXXCtorType Type);
|
||||
void getMangledCXXDtorName(MangleBuffer &Buffer,
|
||||
const CXXDestructorDecl *D,
|
||||
CXXDtorType Type);
|
||||
|
||||
void EmitTentativeDefinition(const VarDecl *D);
|
||||
|
||||
@ -456,14 +435,12 @@ public:
|
||||
std::vector<const CXXRecordDecl*> DeferredVtables;
|
||||
|
||||
private:
|
||||
/// UniqueMangledName - Unique a name by (if necessary) inserting it into the
|
||||
/// MangledNames string map.
|
||||
const char *UniqueMangledName(const char *NameStart, const char *NameEnd);
|
||||
llvm::GlobalValue *GetGlobalValue(llvm::StringRef Ref);
|
||||
|
||||
llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName,
|
||||
llvm::Constant *GetOrCreateLLVMFunction(llvm::StringRef MangledName,
|
||||
const llvm::Type *Ty,
|
||||
GlobalDecl D);
|
||||
llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
llvm::Constant *GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
|
||||
const llvm::PointerType *PTy,
|
||||
const VarDecl *D);
|
||||
|
||||
@ -492,7 +469,7 @@ private:
|
||||
|
||||
void EmitGlobalFunctionDefinition(GlobalDecl GD);
|
||||
void EmitGlobalVarDefinition(const VarDecl *D);
|
||||
void EmitAliasDefinition(const ValueDecl *D);
|
||||
void EmitAliasDefinition(GlobalDecl GD);
|
||||
void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
|
||||
|
||||
// C++ related functions.
|
||||
|
@ -21,10 +21,8 @@
|
||||
#include "CGCXX.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace llvm {
|
||||
template<typename T> class SmallVectorImpl;
|
||||
}
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
@ -37,6 +35,33 @@ namespace clang {
|
||||
namespace CodeGen {
|
||||
class CovariantThunkAdjustment;
|
||||
class ThunkAdjustment;
|
||||
|
||||
/// MangleBuffer - a convenient class for storing a name which is
|
||||
/// either the result of a mangling or is a constant string with
|
||||
/// external memory ownership.
|
||||
class MangleBuffer {
|
||||
public:
|
||||
void setString(llvm::StringRef Ref) {
|
||||
String = Ref;
|
||||
}
|
||||
|
||||
llvm::SmallVectorImpl<char> &getBuffer() {
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
llvm::StringRef getString() const {
|
||||
if (!String.empty()) return String;
|
||||
return Buffer.str();
|
||||
}
|
||||
|
||||
operator llvm::StringRef() const {
|
||||
return getString();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::StringRef String;
|
||||
llvm::SmallString<256> Buffer;
|
||||
};
|
||||
|
||||
/// MangleContext - Context for tracking state which persists across multiple
|
||||
/// calls to the C++ name mangler.
|
||||
|
@ -1,5 +1,7 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
// CHECK: @test2 = alias i32 ()* @_Z5test1v
|
||||
|
||||
// CHECK: define i32 @_Z3foov() nounwind align 1024
|
||||
int foo() __attribute__((aligned(1024)));
|
||||
int foo() { }
|
||||
@ -18,3 +20,9 @@ void C::bar2() { }
|
||||
|
||||
// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024
|
||||
void C::bar3() { }
|
||||
|
||||
// PR6635
|
||||
// CHECK: define i32 @_Z5test1v()
|
||||
int test1() { return 10; }
|
||||
// CHECK at top of file
|
||||
extern "C" int test2() __attribute__((alias("_Z5test1v")));
|
||||
|
Loading…
x
Reference in New Issue
Block a user