diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp | 712 |
1 files changed, 397 insertions, 315 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp index 0668039..924ec84 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -16,8 +16,10 @@ #include "CodeGenFunction.h" #include "CodeGenTBAA.h" #include "CGCall.h" +#include "CGCUDARuntime.h" #include "CGCXXABI.h" #include "CGObjCRuntime.h" +#include "CGOpenCLRuntime.h" #include "TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/AST/ASTContext.h" @@ -27,7 +29,6 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" -#include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -44,8 +45,10 @@ using namespace clang; using namespace CodeGen; +static const char AnnotationSection[] = "llvm.metadata"; + static CGCXXABI &createCXXABI(CodeGenModule &CGM) { - switch (CGM.getContext().Target.getCXXABI()) { + switch (CGM.getContext().getTargetInfo().getCXXABI()) { case CXXABI_ARM: return *CreateARMCXXABI(CGM); case CXXABI_Itanium: return *CreateItaniumCXXABI(CGM); case CXXABI_Microsoft: return *CreateMicrosoftCXXABI(CGM); @@ -58,22 +61,25 @@ static CGCXXABI &createCXXABI(CodeGenModule &CGM) { CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, llvm::Module &M, const llvm::TargetData &TD, - Diagnostic &diags) + DiagnosticsEngine &diags) : Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M), TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags), ABI(createCXXABI(*this)), Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI, CGO), TBAA(0), - VTables(*this), Runtime(0), DebugInfo(0), ARCData(0), RRData(0), - CFConstantStringClassRef(0), ConstantStringClassRef(0), + VTables(*this), ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0), + DebugInfo(0), ARCData(0), RRData(0), CFConstantStringClassRef(0), + ConstantStringClassRef(0), NSConstantStringType(0), VMContext(M.getContext()), - NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), - BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0), BlockObjectAssign(0), BlockObjectDispose(0), BlockDescriptorType(0), GenericBlockLiteralType(0) { if (Features.ObjC1) - createObjCRuntime(); + createObjCRuntime(); + if (Features.OpenCL) + createOpenCLRuntime(); + if (Features.CUDA) + createCUDARuntime(); // Enable TBAA unless it's suppressed. if (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0) @@ -98,17 +104,20 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, Int8Ty = llvm::Type::getInt8Ty(LLVMContext); Int32Ty = llvm::Type::getInt32Ty(LLVMContext); Int64Ty = llvm::Type::getInt64Ty(LLVMContext); - PointerWidthInBits = C.Target.getPointerWidth(0); + PointerWidthInBits = C.getTargetInfo().getPointerWidth(0); PointerAlignInBytes = - C.toCharUnitsFromBits(C.Target.getPointerAlign(0)).getQuantity(); - IntTy = llvm::IntegerType::get(LLVMContext, C.Target.getIntWidth()); + C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(0)).getQuantity(); + IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth()); IntPtrTy = llvm::IntegerType::get(LLVMContext, PointerWidthInBits); Int8PtrTy = Int8Ty->getPointerTo(0); Int8PtrPtrTy = Int8PtrTy->getPointerTo(0); } CodeGenModule::~CodeGenModule() { - delete Runtime; + delete ObjCRuntime; + delete OpenCLRuntime; + delete CUDARuntime; + delete TheTargetCodeGenInfo; delete &ABI; delete TBAA; delete DebugInfo; @@ -118,21 +127,29 @@ CodeGenModule::~CodeGenModule() { void CodeGenModule::createObjCRuntime() { if (!Features.NeXTRuntime) - Runtime = CreateGNUObjCRuntime(*this); + ObjCRuntime = CreateGNUObjCRuntime(*this); else - Runtime = CreateMacObjCRuntime(*this); + ObjCRuntime = CreateMacObjCRuntime(*this); +} + +void CodeGenModule::createOpenCLRuntime() { + OpenCLRuntime = new CGOpenCLRuntime(*this); +} + +void CodeGenModule::createCUDARuntime() { + CUDARuntime = CreateNVCUDARuntime(*this); } void CodeGenModule::Release() { EmitDeferred(); EmitCXXGlobalInitFunc(); EmitCXXGlobalDtorFunc(); - if (Runtime) - if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction()) + if (ObjCRuntime) + if (llvm::Function *ObjCInitFunction = ObjCRuntime->ModuleInitFunction()) AddGlobalCtor(ObjCInitFunction); EmitCtorList(GlobalCtors, "llvm.global_ctors"); EmitCtorList(GlobalDtors, "llvm.global_dtors"); - EmitAnnotations(); + EmitGlobalAnnotations(); EmitLLVMUsed(); SimplifyPersonality(); @@ -142,6 +159,9 @@ void CodeGenModule::Release() { if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes) EmitCoverageFile(); + + if (DebugInfo) + DebugInfo->finalize(); } void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { @@ -163,11 +183,11 @@ void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, } bool CodeGenModule::isTargetDarwin() const { - return getContext().Target.getTriple().isOSDarwin(); + return getContext().getTargetInfo().getTriple().isOSDarwin(); } -void CodeGenModule::Error(SourceLocation loc, llvm::StringRef error) { - unsigned diagID = getDiags().getCustomDiagID(Diagnostic::Error, error); +void CodeGenModule::Error(SourceLocation loc, StringRef error) { + unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, error); getDiags().Report(Context.getFullLoc(loc), diagID); } @@ -177,7 +197,7 @@ void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, bool OmitOnError) { if (OmitOnError && getDiags().hasErrorOccurred()) return; - unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "cannot compile this %0 yet"); std::string Msg = Type; getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID) @@ -190,7 +210,7 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type, bool OmitOnError) { if (OmitOnError && getDiags().hasErrorOccurred()) return; - unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, + unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "cannot compile this %0 yet"); std::string Msg = Type; getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg; @@ -281,10 +301,10 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, GV->setUnnamedAddr(true); } -llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) { +StringRef CodeGenModule::getMangledName(GlobalDecl GD) { const NamedDecl *ND = cast<NamedDecl>(GD.getDecl()); - llvm::StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()]; + StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()]; if (!Str.empty()) return Str; @@ -313,7 +333,7 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) { char *Name = MangledNamesAllocator.Allocate<char>(Length); std::copy(Buffer.begin(), Buffer.end(), Name); - Str = llvm::StringRef(Name, Length); + Str = StringRef(Name, Length); return Str; } @@ -333,7 +353,7 @@ void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer, MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out); } -llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) { +llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) { return getModule().getNamedValue(Name); } @@ -380,22 +400,6 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { } } -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(TheModule, Array->getType(), false, - llvm::GlobalValue::AppendingLinkage, Array, - "llvm.global.annotations"); - gv->setSection("llvm.metadata"); -} - llvm::GlobalValue::LinkageTypes CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { GVALinkage Linkage = getContext().GetGVALinkageForFunction(D); @@ -413,7 +417,12 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { // definition somewhere else, so we can use available_externally linkage. if (Linkage == GVA_C99Inline) return llvm::Function::AvailableExternallyLinkage; - + + // Note that Apple's kernel linker doesn't support symbol + // coalescing, so we need to avoid linkonce and weak linkages there. + // Normally, this means we just map to internal, but for explicit + // instantiations we'll map to external. + // In C++, the compiler has to emit a definition in every translation unit // that references the function. We should use linkonce_odr because // a) if all references in this translation unit are optimized away, we @@ -432,7 +441,7 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { if (Linkage == GVA_ExplicitTemplateInstantiation) return !Context.getLangOptions().AppleKext ? llvm::Function::WeakODRLinkage - : llvm::Function::InternalLinkage; + : llvm::Function::ExternalLinkage; // Otherwise, we have strong external linkage. assert(Linkage == GVA_StrongExternal); @@ -460,29 +469,54 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); } +/// Determines whether the language options require us to model +/// unwind exceptions. We treat -fexceptions as mandating this +/// except under the fragile ObjC ABI with only ObjC exceptions +/// enabled. This means, for example, that C with -fexceptions +/// enables this. +static bool hasUnwindExceptions(const LangOptions &Features) { + // If exceptions are completely disabled, obviously this is false. + if (!Features.Exceptions) return false; + + // If C++ exceptions are enabled, this is true. + if (Features.CXXExceptions) return true; + + // If ObjC exceptions are enabled, this depends on the ABI. + if (Features.ObjCExceptions) { + if (!Features.ObjCNonFragileABI) return false; + } + + return true; +} + void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F) { if (CodeGenOpts.UnwindTables) F->setHasUWTable(); - if (!Features.Exceptions && !Features.ObjCNonFragileABI) + if (!hasUnwindExceptions(Features)) F->addFnAttr(llvm::Attribute::NoUnwind); - if (D->hasAttr<AlwaysInlineAttr>()) - F->addFnAttr(llvm::Attribute::AlwaysInline); - - if (D->hasAttr<NakedAttr>()) + if (D->hasAttr<NakedAttr>()) { + // Naked implies noinline: we should not be inlining such functions. F->addFnAttr(llvm::Attribute::Naked); + F->addFnAttr(llvm::Attribute::NoInline); + } if (D->hasAttr<NoInlineAttr>()) F->addFnAttr(llvm::Attribute::NoInline); + // (noinline wins over always_inline, and we can't specify both in IR) + if (D->hasAttr<AlwaysInlineAttr>() && + !F->hasFnAttr(llvm::Attribute::NoInline)) + F->addFnAttr(llvm::Attribute::AlwaysInline); + if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) F->setUnnamedAddr(true); - if (Features.getStackProtectorMode() == LangOptions::SSPOn) + if (Features.getStackProtector() == LangOptions::SSPOn) F->addFnAttr(llvm::Attribute::StackProtect); - else if (Features.getStackProtectorMode() == LangOptions::SSPReq) + else if (Features.getStackProtector() == LangOptions::SSPReq) F->addFnAttr(llvm::Attribute::StackProtectReq); unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); @@ -570,7 +604,7 @@ void CodeGenModule::EmitLLVMUsed() { if (LLVMUsed.empty()) return; - const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext); + llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext); // Convert LLVMUsed to what ConstantArray needs. std::vector<llvm::Constant*> UsedArray; @@ -597,7 +631,7 @@ void CodeGenModule::EmitLLVMUsed() { void CodeGenModule::EmitDeferred() { // Emit code for any potentially referenced deferred decls. Since a // previously unused static decl may become used during the generation of code - // for a static function, iterate until no changes are made. + // for a static function, iterate until no changes are made. while (!DeferredDeclsToEmit.empty() || !DeferredVTables.empty()) { if (!DeferredVTables.empty()) { @@ -618,7 +652,7 @@ void CodeGenModule::EmitDeferred() { // ignore these cases. // // TODO: That said, looking this up multiple times is very wasteful. - llvm::StringRef Name = getMangledName(D); + StringRef Name = getMangledName(D); llvm::GlobalValue *CGRef = GetGlobalValue(Name); assert(CGRef && "Deferred decl wasn't referenced?"); @@ -635,54 +669,78 @@ void CodeGenModule::EmitDeferred() { } } -/// 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 field is the 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. -/// +void CodeGenModule::EmitGlobalAnnotations() { + 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(getModule(), + Array->getType(), false, llvm::GlobalValue::AppendingLinkage, Array, + "llvm.global.annotations"); + gv->setSection(AnnotationSection); +} + +llvm::Constant *CodeGenModule::EmitAnnotationString(llvm::StringRef Str) { + llvm::StringMap<llvm::Constant*>::iterator i = AnnotationStrings.find(Str); + if (i != AnnotationStrings.end()) + return i->second; + + // Not found yet, create a new global. + llvm::Constant *s = llvm::ConstantArray::get(getLLVMContext(), Str, true); + llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(), s->getType(), + true, llvm::GlobalValue::PrivateLinkage, s, ".str"); + gv->setSection(AnnotationSection); + gv->setUnnamedAddr(true); + AnnotationStrings[Str] = gv; + return gv; +} + +llvm::Constant *CodeGenModule::EmitAnnotationUnit(SourceLocation Loc) { + SourceManager &SM = getContext().getSourceManager(); + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + if (PLoc.isValid()) + return EmitAnnotationString(PLoc.getFilename()); + return EmitAnnotationString(SM.getBufferName(Loc)); +} + +llvm::Constant *CodeGenModule::EmitAnnotationLineNo(SourceLocation L) { + SourceManager &SM = getContext().getSourceManager(); + PresumedLoc PLoc = SM.getPresumedLoc(L); + unsigned LineNo = PLoc.isValid() ? PLoc.getLine() : + SM.getExpansionLineNumber(L); + return llvm::ConstantInt::get(Int32Ty, LineNo); +} + 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::Type::getInt8PtrTy(VMContext); - llvm::Constant *anno = llvm::ConstantArray::get(VMContext, - AA->getAnnotation(), true); - llvm::Constant *unit = llvm::ConstantArray::get(VMContext, - 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(*M, anno->getType(), false, - llvm::GlobalValue::PrivateLinkage, anno, - GV->getName()); - // translation unit name string, emitted into the llvm.metadata section. - llvm::GlobalValue *unitGV = - new llvm::GlobalVariable(*M, unit->getType(), false, - llvm::GlobalValue::PrivateLinkage, unit, - ".str"); - unitGV->setUnnamedAddr(true); + SourceLocation L) { + // Get the globals for file name, annotation, and the line number. + llvm::Constant *AnnoGV = EmitAnnotationString(AA->getAnnotation()), + *UnitGV = EmitAnnotationUnit(L), + *LineNoCst = EmitAnnotationLineNo(L); // Create the ConstantStruct for the global annotation. llvm::Constant *Fields[4] = { - llvm::ConstantExpr::getBitCast(GV, SBP), - llvm::ConstantExpr::getBitCast(annoGV, SBP), - llvm::ConstantExpr::getBitCast(unitGV, SBP), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo) + llvm::ConstantExpr::getBitCast(GV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(AnnoGV, Int8PtrTy), + llvm::ConstantExpr::getBitCast(UnitGV, Int8PtrTy), + LineNoCst }; return llvm::ConstantStruct::getAnon(Fields); } +void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D, + llvm::GlobalValue *GV) { + assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute"); + // Get the struct elements for these annotations. + for (specific_attr_iterator<AnnotateAttr> + ai = D->specific_attr_begin<AnnotateAttr>(), + ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai) + Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation())); +} + bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { // Never defer when EmitAllDecls is specified. if (Features.EmitAllDecls) @@ -695,7 +753,7 @@ llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) { const AliasAttr *AA = VD->getAttr<AliasAttr>(); assert(AA && "No alias?"); - const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType()); + llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType()); // See if there is already something with the target's name in the module. llvm::GlobalValue *Entry = GetGlobalValue(AA->getAliasee()); @@ -728,34 +786,45 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { if (Global->hasAttr<AliasAttr>()) return EmitAliasDefinition(GD); - // Ignore declarations, they will be emitted on their first use. - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) { - if (FD->getIdentifier()) { - llvm::StringRef Name = FD->getName(); - if (Name == "_Block_object_assign") { - BlockObjectAssignDecl = FD; - } else if (Name == "_Block_object_dispose") { - BlockObjectDisposeDecl = FD; - } + // If this is CUDA, be selective about which declarations we emit. + if (Features.CUDA) { + if (CodeGenOpts.CUDAIsDevice) { + if (!Global->hasAttr<CUDADeviceAttr>() && + !Global->hasAttr<CUDAGlobalAttr>() && + !Global->hasAttr<CUDAConstantAttr>() && + !Global->hasAttr<CUDASharedAttr>()) + return; + } else { + if (!Global->hasAttr<CUDAHostAttr>() && ( + Global->hasAttr<CUDADeviceAttr>() || + Global->hasAttr<CUDAConstantAttr>() || + Global->hasAttr<CUDASharedAttr>())) + return; } + } + // Ignore declarations, they will be emitted on their first use. + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) { // Forward declarations are emitted lazily on first use. - if (!FD->doesThisDeclarationHaveABody()) + if (!FD->doesThisDeclarationHaveABody()) { + if (!FD->doesDeclarationForceExternallyVisibleDefinition()) + return; + + const FunctionDecl *InlineDefinition = 0; + FD->getBody(InlineDefinition); + + StringRef MangledName = getMangledName(GD); + llvm::StringMap<GlobalDecl>::iterator DDI = + DeferredDecls.find(MangledName); + if (DDI != DeferredDecls.end()) + DeferredDecls.erase(DDI); + EmitGlobalDefinition(InlineDefinition); return; + } } else { const VarDecl *VD = cast<VarDecl>(Global); assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); - if (VD->getIdentifier()) { - llvm::StringRef Name = VD->getName(); - if (Name == "_NSConcreteGlobalBlock") { - NSConcreteGlobalBlockDecl = VD; - } else if (Name == "_NSConcreteStackBlock") { - NSConcreteStackBlockDecl = VD; - } - } - - if (VD->isThisDeclarationADefinition() != VarDecl::Definition) return; } @@ -778,7 +847,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // If the value has already been used, add it directly to the // DeferredDeclsToEmit list. - llvm::StringRef MangledName = getMangledName(GD); + StringRef MangledName = getMangledName(GD); if (GetGlobalValue(MangledName)) DeferredDeclsToEmit.push_back(GD); else { @@ -827,7 +896,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { if (const VarDecl *VD = dyn_cast<VarDecl>(D)) return EmitGlobalVarDefinition(VD); - assert(0 && "Invalid argument to EmitGlobalDefinition()"); + llvm_unreachable("Invalid argument to EmitGlobalDefinition()"); } /// GetOrCreateLLVMFunction - If the specified mangled name is not in the @@ -838,8 +907,8 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { /// 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 * -CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName, - const llvm::Type *Ty, +CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, + llvm::Type *Ty, GlobalDecl D, bool ForVTable, llvm::Attributes ExtraAttrs) { // Lookup the entry, lazily creating it if necessary. @@ -865,7 +934,7 @@ CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName, // sure not to try to set attributes. bool IsIncompleteFunction = false; - const llvm::FunctionType *FTy; + llvm::FunctionType *FTy; if (isa<llvm::FunctionType>(Ty)) { FTy = cast<llvm::FunctionType>(Ty); } else { @@ -935,21 +1004,21 @@ CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName, /// 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, - const llvm::Type *Ty, + llvm::Type *Ty, bool ForVTable) { // If there was no specific requested type, just convert it now. if (!Ty) Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType()); - llvm::StringRef MangledName = getMangledName(GD); + StringRef MangledName = getMangledName(GD); return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable); } /// CreateRuntimeFunction - Create a new runtime function with the specified /// type and name. llvm::Constant * -CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, - llvm::StringRef Name, +CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, + StringRef Name, llvm::Attributes ExtraAttrs) { return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false, ExtraAttrs); @@ -979,8 +1048,8 @@ static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D, /// 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 * -CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName, - const llvm::PointerType *Ty, +CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, + llvm::PointerType *Ty, const VarDecl *D, bool UnnamedAddr) { // Lookup the entry, lazily creating it if necessary. @@ -1049,8 +1118,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName, llvm::GlobalVariable * -CodeGenModule::CreateOrReplaceCXXRuntimeVariable(llvm::StringRef Name, - const llvm::Type *Ty, +CodeGenModule::CreateOrReplaceCXXRuntimeVariable(StringRef Name, + llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage) { llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name); llvm::GlobalVariable *OldGV = 0; @@ -1092,24 +1161,24 @@ CodeGenModule::CreateOrReplaceCXXRuntimeVariable(llvm::StringRef Name, /// then it will be greated with the specified type instead of whatever the /// normal requested type would be. llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, - const llvm::Type *Ty) { + llvm::Type *Ty) { assert(D->hasGlobalStorage() && "Not a global variable"); QualType ASTTy = D->getType(); if (Ty == 0) Ty = getTypes().ConvertTypeForMem(ASTTy); - const llvm::PointerType *PTy = + llvm::PointerType *PTy = llvm::PointerType::get(Ty, getContext().getTargetAddressSpace(ASTTy)); - llvm::StringRef MangledName = getMangledName(D); + StringRef MangledName = getMangledName(D); return GetOrCreateLLVMGlobal(MangledName, PTy, D); } /// CreateRuntimeVariable - Create a new runtime global variable with the /// specified type and name. llvm::Constant * -CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty, - llvm::StringRef Name) { +CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty, + StringRef Name) { return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0, true); } @@ -1121,7 +1190,7 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *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. - llvm::StringRef MangledName = getMangledName(D); + StringRef MangledName = getMangledName(D); if (!GetGlobalValue(MangledName)) { DeferredDecls[MangledName] = D; return; @@ -1207,7 +1276,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { return llvm::GlobalVariable::LinkOnceODRLinkage; } -CharUnits CodeGenModule::GetTargetTypeStoreSize(const llvm::Type *Ty) const { +CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const { return Context.toCharUnitsFromBits( TheTargetData.getTypeStoreSizeInBits(Ty)); } @@ -1253,7 +1322,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { } } - const llvm::Type* InitType = Init->getType(); + llvm::Type* InitType = Init->getType(); llvm::Constant *Entry = GetAddrOfGlobalVar(D, InitType); // Strip off a bitcast if we got one back. @@ -1282,7 +1351,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { getContext().getTargetAddressSpace(ASTTy)) { // Move the old entry aside so that we'll create a new one. - Entry->setName(llvm::StringRef()); + Entry->setName(StringRef()); // Make a new global with the correct type, this is now guaranteed to work. GV = cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, InitType)); @@ -1296,11 +1365,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { cast<llvm::GlobalValue>(Entry)->eraseFromParent(); } - if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) { - SourceManager &SM = Context.getSourceManager(); - AddAnnotation(EmitAnnotateAttr(GV, AA, - SM.getInstantiationLineNumber(D->getLocation()))); - } + if (D->hasAttr<AnnotateAttr>()) + AddGlobalAnnotations(D, GV); GV->setInitializer(Init); @@ -1326,10 +1392,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { EmitCXXGlobalVarDeclInitFunc(D, GV); // Emit global variable debug information. - if (CGDebugInfo *DI = getModuleDebugInfo()) { - DI->setLocation(D->getLocation()); + if (CGDebugInfo *DI = getModuleDebugInfo()) DI->EmitGlobalVariable(GV, D); - } } llvm::GlobalValue::LinkageTypes @@ -1377,8 +1441,8 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, llvm::Function *OldFn = dyn_cast<llvm::Function>(Old); if (OldFn == 0) return; - const llvm::Type *NewRetTy = NewFn->getReturnType(); - llvm::SmallVector<llvm::Value*, 4> ArgList; + llvm::Type *NewRetTy = NewFn->getReturnType(); + SmallVector<llvm::Value*, 4> ArgList; for (llvm::Value::use_iterator UI = OldFn->use_begin(), E = OldFn->use_end(); UI != E; ) { @@ -1394,6 +1458,17 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, 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. @@ -1406,10 +1481,17 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, 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); @@ -1417,7 +1499,8 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, ArgList.clear(); if (!NewCall->getType()->isVoidTy()) NewCall->takeName(CI); - NewCall->setAttributes(CI->getAttributes()); + NewCall->setAttributes(llvm::AttrListPtr::get(AttrVec.begin(), + AttrVec.end())); NewCall->setCallingConv(CI->getCallingConv()); // Finally, remove the old call, replacing any uses with the new one. @@ -1440,7 +1523,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { bool variadic = false; if (const FunctionProtoType *fpt = D->getType()->getAs<FunctionProtoType>()) variadic = fpt->isVariadic(); - const llvm::FunctionType *Ty = getTypes().GetFunctionType(FI, variadic); + llvm::FunctionType *Ty = getTypes().GetFunctionType(FI, variadic); // Get or create the prototype for the function. llvm::Constant *Entry = GetAddrOfFunction(GD, Ty); @@ -1467,7 +1550,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { // (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. - OldFn->setName(llvm::StringRef()); + 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 @@ -1510,6 +1593,8 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { AddGlobalCtor(Fn, CA->getPriority()); if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) AddGlobalDtor(Fn, DA->getPriority()); + if (D->hasAttr<AnnotateAttr>()) + AddGlobalAnnotations(D, Fn); } void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { @@ -1517,7 +1602,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { const AliasAttr *AA = D->getAttr<AliasAttr>(); assert(AA && "Not an alias?"); - llvm::StringRef MangledName = getMangledName(GD); + 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. @@ -1525,7 +1610,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { if (Entry && !Entry->isDeclaration()) return; - const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); + llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); // Create a reference to the named value. This ensures that it is emitted // if a deferred decl. @@ -1582,37 +1667,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { SetCommonAttributes(D, GA); } -/// getBuiltinLibFunction - Given a builtin id for a function like -/// "__builtin_fabsf", return a Function* for "fabsf". -llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, - unsigned BuiltinID) { - assert((Context.BuiltinInfo.isLibFunction(BuiltinID) || - Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) && - "isn't a lib fn"); - - // Get the name, skip over the __builtin_ prefix (if necessary). - llvm::StringRef Name; - GlobalDecl D(FD); - - // If the builtin has been declared explicitly with an assembler label, - // use the mangled name. This differs from the plain label on platforms - // that prefix labels. - if (FD->hasAttr<AsmLabelAttr>()) - Name = getMangledName(D); - else if (Context.BuiltinInfo.isLibFunction(BuiltinID)) - Name = Context.BuiltinInfo.GetName(BuiltinID) + 10; - else - Name = Context.BuiltinInfo.GetName(BuiltinID); - - - const llvm::FunctionType *Ty = - cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); - - return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); -} - llvm::Function *CodeGenModule::getIntrinsic(unsigned IID, - llvm::ArrayRef<llvm::Type*> Tys) { + ArrayRef<llvm::Type*> Tys) { return llvm::Intrinsic::getDeclaration(&getModule(), (llvm::Intrinsic::ID)IID, Tys); } @@ -1623,7 +1679,7 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map, bool TargetIsLSB, bool &IsUTF16, unsigned &StringLength) { - llvm::StringRef String = Literal->getString(); + StringRef String = Literal->getString(); unsigned NumBytes = String.size(); // Check for simple case. @@ -1633,7 +1689,7 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map, } // Otherwise, convert the UTF8 literals into a byte string. - llvm::SmallVector<UTF16, 128> ToBuf(NumBytes); + SmallVector<UTF16, 128> ToBuf(NumBytes); const UTF8 *FromPtr = (UTF8 *)String.data(); UTF16 *ToPtr = &ToBuf[0]; @@ -1665,7 +1721,7 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map, AsBytes.push_back(0); IsUTF16 = true; - return Map.GetOrCreateValue(llvm::StringRef(AsBytes.data(), AsBytes.size())); + return Map.GetOrCreateValue(StringRef(AsBytes.data(), AsBytes.size())); } static llvm::StringMapEntry<llvm::Constant*> & @@ -1673,7 +1729,7 @@ GetConstantStringEntry(llvm::StringMap<llvm::Constant*> &Map, const StringLiteral *Literal, unsigned &StringLength) { - llvm::StringRef String = Literal->getString(); + StringRef String = Literal->getString(); StringLength = String.size(); return Map.GetOrCreateValue(String); } @@ -1696,18 +1752,18 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { // If we don't already have it, get __CFConstantStringClassReference. if (!CFConstantStringClassRef) { - const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); + llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); Ty = llvm::ArrayType::get(Ty, 0); llvm::Constant *GV = CreateRuntimeVariable(Ty, "__CFConstantStringClassReference"); // Decay array -> ptr CFConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); + llvm::ConstantExpr::getGetElementPtr(GV, Zeros); } QualType CFTy = getContext().getCFConstantStringType(); - const llvm::StructType *STy = + llvm::StructType *STy = cast<llvm::StructType>(getTypes().ConvertType(CFTy)); std::vector<llvm::Constant*> Fields(4); @@ -1716,7 +1772,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { Fields[0] = CFConstantStringClassRef; // Flags. - const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy); + llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy); Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0) : llvm::ConstantInt::get(Ty, 0x07C8); @@ -1750,7 +1806,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy); GV->setAlignment(Align.getQuantity()); } - Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); + Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros); // String length. Ty = getTypes().ConvertType(getContext().LongTy); @@ -1761,13 +1817,23 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { GV = new llvm::GlobalVariable(getModule(), C->getType(), true, llvm::GlobalVariable::PrivateLinkage, C, "_unnamed_cfstring_"); - if (const char *Sect = getContext().Target.getCFStringSection()) + if (const char *Sect = getContext().getTargetInfo().getCFStringSection()) GV->setSection(Sect); Entry.setValue(GV); return GV; } +static RecordDecl * +CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK, + DeclContext *DC, IdentifierInfo *Id) { + SourceLocation Loc; + if (Ctx.getLangOptions().CPlusPlus) + return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); + else + return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); +} + llvm::Constant * CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { unsigned StringLength = 0; @@ -1784,7 +1850,7 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { // If we don't already have it, get _NSConstantStringClassReference. if (!ConstantStringClassRef) { std::string StringClass(getLangOptions().ObjCConstantStringClass); - const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); + llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); llvm::Constant *GV; if (Features.ObjCNonFragileABI) { std::string str = @@ -1792,25 +1858,54 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { : "OBJC_CLASS_$_" + StringClass; GV = getObjCRuntime().GetClassGlobal(str); // Make sure the result is of the correct type. - const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); + llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); ConstantStringClassRef = llvm::ConstantExpr::getBitCast(GV, PTy); } else { std::string str = StringClass.empty() ? "_NSConstantStringClassReference" : "_" + StringClass + "ClassReference"; - const llvm::Type *PTy = llvm::ArrayType::get(Ty, 0); + llvm::Type *PTy = llvm::ArrayType::get(Ty, 0); GV = CreateRuntimeVariable(PTy, str); // Decay array -> ptr ConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); + llvm::ConstantExpr::getGetElementPtr(GV, Zeros); } } - - QualType NSTy = getContext().getNSConstantStringType(); - - const llvm::StructType *STy = - cast<llvm::StructType>(getTypes().ConvertType(NSTy)); + + 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, + /*HasInit=*/false); + Field->setAccess(AS_public); + D->addDecl(Field); + } + + D->completeDefinition(); + QualType NSTy = Context.getTagDeclType(D); + NSConstantStringType = cast<llvm::StructType>(getTypes().ConvertType(NSTy)); + } std::vector<llvm::Constant*> Fields(3); @@ -1831,28 +1926,63 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { GV->setUnnamedAddr(true); CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy); GV->setAlignment(Align.getQuantity()); - Fields[1] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); + Fields[1] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros); // String length. - const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy); + llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy); Fields[2] = llvm::ConstantInt::get(Ty, StringLength); // The struct. - C = llvm::ConstantStruct::get(STy, Fields); + C = llvm::ConstantStruct::get(NSConstantStringType, Fields); GV = new llvm::GlobalVariable(getModule(), C->getType(), true, llvm::GlobalVariable::PrivateLinkage, C, "_unnamed_nsstring_"); // FIXME. Fix section. if (const char *Sect = Features.ObjCNonFragileABI - ? getContext().Target.getNSStringNonFragileABISection() - : getContext().Target.getNSStringSection()) + ? getContext().getTargetInfo().getNSStringNonFragileABISection() + : getContext().getTargetInfo().getNSStringSection()) GV->setSection(Sect); Entry.setValue(GV); return GV; } +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, + /*HasInit=*/false); + Field->setAccess(AS_public); + D->addDecl(Field); + } + + D->completeDefinition(); + ObjCFastEnumerationStateType = Context.getTagDeclType(D); + } + + return ObjCFastEnumerationStateType; +} + /// GetStringForStringLiteral - Return the appropriate bytes for a /// string literal, properly padded to match the literal type. std::string CodeGenModule::GetStringForStringLiteral(const StringLiteral *E) { @@ -1864,8 +1994,20 @@ std::string CodeGenModule::GetStringForStringLiteral(const StringLiteral *E) { // Resize the string to the right size. uint64_t RealLen = CAT->getSize().getZExtValue(); - if (E->isWide()) - RealLen *= Context.Target.getWCharWidth() / Context.getCharWidth(); + switch (E->getKind()) { + case StringLiteral::Ascii: + case StringLiteral::UTF8: + break; + case StringLiteral::Wide: + RealLen *= Context.getTargetInfo().getWCharWidth() / Context.getCharWidth(); + break; + case StringLiteral::UTF16: + RealLen *= Context.getTargetInfo().getChar16Width() / Context.getCharWidth(); + break; + case StringLiteral::UTF32: + RealLen *= Context.getTargetInfo().getChar32Width() / Context.getCharWidth(); + break; + } std::string Str = E->getString().str(); Str.resize(RealLen, '\0'); @@ -1879,8 +2021,11 @@ llvm::Constant * CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) { // FIXME: This can be more efficient. // FIXME: We shouldn't need to bitcast the constant in the wide string case. - llvm::Constant *C = GetAddrOfConstantString(GetStringForStringLiteral(S)); - if (S->isWide()) { + CharUnits Align = getContext().getTypeAlignInChars(S->getType()); + llvm::Constant *C = GetAddrOfConstantString(GetStringForStringLiteral(S), + /* GlobalName */ 0, + Align.getQuantity()); + if (S->isWide() || S->isUTF16() || S->isUTF32()) { llvm::Type *DestTy = llvm::PointerType::getUnqual(getTypes().ConvertType(S->getType())); C = llvm::ConstantExpr::getBitCast(C, DestTy); @@ -1900,10 +2045,11 @@ CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) { /// GenerateWritableString -- Creates storage for a string literal. -static llvm::Constant *GenerateStringLiteral(llvm::StringRef str, +static llvm::GlobalVariable *GenerateStringLiteral(StringRef str, bool constant, CodeGenModule &CGM, - const char *GlobalName) { + const char *GlobalName, + unsigned Alignment) { // Create Constant for this string literal. Don't add a '\0'. llvm::Constant *C = llvm::ConstantArray::get(CGM.getLLVMContext(), str, false); @@ -1913,7 +2059,7 @@ static llvm::Constant *GenerateStringLiteral(llvm::StringRef str, new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant, llvm::GlobalValue::PrivateLinkage, C, GlobalName); - GV->setAlignment(1); + GV->setAlignment(Alignment); GV->setUnnamedAddr(true); return GV; } @@ -1926,8 +2072,9 @@ static llvm::Constant *GenerateStringLiteral(llvm::StringRef str, /// Feature.WriteableStrings. /// /// The result has pointer to array type. -llvm::Constant *CodeGenModule::GetAddrOfConstantString(llvm::StringRef Str, - const char *GlobalName) { +llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str, + const char *GlobalName, + unsigned Alignment) { bool IsConstant = !Features.WritableStrings; // Get the default prefix if a name wasn't specified. @@ -1936,27 +2083,32 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantString(llvm::StringRef Str, // Don't share any string literals if strings aren't constant. if (!IsConstant) - return GenerateStringLiteral(Str, false, *this, GlobalName); + return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment); - llvm::StringMapEntry<llvm::Constant *> &Entry = + llvm::StringMapEntry<llvm::GlobalVariable *> &Entry = ConstantStringMap.GetOrCreateValue(Str); - if (Entry.getValue()) - return Entry.getValue(); + if (llvm::GlobalVariable *GV = Entry.getValue()) { + if (Alignment > GV->getAlignment()) { + GV->setAlignment(Alignment); + } + return GV; + } // Create a global variable for this. - llvm::Constant *C = GenerateStringLiteral(Str, true, *this, GlobalName); - Entry.setValue(C); - return C; + 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){ - llvm::StringRef StrWithNull(Str.c_str(), Str.size() + 1); - return GetAddrOfConstantString(StrWithNull, GlobalName); + const char *GlobalName, + unsigned Alignment) { + StringRef StrWithNull(Str.c_str(), Str.size() + 1); + return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment); } /// EmitObjCPropertyImplementations - Emit information for synthesized @@ -1988,9 +2140,8 @@ void CodeGenModule::EmitObjCPropertyImplementations(const } static bool needsDestructMethod(ObjCImplementationDecl *impl) { - ObjCInterfaceDecl *iface - = const_cast<ObjCInterfaceDecl*>(impl->getClassInterface()); - for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); + const ObjCInterfaceDecl *iface = impl->getClassInterface(); + for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); ivar; ivar = ivar->getNextIvar()) if (ivar->getType().isDestructedType()) return true; @@ -2007,8 +2158,10 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { Selector cxxSelector = getContext().Selectors.getSelector(0, &II); ObjCMethodDecl *DTORMethod = ObjCMethodDecl::Create(getContext(), D->getLocation(), D->getLocation(), - cxxSelector, getContext().VoidTy, 0, D, true, - false, true, false, ObjCMethodDecl::Required); + cxxSelector, getContext().VoidTy, 0, D, + /*isInstance=*/true, /*isVariadic=*/false, + /*isSynthesized=*/true, /*isImplicitlyDeclared=*/true, + /*isDefined=*/false, ObjCMethodDecl::Required); D->addInstanceMethod(DTORMethod); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false); D->setHasCXXStructors(true); @@ -2024,9 +2177,14 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { // The constructor returns 'self'. ObjCMethodDecl *CTORMethod = ObjCMethodDecl::Create(getContext(), D->getLocation(), - D->getLocation(), cxxSelector, + D->getLocation(), + cxxSelector, getContext().getObjCIdType(), 0, - D, true, false, true, false, + D, /*isInstance=*/true, + /*isVariadic=*/false, + /*isSynthesized=*/true, + /*isImplicitlyDeclared=*/true, + /*isDefined=*/false, ObjCMethodDecl::Required); D->addInstanceMethod(CTORMethod); CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true); @@ -2134,13 +2292,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { } case Decl::ObjCProtocol: - Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D)); + ObjCRuntime->GenerateProtocol(cast<ObjCProtocolDecl>(D)); break; case Decl::ObjCCategoryImpl: // Categories have properties but don't support synthesize so we // can ignore them here. - Runtime->GenerateCategory(cast<ObjCCategoryImplDecl>(D)); + ObjCRuntime->GenerateCategory(cast<ObjCCategoryImplDecl>(D)); break; case Decl::ObjCImplementation: { @@ -2149,7 +2307,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { Context.ResetObjCLayout(OMD->getClassInterface()); EmitObjCPropertyImplementations(OMD); EmitObjCIvarInitializations(OMD); - Runtime->GenerateClass(OMD); + ObjCRuntime->GenerateClass(OMD); break; } case Decl::ObjCMethod: { @@ -2169,11 +2327,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::FileScopeAsm: { FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D); - llvm::StringRef AsmString = AD->getAsmString()->getString(); + StringRef AsmString = AD->getAsmString()->getString(); const std::string &S = getModule().getModuleInlineAsm(); if (S.empty()) getModule().setModuleInlineAsm(AsmString); + else if (*--S.end() == '\n') + getModule().setModuleInlineAsm(S + AsmString.str()); else getModule().setModuleInlineAsm(S + '\n' + AsmString.str()); break; @@ -2191,7 +2351,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { 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); + llvm::Type *i64 = llvm::Type::getInt64Ty(Context); return llvm::ConstantInt::get(i64, PtrInt); } @@ -2222,7 +2382,7 @@ void CodeGenModule::EmitDeclMetadata() { llvm::NamedMDNode *GlobalMetadata = 0; // StaticLocalDeclMap - for (llvm::DenseMap<GlobalDecl,llvm::StringRef>::iterator + for (llvm::DenseMap<GlobalDecl,StringRef>::iterator I = MangledDeclNames.begin(), E = MangledDeclNames.end(); I != E; ++I) { llvm::GlobalValue *Addr = getModule().getNamedValue(I->second); @@ -2273,81 +2433,3 @@ void CodeGenModule::EmitCoverageFile() { } } } - -///@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. - llvm::Type *args[] = { Int8PtrTy, Int32Ty }; - const llvm::FunctionType *fty - = llvm::FunctionType::get(VoidTy, args, 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. - llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; - const llvm::FunctionType *fty - = llvm::FunctionType::get(VoidTy, args, 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(Int8PtrTy, "_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(Int8PtrTy, "_NSConcreteStackBlock"); -} - -///@} |