Newer
Older
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.count(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 != llvm::Attribute::None)
F->addFnAttr(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());
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.count(Entry)) {
if (D && !D->hasAttr<WeakAttr>())
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
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
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(
TheTargetData.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.
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
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.
Expr *arrayInit = new (ctx) InitListExpr(ctx, init->getLBraceLoc(),
const_cast<InitListExpr*>(init)->getInits(),
init->getNumInits(),
init->getRBraceLoc());
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);
// Emit global variable debug information.
if (getCodeGenOpts().DebugInfo >= 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
}
/// 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.
llvm::Function *OldFn = dyn_cast<llvm::Function>(Old);
if (OldFn == 0) return;
llvm::Type *NewRetTy = NewFn->getReturnType();
Chris Lattner
committed
SmallVector<llvm::Value*, 4> ArgList;
for (llvm::Value::use_iterator UI = OldFn->use_begin(), E = OldFn->use_end();
Benjamin Kramer
committed
UI != E; ) {
// TODO: Do invokes ever occur in C code? If so, we should handle them too.
Benjamin Kramer
committed
llvm::Value::use_iterator I = UI++; // Increment before the CI is erased.
llvm::CallInst *CI = dyn_cast<llvm::CallInst>(*I);
Gabor Greif
committed
if (!CI) continue; // FIXME: when we allow Invoke, just do CallSite CS(*I)
Benjamin Kramer
committed
if (!CI || !CS.isCallee(I)) continue;
// If the return types don't match exactly, and if the call isn't dead, then
// we can't transform this call.
if (CI->getType() != NewRetTy && !CI->use_empty())
continue;
// Get the attribute list.
llvm::SmallVector<llvm::AttributeWithIndex, 8> AttrVec;
llvm::AttrListPtr AttrList = CI->getAttributes();
// Get any return attributes.
llvm::Attributes RAttrs = AttrList.getRetAttributes();
// Add the return attributes.
if (RAttrs)
AttrVec.push_back(llvm::AttributeWithIndex::get(0, RAttrs));
// If the function was passed too few arguments, don't transform. 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(),
E = NewFn->arg_end(); AI != E; ++AI, ++ArgNo) {
if (CS.arg_size() == ArgNo ||
CS.getArgument(ArgNo)->getType() != AI->getType()) {
DontTransform = true;
break;
}
// Add any parameter attributes.
if (llvm::Attributes PAttrs = AttrList.getParamAttributes(ArgNo + 1))
AttrVec.push_back(llvm::AttributeWithIndex::get(ArgNo + 1, PAttrs));
}
if (DontTransform)
continue;
if (llvm::Attributes FnAttrs = AttrList.getFnAttributes())
AttrVec.push_back(llvm::AttributeWithIndex::get(~0, FnAttrs));
// Okay, we can transform this. Create the new call instruction and copy
// over the required information.
ArgList.append(CS.arg_begin(), CS.arg_begin() + ArgNo);
llvm::CallInst *NewCall = llvm::CallInst::Create(NewFn, ArgList, "", CI);
ArgList.clear();
if (!NewCall->getType()->isVoidTy())
NewCall->takeName(CI);
NewCall->setAttributes(llvm::AttrListPtr::get(AttrVec));
Daniel Dunbar
committed
NewCall->setCallingConv(CI->getCallingConv());
// Finally, remove the old call, replacing any uses with the new one.
if (!CI->use_empty())
CI->replaceAllUsesWith(NewCall);
// Copy debug location attached to CI.
if (!CI->getDebugLoc().isUnknown())
NewCall->setDebugLoc(CI->getDebugLoc());
CI->eraseFromParent();
}
}
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));
// If this is an implementation of a function without a prototype, try to
// replace any existing uses of the function (which may be calls) with uses
// of the new function
if (D->getType()->isFunctionNoProtoType()) {
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>())
AddGlobalAnnotations(D, Fn);
void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
Argyrios Kyrtzidis
committed
const AliasAttr *AA = D->getAttr<AliasAttr>();
assert(AA && "Not an alias?");
Chris Lattner
committed
StringRef MangledName = getMangledName(GD);
// If there is a definition in the module, then it wins over the alias.
// This is dubious, but allow it to be safe. Just ignore the alias.
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (Entry && !Entry->isDeclaration())
return;
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
// Create a reference to the named value. This ensures that it is emitted
// if a deferred decl.
llvm::Constant *Aliasee;
if (isa<llvm::FunctionType>(DeclTy))
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl(),
/*ForVTable=*/false);
else
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
// Create the new alias itself, but don't set a name yet.
new llvm::GlobalAlias(Aliasee->getType(),
llvm::Function::ExternalLinkage,
"", Aliasee, &getModule());
if (Entry) {
assert(Entry->isDeclaration());
// If there is a declaration in the module, then we had an extern followed
// by the alias, as in:
// extern int test6();
// ...
// int test6() __attribute__((alias("test7")));
//
// Remove it and replace uses of it with the alias.
GA->takeName(Entry);
Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
Entry->getType()));
Entry->eraseFromParent();
} else {
GA->setName(MangledName);
// Set attributes which are particular to an alias; this is a
// specialization of the attributes which may be set on a global
// variable/function.
Argyrios Kyrtzidis
committed
if (D->hasAttr<DLLExportAttr>()) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// The dllexport attribute is ignored for undefined symbols.
Argyrios Kyrtzidis
committed
if (FD->hasBody())
GA->setLinkage(llvm::Function::DLLExportLinkage);
} else {
GA->setLinkage(llvm::Function::DLLExportLinkage);
}
} else if (D->hasAttr<WeakAttr>() ||
Rafael Espindola
committed
D->hasAttr<WeakRefAttr>() ||
D->isWeakImported()) {
GA->setLinkage(llvm::Function::WeakAnyLinkage);
}
SetCommonAttributes(D, GA);
}
Benjamin Kramer
committed
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,
Chris Lattner
committed
ArrayRef<llvm::Type*> Tys) {
return llvm::Intrinsic::getDeclaration(&getModule(), (llvm::Intrinsic::ID)IID,
Benjamin Kramer
committed
Tys);
Chris Lattner
committed
static llvm::StringMapEntry<llvm::Constant*> &
GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map,
const StringLiteral *Literal,
bool TargetIsLSB,
bool &IsUTF16,
unsigned &StringLength) {
Chris Lattner
committed
StringRef String = Literal->getString();
Benjamin Kramer
committed
unsigned NumBytes = String.size();
// Check for simple case.
if (!Literal->containsNonAsciiOrNull()) {
StringLength = NumBytes;
Benjamin Kramer
committed
return Map.GetOrCreateValue(String);
}
Bill Wendling
committed
// Otherwise, convert the UTF8 literals into a string of shorts.
IsUTF16 = true;
SmallVector<UTF16, 128> ToBuf(NumBytes + 1); // +1 for ending nulls.
Benjamin Kramer
committed
const UTF8 *FromPtr = (UTF8 *)String.data();
UTF16 *ToPtr = &ToBuf[0];
(void)ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes,
&ToPtr, ToPtr + NumBytes,
strictConversion);
// ConvertUTF8toUTF16 returns the length in ToPtr.
StringLength = ToPtr - &ToBuf[0];
Bill Wendling
committed
// Add an explicit null.
*ToPtr = 0;
return Map.