In C++, allow us to emit a global as 'constant' even if it has class

type, so long as it is known to have a constant initializer and the
class type is a POD class. Fixes <rdar://problem/9306265>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131060 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-05-07 22:06:45 +00:00
Родитель 6f08777445
Коммит da55074866
2 изменённых файлов: 20 добавлений и 7 удалений

Просмотреть файл

@ -938,14 +938,17 @@ CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false);
}
static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) {
static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D,
bool ConstantInit) {
if (!D->getType().isConstant(Context) && !D->getType()->isReferenceType())
return false;
if (Context.getLangOptions().CPlusPlus &&
Context.getBaseElementType(D->getType())->getAs<RecordType>()) {
// FIXME: We should do something fancier here!
return false;
if (Context.getLangOptions().CPlusPlus) {
if (const RecordType *Record
= Context.getBaseElementType(D->getType())->getAs<RecordType>())
return ConstantInit && cast<CXXRecordDecl>(Record->getDecl())->isPOD();
}
return true;
}
@ -1002,7 +1005,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
if (D) {
// FIXME: This code is overly simple and should be merged with other global
// handling.
GV->setConstant(DeclIsConstantGlobal(Context, D));
GV->setConstant(DeclIsConstantGlobal(Context, D, false));
// Set linkage and visibility in case we never see a definition.
NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
@ -1284,7 +1287,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// If it is safe to mark the global 'constant', do so now.
GV->setConstant(false);
if (!NonConstInit && DeclIsConstantGlobal(Context, D))
if (!NonConstInit && DeclIsConstantGlobal(Context, D, true))
GV->setConstant(true);
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());

Просмотреть файл

@ -8,3 +8,13 @@ struct A {
const A x;
// CHECK: @_ZL1x = internal global
struct X {
int (*fp)(int, int);
};
int add(int x, int y) { return x + y; }
// CHECK: @x2 = constant
extern const X x2;
const X x2 = { &add };