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 "CodeGenFunction.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
Nate Begeman
committed
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
Chris Lattner
committed
#include "llvm/Module.h"
#include "llvm/Intrinsics.h"
Christopher Lamb
committed
#include <algorithm>
using namespace clang;
using namespace CodeGen;
CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
llvm::Module &M, const llvm::TargetData &TD,
Diagnostic &diags)
: Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
Types(C, M, TD), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
//TODO: Make this selectable at runtime
Runtime = CreateObjCRuntime(M,
getTypes().ConvertType(getContext().IntTy),
getTypes().ConvertType(getContext().LongTy));
}
CodeGenModule::~CodeGenModule() {
llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction();
if (ObjCInitFunction)
AddGlobalCtor(ObjCInitFunction);
Chris Lattner
committed
EmitGlobalCtors();
EmitAnnotations();
delete Runtime;
}
/// WarnUnsupported - Print out a warning that codegen doesn't support the
/// specified stmt yet.
void CodeGenModule::WarnUnsupported(const Stmt *S, const char *Type) {
unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
"cannot codegen this %0 yet");
SourceRange Range = S->getSourceRange();
std::string Msg = Type;
getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID,
&Msg, 1, &Range, 1);
/// WarnUnsupported - Print out a warning that codegen doesn't support the
/// specified decl yet.
void CodeGenModule::WarnUnsupported(const Decl *D, const char *Type) {
unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
"cannot codegen this %0 yet");
std::string Msg = Type;
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID,
&Msg, 1);
}
Chris Lattner
committed
/// AddGlobalCtor - Add a function to the list that will be called before
/// main() runs.
void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor) {
// TODO: Type coercion of void()* types.
GlobalCtors.push_back(Ctor);
}
/// EmitGlobalCtors - Generates the array of contsturctor functions to be
/// called on module load, if any have been registered with AddGlobalCtor.
Chris Lattner
committed
void CodeGenModule::EmitGlobalCtors() {
if (GlobalCtors.empty()) return;
Chris Lattner
committed
// Get the type of @llvm.global_ctors
std::vector<const llvm::Type*> CtorFields;
CtorFields.push_back(llvm::IntegerType::get(32));
// Constructor function type
std::vector<const llvm::Type*> VoidArgs;
llvm::FunctionType* CtorFuncTy =
llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false);
Chris Lattner
committed
// i32, function type pair
const llvm::Type *FPType = llvm::PointerType::getUnqual(CtorFuncTy);
llvm::StructType* CtorStructTy =
llvm::StructType::get(llvm::Type::Int32Ty, FPType, NULL);
Chris Lattner
committed
// Array of fields
llvm::ArrayType* GlobalCtorsTy =
llvm::ArrayType::get(CtorStructTy, GlobalCtors.size());
Chris Lattner
committed
// Define the global variable
llvm::GlobalVariable *GlobalCtorsVal =
new llvm::GlobalVariable(GlobalCtorsTy, false,
llvm::GlobalValue::AppendingLinkage,
(llvm::Constant*)0, "llvm.global_ctors",
&TheModule);
Chris Lattner
committed
// Populate the array
std::vector<llvm::Constant*> CtorValues;
llvm::Constant *MagicNumber =
llvm::ConstantInt::get(llvm::Type::Int32Ty, 65535, false);
std::vector<llvm::Constant*> StructValues;
Chris Lattner
committed
for (std::vector<llvm::Constant*>::iterator I = GlobalCtors.begin(),
E = GlobalCtors.end(); I != E; ++I) {
StructValues.clear();
Chris Lattner
committed
StructValues.push_back(MagicNumber);
StructValues.push_back(*I);
CtorValues.push_back(llvm::ConstantStruct::get(CtorStructTy, StructValues));
Chris Lattner
committed
}
GlobalCtorsVal->setInitializer(llvm::ConstantArray::get(GlobalCtorsTy,
CtorValues));
Chris Lattner
committed
}
void CodeGenModule::EmitAnnotations() {
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(Array->getType(), false,
llvm::GlobalValue::AppendingLinkage, Array,
"llvm.global.annotations", &TheModule);
gv->setSection("llvm.metadata");
}
/// ReplaceMapValuesWith - This is a really slow and bad function that
/// searches for any entries in GlobalDeclMap that point to OldVal, changing
/// them to point to NewVal. This is badbadbad, FIXME!
void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal,
llvm::Constant *NewVal) {
for (llvm::DenseMap<const Decl*, llvm::Constant*>::iterator
I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I)
if (I->second == OldVal) I->second = NewVal;
}
Chris Lattner
committed
llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
bool isDefinition) {
// See if it is already in the map. If so, just return it.
llvm::Constant *&Entry = GlobalDeclMap[D];
if (Entry) return Entry;
Chris Lattner
committed
const llvm::Type *Ty = getTypes().ConvertType(D->getType());
// Check to see if the function already exists.
llvm::Function *F = getModule().getFunction(D->getName());
const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
// If it doesn't already exist, just create and return an entry.
if (F == 0) {
// FIXME: param attributes for sext/zext etc.
F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage, D->getName(),
Nate Begeman
committed
&getModule());
// Set the appropriate calling convention for the Function.
if (D->getAttr<FastCallAttr>())
F->setCallingConv(llvm::CallingConv::Fast);
return Entry = F;
}
Chris Lattner
committed
// If the pointer type matches, just return it.
llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty);
Chris Lattner
committed
if (PFTy == F->getType()) return Entry = F;
Chris Lattner
committed
// If this isn't a definition, just return it casted to the right type.
if (!isDefinition)
return Entry = llvm::ConstantExpr::getBitCast(F, PFTy);
// Otherwise, we have a definition after a prototype with the wrong type.
// 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)"). Start by
// making a new function of the correct type, RAUW, then steal the name.
llvm::Function *NewFn = llvm::Function::Create(FTy,
Chris Lattner
committed
llvm::Function::ExternalLinkage,
"", &getModule());
NewFn->takeName(F);
// Replace uses of F with the Function we will endow with a body.
llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(NewFn, F->getType());
F->replaceAllUsesWith(NewPtrForOldDecl);
// FIXME: Update the globaldeclmap for the previous decl of this name. We
// really want a way to walk all of these, but we don't have it yet. This
// is incredibly slow!
ReplaceMapValuesWith(F, NewPtrForOldDecl);
// Ok, delete the old function now, which is dead.
assert(F->isDeclaration() && "Shouldn't replace non-declaration");
F->eraseFromParent();
// Return the new function which has the right type.
return Entry = NewFn;
}
static bool IsZeroElementArray(const llvm::Type *Ty) {
if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(Ty))
return ATy->getNumElements() == 0;
return false;
}
llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
bool isDefinition) {
assert(D->hasGlobalStorage() && "Not a global variable");
Chris Lattner
committed
// See if it is already in the map.
llvm::Constant *&Entry = GlobalDeclMap[D];
if (Entry) return Entry;
Christopher Lamb
committed
QualType ASTTy = D->getType();
const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
Chris Lattner
committed
// Check to see if the global already exists.
llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true);
Chris Lattner
committed
// If it doesn't already exist, just create and return an entry.
if (GV == 0) {
return Entry = new llvm::GlobalVariable(Ty, false,
llvm::GlobalValue::ExternalLinkage,
Christopher Lamb
committed
0, D->getName(), &getModule(), 0,
ASTTy.getAddressSpace());
Chris Lattner
committed
// If the pointer type matches, just return it.
llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
Chris Lattner
committed
if (PTy == GV->getType()) return Entry = GV;
// If this isn't a definition, just return it casted to the right type.
if (!isDefinition)
return Entry = llvm::ConstantExpr::getBitCast(GV, PTy);
// Otherwise, we have a definition after a prototype with the wrong type.
// GV is the GlobalVariable* for the one with the wrong type, we must make a
/// new GlobalVariable* and update everything that used GV (a declaration)
// 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];"). Start by
// making a new global of the correct type, RAUW, then steal the name.
llvm::GlobalVariable *NewGV =
new llvm::GlobalVariable(Ty, false, llvm::GlobalValue::ExternalLinkage,
Christopher Lamb
committed
0, D->getName(), &getModule(), 0,
ASTTy.getAddressSpace());
Chris Lattner
committed
NewGV->takeName(GV);
// Replace uses of GV with the globalvalue we will endow with a body.
llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(NewGV, GV->getType());
GV->replaceAllUsesWith(NewPtrForOldDecl);
// FIXME: Update the globaldeclmap for the previous decl of this name. We
// really want a way to walk all of these, but we don't have it yet. This
// is incredibly slow!
ReplaceMapValuesWith(GV, NewPtrForOldDecl);
// Verify that GV was a declaration or something like x[] which turns into
// [0 x type].
assert((GV->isDeclaration() ||
IsZeroElementArray(GV->getType()->getElementType())) &&
"Shouldn't replace non-declaration");
Chris Lattner
committed
// Ok, delete the old global now, which is dead.
GV->eraseFromParent();
// Return the new global which has the right type.
return Entry = NewGV;
}
Chris Lattner
committed
void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
// If this is not a prototype, emit the body.
if (OMD->getBody())
CodeGenFunction(*this).GenerateObjCMethod(OMD);
}
Chris Lattner
committed
void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
// If this is not a prototype, emit the body.
if (FD->getBody())
CodeGenFunction(*this).GenerateCode(FD);
llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
return EmitConstantExpr(Expr);
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
/// annotation information for a given GlobalValue. The annotation struct is
/// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
/// GlobalValue being annotated. The second filed is thee constant string
/// created from the AnnotateAttr's annotation. The third field is a constant
/// string containing the name of the translation unit. The fourth field is
/// the line number in the file of the annotated value declaration.
///
/// FIXME: this does not unique the annotation string constants, as llvm-gcc
/// appears to.
///
llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
const AnnotateAttr *AA,
unsigned LineNo) {
llvm::Module *M = &getModule();
// get [N x i8] constants for the annotation string, and the filename string
// which are the 2nd and 3rd elements of the global annotation structure.
const llvm::Type *SBP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
llvm::Constant *anno = llvm::ConstantArray::get(AA->getAnnotation(), true);
llvm::Constant *unit = llvm::ConstantArray::get(M->getModuleIdentifier(),
true);
// Get the two global values corresponding to the ConstantArrays we just
// created to hold the bytes of the strings.
llvm::GlobalValue *annoGV =
new llvm::GlobalVariable(anno->getType(), false,
llvm::GlobalValue::InternalLinkage, anno,
GV->getName() + ".str", M);
// translation unit name string, emitted into the llvm.metadata section.
llvm::GlobalValue *unitGV =
new llvm::GlobalVariable(unit->getType(), false,
llvm::GlobalValue::InternalLinkage, unit, ".str", M);
// Create the ConstantStruct that is the global annotion.
llvm::Constant *Fields[4] = {
llvm::ConstantExpr::getBitCast(GV, SBP),
llvm::ConstantExpr::getBitCast(annoGV, SBP),
llvm::ConstantExpr::getBitCast(unitGV, SBP),
llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo)
};
return llvm::ConstantStruct::get(Fields, 4, false);
}
void CodeGenModule::EmitGlobalVar(const VarDecl *D) {
Chris Lattner
committed
// If this is just a forward declaration of the variable, don't emit it now,
// allow it to be emitted lazily on its first use.
Chris Lattner
committed
if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
return;
Chris Lattner
committed
// Get the global, forcing it to be a direct reference.
llvm::GlobalVariable *GV =
cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, true));
Chris Lattner
committed
// Convert the initializer, or use zero if appropriate.
llvm::Constant *Init = 0;
if (D->getInit() == 0) {
Chris Lattner
committed
Init = llvm::Constant::getNullValue(GV->getType()->getElementType());
} else if (D->getType()->isIntegerType()) {
getContext().getTypeSize(D->getInit()->getType())));
if (D->getInit()->isIntegerConstantExpr(Value, Context))
Init = llvm::ConstantInt::get(Value);
}
Init = EmitGlobalInit(D->getInit());
if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
SourceManager &SM = Context.getSourceManager();
AddAnnotation(EmitAnnotateAttr(GV, AA,
SM.getLogicalLineNumber(D->getLocation())));
}
Chris Lattner
committed
assert(GV->getType()->getElementType() == Init->getType() &&
"Initializer codegen type mismatch!");
Chris Lattner
committed
GV->setInitializer(Init);
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
GV->setVisibility(attr->getVisibility());
// FIXME: else handle -fvisibility
Chris Lattner
committed
// Set the llvm linkage type as appropriate.
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
if (D->getAttr<DLLImportAttr>())
GV->setLinkage(llvm::Function::DLLImportLinkage);
else if (D->getAttr<DLLExportAttr>())
GV->setLinkage(llvm::Function::DLLExportLinkage);
else if (D->getAttr<WeakAttr>()) {
GV->setLinkage(llvm::GlobalVariable::WeakLinkage);
} else {
// FIXME: This isn't right. This should handle common linkage and other
// stuff.
switch (D->getStorageClass()) {
case VarDecl::Auto:
case VarDecl::Register:
assert(0 && "Can't have auto or register globals");
case VarDecl::None:
if (!D->getInit())
GV->setLinkage(llvm::GlobalVariable::WeakLinkage);
break;
case VarDecl::Extern:
case VarDecl::PrivateExtern:
// todo: common
break;
case VarDecl::Static:
GV->setLinkage(llvm::GlobalVariable::InternalLinkage);
break;
}
Chris Lattner
committed
}
}
/// EmitGlobalVarDeclarator - Emit all the global vars attached to the specified
/// declarator chain.
void CodeGenModule::EmitGlobalVarDeclarator(const VarDecl *D) {
for (; D; D = cast_or_null<VarDecl>(D->getNextDeclarator()))
if (D->isFileVarDecl())
EmitGlobalVar(D);
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
// Make sure that this type is translated.
Types.UpdateCompletedType(TD);
}
Chris Lattner
committed
/// getBuiltinLibFunction
llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
if (BuiltinID > BuiltinFunctions.size())
BuiltinFunctions.resize(BuiltinID);
Chris Lattner
committed
// Cache looked up functions. Since builtin id #0 is invalid we don't reserve
// a slot for it.
assert(BuiltinID && "Invalid Builtin ID");
llvm::Function *&FunctionSlot = BuiltinFunctions[BuiltinID-1];
Chris Lattner
committed
if (FunctionSlot)
return FunctionSlot;
assert(Context.BuiltinInfo.isLibFunction(BuiltinID) && "isn't a lib fn");
// Get the name, skip over the __builtin_ prefix.
const char *Name = Context.BuiltinInfo.GetName(BuiltinID)+10;
// Get the type for the builtin.
QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context);
const llvm::FunctionType *Ty =
cast<llvm::FunctionType>(getTypes().ConvertType(Type));
// FIXME: This has a serious problem with code like this:
// void abs() {}
// ... __builtin_abs(x);
// The two versions of abs will collide. The fix is for the builtin to win,
// and for the existing one to be turned into a constantexpr cast of the
// builtin. In the case where the existing one is a static function, it
// should just be renamed.
Chris Lattner
committed
if (llvm::Function *Existing = getModule().getFunction(Name)) {
if (Existing->getFunctionType() == Ty && Existing->hasExternalLinkage())
return FunctionSlot = Existing;
assert(Existing == 0 && "FIXME: Name collision");
}
Chris Lattner
committed
// FIXME: param attributes for sext/zext etc.
return FunctionSlot = llvm::Function::Create(Ty, llvm::Function::ExternalLinkage,
Chris Lattner
committed
Name, &getModule());
}
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
unsigned NumTys) {
return llvm::Intrinsic::getDeclaration(&getModule(),
(llvm::Intrinsic::ID)IID, Tys, NumTys);
}
Chris Lattner
committed
llvm::Function *CodeGenModule::getMemCpyFn() {
if (MemCpyFn) return MemCpyFn;
llvm::Intrinsic::ID IID;
switch (Context.Target.getPointerWidth(0)) {
default: assert(0 && "Unknown ptr width");
case 32: IID = llvm::Intrinsic::memcpy_i32; break;
case 64: IID = llvm::Intrinsic::memcpy_i64; break;
}
return MemCpyFn = getIntrinsic(IID);
llvm::Function *CodeGenModule::getMemSetFn() {
if (MemSetFn) return MemSetFn;
llvm::Intrinsic::ID IID;
switch (Context.Target.getPointerWidth(0)) {
default: assert(0 && "Unknown ptr width");
case 32: IID = llvm::Intrinsic::memset_i32; break;
case 64: IID = llvm::Intrinsic::memset_i64; break;
}
return MemSetFn = getIntrinsic(IID);
}
Chris Lattner
committed
llvm::Constant *CodeGenModule::
GetAddrOfConstantCFString(const std::string &str) {
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
llvm::StringMapEntry<llvm::Constant *> &Entry =
CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
if (Entry.getValue())
return Entry.getValue();
std::vector<llvm::Constant*> Fields;
if (!CFConstantStringClassRef) {
const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
Ty = llvm::ArrayType::get(Ty, 0);
CFConstantStringClassRef =
new llvm::GlobalVariable(Ty, false,
llvm::GlobalVariable::ExternalLinkage, 0,
"__CFConstantStringClassReference",
&getModule());
}
// Class pointer.
llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
llvm::Constant *Zeros[] = { Zero, Zero };
llvm::Constant *C =
llvm::ConstantExpr::getGetElementPtr(CFConstantStringClassRef, Zeros, 2);
Fields.push_back(C);
// Flags.
const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
Fields.push_back(llvm::ConstantInt::get(Ty, 1992));
// String pointer.
C = llvm::ConstantArray::get(str);
C = new llvm::GlobalVariable(C->getType(), true,
llvm::GlobalValue::InternalLinkage,
C, ".str", &getModule());
C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
Fields.push_back(C);
// String length.
Ty = getTypes().ConvertType(getContext().LongTy);
Fields.push_back(llvm::ConstantInt::get(Ty, str.length()));
// The struct.
Ty = getTypes().ConvertType(getContext().getCFConstantStringType());
C = llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Fields);
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(C->getType(), true,
llvm::GlobalVariable::InternalLinkage,
C, "", &getModule());
GV->setSection("__DATA,__cfstring");
Entry.setValue(GV);
return GV;
/// GenerateWritableString -- Creates storage for a string literal.
static llvm::Constant *GenerateStringLiteral(const std::string &str,
bool constant,
CodeGenModule &CGM) {
// Create Constant for this string literal
llvm::Constant *C=llvm::ConstantArray::get(str);
// Create a global variable for this string
C = new llvm::GlobalVariable(C->getType(), constant,
llvm::GlobalValue::InternalLinkage,
C, ".str", &CGM.getModule());
return C;
}
/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the character
/// array containing the literal. The result is pointer to array type.
llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) {
// Don't share any string literals if writable-strings is turned on.
if (Features.WritableStrings)
return GenerateStringLiteral(str, false, *this);
llvm::StringMapEntry<llvm::Constant *> &Entry =
ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
if (Entry.getValue())
return Entry.getValue();
// Create a global variable for this.
llvm::Constant *C = GenerateStringLiteral(str, true, *this);
Entry.setValue(C);
return C;
}