Newer
Older
Rafael Espindola
committed
bool TraverseCallExpr(CallExpr *E) {
const FunctionDecl *FD = E->getDirectCallee();
if (!FD)
Rafael Espindola
committed
return true;
AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
if (Attr && Name == Attr->getLabel()) {
Result = true;
return false;
}
unsigned BuiltinID = FD->getBuiltinID();
if (!BuiltinID)
Rafael Espindola
committed
return true;
StringRef BuiltinName = BI.GetName(BuiltinID);
if (BuiltinName.startswith("__builtin_") &&
Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) {
Rafael Espindola
committed
Result = true;
return false;
}
return true;
}
};
}
// isTriviallyRecursive - Check if this function calls another
// decl that, because of the asm attribute or the other decl being a builtin,
// ends up pointing to itself.
Rafael Espindola
committed
bool
CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
StringRef Name;
if (getCXXABI().getMangleContext().shouldMangleDeclName(FD)) {
// asm labels are a special kind of mangling we have to support.
AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
if (!Attr)
return false;
Name = Attr->getLabel();
} else {
Name = FD->getName();
}
Rafael Espindola
committed
FunctionIsDirectlyRecursive Walker(Name, Context.BuiltinInfo);
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(FD));
Rafael Espindola
committed
return Walker.Result;
}
bool
CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
return true;
if (CodeGenOpts.OptimizationLevel == 0 &&
!F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>())
Rafael Espindola
committed
return false;
// PR9614. Avoid cases where the source code is lying to us. An available
// externally function should have an equivalent function somewhere else,
// but a function that calls itself is clearly not equivalent to the real
// implementation.
// This happens in glibc's btowc and in some configure checks.
return !isTriviallyRecursive(F);
Rafael Espindola
committed
}
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
PrettyStackTraceDecl CrashInfo(const_cast<ValueDecl *>(D), D->getLocation(),
Context.getSourceManager(),
"Generating code for declaration");
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// At -O0, don't generate IR for functions with available_externally
// linkage.
Rafael Espindola
committed
if (!shouldEmitFunction(Function))
return;
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
Eli Friedman
committed
// Make sure to emit the definition(s) before we emit the thunks.
// This is necessary for the generation of certain thunks.
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method))
EmitCXXConstructor(CD, GD.getCtorType());
else if (const CXXDestructorDecl *DD =dyn_cast<CXXDestructorDecl>(Method))
EmitCXXDestructor(DD, GD.getDtorType());
else
EmitGlobalFunctionDefinition(GD);
if (Method->isVirtual())
getVTables().EmitThunks(GD);
Anders Carlsson
committed
Eli Friedman
committed
return;
}
}
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
return EmitGlobalVarDefinition(VD);
llvm_unreachable("Invalid argument to EmitGlobalDefinition()");
Chris Lattner
committed
/// GetOrCreateLLVMFunction - If the specified mangled name is not in the
/// module, create and return an llvm Function with the specified type. If there
/// is something in the module with the specified name, return it potentially
/// bitcasted to the right type.
///
/// 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 *
Chris Lattner
committed
CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
GlobalDecl D, bool ForVTable,
llvm::Attributes ExtraAttrs) {
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (Entry) {
if (WeakRefReferences.erase(Entry)) {
const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl());
if (FD && !FD->hasAttr<WeakAttr>())
Anders Carlsson
committed
Entry->setLinkage(llvm::Function::ExternalLinkage);
if (Entry->getType()->getElementType() == Ty)
return Entry;
// Make sure the result is of the correct type.
return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo());
// This function doesn't have a complete type (for example, the return
// type is an incomplete struct). Use a fake type instead, and make
// sure not to try to set attributes.
bool IsIncompleteFunction = false;
llvm::FunctionType *FTy;
if (isa<llvm::FunctionType>(Ty)) {
FTy = cast<llvm::FunctionType>(Ty);
} else {
FTy = llvm::FunctionType::get(VoidTy, false);
IsIncompleteFunction = true;
}
llvm::Function *F = llvm::Function::Create(FTy,
llvm::Function::ExternalLinkage,
MangledName, &getModule());
assert(F->getName() == MangledName && "name was uniqued!");
Anders Carlsson
committed
SetFunctionAttributes(D, F, IsIncompleteFunction);
if (ExtraAttrs.hasAttributes())
Bill Wendling
committed
F->addAttribute(llvm::AttributeSet::FunctionIndex, ExtraAttrs);
// 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::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).
DeferredDeclsToEmit.push_back(DDI->second);
DeferredDecls.erase(DDI);
// Otherwise, there are cases we have to worry about where we're
// using a declaration for which we must emit a definition but where
// we might not find a top-level definition:
// - member functions defined inline in their classes
// - friend functions defined inline in some class
// - special member functions with implicit definitions
// If we ever change our AST traversal to walk into class methods,
// this will be unnecessary.
//
// We also don't emit a definition for a function if it's going to be an entry
// in a vtable, unless it's already marked as used.
David Blaikie
committed
} else if (getLangOpts().CPlusPlus && D.getDecl()) {
// Look for a declaration that's lexically in a record.
const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl());
FD = FD->getMostRecentDecl();
do {
if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
if (FD->isImplicit() && !ForVTable) {
assert(FD->isUsed() && "Sema didn't mark implicit function as used!");
DeferredDeclsToEmit.push_back(D.getWithDecl(FD));
break;
} else if (FD->doesThisDeclarationHaveABody()) {
DeferredDeclsToEmit.push_back(D.getWithDecl(FD));
break;
}
Rafael Espindola
committed
}
FD = FD->getPreviousDecl();
} while (FD);
}
// Make sure the result is of the requested type.
if (!IsIncompleteFunction) {
assert(F->getType()->getElementType() == Ty);
return F;
}
llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
return llvm::ConstantExpr::getBitCast(F, PTy);
}
Chris Lattner
committed
/// GetAddrOfFunction - Return the address of the given function. If Ty is
/// non-null, then this function will use the specified type if it has to
/// create it (this occurs when we see a definition of the function).
llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
Chris Lattner
committed
// If there was no specific requested type, just convert it now.
if (!Ty)
Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
Chris Lattner
committed
StringRef MangledName = getMangledName(GD);
return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable);
Chris Lattner
committed
}
Chris Lattner
committed
/// CreateRuntimeFunction - Create a new runtime function with the specified
/// type and name.
llvm::Constant *
CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy,
Chris Lattner
committed
StringRef Name,
llvm::Attributes ExtraAttrs) {
return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
ExtraAttrs);
Chris Lattner
committed
}
/// isTypeConstant - Determine whether an object of this type can be emitted
/// as a constant.
///
/// If ExcludeCtor is true, the duration when the object's constructor runs
/// will not be considered. The caller will need to verify that the object is
/// not written to during its construction.
bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
if (!Ty.isConstant(Context) && !Ty->isReferenceType())
return false;
David Blaikie
committed
if (Context.getLangOpts().CPlusPlus) {
if (const CXXRecordDecl *Record
= Context.getBaseElementType(Ty)->getAsCXXRecordDecl())
return ExcludeCtor && !Record->hasMutableFields() &&
Record->hasTrivialDestructor();
}
return true;
}
Chris Lattner
committed
/// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
/// create and return an llvm GlobalVariable with the specified type. If there
/// is something in the module with the specified name, return it potentially
/// bitcasted to the right type.
///
/// 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 *
Chris Lattner
committed
CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
const VarDecl *D,
bool UnnamedAddr) {
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (WeakRefReferences.erase(Entry)) {
Anders Carlsson
committed
Entry->setLinkage(llvm::Function::ExternalLinkage);
if (UnnamedAddr)
Entry->setUnnamedAddr(true);
Chris Lattner
committed
if (Entry->getType() == Ty)
return Entry;
// Make sure the result is of the correct type.
return llvm::ConstantExpr::getBitCast(Entry, Ty);
// 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::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).
DeferredDeclsToEmit.push_back(DDI->second);
DeferredDecls.erase(DDI);
}
unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
0, MangledName, 0,
llvm::GlobalVariable::NotThreadLocal, AddrSpace);
// Handle things which are present even on external declarations.
Chris Lattner
committed
if (D) {
// FIXME: This code is overly simple and should be merged with other global
// handling.
GV->setConstant(isTypeConstant(D->getType(), false));
// Set linkage and visibility in case we never see a definition.
NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
if (LV.linkage() != ExternalLinkage) {
// Don't set internal linkage on declarations.
} else {
if (D->hasAttr<DLLImportAttr>())
GV->setLinkage(llvm::GlobalValue::DLLImportLinkage);
else if (D->hasAttr<WeakAttr>() || D->isWeakImported())
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
// Set visibility on a declaration only if it's explicit.
if (LV.visibilityExplicit())
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
}
if (D->isThreadSpecified())
setTLSMode(GV, *D);
Chris Lattner
committed
}
if (AddrSpace != Ty->getAddressSpace())
return llvm::ConstantExpr::getBitCast(GV, Ty);
else
return GV;
Chris Lattner
committed
}
Anders Carlsson
committed
llvm::GlobalVariable *
Chris Lattner
committed
CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name,
Anders Carlsson
committed
llvm::GlobalValue::LinkageTypes Linkage) {
llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name);
llvm::GlobalVariable *OldGV = 0;
if (GV) {
// Check if the variable has the right type.
if (GV->getType()->getElementType() == Ty)
return GV;
// Because C++ name mangling, the only way we can end up with an already
// existing global with the same name is if it has been declared extern "C".
assert(GV->isDeclaration() && "Declaration has wrong type!");
Anders Carlsson
committed
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
OldGV = GV;
}
// Create a new variable.
GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
Linkage, 0, Name);
if (OldGV) {
// Replace occurrences of the old variable if needed.
GV->takeName(OldGV);
if (!OldGV->use_empty()) {
llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
OldGV->replaceAllUsesWith(NewPtrForOldDecl);
}
OldGV->eraseFromParent();
}
return GV;
}
Chris Lattner
committed
/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
/// given global variable. If Ty is non-null and if the global doesn't exist,
/// then it will be created with the specified type instead of whatever the
Chris Lattner
committed
/// normal requested type would be.
llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
Chris Lattner
committed
assert(D->hasGlobalStorage() && "Not a global variable");
QualType ASTTy = D->getType();
if (Ty == 0)
Ty = getTypes().ConvertTypeForMem(ASTTy);
llvm::PointerType *PTy =
llvm::PointerType::get(Ty, getContext().getTargetAddressSpace(ASTTy));
Chris Lattner
committed
StringRef MangledName = getMangledName(D);
return GetOrCreateLLVMGlobal(MangledName, PTy, D);
Chris Lattner
committed
}
Chris Lattner
committed
/// CreateRuntimeVariable - Create a new runtime global variable with the
/// specified type and name.
llvm::Constant *
CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty,
Chris Lattner
committed
StringRef Name) {
return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0,
void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
assert(!D->getInit() && "Cannot emit definite definitions here!");
Douglas Gregor
committed
if (MayDeferGeneration(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.
Chris Lattner
committed
StringRef MangledName = getMangledName(D);
if (!GetGlobalValue(MangledName)) {
DeferredDecls[MangledName] = D;
Douglas Gregor
committed
}
}
// The tentative definition is the only definition.
EmitGlobalVarDefinition(D);
}
void CodeGenModule::EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired) {
if (DefinitionRequired)
getCXXABI().EmitVTables(Class);
}
Douglas Gregor
committed
llvm::GlobalVariable::LinkageTypes
CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
Eli Friedman
committed
if (RD->getLinkage() != ExternalLinkage)
return llvm::GlobalVariable::InternalLinkage;
if (const CXXMethodDecl *KeyFunction
= RD->getASTContext().getKeyFunction(RD)) {
// If this class has a key function, use that to determine the linkage of
// the vtable.
Douglas Gregor
committed
const FunctionDecl *Def = 0;
Argyrios Kyrtzidis
committed
if (KeyFunction->hasBody(Def))
Douglas Gregor
committed
KeyFunction = cast<CXXMethodDecl>(Def);
Douglas Gregor
committed
switch (KeyFunction->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
Anders Carlsson
committed
// When compiling with optimizations turned on, we emit all vtables,
// even if the key function is not defined in the current translation
// unit. If this is the case, use available_externally linkage.
if (!Def && CodeGenOpts.OptimizationLevel)
return llvm::GlobalVariable::AvailableExternallyLinkage;
Douglas Gregor
committed
if (KeyFunction->isInlined())
David Blaikie
committed
return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::LinkOnceODRLinkage :
llvm::Function::InternalLinkage;
Douglas Gregor
committed
return llvm::GlobalVariable::ExternalLinkage;
case TSK_ImplicitInstantiation:
David Blaikie
committed
return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::LinkOnceODRLinkage :
llvm::Function::InternalLinkage;
Douglas Gregor
committed
case TSK_ExplicitInstantiationDefinition:
David Blaikie
committed
return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::WeakODRLinkage :
llvm::Function::InternalLinkage;
Douglas Gregor
committed
case TSK_ExplicitInstantiationDeclaration:
// FIXME: Use available_externally linkage. However, this currently
// breaks LLVM's build due to undefined symbols.
// return llvm::GlobalVariable::AvailableExternallyLinkage;
David Blaikie
committed
return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::LinkOnceODRLinkage :
llvm::Function::InternalLinkage;
Douglas Gregor
committed
}
}
David Blaikie
committed
if (Context.getLangOpts().AppleKext)
return llvm::Function::InternalLinkage;
switch (RD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
case TSK_ImplicitInstantiation:
// FIXME: Use available_externally linkage. However, this currently
// breaks LLVM's build due to undefined symbols.
// return llvm::GlobalVariable::AvailableExternallyLinkage;
case TSK_ExplicitInstantiationDeclaration:
return llvm::GlobalVariable::LinkOnceODRLinkage;
case TSK_ExplicitInstantiationDefinition:
return llvm::GlobalVariable::WeakODRLinkage;
Douglas Gregor
committed
}
llvm_unreachable("Invalid TemplateSpecializationKind!");
Douglas Gregor
committed
}
CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
return Context.toCharUnitsFromBits(
TheDataLayout.getTypeStoreSizeInBits(Ty));
}
llvm::Constant *
CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D,
const Expr *rawInit) {
ArrayRef<ExprWithCleanups::CleanupObject> cleanups;
if (const ExprWithCleanups *withCleanups =
dyn_cast<ExprWithCleanups>(rawInit)) {
cleanups = withCleanups->getObjects();
rawInit = withCleanups->getSubExpr();
}
const InitListExpr *init = dyn_cast<InitListExpr>(rawInit);
if (!init || !init->initializesStdInitializerList() ||
init->getNumInits() == 0)
return 0;
ASTContext &ctx = getContext();
unsigned numInits = init->getNumInits();
// FIXME: This check is here because we would otherwise silently miscompile
// nested global std::initializer_lists. Better would be to have a real
// implementation.
for (unsigned i = 0; i < numInits; ++i) {
const InitListExpr *inner = dyn_cast<InitListExpr>(init->getInit(i));
if (inner && inner->initializesStdInitializerList()) {
ErrorUnsupported(inner, "nested global std::initializer_list");
return 0;
}
}
// Synthesize a fake VarDecl for the array and initialize that.
QualType elementType = init->getInit(0)->getType();
llvm::APInt numElements(ctx.getTypeSize(ctx.getSizeType()), numInits);
QualType arrayType = ctx.getConstantArrayType(elementType, numElements,
ArrayType::Normal, 0);
IdentifierInfo *name = &ctx.Idents.get(D->getNameAsString() + "__initlist");
TypeSourceInfo *sourceInfo = ctx.getTrivialTypeSourceInfo(
arrayType, D->getLocation());
VarDecl *backingArray = VarDecl::Create(ctx, const_cast<DeclContext*>(
D->getDeclContext()),
D->getLocStart(), D->getLocation(),
name, arrayType, sourceInfo,
SC_Static, SC_Static);
// Now clone the InitListExpr to initialize the array instead.
// Incredible hack: we want to use the existing InitListExpr here, so we need
// to tell it that it no longer initializes a std::initializer_list.
ArrayRef<Expr*> Inits(const_cast<InitListExpr*>(init)->getInits(),
init->getNumInits());
Expr *arrayInit = new (ctx) InitListExpr(ctx, init->getLBraceLoc(), Inits,
init->getRBraceLoc());
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
arrayInit->setType(arrayType);
if (!cleanups.empty())
arrayInit = ExprWithCleanups::Create(ctx, arrayInit, cleanups);
backingArray->setInit(arrayInit);
// Emit the definition of the array.
EmitGlobalVarDefinition(backingArray);
// Inspect the initializer list to validate it and determine its type.
// FIXME: doing this every time is probably inefficient; caching would be nice
RecordDecl *record = init->getType()->castAs<RecordType>()->getDecl();
RecordDecl::field_iterator field = record->field_begin();
if (field == record->field_end()) {
ErrorUnsupported(D, "weird std::initializer_list");
return 0;
}
QualType elementPtr = ctx.getPointerType(elementType.withConst());
// Start pointer.
if (!ctx.hasSameType(field->getType(), elementPtr)) {
ErrorUnsupported(D, "weird std::initializer_list");
return 0;
}
++field;
if (field == record->field_end()) {
ErrorUnsupported(D, "weird std::initializer_list");
return 0;
}
bool isStartEnd = false;
if (ctx.hasSameType(field->getType(), elementPtr)) {
// End pointer.
isStartEnd = true;
} else if(!ctx.hasSameType(field->getType(), ctx.getSizeType())) {
ErrorUnsupported(D, "weird std::initializer_list");
return 0;
}
// Now build an APValue representing the std::initializer_list.
APValue initListValue(APValue::UninitStruct(), 0, 2);
APValue &startField = initListValue.getStructField(0);
APValue::LValuePathEntry startOffsetPathEntry;
startOffsetPathEntry.ArrayIndex = 0;
startField = APValue(APValue::LValueBase(backingArray),
CharUnits::fromQuantity(0),
llvm::makeArrayRef(startOffsetPathEntry),
/*IsOnePastTheEnd=*/false, 0);
if (isStartEnd) {
APValue &endField = initListValue.getStructField(1);
APValue::LValuePathEntry endOffsetPathEntry;
endOffsetPathEntry.ArrayIndex = numInits;
endField = APValue(APValue::LValueBase(backingArray),
ctx.getTypeSizeInChars(elementType) * numInits,
llvm::makeArrayRef(endOffsetPathEntry),
/*IsOnePastTheEnd=*/true, 0);
} else {
APValue &sizeField = initListValue.getStructField(1);
sizeField = APValue(llvm::APSInt(numElements));
}
// Emit the constant for the initializer_list.
llvm::Constant *llvmInit =
EmitConstantValueForMemory(initListValue, D->getType());
assert(llvmInit && "failed to initialize as constant");
return llvmInit;
}
unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,
unsigned AddrSpace) {
if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) {
if (D->hasAttr<CUDAConstantAttr>())
AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_constant);
else if (D->hasAttr<CUDASharedAttr>())
AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_shared);
else
AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_device);
}
return AddrSpace;
}
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::Constant *Init = 0;
QualType ASTTy = D->getType();
Richard Smith
committed
CXXRecordDecl *RD = ASTTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
bool NeedsGlobalCtor = false;
bool NeedsGlobalDtor = RD && !RD->hasTrivialDestructor();
const VarDecl *InitDecl;
const Expr *InitExpr = D->getAnyInitializer(InitDecl);
if (!InitExpr) {
// This is a tentative definition; tentative definitions are
// implicitly initialized with { 0 }.
//
// Note that tentative definitions are only emitted at the end of
// a translation unit, so they should never have incomplete
// type. In addition, EmitTentativeDefinition makes sure that we
// never attempt to emit a tentative definition if a real one
// exists. A use may still exists, however, so we still may need
// to do a RAUW.
assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");
Init = EmitNullConstant(D->getType());
} else {
// If this is a std::initializer_list, emit the special initializer.
Init = MaybeEmitGlobalStdInitializerListInitializer(D, InitExpr);
// An empty init list will perform zero-initialization, which happens
// to be exactly what we want.
// FIXME: It does so in a global constructor, which is *not* what we
// want.
if (!Init) {
initializedGlobalDecl = GlobalDecl(D);
Init = EmitConstantInit(*InitDecl);
if (!Init) {
QualType T = InitExpr->getType();
if (D->getType()->isReferenceType())
T = D->getType();
David Blaikie
committed
if (getLangOpts().CPlusPlus) {
Richard Smith
committed
NeedsGlobalCtor = true;
} else {
ErrorUnsupported(D, "static initializer");
Init = llvm::UndefValue::get(getTypes().ConvertType(T));
}
John McCall
committed
} else {
// We don't need an initializer, so remove the entry for the delayed
Richard Smith
committed
// initializer position (just in case this entry was delayed) if we
// also don't need to register a destructor.
David Blaikie
committed
if (getLangOpts().CPlusPlus && !NeedsGlobalDtor)
John McCall
committed
DelayedCXXInitPosition.erase(D);
llvm::Type* InitType = Init->getType();
llvm::Constant *Entry = GetAddrOfGlobalVar(D, InitType);
// Strip off a bitcast if we got one back.
if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
assert(CE->getOpcode() == llvm::Instruction::BitCast ||
// all zero index gep.
CE->getOpcode() == llvm::Instruction::GetElementPtr);
Entry = CE->getOperand(0);
}
// Entry is now either a Function or GlobalVariable.
llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Entry);
// We have a definition after a declaration with the wrong type.
// We must make a new GlobalVariable* and update everything that used OldGV
// (a declaration or tentative definition) with the new GlobalVariable*
// (which will be a definition).
//
// This happens if there is a prototype for a global (e.g.
// "extern int x[];") and then a definition of a different type (e.g.
// "int x[10];"). This also happens when an initializer has a different type
// from the type of the global (this happens with unions).
if (GV == 0 ||
GV->getType()->getElementType() != InitType ||
GV->getType()->getAddressSpace() !=
GetGlobalVarAddressSpace(D, getContext().getTargetAddressSpace(ASTTy))) {
// Move the old entry aside so that we'll create a new one.
Chris Lattner
committed
Entry->setName(StringRef());
// Make a new global with the correct type, this is now guaranteed to work.
GV = cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, InitType));
// Replace all uses of the old global with the new global
llvm::ConstantExpr::getBitCast(GV, Entry->getType());
Entry->replaceAllUsesWith(NewPtrForOldDecl);
// Erase the old global, since it is no longer used.
cast<llvm::GlobalValue>(Entry)->eraseFromParent();
Julien Lerouge
committed
if (D->hasAttr<AnnotateAttr>())
AddGlobalAnnotations(D, GV);
Chris Lattner
committed
GV->setInitializer(Init);
// If it is safe to mark the global 'constant', do so now.
GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
isTypeConstant(D->getType(), true));
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
Chris Lattner
committed
// Set the llvm linkage type as appropriate.
llvm::GlobalValue::LinkageTypes Linkage =
GetLLVMLinkageVarDefinition(D, GV);
GV->setLinkage(Linkage);
if (Linkage == llvm::GlobalVariable::CommonLinkage)
// common vars aren't constant even if declared const.
GV->setConstant(false);
SetCommonAttributes(D, GV);
// Emit the initializer function if necessary.
Richard Smith
committed
if (NeedsGlobalCtor || NeedsGlobalDtor)
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
Kostya Serebryany
committed
// If we are compiling with ASan, add metadata indicating dynamically
// initialized globals.
if (LangOpts.SanitizeAddress && NeedsGlobalCtor) {
Kostya Serebryany
committed
llvm::Module &M = getModule();
llvm::NamedMDNode *DynamicInitializers =
M.getOrInsertNamedMetadata("llvm.asan.dynamically_initialized_globals");
llvm::Value *GlobalToAdd[] = { GV };
llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalToAdd);
DynamicInitializers->addOperand(ThisGlobal);
}
// Emit global variable debug information.
if (getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo)
DI->EmitGlobalVariable(GV, D);
}
llvm::GlobalValue::LinkageTypes
CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,
llvm::GlobalVariable *GV) {
Argyrios Kyrtzidis
committed
GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
return llvm::Function::InternalLinkage;
Argyrios Kyrtzidis
committed
else if (D->hasAttr<DLLImportAttr>())
return llvm::Function::DLLImportLinkage;
Argyrios Kyrtzidis
committed
else if (D->hasAttr<DLLExportAttr>())
return llvm::Function::DLLExportLinkage;
else if (D->hasAttr<WeakAttr>()) {
if (GV->isConstant())
return llvm::GlobalVariable::WeakODRLinkage;
return llvm::GlobalVariable::WeakAnyLinkage;
} else if (Linkage == GVA_TemplateInstantiation ||
Linkage == GVA_ExplicitTemplateInstantiation)
return llvm::GlobalVariable::WeakODRLinkage;
David Blaikie
committed
else if (!getLangOpts().CPlusPlus &&
((!CodeGenOpts.NoCommon && !D->getAttr<NoCommonAttr>()) ||
D->getAttr<CommonAttr>()) &&
!D->hasExternalStorage() && !D->getInit() &&
!D->getAttr<SectionAttr>() && !D->isThreadSpecified() &&
!D->getAttr<WeakImportAttr>()) {
// Thread local vars aren't considered common linkage.
return llvm::GlobalVariable::CommonLinkage;
}
return llvm::GlobalVariable::ExternalLinkage;
Chris Lattner
committed
}
/// Replace the uses of a function that was declared with a non-proto type.
/// We want to silently drop extra arguments from call sites
static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
llvm::Function *newFn) {
// Fast path.
if (old->use_empty()) return;
llvm::Type *newRetTy = newFn->getReturnType();
SmallVector<llvm::Value*, 4> newArgs;
for (llvm::Value::use_iterator ui = old->use_begin(), ue = old->use_end();
ui != ue; ) {
llvm::Value::use_iterator use = ui++; // Increment before the use is erased.
llvm::User *user = *use;
// Recognize and replace uses of bitcasts. Most calls to
// unprototyped functions will use bitcasts.
if (llvm::ConstantExpr *bitcast = dyn_cast<llvm::ConstantExpr>(user)) {
if (bitcast->getOpcode() == llvm::Instruction::BitCast)
replaceUsesOfNonProtoConstant(bitcast, newFn);
continue;
}
// Recognize calls to the function.
llvm::CallSite callSite(user);
if (!callSite) continue;
if (!callSite.isCallee(use)) continue;
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
// If the return types don't match exactly, then we can't
// transform this call unless it's dead.
if (callSite->getType() != newRetTy && !callSite->use_empty())
continue;
// Get the call site's attribute list.
llvm::SmallVector<llvm::AttributeWithIndex, 8> newAttrs;
llvm::AttributeSet oldAttrs = callSite.getAttributes();
// Collect any return attributes from the call.
llvm::Attributes returnAttrs = oldAttrs.getRetAttributes();
if (returnAttrs.hasAttributes())
newAttrs.push_back(llvm::AttributeWithIndex::get(
llvm::AttributeSet::ReturnIndex, returnAttrs));
// If the function was passed too few arguments, don't transform.
unsigned newNumArgs = newFn->arg_size();
if (callSite.arg_size() < newNumArgs) continue;
// If extra arguments were passed, we silently drop them.
// If any of the types mismatch, we don't transform.
unsigned argNo = 0;
bool dontTransform = false;
for (llvm::Function::arg_iterator ai = newFn->arg_begin(),
ae = newFn->arg_end(); ai != ae; ++ai, ++argNo) {
if (callSite.getArgument(argNo)->getType() != ai->getType()) {
dontTransform = true;
break;
}
// Add any parameter attributes.
llvm::Attributes pAttrs = oldAttrs.getParamAttributes(argNo + 1);
if (pAttrs.hasAttributes())
newAttrs.push_back(llvm::AttributeWithIndex::get(argNo + 1, pAttrs));
if (dontTransform)
continue;
llvm::Attributes fnAttrs = oldAttrs.getFnAttributes();
if (fnAttrs.hasAttributes())
newAttrs.push_back(llvm::
Bill Wendling
committed
AttributeWithIndex::get(llvm::AttributeSet::FunctionIndex,
fnAttrs));
// Okay, we can transform this. Create the new call instruction and copy
// over the required information.
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
newArgs.append(callSite.arg_begin(), callSite.arg_begin() + argNo);
llvm::CallSite newCall;
if (callSite.isCall()) {
newCall = llvm::CallInst::Create(newFn, newArgs, "",
callSite.getInstruction());
} else {
llvm::InvokeInst *oldInvoke =
cast<llvm::InvokeInst>(callSite.getInstruction());
newCall = llvm::InvokeInst::Create(newFn,
oldInvoke->getNormalDest(),
oldInvoke->getUnwindDest(),
newArgs, "",
callSite.getInstruction());
}
newArgs.clear(); // for the next iteration
if (!newCall->getType()->isVoidTy())
newCall->takeName(callSite.getInstruction());
newCall.setAttributes(
llvm::AttributeSet::get(newFn->getContext(), newAttrs));
newCall.setCallingConv(callSite.getCallingConv());
// Finally, remove the old call, replacing any uses with the new one.
if (!callSite->use_empty())
callSite->replaceAllUsesWith(newCall.getInstruction());
// Copy debug location attached to CI.
if (!callSite->getDebugLoc().isUnknown())
newCall->setDebugLoc(callSite->getDebugLoc());
callSite->eraseFromParent();
}
}
/// ReplaceUsesOfNonProtoTypeWithRealFunction - This function is called when we
/// implement a function with no prototype, e.g. "int foo() {}". If there are
/// existing call uses of the old function in the module, this adjusts them to
/// call the new function directly.
///
/// This is not just a cleanup: the always_inline pass requires direct calls to
/// functions to be able to inline them. If there is a bitcast in the way, it
/// won't inline them. Instcombine normally deletes these calls, but it isn't
/// run at -O0.
static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
llvm::Function *NewFn) {
// If we're redefining a global as a function, don't transform it.
if (!isa<llvm::Function>(Old)) return;
replaceUsesOfNonProtoConstant(Old, NewFn);
}
void CodeGenModule::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
TemplateSpecializationKind TSK = VD->getTemplateSpecializationKind();
// If we have a definition, this might be a deferred decl. If the
// instantiation is explicit, make sure we emit it at the end.
if (VD->getDefinition() && TSK == TSK_ExplicitInstantiationDefinition)
GetAddrOfGlobalVar(VD);
Rafael Espindola
committed
}
void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
// Compute the function info and LLVM type.
const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
// Get or create the prototype for the function.
llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
// Strip off a bitcast if we got one back.
if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
assert(CE->getOpcode() == llvm::Instruction::BitCast);
Entry = CE->getOperand(0);
}
if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != Ty) {
llvm::GlobalValue *OldFn = cast<llvm::GlobalValue>(Entry);
// If the types mismatch then we have to rewrite the definition.
assert(OldFn->isDeclaration() &&
"Shouldn't replace non-declaration");
// F is the Function* for the one with the wrong type, we must make a new
// Function* and update everything that used F (a declaration) with the new
// Function* (which will be a definition).
//
// 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)"). Move the old function aside so that it
// doesn't interfere with GetAddrOfFunction.
Chris Lattner
committed
OldFn->setName(StringRef());
llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
// This might be an implementation of a function without a
// prototype, in which case, try to do special replacement of
// calls which match the new prototype. The really key thing here
// is that we also potentially drop arguments from the call site
// so as to make a direct call, which makes the inliner happier
// and suppresses a number of optimizer warnings (!) about
// dropping arguments.
if (!OldFn->use_empty()) {
ReplaceUsesOfNonProtoTypeWithRealFunction(OldFn, NewFn);
OldFn->removeDeadConstantUsers();
}
// Replace uses of F with the Function we will endow with a body.
if (!Entry->use_empty()) {
llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
Entry->replaceAllUsesWith(NewPtrForOldDecl);
}
// Ok, delete the old function now, which is dead.
OldFn->eraseFromParent();
Entry = NewFn;
// We need to set linkage and visibility on the function before
// generating code for it because various parts of IR generation
// want to propagate this information down (e.g. to local static
// declarations).
llvm::Function *Fn = cast<llvm::Function>(Entry);
setFunctionLinkage(D, Fn);
// FIXME: this is redundant with part of SetFunctionDefinitionAttributes
setGlobalVisibility(Fn, D);
CodeGenFunction(*this).GenerateCode(D, Fn, FI);
SetFunctionDefinitionAttributes(D, Fn);
SetLLVMFunctionAttributesForDefinition(D, Fn);
Argyrios Kyrtzidis
committed
if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
AddGlobalCtor(Fn, CA->getPriority());
Argyrios Kyrtzidis
committed
if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
AddGlobalDtor(Fn, DA->getPriority());
Julien Lerouge
committed
if (D->hasAttr<AnnotateAttr>())