summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp252
1 files changed, 152 insertions, 100 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 54d0ff2..7c679b9 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -16,7 +16,8 @@
#include "CGRecordLayout.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
-#include "CGException.h"
+#include "CGBlocks.h"
+#include "CGCleanup.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
@@ -77,6 +78,7 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
++Index;
}
assert(Index != Ivars.size() && "Ivar is not inside container!");
+ assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
return RL->getFieldOffset(Index);
}
@@ -129,7 +131,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
// a synthesized ivar can never be a bit-field, so this is safe.
const ASTRecordLayout &RL =
CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
- uint64_t TypeSizeInBits = RL.getSize();
+ uint64_t TypeSizeInBits = CGF.CGM.getContext().toBits(RL.getSize());
uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
uint64_t BitOffset = FieldBitOffset % 8;
uint64_t ContainingTypeAlign = 8;
@@ -462,7 +464,7 @@ public:
// void objc_exception_rethrow(void)
std::vector<const llvm::Type*> Args;
llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, true);
+ llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false);
return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
}
@@ -999,8 +1001,8 @@ public:
/// forward references will be filled in with empty bodies if no
/// definition is seen. The return value has type ProtocolPtrTy.
virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
- virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF,
- const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &);
+ virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
+ const CGBlockInfo &blockInfo);
};
@@ -1156,7 +1158,8 @@ public:
virtual llvm::Constant *GetPropertyGetFunction();
virtual llvm::Constant *GetPropertySetFunction();
- virtual llvm::Constant *GetCopyStructFunction();
+ virtual llvm::Constant *GetGetStructFunction();
+ virtual llvm::Constant *GetSetStructFunction();
virtual llvm::Constant *EnumerationMutationFunction();
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
@@ -1401,7 +1404,10 @@ public:
return ObjCTypes.getSetPropertyFn();
}
- virtual llvm::Constant *GetCopyStructFunction() {
+ virtual llvm::Constant *GetSetStructFunction() {
+ return ObjCTypes.getCopyStructFn();
+ }
+ virtual llvm::Constant *GetGetStructFunction() {
return ObjCTypes.getCopyStructFn();
}
@@ -1520,7 +1526,7 @@ llvm::Constant *CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
return (CGM.getLangOptions().NoConstantCFStrings == 0 ?
CGM.GetAddrOfConstantCFString(SL) :
- CGM.GetAddrOfConstantNSString(SL));
+ CGM.GetAddrOfConstantString(SL));
}
/// Generates a message send where the super is the receiver. This is
@@ -1662,57 +1668,76 @@ static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
return Qualifiers::GCNone;
}
-llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF,
- const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &DeclRefs) {
- llvm::Constant *NullPtr =
+llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
+ const CGBlockInfo &blockInfo) {
+ llvm::Constant *nullPtr =
llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext));
- if ((CGM.getLangOptions().getGCMode() == LangOptions::NonGC) ||
- DeclRefs.empty())
- return NullPtr;
+
+ if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
+ return nullPtr;
+
bool hasUnion = false;
SkipIvars.clear();
IvarsInfo.clear();
unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
- for (size_t i = 0; i < DeclRefs.size(); ++i) {
- const BlockDeclRefExpr *BDRE = DeclRefs[i];
- const ValueDecl *VD = BDRE->getDecl();
- CharUnits Offset = CGF.BlockDecls[VD];
- uint64_t FieldOffset = Offset.getQuantity();
- QualType Ty = VD->getType();
- assert(!Ty->isArrayType() &&
- "Array block variable should have been caught");
- if ((Ty->isRecordType() || Ty->isUnionType()) && !BDRE->isByRef()) {
- BuildAggrIvarRecordLayout(Ty->getAs<RecordType>(),
- FieldOffset,
- true,
- hasUnion);
+ // __isa is the first field in block descriptor and must assume by runtime's
+ // convention that it is GC'able.
+ IvarsInfo.push_back(GC_IVAR(0, 1));
+
+ const BlockDecl *blockDecl = blockInfo.getBlockDecl();
+
+ // Calculate the basic layout of the block structure.
+ const llvm::StructLayout *layout =
+ CGM.getTargetData().getStructLayout(blockInfo.StructureType);
+
+ // Ignore the optional 'this' capture: C++ objects are not assumed
+ // to be GC'ed.
+
+ // Walk the captured variables.
+ for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
+ ce = blockDecl->capture_end(); ci != ce; ++ci) {
+ const VarDecl *variable = ci->getVariable();
+ QualType type = variable->getType();
+
+ const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
+
+ // Ignore constant captures.
+ if (capture.isConstant()) continue;
+
+ uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
+
+ // __block variables are passed by their descriptor address.
+ if (ci->isByRef()) {
+ IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
+ continue;
+ }
+
+ assert(!type->isArrayType() && "array variable should not be caught");
+ if (const RecordType *record = type->getAs<RecordType>()) {
+ BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
continue;
}
- Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), Ty);
- unsigned FieldSize = CGM.getContext().getTypeSize(Ty);
- // __block variables are passed by their descriptior address. So, size
- // must reflect this.
- if (BDRE->isByRef())
- FieldSize = WordSizeInBits;
- if (GCAttr == Qualifiers::Strong || BDRE->isByRef())
- IvarsInfo.push_back(GC_IVAR(FieldOffset,
- FieldSize / WordSizeInBits));
+ Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
+ unsigned fieldSize = CGM.getContext().getTypeSize(type);
+
+ if (GCAttr == Qualifiers::Strong)
+ IvarsInfo.push_back(GC_IVAR(fieldOffset,
+ fieldSize / WordSizeInBits));
else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
- SkipIvars.push_back(GC_IVAR(FieldOffset,
- FieldSize / ByteSizeInBits));
+ SkipIvars.push_back(GC_IVAR(fieldOffset,
+ fieldSize / ByteSizeInBits));
}
if (IvarsInfo.empty())
- return NullPtr;
- // Sort on byte position in case we encounterred a union nested in
- // block variable type's aggregate type.
- if (hasUnion && !IvarsInfo.empty())
- std::sort(IvarsInfo.begin(), IvarsInfo.end());
- if (hasUnion && !SkipIvars.empty())
- std::sort(SkipIvars.begin(), SkipIvars.end());
+ return nullPtr;
+
+ // Sort on byte position; captures might not be allocated in order,
+ // and unions can do funny things.
+ llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
+ llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
std::string BitMap;
llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
@@ -2189,10 +2214,10 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
if (ID->getNumIvarInitializers())
Flags |= eClassFlags_HasCXXStructors;
unsigned Size =
- CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
+ CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
// FIXME: Set CXX-structors flag.
- if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
+ if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
Flags |= eClassFlags_Hidden;
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
@@ -2277,7 +2302,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
unsigned Flags = eClassFlags_Meta;
unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
- if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
+ if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
Flags |= eClassFlags_Hidden;
std::vector<llvm::Constant*> Values(12);
@@ -2578,7 +2603,10 @@ llvm::Constant *CGObjCMac::GetPropertySetFunction() {
return ObjCTypes.getSetPropertyFn();
}
-llvm::Constant *CGObjCMac::GetCopyStructFunction() {
+llvm::Constant *CGObjCMac::GetGetStructFunction() {
+ return ObjCTypes.getCopyStructFn();
+}
+llvm::Constant *CGObjCMac::GetSetStructFunction() {
return ObjCTypes.getCopyStructFn();
}
@@ -2968,6 +2996,10 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
"_call_try_exit");
+ // A slot containing the exception to rethrow. Only needed when we
+ // have both a @catch and a @finally.
+ llvm::Value *PropagatingExnVar = 0;
+
// Push a normal cleanup to leave the try scope.
CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S,
SyncArgSlot,
@@ -3039,6 +3071,12 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
llvm::BasicBlock *CatchBlock = 0;
llvm::BasicBlock *CatchHandler = 0;
if (HasFinally) {
+ // Save the currently-propagating exception before
+ // objc_exception_try_enter clears the exception slot.
+ PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
+ "propagating_exception");
+ CGF.Builder.CreateStore(Caught, PropagatingExnVar);
+
// Enter a new exception try block (in case a @catch block
// throws an exception).
CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
@@ -3090,7 +3128,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
if (CatchParam) {
- CGF.EmitLocalBlockVarDecl(*CatchParam);
+ CGF.EmitAutoVarDecl(*CatchParam);
assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
// These types work out because ConvertType(id) == i8*.
@@ -3134,7 +3172,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// the end of the catch body.
CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
- CGF.EmitLocalBlockVarDecl(*CatchParam);
+ CGF.EmitAutoVarDecl(*CatchParam);
assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
// Initialize the catch variable.
@@ -3173,6 +3211,15 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// the try's write hazard and here.
//Hazards.emitWriteHazard();
+ // Extract the new exception and save it to the
+ // propagating-exception slot.
+ assert(PropagatingExnVar);
+ llvm::CallInst *NewCaught =
+ CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
+ ExceptionData, "caught");
+ NewCaught->setDoesNotThrow();
+ CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
+
// Don't pop the catch handler; the throw already did.
CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
CGF.EmitBranchThroughCleanup(FinallyRethrow);
@@ -3193,13 +3240,21 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
CGF.EmitBlock(FinallyRethrow.getBlock(), true);
if (CGF.HaveInsertPoint()) {
- // Just look in the buffer for the exception to throw.
- llvm::CallInst *Caught =
- CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
- ExceptionData);
- Caught->setDoesNotThrow();
+ // If we have a propagating-exception variable, check it.
+ llvm::Value *PropagatingExn;
+ if (PropagatingExnVar) {
+ PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
+
+ // Otherwise, just look in the buffer for the exception to throw.
+ } else {
+ llvm::CallInst *Caught =
+ CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
+ ExceptionData);
+ Caught->setDoesNotThrow();
+ PropagatingExn = Caught;
+ }
- CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), Caught)
+ CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
->setDoesNotThrow();
CGF.Builder.CreateUnreachable();
}
@@ -3586,10 +3641,10 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
uint64_t MaxSkippedUnionIvarSize = 0;
FieldDecl *MaxField = 0;
FieldDecl *MaxSkippedField = 0;
- FieldDecl *LastFieldBitfield = 0;
+ FieldDecl *LastFieldBitfieldOrUnnamed = 0;
uint64_t MaxFieldOffset = 0;
uint64_t MaxSkippedFieldOffset = 0;
- uint64_t LastBitfieldOffset = 0;
+ uint64_t LastBitfieldOrUnnamedOffset = 0;
if (RecFields.empty())
return;
@@ -3609,12 +3664,12 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
// Skip over unnamed or bitfields
if (!Field->getIdentifier() || Field->isBitField()) {
- LastFieldBitfield = Field;
- LastBitfieldOffset = FieldOffset;
+ LastFieldBitfieldOrUnnamed = Field;
+ LastBitfieldOrUnnamedOffset = FieldOffset;
continue;
}
- LastFieldBitfield = 0;
+ LastFieldBitfieldOrUnnamed = 0;
QualType FQT = Field->getType();
if (FQT->isRecordType() || FQT->isUnionType()) {
if (FQT->isUnionType())
@@ -3641,7 +3696,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
assert(!FQT->isUnionType() &&
"layout for array of unions not supported");
- if (FQT->isRecordType()) {
+ if (FQT->isRecordType() && ElCount) {
int OldIndex = IvarsInfo.size() - 1;
int OldSkIndex = SkipIvars.size() -1;
@@ -3703,16 +3758,25 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
}
}
- if (LastFieldBitfield) {
- // Last field was a bitfield. Must update skip info.
- Expr *BitWidth = LastFieldBitfield->getBitWidth();
- uint64_t BitFieldSize =
- BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
- GC_IVAR skivar;
- skivar.ivar_bytepos = BytePos + LastBitfieldOffset;
- skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
- + ((BitFieldSize % ByteSizeInBits) != 0);
- SkipIvars.push_back(skivar);
+ if (LastFieldBitfieldOrUnnamed) {
+ if (LastFieldBitfieldOrUnnamed->isBitField()) {
+ // Last field was a bitfield. Must update skip info.
+ Expr *BitWidth = LastFieldBitfieldOrUnnamed->getBitWidth();
+ uint64_t BitFieldSize =
+ BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+ GC_IVAR skivar;
+ skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
+ skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
+ + ((BitFieldSize % ByteSizeInBits) != 0);
+ SkipIvars.push_back(skivar);
+ } else {
+ assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
+ // Last field was unnamed. Must update skip info.
+ unsigned FieldSize
+ = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
+ SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
+ FieldSize / ByteSizeInBits));
+ }
}
if (MaxField)
@@ -4886,7 +4950,7 @@ void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
CGM.getContext().getASTObjCImplementationLayout(OID);
// InstanceSize is really instance end.
- InstanceSize = llvm::RoundUpToAlignment(RL.getDataSize(), 8) / 8;
+ InstanceSize = RL.getDataSize().getQuantity();
// If there are no fields, the start is the same as the end.
if (!RL.getFieldCount())
@@ -4927,7 +4991,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
llvm::GlobalVariable *SuperClassGV, *IsAGV;
bool classIsHidden =
- CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden;
+ ID->getClassInterface()->getVisibility() == HiddenVisibility;
if (classIsHidden)
flags |= OBJC2_CLS_HIDDEN;
if (ID->getNumIvarInitializers())
@@ -5222,7 +5286,7 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
// well (i.e., in ObjCIvarOffsetVariable).
if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
Ivar->getAccessControl() == ObjCIvarDecl::Package ||
- CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden)
+ ID->getVisibility() == HiddenVisibility)
IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
else
IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
@@ -6096,7 +6160,7 @@ void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
- CGF.EmitLocalBlockVarDecl(*CatchParam);
+ CGF.EmitAutoVarDecl(*CatchParam);
CGF.Builder.CreateStore(CastExn, CGF.GetAddrOfLocalVar(CatchParam));
}
@@ -6124,32 +6188,20 @@ void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
/// EmitThrowStmt - Generate code for a throw statement.
void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S) {
- llvm::Value *Exception;
- llvm::Constant *FunctionThrowOrRethrow;
if (const Expr *ThrowExpr = S.getThrowExpr()) {
- Exception = CGF.EmitScalarExpr(ThrowExpr);
- FunctionThrowOrRethrow = ObjCTypes.getExceptionThrowFn();
- } else {
- assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
- "Unexpected rethrow outside @catch block.");
- Exception = CGF.ObjCEHValueStack.back();
- FunctionThrowOrRethrow = ObjCTypes.getExceptionRethrowFn();
- }
-
- llvm::Value *ExceptionAsObject =
- CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
- llvm::BasicBlock *InvokeDest = CGF.getInvokeDest();
- if (InvokeDest) {
- CGF.Builder.CreateInvoke(FunctionThrowOrRethrow,
- CGF.getUnreachableBlock(), InvokeDest,
- &ExceptionAsObject, &ExceptionAsObject + 1);
+ llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
+ Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy,
+ "tmp");
+ llvm::Value *Args[] = { Exception };
+ CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(),
+ Args, Args+1)
+ .setDoesNotReturn();
} else {
- CGF.Builder.CreateCall(FunctionThrowOrRethrow, ExceptionAsObject)
- ->setDoesNotReturn();
- CGF.Builder.CreateUnreachable();
+ CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn(), 0, 0)
+ .setDoesNotReturn();
}
- // Clear the insertion point to indicate we are in unreachable code.
+ CGF.Builder.CreateUnreachable();
CGF.Builder.ClearInsertionPoint();
}
@@ -6208,7 +6260,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
ID->getIdentifier()->getName()));
}
- if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden)
+ if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility)
Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
ObjCTypes.EHTypeTy));
OpenPOWER on IntegriCloud