Newer
Older
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.
const UTF8 *FromPtr = (const 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.
GetOrCreateValue(StringRef(reinterpret_cast<const char *>(ToBuf.data()),
(StringLength + 1) * 2));
static llvm::StringMapEntry<llvm::Constant*> &
GetConstantStringEntry(llvm::StringMap<llvm::Constant*> &Map,
const StringLiteral *Literal,
unsigned &StringLength) {
StringRef String = Literal->getString();
StringLength = String.size();
return Map.GetOrCreateValue(String);
llvm::Constant *
CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
unsigned StringLength = 0;
bool isUTF16 = false;
llvm::StringMapEntry<llvm::Constant*> &Entry =
GetConstantCFStringEntry(CFConstantStringMap, Literal,
isUTF16, StringLength);
if (llvm::Constant *C = Entry.getValue())
return C;
Chris Lattner
committed
llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty);
llvm::Constant *Zeros[] = { Zero, Zero };
// If we don't already have it, get __CFConstantStringClassReference.
if (!CFConstantStringClassRef) {
llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
llvm::Constant *GV = CreateRuntimeVariable(Ty,
"__CFConstantStringClassReference");
// Decay array -> ptr
CFConstantStringClassRef =
llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
QualType CFTy = getContext().getCFConstantStringType();
llvm::StructType *STy =
cast<llvm::StructType>(getTypes().ConvertType(CFTy));
Anders Carlsson
committed
Fields[0] = CFConstantStringClassRef;
llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0) :
Anders Carlsson
committed
llvm::ConstantInt::get(Ty, 0x07C8);
Bill Wendling
committed
llvm::Constant *C = 0;
if (isUTF16) {
ArrayRef<uint16_t> Arr =
llvm::makeArrayRef<uint16_t>((uint16_t*)Entry.getKey().data(),
Entry.getKey().size() / 2);
C = llvm::ConstantDataArray::get(VMContext, Arr);
} else {
C = llvm::ConstantDataArray::getString(VMContext, Entry.getKey());
}
Chris Lattner
committed
llvm::GlobalValue::LinkageTypes Linkage;
if (isUTF16)
// FIXME: why do utf strings get "_" labels instead of "L" labels?
Chris Lattner
committed
Linkage = llvm::GlobalValue::InternalLinkage;
else
Rafael Espindola
committed
// FIXME: With OS X ld 123.2 (xcode 4) and LTO we would get a linker error
// when using private linkage. It is not clear if this is a bug in ld
// or a reasonable new restriction.
Rafael Espindola
committed
Linkage = llvm::GlobalValue::LinkerPrivateLinkage;
// Note: -fwritable-strings doesn't make the backing store strings of
// CFStrings writable. (See <rdar://problem/10657500>)
new llvm::GlobalVariable(getModule(), C->getType(), /*isConstant=*/true,
Linkage, C, ".str");
GV->setUnnamedAddr(true);
if (isUTF16) {
CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy);
GV->setAlignment(Align.getQuantity());
Daniel Dunbar
committed
} else {
CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy);
GV->setAlignment(Align.getQuantity());
Bill Wendling
committed
// String.
Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
Anders Carlsson
committed
Bill Wendling
committed
if (isUTF16)
// Cast the UTF16 string to the correct type.
Fields[2] = llvm::ConstantExpr::getBitCast(Fields[2], Int8PtrTy);
// String length.
Ty = getTypes().ConvertType(getContext().LongTy);
Anders Carlsson
committed
Fields[3] = llvm::ConstantInt::get(Ty, StringLength);
C = llvm::ConstantStruct::get(STy, Fields);
GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
llvm::GlobalVariable::PrivateLinkage, C,
Chris Lattner
committed
"_unnamed_cfstring_");
if (const char *Sect = getContext().getTargetInfo().getCFStringSection())
GV->setSection(Sect);
static RecordDecl *
CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
DeclContext *DC, IdentifierInfo *Id) {
SourceLocation Loc;
David Blaikie
committed
if (Ctx.getLangOpts().CPlusPlus)
return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
else
return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
}
Fariborz Jahanian
committed
CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
unsigned StringLength = 0;
llvm::StringMapEntry<llvm::Constant*> &Entry =
GetConstantStringEntry(CFConstantStringMap, Literal, StringLength);
if (llvm::Constant *C = Entry.getValue())
return C;
Chris Lattner
committed
llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty);
llvm::Constant *Zeros[] = { Zero, Zero };
// If we don't already have it, get _NSConstantStringClassReference.
Fariborz Jahanian
committed
if (!ConstantStringClassRef) {
David Blaikie
committed
std::string StringClass(getLangOpts().ObjCConstantStringClass);
llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
Fariborz Jahanian
committed
llvm::Constant *GV;
if (LangOpts.ObjCRuntime.isNonFragile()) {
std::string str =
StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
: "OBJC_CLASS_$_" + StringClass;
GV = getObjCRuntime().GetClassGlobal(str);
// Make sure the result is of the correct type.
llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
ConstantStringClassRef =
llvm::ConstantExpr::getBitCast(GV, PTy);
} else {
std::string str =
StringClass.empty() ? "_NSConstantStringClassReference"
: "_" + StringClass + "ClassReference";
llvm::Type *PTy = llvm::ArrayType::get(Ty, 0);
GV = CreateRuntimeVariable(PTy, str);
// Decay array -> ptr
ConstantStringClassRef =
llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
Fariborz Jahanian
committed
}
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
if (!NSConstantStringType) {
// Construct the type for a constant NSString.
RecordDecl *D = CreateRecordDecl(Context, TTK_Struct,
Context.getTranslationUnitDecl(),
&Context.Idents.get("__builtin_NSString"));
D->startDefinition();
QualType FieldTypes[3];
// const int *isa;
FieldTypes[0] = Context.getPointerType(Context.IntTy.withConst());
// const char *str;
FieldTypes[1] = Context.getPointerType(Context.CharTy.withConst());
// unsigned int length;
FieldTypes[2] = Context.UnsignedIntTy;
// Create fields
for (unsigned i = 0; i < 3; ++i) {
FieldDecl *Field = FieldDecl::Create(Context, D,
SourceLocation(),
SourceLocation(), 0,
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
D->completeDefinition();
QualType NSTy = Context.getTagDeclType(D);
NSConstantStringType = cast<llvm::StructType>(getTypes().ConvertType(NSTy));
}
Fariborz Jahanian
committed
Fields[0] = ConstantStringClassRef;
llvm::Constant *C =
llvm::ConstantDataArray::getString(VMContext, Entry.getKey());
llvm::GlobalValue::LinkageTypes Linkage;
bool isConstant;
Linkage = llvm::GlobalValue::PrivateLinkage;
David Blaikie
committed
isConstant = !LangOpts.WritableStrings;
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
".str");
CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy);
GV->setAlignment(Align.getQuantity());
Fields[1] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
Fields[2] = llvm::ConstantInt::get(Ty, StringLength);
// The struct.
C = llvm::ConstantStruct::get(NSConstantStringType, Fields);
GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
llvm::GlobalVariable::PrivateLinkage, C,
"_unnamed_nsstring_");
// FIXME. Fix section.
LangOpts.ObjCRuntime.isNonFragile()
? getContext().getTargetInfo().getNSStringNonFragileABISection()
: getContext().getTargetInfo().getNSStringSection())
GV->setSection(Sect);
Entry.setValue(GV);
return GV;
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
QualType CodeGenModule::getObjCFastEnumerationStateType() {
if (ObjCFastEnumerationStateType.isNull()) {
RecordDecl *D = CreateRecordDecl(Context, TTK_Struct,
Context.getTranslationUnitDecl(),
&Context.Idents.get("__objcFastEnumerationState"));
D->startDefinition();
QualType FieldTypes[] = {
Context.UnsignedLongTy,
Context.getPointerType(Context.getObjCIdType()),
Context.getPointerType(Context.UnsignedLongTy),
Context.getConstantArrayType(Context.UnsignedLongTy,
llvm::APInt(32, 5), ArrayType::Normal, 0)
};
for (size_t i = 0; i < 4; ++i) {
FieldDecl *Field = FieldDecl::Create(Context,
D,
SourceLocation(),
SourceLocation(), 0,
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
D->addDecl(Field);
}
D->completeDefinition();
ObjCFastEnumerationStateType = Context.getTagDeclType(D);
}
return ObjCFastEnumerationStateType;
}
Eli Friedman
committed
llvm::Constant *
CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
assert(!E->getType()->isPointerType() && "Strings are always arrays");
// Don't emit it as the address of the string, emit the string data itself
// as an inline array.
Chris Lattner
committed
if (E->getCharByteWidth() == 1) {
SmallString<64> Str(E->getString());
// Resize the string to the right size, which is indicated by its type.
const ConstantArrayType *CAT = Context.getAsConstantArrayType(E->getType());
Str.resize(CAT->getSize().getZExtValue());
return llvm::ConstantDataArray::getString(VMContext, Str, false);
}
llvm::ArrayType *AType =
cast<llvm::ArrayType>(getTypes().ConvertType(E->getType()));
llvm::Type *ElemTy = AType->getElementType();
unsigned NumElements = AType->getNumElements();
// Wide strings have either 2-byte or 4-byte elements.
if (ElemTy->getPrimitiveSizeInBits() == 16) {
SmallVector<uint16_t, 32> Elements;
Elements.reserve(NumElements);
for(unsigned i = 0, e = E->getLength(); i != e; ++i)
Elements.push_back(E->getCodeUnit(i));
Elements.resize(NumElements);
return llvm::ConstantDataArray::get(VMContext, Elements);
}
assert(ElemTy->getPrimitiveSizeInBits() == 32);
SmallVector<uint32_t, 32> Elements;
Elements.reserve(NumElements);
for(unsigned i = 0, e = E->getLength(); i != e; ++i)
Elements.push_back(E->getCodeUnit(i));
Elements.resize(NumElements);
return llvm::ConstantDataArray::get(VMContext, Elements);
Eli Friedman
committed
}
/// GetAddrOfConstantStringFromLiteral - Return a pointer to a
/// constant array for the given string literal.
llvm::Constant *
CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
CharUnits Align = getContext().getTypeAlignInChars(S->getType());
Eli Friedman
committed
if (S->isAscii() || S->isUTF8()) {
Chris Lattner
committed
SmallString<64> Str(S->getString());
// Resize the string to the right size, which is indicated by its type.
const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());
Str.resize(CAT->getSize().getZExtValue());
return GetAddrOfConstantString(Str, /*GlobalName*/ 0, Align.getQuantity());
Eli Friedman
committed
}
Eli Friedman
committed
Chris Lattner
committed
// FIXME: the following does not memoize wide strings.
Eli Friedman
committed
llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(),C->getType(),
David Blaikie
committed
!LangOpts.WritableStrings,
Eli Friedman
committed
llvm::GlobalValue::PrivateLinkage,
C,".str");
Eli Friedman
committed
GV->setAlignment(Align.getQuantity());
GV->setUnnamedAddr(true);
return GV;
/// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
/// array for the given ObjCEncodeExpr node.
llvm::Constant *
CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
std::string Str;
getContext().getObjCEncodingForType(E->getEncodedType(), Str);
return GetAddrOfConstantCString(Str);
}
/// GenerateWritableString -- Creates storage for a string literal.
static llvm::GlobalVariable *GenerateStringLiteral(StringRef str,
bool constant,
CodeGenModule &CGM,
const char *GlobalName,
unsigned Alignment) {
// Create Constant for this string literal. Don't add a '\0'.
llvm::ConstantDataArray::getString(CGM.getLLVMContext(), str, false);
// Create a global variable for this string
Rafael Espindola
committed
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant,
llvm::GlobalValue::PrivateLinkage,
C, GlobalName);
GV->setAlignment(Alignment);
Rafael Espindola
committed
GV->setUnnamedAddr(true);
return GV;
}
/// GetAddrOfConstantString - Returns a pointer to a character array
/// containing the literal. This contents are exactly that of the
/// given string, i.e. it will not be null terminated automatically;
/// see GetAddrOfConstantCString. Note that whether the result is
/// actually a pointer to an LLVM constant depends on
/// Feature.WriteableStrings.
///
/// The result has pointer to array type.
Chris Lattner
committed
llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str,
const char *GlobalName,
unsigned Alignment) {
// Get the default prefix if a name wasn't specified.
if (!GlobalName)
Chris Lattner
committed
GlobalName = ".str";
// Don't share any string literals if strings aren't constant.
David Blaikie
committed
if (LangOpts.WritableStrings)
return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment);
llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
if (llvm::GlobalVariable *GV = Entry.getValue()) {
if (Alignment > GV->getAlignment()) {
GV->setAlignment(Alignment);
}
return GV;
}
// Create a global variable for this.
Chris Lattner
committed
llvm::GlobalVariable *GV = GenerateStringLiteral(Str, true, *this, GlobalName,
Alignment);
Entry.setValue(GV);
return GV;
/// GetAddrOfConstantCString - Returns a pointer to a character
/// array containing the literal and a terminating '\0'
/// character. The result has pointer to array type.
llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str,
const char *GlobalName,
unsigned Alignment) {
Chris Lattner
committed
StringRef StrWithNull(Str.c_str(), Str.size() + 1);
return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment);
/// EmitObjCPropertyImplementations - Emit information for synthesized
/// properties for an implementation.
void CodeGenModule::EmitObjCPropertyImplementations(const
for (ObjCImplementationDecl::propimpl_iterator
i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
David Blaikie
committed
ObjCPropertyImplDecl *PID = *i;
// Dynamic is just for type-checking.
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
ObjCPropertyDecl *PD = PID->getPropertyDecl();
// Determine which methods need to be implemented, some may have
// been overridden. Note that ::isPropertyAccessor is not the method
// we want, that just indicates if the decl came from a
// property. What we want to know is if the method is defined in
// this implementation.
if (!D->getInstanceMethod(PD->getGetterName()))
CodeGenFunction(*this).GenerateObjCGetter(
const_cast<ObjCImplementationDecl *>(D), PID);
!D->getInstanceMethod(PD->getSetterName()))
CodeGenFunction(*this).GenerateObjCSetter(
const_cast<ObjCImplementationDecl *>(D), PID);
static bool needsDestructMethod(ObjCImplementationDecl *impl) {
const ObjCInterfaceDecl *iface = impl->getClassInterface();
for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
ivar; ivar = ivar->getNextIvar())
if (ivar->getType().isDestructedType())
return true;
return false;
}
/// EmitObjCIvarInitializations - Emit information for ivar initialization
/// for an implementation.
void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
// We might need a .cxx_destruct even if we don't have any ivar initializers.
if (needsDestructMethod(D)) {
IdentifierInfo *II = &getContext().Idents.get(".cxx_destruct");
Selector cxxSelector = getContext().Selectors.getSelector(0, &II);
ObjCMethodDecl *DTORMethod =
ObjCMethodDecl::Create(getContext(), D->getLocation(), D->getLocation(),
Argyrios Kyrtzidis
committed
cxxSelector, getContext().VoidTy, 0, D,
/*isInstance=*/true, /*isVariadic=*/false,
/*isPropertyAccessor=*/true, /*isImplicitlyDeclared=*/true,
Argyrios Kyrtzidis
committed
/*isDefined=*/false, ObjCMethodDecl::Required);
D->addInstanceMethod(DTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false);
}
// If the implementation doesn't have any ivar initializers, we don't need
// a .cxx_construct.
David Chisnall
committed
if (D->getNumIvarInitializers() == 0)
IdentifierInfo *II = &getContext().Idents.get(".cxx_construct");
Selector cxxSelector = getContext().Selectors.getSelector(0, &II);
// The constructor returns 'self'.
ObjCMethodDecl *CTORMethod = ObjCMethodDecl::Create(getContext(),
D->getLocation(),
Argyrios Kyrtzidis
committed
D->getLocation(),
cxxSelector,
getContext().getObjCIdType(), 0,
Argyrios Kyrtzidis
committed
D, /*isInstance=*/true,
/*isVariadic=*/false,
/*isPropertyAccessor=*/true,
Argyrios Kyrtzidis
committed
/*isImplicitlyDeclared=*/true,
/*isDefined=*/false,
ObjCMethodDecl::Required);
D->addInstanceMethod(CTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true);
/// EmitNamespace - Emit all declarations in a namespace.
void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end();
I != E; ++I)
EmitTopLevelDecl(*I);
}
// EmitLinkageSpec - Emit all declarations in a linkage spec.
void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {
if (LSD->getLanguage() != LinkageSpecDecl::lang_c &&
LSD->getLanguage() != LinkageSpecDecl::lang_cxx) {
ErrorUnsupported(LSD, "linkage spec");
return;
}
for (RecordDecl::decl_iterator I = LSD->decls_begin(), E = LSD->decls_end();
I != E; ++I)
EmitTopLevelDecl(*I);
}
/// EmitTopLevelDecl - Emit code for a single top level declaration.
void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// If an error has occurred, stop code generation, but continue
// parsing and semantic analysis (to ensure all warnings and errors
// are emitted).
if (Diags.hasErrorOccurred())
return;
// Ignore dependent declarations.
if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
return;
case Decl::CXXMethod:
// Skip function templates
if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() ||
cast<FunctionDecl>(D)->isLateTemplateParsed())
return;
EmitGlobal(cast<FunctionDecl>(D));
break;
EmitGlobal(cast<VarDecl>(D));
// Indirect fields from global anonymous structs and unions can be
// ignored; only the actual variable requires IR gen support.
case Decl::IndirectField:
break;
EmitNamespace(cast<NamespaceDecl>(D));
// No code generation needed.
case Decl::Using:
case Decl::UsingDirective:
case Decl::ClassTemplate:
case Decl::FunctionTemplate:
case Decl::TypeAliasTemplate:
case Decl::Block:
Douglas Gregor
committed
case Decl::Import:
break;
case Decl::CXXConstructor:
// Skip function templates
if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() ||
cast<FunctionDecl>(D)->isLateTemplateParsed())
return;
EmitCXXConstructors(cast<CXXConstructorDecl>(D));
break;
Anders Carlsson
committed
case Decl::CXXDestructor:
if (cast<FunctionDecl>(D)->isLateTemplateParsed())
return;
Anders Carlsson
committed
EmitCXXDestructors(cast<CXXDestructorDecl>(D));
break;
case Decl::StaticAssert:
// Nothing to do.
break;
// Objective-C Decls
// Forward declarations, no (immediate) code generation.
case Decl::ObjCInterface:
case Decl::ObjCCategory:
case Decl::ObjCProtocol: {
ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(D);
if (Proto->isThisDeclarationADefinition())
ObjCRuntime->GenerateProtocol(Proto);
// Categories have properties but don't support synthesize so we
// can ignore them here.
ObjCRuntime->GenerateCategory(cast<ObjCCategoryImplDecl>(D));
case Decl::ObjCImplementation: {
ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
EmitObjCPropertyImplementations(OMD);
EmitObjCIvarInitializations(OMD);
ObjCRuntime->GenerateClass(OMD);
// Emit global variable debug information.
if (CGDebugInfo *DI = getModuleDebugInfo())
DI->getOrCreateInterfaceType(getContext().getObjCInterfaceType(OMD->getClassInterface()),
OMD->getLocation());
case Decl::ObjCMethod: {
ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
// If this is not a prototype, emit the body.
Argyrios Kyrtzidis
committed
if (OMD->getBody())
CodeGenFunction(*this).GenerateObjCMethod(OMD);
break;
}
ObjCRuntime->RegisterAlias(cast<ObjCCompatibleAliasDecl>(D));
case Decl::LinkageSpec:
EmitLinkageSpec(cast<LinkageSpecDecl>(D));
break;
case Decl::FileScopeAsm: {
FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
Chris Lattner
committed
StringRef AsmString = AD->getAsmString()->getString();
const std::string &S = getModule().getModuleInlineAsm();
if (S.empty())
getModule().setModuleInlineAsm(AsmString);
Joerg Sonnenberger
committed
else if (S.end()[-1] == '\n')
getModule().setModuleInlineAsm(S + AsmString.str());
getModule().setModuleInlineAsm(S + '\n' + AsmString.str());
// Make sure we handled everything we should, every other kind is a
// non-top-level decl. FIXME: Would be nice to have an isTopLevelDeclKind
// function. Need to recode Decl::Kind to do that easily.
assert(isa<TypeDecl>(D) && "Unsupported decl kind");
}
}
/// Turns the given pointer into a constant.
static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context,
const void *Ptr) {
uintptr_t PtrInt = reinterpret_cast<uintptr_t>(Ptr);
llvm::Type *i64 = llvm::Type::getInt64Ty(Context);
return llvm::ConstantInt::get(i64, PtrInt);
}
static void EmitGlobalDeclMetadata(CodeGenModule &CGM,
llvm::NamedMDNode *&GlobalMetadata,
GlobalDecl D,
llvm::GlobalValue *Addr) {
if (!GlobalMetadata)
GlobalMetadata =
CGM.getModule().getOrInsertNamedMetadata("clang.global.decl.ptrs");
// TODO: should we report variant information for ctors/dtors?
llvm::Value *Ops[] = {
Addr,
GetPointerConstant(CGM.getLLVMContext(), D.getDecl())
};
GlobalMetadata->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
}
/// Emits metadata nodes associating all the global values in the
/// current module with the Decls they came from. This is useful for
/// projects using IR gen as a subroutine.
///
/// Since there's currently no way to associate an MDNode directly
/// with an llvm::GlobalValue, we create a global named metadata
/// with the name 'clang.global.decl.ptrs'.
void CodeGenModule::EmitDeclMetadata() {
llvm::NamedMDNode *GlobalMetadata = 0;
// StaticLocalDeclMap
Chris Lattner
committed
for (llvm::DenseMap<GlobalDecl,StringRef>::iterator
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
I = MangledDeclNames.begin(), E = MangledDeclNames.end();
I != E; ++I) {
llvm::GlobalValue *Addr = getModule().getNamedValue(I->second);
EmitGlobalDeclMetadata(*this, GlobalMetadata, I->first, Addr);
}
}
/// Emits metadata nodes for all the local variables in the current
/// function.
void CodeGenFunction::EmitDeclMetadata() {
if (LocalDeclMap.empty()) return;
llvm::LLVMContext &Context = getLLVMContext();
// Find the unique metadata ID for this name.
unsigned DeclPtrKind = Context.getMDKindID("clang.decl.ptr");
llvm::NamedMDNode *GlobalMetadata = 0;
for (llvm::DenseMap<const Decl*, llvm::Value*>::iterator
I = LocalDeclMap.begin(), E = LocalDeclMap.end(); I != E; ++I) {
const Decl *D = I->first;
llvm::Value *Addr = I->second;
if (llvm::AllocaInst *Alloca = dyn_cast<llvm::AllocaInst>(Addr)) {
llvm::Value *DAddr = GetPointerConstant(getLLVMContext(), D);
Alloca->setMetadata(DeclPtrKind, llvm::MDNode::get(Context, DAddr));
} else if (llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Addr)) {
GlobalDecl GD = GlobalDecl(cast<VarDecl>(D));
EmitGlobalDeclMetadata(CGM, GlobalMetadata, GD, GV);
}
}
}
void CodeGenModule::EmitCoverageFile() {
if (!getCodeGenOpts().CoverageFile.empty()) {
if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) {
llvm::NamedMDNode *GCov = TheModule.getOrInsertNamedMetadata("llvm.gcov");
llvm::LLVMContext &Ctx = TheModule.getContext();
llvm::MDString *CoverageFile =
llvm::MDString::get(Ctx, getCodeGenOpts().CoverageFile);
for (int i = 0, e = CUNode->getNumOperands(); i != e; ++i) {
llvm::MDNode *CU = CUNode->getOperand(i);
llvm::Value *node[] = { CoverageFile, CU };
llvm::MDNode *N = llvm::MDNode::get(Ctx, node);
GCov->addOperand(N);
}
}
}
}
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid,
QualType GuidType) {
// Sema has checked that all uuid strings are of the form
// "12345678-1234-1234-1234-1234567890ab".
assert(Uuid.size() == 36);
const char *Uuidstr = Uuid.data();
for (int i = 0; i < 36; ++i) {
if (i == 8 || i == 13 || i == 18 || i == 23) assert(Uuidstr[i] == '-');
else assert(isxdigit(Uuidstr[i]));
}
llvm::APInt Field0(32, StringRef(Uuidstr , 8), 16);
llvm::APInt Field1(16, StringRef(Uuidstr + 9, 4), 16);
llvm::APInt Field2(16, StringRef(Uuidstr + 14, 4), 16);
llvm::APInt Field3Values[] = {
llvm::APInt(8, StringRef(Uuidstr + 19, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 21, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 24, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 26, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 28, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 30, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 32, 2), 16),
llvm::APInt(8, StringRef(Uuidstr + 34, 2), 16),
};
APValue InitStruct(APValue::UninitStruct(), /*NumBases=*/0, /*NumFields=*/4);
InitStruct.getStructField(0) = APValue(llvm::APSInt(Field0));
InitStruct.getStructField(1) = APValue(llvm::APSInt(Field1));
InitStruct.getStructField(2) = APValue(llvm::APSInt(Field2));
APValue& Arr = InitStruct.getStructField(3);
Arr = APValue(APValue::UninitArray(), 8, 8);
for (int t = 0; t < 8; ++t)
Arr.getArrayInitializedElt(t) = APValue(llvm::APSInt(Field3Values[t]));
return EmitConstantValue(InitStruct, GuidType);
}