Newer
Older
case Decl::FileScopeAsm: {
FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
llvm::StringRef AsmString = AD->getAsmString()->getString();
const std::string &S = getModule().getModuleInlineAsm();
if (S.empty())
getModule().setModuleInlineAsm(AsmString);
else
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");
}
}
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
/// 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);
const 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, 2));
}
/// 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
for (llvm::DenseMap<GlobalDecl,llvm::StringRef>::iterator
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, 1));
} else if (llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Addr)) {
GlobalDecl GD = GlobalDecl(cast<VarDecl>(D));
EmitGlobalDeclMetadata(CGM, GlobalMetadata, GD, GV);
}
}
}
///@name Custom Runtime Function Interfaces
///@{
//
// FIXME: These can be eliminated once we can have clients just get the required
// AST nodes from the builtin tables.
llvm::Constant *CodeGenModule::getBlockObjectDispose() {
if (BlockObjectDispose)
return BlockObjectDispose;
// If we saw an explicit decl, use that.
if (BlockObjectDisposeDecl) {
return BlockObjectDispose = GetAddrOfFunction(
BlockObjectDisposeDecl,
getTypes().GetFunctionType(BlockObjectDisposeDecl));
}
// Otherwise construct the function by hand.
const llvm::FunctionType *FTy;
std::vector<const llvm::Type*> ArgTys;
const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
ArgTys.push_back(PtrToInt8Ty);
ArgTys.push_back(llvm::Type::getInt32Ty(VMContext));
FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
return BlockObjectDispose =
CreateRuntimeFunction(FTy, "_Block_object_dispose");
}
llvm::Constant *CodeGenModule::getBlockObjectAssign() {
if (BlockObjectAssign)
return BlockObjectAssign;
// If we saw an explicit decl, use that.
if (BlockObjectAssignDecl) {
return BlockObjectAssign = GetAddrOfFunction(
BlockObjectAssignDecl,
getTypes().GetFunctionType(BlockObjectAssignDecl));
}
// Otherwise construct the function by hand.
const llvm::FunctionType *FTy;
std::vector<const llvm::Type*> ArgTys;
const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
ArgTys.push_back(PtrToInt8Ty);
ArgTys.push_back(PtrToInt8Ty);
ArgTys.push_back(llvm::Type::getInt32Ty(VMContext));
FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
return BlockObjectAssign =
CreateRuntimeFunction(FTy, "_Block_object_assign");
}
llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
if (NSConcreteGlobalBlock)
return NSConcreteGlobalBlock;
// If we saw an explicit decl, use that.
if (NSConcreteGlobalBlockDecl) {
return NSConcreteGlobalBlock = GetAddrOfGlobalVar(
NSConcreteGlobalBlockDecl,
getTypes().ConvertType(NSConcreteGlobalBlockDecl->getType()));
}
// Otherwise construct the variable by hand.
return NSConcreteGlobalBlock = CreateRuntimeVariable(
PtrToInt8Ty, "_NSConcreteGlobalBlock");
}
llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
if (NSConcreteStackBlock)
return NSConcreteStackBlock;
// If we saw an explicit decl, use that.
if (NSConcreteStackBlockDecl) {
return NSConcreteStackBlock = GetAddrOfGlobalVar(
NSConcreteStackBlockDecl,
getTypes().ConvertType(NSConcreteStackBlockDecl->getType()));
}
// Otherwise construct the variable by hand.
return NSConcreteStackBlock = CreateRuntimeVariable(
PtrToInt8Ty, "_NSConcreteStackBlock");
}
///@}