aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-06-03 02:42:01 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-06-03 02:42:01 +0000
commit27c60b512a5f9f602602748eb592d6c6909671c4 (patch)
treeaf43624fbaf5c1392a5e60f01b8e7a5d9edce352 /clang/lib/CodeGen/CodeGenModule.cpp
parent64c1e1803311610e359e26a5f0ece867f0dabd3e (diff)
downloadllvm-27c60b512a5f9f602602748eb592d6c6909671c4.zip
llvm-27c60b512a5f9f602602748eb592d6c6909671c4.tar.gz
llvm-27c60b512a5f9f602602748eb592d6c6909671c4.tar.bz2
Update for llvm API change.
Aliases in llvm now hold an arbitrary expression. llvm-svn: 210063
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp80
1 files changed, 49 insertions, 31 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b0e08a2..5f23bd4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -225,6 +225,25 @@ void CodeGenModule::applyReplacements() {
}
}
+// This is only used in aliases that we created and we know they have a
+// linear structure.
+static const llvm::GlobalObject *getAliasedGlobal(const llvm::GlobalAlias &GA) {
+ llvm::SmallPtrSet<const llvm::GlobalAlias*, 4> Visited;
+ const llvm::Constant *C = &GA;
+ for (;;) {
+ C = cast<llvm::Constant>(C->stripPointerCasts());
+ if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
+ return GO;
+ // stripPointerCasts will not walk over weak aliases.
+ auto *GA2 = dyn_cast<llvm::GlobalAlias>(C);
+ if (!GA2)
+ return nullptr;
+ if (!Visited.insert(GA2))
+ return nullptr;
+ C = GA2->getAliasee();
+ }
+}
+
void CodeGenModule::checkAliases() {
// Check if the constructed aliases are well formed. It is really unfortunate
// that we have to do this in CodeGen, but we only construct mangled names
@@ -239,19 +258,43 @@ void CodeGenModule::checkAliases() {
StringRef MangledName = getMangledName(GD);
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
auto *Alias = cast<llvm::GlobalAlias>(Entry);
- llvm::GlobalValue *GV = Alias->getAliasee();
- if (GV->isDeclaration()) {
+ const llvm::GlobalValue *GV = getAliasedGlobal(*Alias);
+ if (!GV) {
+ Error = true;
+ Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
+ } else if (GV->isDeclaration()) {
Error = true;
Diags.Report(AA->getLocation(), diag::err_alias_to_undefined);
}
- llvm::GlobalObject *Aliasee = Alias->getAliasee();
+ llvm::Constant *Aliasee = Alias->getAliasee();
+ llvm::GlobalValue *AliaseeGV;
+ if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee))
+ AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0));
+ else
+ AliaseeGV = cast<llvm::GlobalValue>(Aliasee);
+
if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
StringRef AliasSection = SA->getName();
- if (AliasSection != Aliasee->getSection())
+ if (AliasSection != AliaseeGV->getSection())
Diags.Report(SA->getLocation(), diag::warn_alias_with_section)
<< AliasSection;
}
+
+ // We have to handle alias to weak aliases in here. LLVM itself disallows
+ // this since the object semantics would not match the IL one. For
+ // compatibility with gcc we implement it by just pointing the alias
+ // to its aliasee's aliasee. We also warn, since the user is probably
+ // expecting the link to be weak.
+ if (auto GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) {
+ if (GA->mayBeOverridden()) {
+ Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
+ << GV->getName() << GA->getName();
+ Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+ GA->getAliasee(), Alias->getType());
+ Alias->setAliasee(Aliasee);
+ }
+ }
}
if (!Error)
return;
@@ -2228,29 +2271,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
AddGlobalAnnotations(D, Fn);
}
-static llvm::GlobalObject &getGlobalObjectInExpr(DiagnosticsEngine &Diags,
- const AliasAttr *AA,
- llvm::Constant *C) {
- if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
- return *GO;
-
- auto *GA = dyn_cast<llvm::GlobalAlias>(C);
- if (GA) {
- if (GA->mayBeOverridden()) {
- Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
- << GA->getAliasee()->getName() << GA->getName();
- }
-
- return *GA->getAliasee();
- }
-
- auto *CE = cast<llvm::ConstantExpr>(C);
- assert(CE->getOpcode() == llvm::Instruction::BitCast ||
- CE->getOpcode() == llvm::Instruction::GetElementPtr ||
- CE->getOpcode() == llvm::Instruction::AddrSpaceCast);
- return *cast<llvm::GlobalObject>(CE->getOperand(0));
-}
-
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
const auto *D = cast<ValueDecl>(GD.getDecl());
const AliasAttr *AA = D->getAttr<AliasAttr>();
@@ -2282,8 +2302,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
// Create the new alias itself, but don't set a name yet.
auto *GA = llvm::GlobalAlias::create(
cast<llvm::PointerType>(Aliasee->getType())->getElementType(), 0,
- llvm::Function::ExternalLinkage, "",
- &getGlobalObjectInExpr(Diags, AA, Aliasee));
+ llvm::Function::ExternalLinkage, "", Aliasee, &getModule());
if (Entry) {
if (GA->getAliasee() == Entry) {
@@ -3208,8 +3227,7 @@ void CodeGenModule::EmitStaticExternCAliases() {
IdentifierInfo *Name = I->first;
llvm::GlobalValue *Val = I->second;
if (Val && !getModule().getNamedValue(Name->getName()))
- addUsedGlobal(llvm::GlobalAlias::create(Name->getName(),
- cast<llvm::GlobalObject>(Val)));
+ addUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val));
}
}