Newer
Older
//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This coordinates the per-module state used while generating code.
//
//===----------------------------------------------------------------------===//
#include "CodeGenModule.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGCall.h"
#include "CGDebugInfo.h"
#include "CGObjCRuntime.h"
#include "CGOpenCLRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenTBAA.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
Anders Carlsson
committed
#include "clang/AST/RecordLayout.h"
Rafael Espindola
committed
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/ConvertUTF.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CallingConv.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Target/Mangler.h"
using namespace clang;
using namespace CodeGen;
Julien Lerouge
committed
static const char AnnotationSection[] = "llvm.metadata";
static CGCXXABI &createCXXABI(CodeGenModule &CGM) {
switch (CGM.getContext().getTargetInfo().getCXXABI()) {
case CXXABI_ARM: return *CreateARMCXXABI(CGM);
case CXXABI_Itanium: return *CreateItaniumCXXABI(CGM);
case CXXABI_Microsoft: return *CreateMicrosoftCXXABI(CGM);
}
llvm_unreachable("invalid C++ ABI kind");
}
Chandler Carruth
committed
CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
llvm::Module &M, const llvm::DataLayout &TD,
DiagnosticsEngine &diags)
David Blaikie
committed
: Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M),
TheDataLayout(TD), TheTargetCodeGenInfo(0), Diags(diags),
ABI(createCXXABI(*this)),
VTables(*this), ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0),
DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0),
RRData(0), CFConstantStringClassRef(0),
ConstantStringClassRef(0), NSConstantStringType(0),
VMContext(M.getContext()),
NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
BlockObjectAssign(0), BlockObjectDispose(0),
BlockDescriptorType(0), GenericBlockLiteralType(0) {
Chris Lattner
committed
// Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext();
VoidTy = llvm::Type::getVoidTy(LLVMContext);
Int8Ty = llvm::Type::getInt8Ty(LLVMContext);
Int16Ty = llvm::Type::getInt16Ty(LLVMContext);
Int32Ty = llvm::Type::getInt32Ty(LLVMContext);
Int64Ty = llvm::Type::getInt64Ty(LLVMContext);
FloatTy = llvm::Type::getFloatTy(LLVMContext);
DoubleTy = llvm::Type::getDoubleTy(LLVMContext);
PointerWidthInBits = C.getTargetInfo().getPointerWidth(0);
PointerAlignInBytes =
C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(0)).getQuantity();
IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
IntPtrTy = llvm::IntegerType::get(LLVMContext, PointerWidthInBits);
Int8PtrTy = Int8Ty->getPointerTo(0);
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
David Blaikie
committed
if (LangOpts.ObjC1)
createObjCRuntime();
David Blaikie
committed
if (LangOpts.OpenCL)
createOpenCLRuntime();
David Blaikie
committed
if (LangOpts.CUDA)
createCUDARuntime();
Kostya Serebryany
committed
// Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
if (LangOpts.SanitizeThread ||
Kostya Serebryany
committed
(!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
Nick Lewycky
committed
// If debug info or coverage generation is enabled, create the CGDebugInfo
// object.
if (CodeGenOpts.getDebugInfo() != CodeGenOptions::NoDebugInfo ||
CodeGenOpts.EmitGcovArcs ||
Nick Lewycky
committed
CodeGenOpts.EmitGcovNotes)
DebugInfo = new CGDebugInfo(*this);
Block.GlobalUniqueCount = 0;
David Blaikie
committed
if (C.getLangOpts().ObjCAutoRefCount)
ARCData = new ARCEntrypoints();
RRData = new RREntrypoints();
}
CodeGenModule::~CodeGenModule() {
delete ObjCRuntime;
delete OpenCLRuntime;
delete CUDARuntime;
Ted Kremenek
committed
delete TheTargetCodeGenInfo;
delete &ABI;
Ted Kremenek
committed
delete DebugInfo;
Ted Kremenek
committed
}
David Chisnall
committed
void CodeGenModule::createObjCRuntime() {
// This is just isGNUFamily(), but we want to force implementors of
// new ABIs to decide how best to do this.
switch (LangOpts.ObjCRuntime.getKind()) {
case ObjCRuntime::GNUstep:
case ObjCRuntime::GCC:
case ObjCRuntime::ObjFW:
ObjCRuntime = CreateGNUObjCRuntime(*this);
return;
case ObjCRuntime::FragileMacOSX:
case ObjCRuntime::MacOSX:
case ObjCRuntime::iOS:
ObjCRuntime = CreateMacObjCRuntime(*this);
return;
}
llvm_unreachable("bad runtime kind");
David Chisnall
committed
}
void CodeGenModule::createOpenCLRuntime() {
OpenCLRuntime = new CGOpenCLRuntime(*this);
}
void CodeGenModule::createCUDARuntime() {
CUDARuntime = CreateNVCUDARuntime(*this);
}
Ted Kremenek
committed
void CodeGenModule::Release() {
EmitDeferred();
Eli Friedman
committed
EmitCXXGlobalInitFunc();
if (ObjCRuntime)
if (llvm::Function *ObjCInitFunction = ObjCRuntime->ModuleInitFunction())
AddGlobalCtor(ObjCInitFunction);
EmitCtorList(GlobalCtors, "llvm.global_ctors");
EmitCtorList(GlobalDtors, "llvm.global_dtors");
Julien Lerouge
committed
EmitGlobalAnnotations();
EmitLLVMUsed();
SimplifyPersonality();
if (getCodeGenOpts().EmitDeclMetadata)
EmitDeclMetadata();
if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes)
EmitCoverageFile();
if (DebugInfo)
DebugInfo->finalize();
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
// Make sure that this type is translated.
Types.UpdateCompletedType(TD);
}
llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) {
if (!TBAA)
return 0;
return TBAA->getTBAAInfo(QTy);
}
llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() {
if (!TBAA)
return 0;
return TBAA->getTBAAInfoForVTablePtr();
}
llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) {
if (!TBAA)
return 0;
return TBAA->getTBAAStructInfo(QTy);
}
void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
llvm::MDNode *TBAAInfo) {
Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
}
bool CodeGenModule::isTargetDarwin() const {
return getContext().getTargetInfo().getTriple().isOSDarwin();
}
void CodeGenModule::Error(SourceLocation loc, StringRef error) {
unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, error);
getDiags().Report(Context.getFullLoc(loc), diagID);
}
/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
bool OmitOnError) {
if (OmitOnError && getDiags().hasErrorOccurred())
return;
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot compile this %0 yet");
std::string Msg = Type;
Chris Lattner
committed
getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
<< Msg << S->getSourceRange();
/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified decl yet.
void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
bool OmitOnError) {
if (OmitOnError && getDiags().hasErrorOccurred())
return;
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot compile this %0 yet");
std::string Msg = Type;
Chris Lattner
committed
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
llvm::ConstantInt *CodeGenModule::getSize(CharUnits size) {
return llvm::ConstantInt::get(SizeTy, size.getQuantity());
}
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
const NamedDecl *D) const {
// Internal definitions always have default visibility.
Chris Lattner
committed
if (GV->hasLocalLinkage()) {
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
// Set visibility for definitions.
NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
if (LV.visibilityExplicit() || !GV->hasAvailableExternallyLinkage())
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
.Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
.Case("local-dynamic", llvm::GlobalVariable::LocalDynamicTLSModel)
.Case("initial-exec", llvm::GlobalVariable::InitialExecTLSModel)
.Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel);
}
static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(
CodeGenOptions::TLSModel M) {
switch (M) {
case CodeGenOptions::GeneralDynamicTLSModel:
return llvm::GlobalVariable::GeneralDynamicTLSModel;
case CodeGenOptions::LocalDynamicTLSModel:
return llvm::GlobalVariable::LocalDynamicTLSModel;
case CodeGenOptions::InitialExecTLSModel:
return llvm::GlobalVariable::InitialExecTLSModel;
case CodeGenOptions::LocalExecTLSModel:
return llvm::GlobalVariable::LocalExecTLSModel;
}
llvm_unreachable("Invalid TLS model!");
}
void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV,
const VarDecl &D) const {
assert(D.isThreadSpecified() && "setting TLS mode on non-TLS var!");
llvm::GlobalVariable::ThreadLocalMode TLM;
TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel());
// Override the TLS model if it is explicitly specified.
if (D.hasAttr<TLSModelAttr>()) {
const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
TLM = GetLLVMTLSModel(Attr->getModel());
}
GV->setThreadLocalMode(TLM);
}
/// Set the symbol visibility of type information (vtable and RTTI)
/// associated with the given type.
void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
const CXXRecordDecl *RD,
Anders Carlsson
committed
TypeVisibilityKind TVK) const {
setGlobalVisibility(GV, RD);
if (!CodeGenOpts.HiddenWeakVTables)
return;
Anders Carlsson
committed
// We never want to drop the visibility for RTTI names.
if (TVK == TVK_ForRTTIName)
return;
// We want to drop the visibility to hidden for weak type symbols.
// This isn't possible if there might be unresolved references
// elsewhere that rely on this symbol being visible.
// This should be kept roughly in sync with setThunkVisibility
// in CGVTables.cpp.
// Preconditions.
if (GV->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage ||
GV->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
return;
// Don't override an explicit visibility attribute.
if (RD->getExplicitVisibility())
return;
switch (RD->getTemplateSpecializationKind()) {
// We have to disable the optimization if this is an EI definition
// because there might be EI declarations in other shared objects.
case TSK_ExplicitInstantiationDefinition:
case TSK_ExplicitInstantiationDeclaration:
return;
// Every use of a non-template class's type information has to emit it.
case TSK_Undeclared:
break;
// In theory, implicit instantiations can ignore the possibility of
// an explicit instantiation declaration because there necessarily
// must be an EI definition somewhere with default visibility. In
// practice, it's possible to have an explicit instantiation for
// an arbitrary template class, and linkers aren't necessarily able
// to deal with mixed-visibility symbols.
case TSK_ExplicitSpecialization:
case TSK_ImplicitInstantiation:
Douglas Gregor
committed
return;
}
// If there's a key function, there may be translation units
// that don't have the key function's definition. But ignore
// this if we're emitting RTTI under -fno-rtti.
David Blaikie
committed
if (!(TVK != TVK_ForRTTI) || LangOpts.RTTI) {
if (Context.getKeyFunction(RD))
return;
Anders Carlsson
committed
}
// Otherwise, drop the visibility to hidden.
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
Rafael Espindola
committed
GV->setUnnamedAddr(true);
Chris Lattner
committed
StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
Chris Lattner
committed
StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()];
if (!Str.empty())
return Str;
if (!getCXXABI().getMangleContext().shouldMangleDeclName(ND)) {
IdentifierInfo *II = ND->getIdentifier();
assert(II && "Attempt to mangle unnamed decl.");
Str = II->getName();
return Str;
}
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out);
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
getCXXABI().getMangleContext().mangleBlock(BD, Out,
dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()));
else
getCXXABI().getMangleContext().mangleName(ND, Out);
// Allocate space for the mangled name.
size_t Length = Buffer.size();
char *Name = MangledNamesAllocator.Allocate<char>(Length);
std::copy(Buffer.begin(), Buffer.end(), Name);
Chris Lattner
committed
Str = StringRef(Name, Length);
return Str;
}
void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
const BlockDecl *BD) {
MangleContext &MangleCtx = getCXXABI().getMangleContext();
const Decl *D = GD.getDecl();
llvm::raw_svector_ostream Out(Buffer.getBuffer());
if (D == 0)
MangleCtx.mangleGlobalBlock(BD,
dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out);
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Out);
MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out);
Chris Lattner
committed
llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) {
return getModule().getNamedValue(Name);
}
Chris Lattner
committed
/// AddGlobalCtor - Add a function to the list that will be called before
/// main() runs.
void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor, int Priority) {
// FIXME: Type coercion of void()* types.
GlobalCtors.push_back(std::make_pair(Ctor, Priority));
Chris Lattner
committed
}
/// AddGlobalDtor - Add a function to the list that will be called
/// when the module is unloaded.
void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) {
// FIXME: Type coercion of void()* types.
GlobalDtors.push_back(std::make_pair(Dtor, Priority));
}
void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
// Ctor function type is void()*.
llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false);
llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
// Get the type of a ctor entry, { i32, void ()* }.
llvm::StructType *CtorStructTy =
Chris Lattner
committed
llvm::StructType::get(Int32Ty, llvm::PointerType::getUnqual(CtorFTy), NULL);
// Construct the constructor and destructor arrays.
SmallVector<llvm::Constant*, 8> Ctors;
for (CtorList::const_iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
llvm::Constant *S[] = {
llvm::ConstantInt::get(Int32Ty, I->second, false),
llvm::ConstantExpr::getBitCast(I->first, CtorPFTy)
};
Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S));
}
if (!Ctors.empty()) {
llvm::ArrayType *AT = llvm::ArrayType::get(CtorStructTy, Ctors.size());
new llvm::GlobalVariable(TheModule, AT, false,
llvm::GlobalValue::AppendingLinkage,
Chris Lattner
committed
}
}
llvm::GlobalValue::LinkageTypes
CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
Argyrios Kyrtzidis
committed
GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
return llvm::Function::InternalLinkage;
return llvm::Function::DLLExportLinkage;
return llvm::Function::WeakAnyLinkage;
// In C99 mode, 'inline' functions are guaranteed to have a strong
// definition somewhere else, so we can use available_externally linkage.
if (Linkage == GVA_C99Inline)
return llvm::Function::AvailableExternallyLinkage;
// Note that Apple's kernel linker doesn't support symbol
// coalescing, so we need to avoid linkonce and weak linkages there.
// Normally, this means we just map to internal, but for explicit
// instantiations we'll map to external.
// In C++, the compiler has to emit a definition in every translation unit
// that references the function. We should use linkonce_odr because
// a) if all references in this translation unit are optimized away, we
// don't need to codegen it. b) if the function persists, it needs to be
// merged with other definitions. c) C++ has the ODR, so we know the
// definition is dependable.
if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
David Blaikie
committed
return !Context.getLangOpts().AppleKext
? llvm::Function::LinkOnceODRLinkage
: llvm::Function::InternalLinkage;
// An explicit instantiation of a template has weak linkage, since
// explicit instantiations can occur in multiple translation units
// and must all be equivalent. However, we are not allowed to
// throw away these explicit instantiations.
if (Linkage == GVA_ExplicitTemplateInstantiation)
David Blaikie
committed
return !Context.getLangOpts().AppleKext
? llvm::Function::WeakODRLinkage
: llvm::Function::ExternalLinkage;
// Otherwise, we have strong external linkage.
assert(Linkage == GVA_StrongExternal);
return llvm::Function::ExternalLinkage;
}
/// SetFunctionDefinitionAttributes - Set attributes for a global.
///
/// FIXME: This is currently only done for aliases and functions, but not for
/// variables (these details are set in EmitGlobalVarDefinition for variables).
void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
llvm::GlobalValue *GV) {
void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
llvm::Function *F) {
Daniel Dunbar
committed
unsigned CallingConv;
Daniel Dunbar
committed
ConstructAttributeList(Info, D, AttributeList, CallingConv);
Bill Wendling
committed
F->setAttributes(llvm::AttributeSet::get(getLLVMContext(), AttributeList));
Daniel Dunbar
committed
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
/// Determines whether the language options require us to model
/// unwind exceptions. We treat -fexceptions as mandating this
/// except under the fragile ObjC ABI with only ObjC exceptions
/// enabled. This means, for example, that C with -fexceptions
/// enables this.
David Blaikie
committed
static bool hasUnwindExceptions(const LangOptions &LangOpts) {
// If exceptions are completely disabled, obviously this is false.
David Blaikie
committed
if (!LangOpts.Exceptions) return false;
// If C++ exceptions are enabled, this is true.
David Blaikie
committed
if (LangOpts.CXXExceptions) return true;
// If ObjC exceptions are enabled, this depends on the ABI.
David Blaikie
committed
if (LangOpts.ObjCExceptions) {
return LangOpts.ObjCRuntime.hasUnwindExceptions();
}
return true;
}
void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
llvm::Function *F) {
if (CodeGenOpts.UnwindTables)
F->setHasUWTable();
David Blaikie
committed
if (!hasUnwindExceptions(LangOpts))
F->addFnAttr(llvm::Attributes::NoUnwind);
Eli Friedman
committed
if (D->hasAttr<NakedAttr>()) {
// Naked implies noinline: we should not be inlining such functions.
F->addFnAttr(llvm::Attributes::Naked);
F->addFnAttr(llvm::Attributes::NoInline);
Eli Friedman
committed
}
F->addFnAttr(llvm::Attributes::NoInline);
Eli Friedman
committed
// (noinline wins over always_inline, and we can't specify both in IR)
if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) &&
Bill Wendling
committed
!F->getFnAttributes().hasAttribute(llvm::Attributes::NoInline))
F->addFnAttr(llvm::Attributes::AlwaysInline);
Eli Friedman
committed
// FIXME: Communicate hot and cold attributes to LLVM more directly.
if (D->hasAttr<ColdAttr>())
F->addFnAttr(llvm::Attributes::OptimizeForSize);
if (D->hasAttr<MinSizeAttr>())
F->addFnAttr(llvm::Attributes::MinSize);
if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
F->setUnnamedAddr(true);
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
if (MD->isVirtual())
F->setUnnamedAddr(true);
David Blaikie
committed
if (LangOpts.getStackProtector() == LangOptions::SSPOn)
F->addFnAttr(llvm::Attributes::StackProtect);
David Blaikie
committed
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
F->addFnAttr(llvm::Attributes::StackProtectReq);
Anders Carlsson
committed
if (LangOpts.SanitizeAddress) {
// When AddressSanitizer is enabled, set AddressSafety attribute
// unless __attribute__((no_address_safety_analysis)) is used.
if (!D->hasAttr<NoAddressSafetyAnalysisAttr>())
F->addFnAttr(llvm::Attributes::AddressSafety);
unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
if (alignment)
F->setAlignment(alignment);
// C++ ABI requires 2-byte alignment for member functions.
if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
F->setAlignment(2);
}
void CodeGenModule::SetCommonAttributes(const Decl *D,
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
setGlobalVisibility(GV, ND);
else
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
Argyrios Kyrtzidis
committed
if (D->hasAttr<UsedAttr>())
Argyrios Kyrtzidis
committed
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
GV->setSection(SA->getName());
getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this);
void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,
llvm::Function *F,
const CGFunctionInfo &FI) {
SetLLVMFunctionAttributes(D, FI, F);
SetLLVMFunctionAttributesForDefinition(D, F);
F->setLinkage(llvm::Function::InternalLinkage);
SetCommonAttributes(D, F);
}
Anders Carlsson
committed
void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
bool IsIncompleteFunction) {
Peter Collingbourne
committed
if (unsigned IID = F->getIntrinsicID()) {
// If this is an intrinsic function, set the function's attributes
// to the intrinsic's attributes.
F->setAttributes(llvm::Intrinsic::getAttributes(getLLVMContext(),
(llvm::Intrinsic::ID)IID));
Peter Collingbourne
committed
return;
}
Anders Carlsson
committed
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
if (!IsIncompleteFunction)
SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F);
// Only a few attributes are set on declarations; these may later be
// overridden by a definition.
Argyrios Kyrtzidis
committed
if (FD->hasAttr<DLLImportAttr>()) {
F->setLinkage(llvm::Function::DLLImportLinkage);
} else if (FD->hasAttr<WeakAttr>() ||
FD->isWeakImported()) {
// "extern_weak" is overloaded in LLVM; we probably should have
F->setLinkage(llvm::Function::ExternalWeakLinkage);
} else {
F->setLinkage(llvm::Function::ExternalLinkage);
NamedDecl::LinkageInfo LV = FD->getLinkageAndVisibility();
if (LV.linkage() == ExternalLinkage && LV.visibilityExplicit()) {
F->setVisibility(GetLLVMVisibility(LV.visibility()));
}
Argyrios Kyrtzidis
committed
if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
F->setSection(SA->getName());
}
void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
"Only globals with definition can force usage.");
Chris Lattner
committed
LLVMUsed.push_back(GV);
}
void CodeGenModule::EmitLLVMUsed() {
// Don't create llvm.used if there is no need.
Chris Lattner
committed
if (LLVMUsed.empty())
return;
Chris Lattner
committed
// Convert LLVMUsed to what ConstantArray needs.
SmallVector<llvm::Constant*, 8> UsedArray;
Chris Lattner
committed
UsedArray.resize(LLVMUsed.size());
for (unsigned i = 0, e = LLVMUsed.size(); i != e; ++i) {
UsedArray[i] =
llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*LLVMUsed[i]),
Chris Lattner
committed
}
if (UsedArray.empty())
return;
llvm::ArrayType *ATy = llvm::ArrayType::get(Int8PtrTy, UsedArray.size());
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(), ATy, false,
llvm::GlobalValue::AppendingLinkage,
GV->setSection("llvm.metadata");
}
void CodeGenModule::EmitDeferred() {
// Emit code for any potentially referenced deferred decls. Since a
// previously unused static decl may become used during the generation of code
// for a static function, iterate until no changes are made.
while (!DeferredDeclsToEmit.empty() || !DeferredVTables.empty()) {
if (!DeferredVTables.empty()) {
const CXXRecordDecl *RD = DeferredVTables.back();
DeferredVTables.pop_back();
getCXXABI().EmitVTables(RD);
continue;
}
Anders Carlsson
committed
GlobalDecl D = DeferredDeclsToEmit.back();
DeferredDeclsToEmit.pop_back();
// Check to see if we've already emitted this. This is necessary
// for a couple of reasons: first, decls can end up in the
// deferred-decls queue multiple times, and second, decls can end
// up with definitions in unusual ways (e.g. by an extern inline
// function acquiring a strong function redefinition). Just
// ignore these cases.
//
// TODO: That said, looking this up multiple times is very wasteful.
Chris Lattner
committed
StringRef Name = getMangledName(D);
llvm::GlobalValue *CGRef = GetGlobalValue(Name);
assert(CGRef && "Deferred decl wasn't referenced?");
if (!CGRef->isDeclaration())
continue;
// GlobalAlias::isDeclaration() defers to the aliasee, but for our
// purposes an alias counts as a definition.
if (isa<llvm::GlobalAlias>(CGRef))
continue;
// Otherwise, emit the definition and move on to the next one.
EmitGlobalDefinition(D);
}
Julien Lerouge
committed
void CodeGenModule::EmitGlobalAnnotations() {
if (Annotations.empty())
return;
// Create a new global variable for the ConstantStruct in the Module.
llvm::Constant *Array = llvm::ConstantArray::get(llvm::ArrayType::get(
Annotations[0]->getType(), Annotations.size()), Annotations);
llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(),
Array->getType(), false, llvm::GlobalValue::AppendingLinkage, Array,
"llvm.global.annotations");
gv->setSection(AnnotationSection);
}
llvm::Constant *CodeGenModule::EmitAnnotationString(llvm::StringRef Str) {
llvm::StringMap<llvm::Constant*>::iterator i = AnnotationStrings.find(Str);
if (i != AnnotationStrings.end())
return i->second;
// Not found yet, create a new global.
llvm::Constant *s = llvm::ConstantDataArray::getString(getLLVMContext(), Str);
Julien Lerouge
committed
llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(), s->getType(),
true, llvm::GlobalValue::PrivateLinkage, s, ".str");
gv->setSection(AnnotationSection);
gv->setUnnamedAddr(true);
AnnotationStrings[Str] = gv;
return gv;
}
llvm::Constant *CodeGenModule::EmitAnnotationUnit(SourceLocation Loc) {
SourceManager &SM = getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
if (PLoc.isValid())
return EmitAnnotationString(PLoc.getFilename());
return EmitAnnotationString(SM.getBufferName(Loc));
}
llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) {
SourceManager &SM = getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(L);
unsigned LineNo = PLoc.isValid() ? PLoc.getLine() :
SM.getExpansionLineNumber(L);
return llvm::ConstantInt::get(Int32Ty, LineNo);
}
llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
Julien Lerouge
committed
SourceLocation L) {
// Get the globals for file name, annotation, and the line number.
llvm::Constant *AnnoGV = EmitAnnotationString(AA->getAnnotation()),
*UnitGV = EmitAnnotationUnit(L),
*LineNoCst = EmitAnnotationLineNo(L);
Julien Lerouge
committed
llvm::ConstantExpr::getBitCast(GV, Int8PtrTy),
llvm::ConstantExpr::getBitCast(AnnoGV, Int8PtrTy),
llvm::ConstantExpr::getBitCast(UnitGV, Int8PtrTy),
LineNoCst
return llvm::ConstantStruct::getAnon(Fields);
Julien Lerouge
committed
void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D,
llvm::GlobalValue *GV) {
assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
// Get the struct elements for these annotations.
for (specific_attr_iterator<AnnotateAttr>
ai = D->specific_attr_begin<AnnotateAttr>(),
ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai)
Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation()));
}
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
Argyrios Kyrtzidis
committed
// Never defer when EmitAllDecls is specified.
David Blaikie
committed
if (LangOpts.EmitAllDecls)
Argyrios Kyrtzidis
committed
return !getContext().DeclMustBeEmitted(Global);
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
llvm::Constant *CodeGenModule::GetAddrOfUuidDescriptor(
const CXXUuidofExpr* E) {
// Sema has verified that IIDSource has a __declspec(uuid()), and that its
// well-formed.
StringRef Uuid;
if (E->isTypeOperand())
Uuid = CXXUuidofExpr::GetUuidAttrOfType(E->getTypeOperand())->getGuid();
else {
// Special case: __uuidof(0) means an all-zero GUID.
Expr *Op = E->getExprOperand();
if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid();
else
Uuid = "00000000-0000-0000-0000-000000000000";
}
std::string Name = "__uuid_" + Uuid.str();
// Look for an existing global.
if (llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name))
return GV;
llvm::Constant *Init = EmitUuidofInitializer(Uuid, E->getType());
assert(Init && "failed to initialize as constant");
// GUIDs are assumed to be 16 bytes, spread over 4-2-2-8 bytes. However, the
// first field is declared as "long", which for many targets is 8 bytes.
// Those architectures are not supported. (With the MS abi, long is always 4
// bytes.)
llvm::Type *GuidType = getTypes().ConvertType(E->getType());
if (Init->getType() != GuidType) {
DiagnosticsEngine &Diags = getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"__uuidof codegen is not supported on this architecture");
Diags.Report(E->getExprLoc(), DiagID) << E->getSourceRange();
Init = llvm::UndefValue::get(GuidType);
}
llvm::GlobalVariable *GV = new llvm::GlobalVariable(getModule(), GuidType,
/*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Init, Name);
GV->setUnnamedAddr(true);
return GV;
}
llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
const AliasAttr *AA = VD->getAttr<AliasAttr>();
assert(AA && "No alias?");
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType());
// See if there is already something with the target's name in the module.
llvm::GlobalValue *Entry = GetGlobalValue(AA->getAliasee());
if (Entry) {
unsigned AS = getContext().getTargetAddressSpace(VD->getType());
return llvm::ConstantExpr::getBitCast(Entry, DeclTy->getPointerTo(AS));
}
llvm::Constant *Aliasee;
if (isa<llvm::FunctionType>(DeclTy))
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy,
GlobalDecl(cast<FunctionDecl>(VD)),
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
F->setLinkage(llvm::Function::ExternalWeakLinkage);
WeakRefReferences.insert(F);
void CodeGenModule::EmitGlobal(GlobalDecl GD) {
const ValueDecl *Global = cast<ValueDecl>(GD.getDecl());
// Weak references don't produce any output by themselves.
if (Global->hasAttr<WeakRefAttr>())
return;
// If this is an alias definition (which otherwise looks like a declaration)
// emit it now.
Argyrios Kyrtzidis
committed
if (Global->hasAttr<AliasAttr>())
return EmitAliasDefinition(GD);
// If this is CUDA, be selective about which declarations we emit.
David Blaikie
committed
if (LangOpts.CUDA) {
if (CodeGenOpts.CUDAIsDevice) {
if (!Global->hasAttr<CUDADeviceAttr>() &&
!Global->hasAttr<CUDAGlobalAttr>() &&
!Global->hasAttr<CUDAConstantAttr>() &&
!Global->hasAttr<CUDASharedAttr>())
return;
} else {
if (!Global->hasAttr<CUDAHostAttr>() && (
Global->hasAttr<CUDADeviceAttr>() ||
Global->hasAttr<CUDAConstantAttr>() ||
Global->hasAttr<CUDASharedAttr>()))
return;
}
}
// Ignore declarations, they will be emitted on their first use.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
// Forward declarations are emitted lazily on first use.
if (!FD->doesThisDeclarationHaveABody()) {
if (!FD->doesDeclarationForceExternallyVisibleDefinition())
return;
const FunctionDecl *InlineDefinition = 0;
FD->getBody(InlineDefinition);
Chris Lattner
committed
StringRef MangledName = getMangledName(GD);
DeferredDecls.erase(MangledName);
EmitGlobalDefinition(InlineDefinition);
}
} else {
const VarDecl *VD = cast<VarDecl>(Global);
assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
if (VD->isThisDeclarationADefinition() != VarDecl::Definition)
Nate Begeman
committed
}
// Defer code generation when possible if this is a static definition, inline
// function etc. These we only want to emit if they are used.
if (!MayDeferGeneration(Global)) {
// Emit the definition if it can't be deferred.
EmitGlobalDefinition(GD);
John McCall
committed
// If we're deferring emission of a C++ variable with an
// initializer, remember the order in which it appeared in the file.
David Blaikie
committed
if (getLangOpts().CPlusPlus && isa<VarDecl>(Global) &&
John McCall
committed
cast<VarDecl>(Global)->hasInit()) {
DelayedCXXInitPosition[Global] = CXXGlobalInits.size();
CXXGlobalInits.push_back(0);
}
// If the value has already been used, add it directly to the
// DeferredDeclsToEmit list.
Chris Lattner
committed
StringRef MangledName = getMangledName(GD);
if (GetGlobalValue(MangledName))
DeferredDeclsToEmit.push_back(GD);
else {
// Otherwise, remember that we saw a deferred decl with this name. The
// first use of the mangled name will cause it to move into
// DeferredDeclsToEmit.
DeferredDecls[MangledName] = GD;
}
Nate Begeman
committed
}
Rafael Espindola
committed
namespace {
struct FunctionIsDirectlyRecursive :
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
const StringRef Name;
const Builtin::Context &BI;
Rafael Espindola
committed
bool Result;
FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) :
Name(N), BI(C), Result(false) {
Rafael Espindola
committed
}
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;