diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp | 598 |
1 files changed, 372 insertions, 226 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp index 17972e2..c518a55 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -12,49 +12,57 @@ //===----------------------------------------------------------------------===// #include "CodeGenModule.h" -#include "CGDebugInfo.h" -#include "CodeGenFunction.h" -#include "CodeGenTBAA.h" -#include "CGCall.h" #include "CGCUDARuntime.h" #include "CGCXXABI.h" +#include "CGCall.h" +#include "CGDebugInfo.h" #include "CGObjCRuntime.h" #include "CGOpenCLRuntime.h" +#include "CodeGenFunction.h" +#include "CodeGenTBAA.h" #include "TargetInfo.h" -#include "clang/Frontend/CodeGenOptions.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" -#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Basic/ConvertUTF.h" -#include "llvm/CallingConv.h" -#include "llvm/Module.h" -#include "llvm/Intrinsics.h" -#include "llvm/LLVMContext.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/Triple.h" -#include "llvm/Target/Mangler.h" -#include "llvm/DataLayout.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CallSite.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/Mangler.h" + using namespace clang; using namespace CodeGen; static const char AnnotationSection[] = "llvm.metadata"; static CGCXXABI &createCXXABI(CodeGenModule &CGM) { - switch (CGM.getContext().getTargetInfo().getCXXABI()) { - case CXXABI_ARM: return *CreateARMCXXABI(CGM); - case CXXABI_Itanium: return *CreateItaniumCXXABI(CGM); - case CXXABI_Microsoft: return *CreateMicrosoftCXXABI(CGM); + switch (CGM.getContext().getTargetInfo().getCXXABI().getKind()) { + case TargetCXXABI::GenericAArch64: + case TargetCXXABI::GenericARM: + case TargetCXXABI::iOS: + case TargetCXXABI::GenericItanium: + return *CreateItaniumCXXABI(CGM); + case TargetCXXABI::Microsoft: + return *CreateMicrosoftCXXABI(CGM); } llvm_unreachable("invalid C++ ABI kind"); @@ -62,10 +70,11 @@ static CGCXXABI &createCXXABI(CodeGenModule &CGM) { CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, - llvm::Module &M, const llvm::DataLayout &TD, + const TargetOptions &TO, llvm::Module &M, + const llvm::DataLayout &TD, DiagnosticsEngine &diags) - : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M), - TheDataLayout(TD), TheTargetCodeGenInfo(0), Diags(diags), + : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TargetOpts(TO), + TheModule(M), TheDataLayout(TD), TheTargetCodeGenInfo(0), Diags(diags), ABI(createCXXABI(*this)), Types(*this), TBAA(0), @@ -76,8 +85,12 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, VMContext(M.getContext()), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0), BlockObjectDispose(0), - BlockDescriptorType(0), GenericBlockLiteralType(0) { - + BlockDescriptorType(0), GenericBlockLiteralType(0), + LifetimeStartFn(0), LifetimeEndFn(0), + SanitizerBlacklist(CGO.SanitizerBlacklistFile), + SanOpts(SanitizerBlacklist.isIn(M) ? + SanitizerOptions::Disabled : LangOpts.Sanitize) { + // Initialize the type cache. llvm::LLVMContext &LLVMContext = M.getContext(); VoidTy = llvm::Type::getVoidTy(LLVMContext); @@ -95,6 +108,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, Int8PtrTy = Int8Ty->getPointerTo(0); Int8PtrPtrTy = Int8PtrTy->getPointerTo(0); + RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC(); + if (LangOpts.ObjC1) createObjCRuntime(); if (LangOpts.OpenCL) @@ -103,7 +118,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, createCUDARuntime(); // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. - if (LangOpts.SanitizeThread || + if (SanOpts.Thread || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(), ABI.getMangleContext()); @@ -173,6 +188,10 @@ void CodeGenModule::Release() { EmitGlobalAnnotations(); EmitLLVMUsed(); + if (CodeGenOpts.ModulesAutolink) { + EmitModuleLinkOptions(); + } + SimplifyPersonality(); if (getCodeGenOpts().EmitDeclMetadata) @@ -208,6 +227,20 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { return TBAA->getTBAAStructInfo(QTy); } +llvm::MDNode *CodeGenModule::getTBAAStructTypeInfo(QualType QTy) { + if (!TBAA) + return 0; + return TBAA->getTBAAStructTypeInfo(QTy); +} + +llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, + llvm::MDNode *AccessN, + uint64_t O) { + if (!TBAA) + return 0; + return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O); +} + void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo) { Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); @@ -260,9 +293,9 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV, } // Set visibility for definitions. - NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility(); - if (LV.visibilityExplicit() || !GV->hasAvailableExternallyLinkage()) - GV->setVisibility(GetLLVMVisibility(LV.visibility())); + LinkageInfo LV = D->getLinkageAndVisibility(); + if (LV.isVisibilityExplicit() || !GV->hasAvailableExternallyLinkage()) + GV->setVisibility(GetLLVMVisibility(LV.getVisibility())); } static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) { @@ -331,7 +364,7 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, return; // Don't override an explicit visibility attribute. - if (RD->getExplicitVisibility()) + if (RD->getExplicitVisibility(NamedDecl::VisibilityForType)) return; switch (RD->getTemplateSpecializationKind()) { @@ -360,7 +393,9 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, // that don't have the key function's definition. But ignore // this if we're emitting RTTI under -fno-rtti. if (!(TVK != TVK_ForRTTI) || LangOpts.RTTI) { - if (Context.getKeyFunction(RD)) + // FIXME: what should we do if we "lose" the key function during + // the emission of the file? + if (Context.getCurrentKeyFunction(RD)) return; } @@ -532,8 +567,8 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, llvm::Function *F) { unsigned CallingConv; AttributeListType AttributeList; - ConstructAttributeList(Info, D, AttributeList, CallingConv); - F->setAttributes(llvm::AttrListPtr::get(getLLVMContext(), AttributeList)); + ConstructAttributeList(Info, D, AttributeList, CallingConv, false); + F->setAttributes(llvm::AttributeSet::get(getLLVMContext(), AttributeList)); F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); } @@ -563,28 +598,29 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, F->setHasUWTable(); if (!hasUnwindExceptions(LangOpts)) - F->addFnAttr(llvm::Attributes::NoUnwind); + F->addFnAttr(llvm::Attribute::NoUnwind); if (D->hasAttr<NakedAttr>()) { // Naked implies noinline: we should not be inlining such functions. - F->addFnAttr(llvm::Attributes::Naked); - F->addFnAttr(llvm::Attributes::NoInline); + F->addFnAttr(llvm::Attribute::Naked); + F->addFnAttr(llvm::Attribute::NoInline); } if (D->hasAttr<NoInlineAttr>()) - F->addFnAttr(llvm::Attributes::NoInline); + F->addFnAttr(llvm::Attribute::NoInline); // (noinline wins over always_inline, and we can't specify both in IR) if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) && - !F->getFnAttributes().hasAttribute(llvm::Attributes::NoInline)) - F->addFnAttr(llvm::Attributes::AlwaysInline); + !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::NoInline)) + F->addFnAttr(llvm::Attribute::AlwaysInline); // FIXME: Communicate hot and cold attributes to LLVM more directly. if (D->hasAttr<ColdAttr>()) - F->addFnAttr(llvm::Attributes::OptimizeForSize); + F->addFnAttr(llvm::Attribute::OptimizeForSize); if (D->hasAttr<MinSizeAttr>()) - F->addFnAttr(llvm::Attributes::MinSize); + F->addFnAttr(llvm::Attribute::MinSize); if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) F->setUnnamedAddr(true); @@ -594,15 +630,23 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, F->setUnnamedAddr(true); if (LangOpts.getStackProtector() == LangOptions::SSPOn) - F->addFnAttr(llvm::Attributes::StackProtect); + F->addFnAttr(llvm::Attribute::StackProtect); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) - F->addFnAttr(llvm::Attributes::StackProtectReq); - - if (LangOpts.SanitizeAddress) { - // When AddressSanitizer is enabled, set AddressSafety attribute - // unless __attribute__((no_address_safety_analysis)) is used. - if (!D->hasAttr<NoAddressSafetyAnalysisAttr>()) - F->addFnAttr(llvm::Attributes::AddressSafety); + F->addFnAttr(llvm::Attribute::StackProtectReq); + + // Add sanitizer attributes if function is not blacklisted. + if (!SanitizerBlacklist.isIn(*F)) { + // When AddressSanitizer is enabled, set SanitizeAddress attribute + // unless __attribute__((no_sanitize_address)) is used. + if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>()) + F->addFnAttr(llvm::Attribute::SanitizeAddress); + // Same for ThreadSanitizer and __attribute__((no_sanitize_thread)) + if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) { + F->addFnAttr(llvm::Attribute::SanitizeThread); + } + // Same for MemorySanitizer and __attribute__((no_sanitize_memory)) + if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>()) + F->addFnAttr(llvm::Attribute::SanitizeMemory); } unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); @@ -627,7 +671,9 @@ void CodeGenModule::SetCommonAttributes(const Decl *D, if (const SectionAttr *SA = D->getAttr<SectionAttr>()) GV->setSection(SA->getName()); - getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this); + // Alias cannot have attributes. Filter them here. + if (!isa<llvm::GlobalAlias>(GV)) + getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this); } void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, @@ -670,9 +716,9 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, } else { F->setLinkage(llvm::Function::ExternalLinkage); - NamedDecl::LinkageInfo LV = FD->getLinkageAndVisibility(); - if (LV.linkage() == ExternalLinkage && LV.visibilityExplicit()) { - F->setVisibility(GetLLVMVisibility(LV.visibility())); + LinkageInfo LV = FD->getLinkageAndVisibility(); + if (LV.getLinkage() == ExternalLinkage && LV.isVisibilityExplicit()) { + F->setVisibility(GetLLVMVisibility(LV.getVisibility())); } } @@ -713,19 +759,130 @@ void CodeGenModule::EmitLLVMUsed() { GV->setSection("llvm.metadata"); } +/// \brief Add link options implied by the given module, including modules +/// it depends on, using a postorder walk. +static void addLinkOptionsPostorder(llvm::LLVMContext &Context, + Module *Mod, + SmallVectorImpl<llvm::Value *> &Metadata, + llvm::SmallPtrSet<Module *, 16> &Visited) { + // Import this module's parent. + if (Mod->Parent && Visited.insert(Mod->Parent)) { + addLinkOptionsPostorder(Context, Mod->Parent, Metadata, Visited); + } + + // Import this module's dependencies. + for (unsigned I = Mod->Imports.size(); I > 0; --I) { + if (Visited.insert(Mod->Imports[I-1])) + addLinkOptionsPostorder(Context, Mod->Imports[I-1], Metadata, Visited); + } + + // Add linker options to link against the libraries/frameworks + // described by this module. + for (unsigned I = Mod->LinkLibraries.size(); I > 0; --I) { + // FIXME: -lfoo is Unix-centric and -framework Foo is Darwin-centric. + // We need to know more about the linker to know how to encode these + // options propertly. + + // Link against a framework. + if (Mod->LinkLibraries[I-1].IsFramework) { + llvm::Value *Args[2] = { + llvm::MDString::get(Context, "-framework"), + llvm::MDString::get(Context, Mod->LinkLibraries[I-1].Library) + }; + + Metadata.push_back(llvm::MDNode::get(Context, Args)); + continue; + } + + // Link against a library. + llvm::Value *OptString + = llvm::MDString::get(Context, + "-l" + Mod->LinkLibraries[I-1].Library); + Metadata.push_back(llvm::MDNode::get(Context, OptString)); + } +} + +void CodeGenModule::EmitModuleLinkOptions() { + // Collect the set of all of the modules we want to visit to emit link + // options, which is essentially the imported modules and all of their + // non-explicit child modules. + llvm::SetVector<clang::Module *> LinkModules; + llvm::SmallPtrSet<clang::Module *, 16> Visited; + SmallVector<clang::Module *, 16> Stack; + + // Seed the stack with imported modules. + for (llvm::SetVector<clang::Module *>::iterator M = ImportedModules.begin(), + MEnd = ImportedModules.end(); + M != MEnd; ++M) { + if (Visited.insert(*M)) + Stack.push_back(*M); + } + + // Find all of the modules to import, making a little effort to prune + // non-leaf modules. + while (!Stack.empty()) { + clang::Module *Mod = Stack.back(); + Stack.pop_back(); + + bool AnyChildren = false; + + // Visit the submodules of this module. + for (clang::Module::submodule_iterator Sub = Mod->submodule_begin(), + SubEnd = Mod->submodule_end(); + Sub != SubEnd; ++Sub) { + // Skip explicit children; they need to be explicitly imported to be + // linked against. + if ((*Sub)->IsExplicit) + continue; + + if (Visited.insert(*Sub)) { + Stack.push_back(*Sub); + AnyChildren = true; + } + } + + // We didn't find any children, so add this module to the list of + // modules to link against. + if (!AnyChildren) { + LinkModules.insert(Mod); + } + } + + // Add link options for all of the imported modules in reverse topological + // order. + SmallVector<llvm::Value *, 16> MetadataArgs; + Visited.clear(); + for (llvm::SetVector<clang::Module *>::iterator M = LinkModules.begin(), + MEnd = LinkModules.end(); + M != MEnd; ++M) { + if (Visited.insert(*M)) + addLinkOptionsPostorder(getLLVMContext(), *M, MetadataArgs, Visited); + } + std::reverse(MetadataArgs.begin(), MetadataArgs.end()); + + // Add the linker options metadata flag. + getModule().addModuleFlag(llvm::Module::AppendUnique, "Linker Options", + llvm::MDNode::get(getLLVMContext(), MetadataArgs)); +} + 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. - while (!DeferredDeclsToEmit.empty() || !DeferredVTables.empty()) { + while (true) { if (!DeferredVTables.empty()) { - const CXXRecordDecl *RD = DeferredVTables.back(); - DeferredVTables.pop_back(); - getCXXABI().EmitVTables(RD); - continue; + EmitDeferredVTables(); + + // Emitting a v-table doesn't directly cause more v-tables to + // become deferred, although it can cause functions to be + // emitted that then need those v-tables. + assert(DeferredVTables.empty()); } + // Stop if we're out of both deferred v-tables and deferred declarations. + if (DeferredDeclsToEmit.empty()) break; + GlobalDecl D = DeferredDeclsToEmit.back(); DeferredDeclsToEmit.pop_back(); @@ -767,7 +924,7 @@ void CodeGenModule::EmitGlobalAnnotations() { gv->setSection(AnnotationSection); } -llvm::Constant *CodeGenModule::EmitAnnotationString(llvm::StringRef Str) { +llvm::Constant *CodeGenModule::EmitAnnotationString(StringRef Str) { llvm::StringMap<llvm::Constant*>::iterator i = AnnotationStrings.find(Str); if (i != AnnotationStrings.end()) return i->second; @@ -1106,7 +1263,7 @@ llvm::Constant * CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, - llvm::Attributes ExtraAttrs) { + llvm::AttributeSet ExtraAttrs) { // Lookup the entry, lazily creating it if necessary. llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (Entry) { @@ -1142,8 +1299,13 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, assert(F->getName() == MangledName && "name was uniqued!"); if (D.getDecl()) SetFunctionAttributes(D, F, IsIncompleteFunction); - if (ExtraAttrs.hasAttributes()) - F->addAttribute(llvm::AttrListPtr::FunctionIndex, ExtraAttrs); + if (ExtraAttrs.hasAttributes(llvm::AttributeSet::FunctionIndex)) { + llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeSet::FunctionIndex); + F->addAttributes(llvm::AttributeSet::FunctionIndex, + llvm::AttributeSet::get(VMContext, + llvm::AttributeSet::FunctionIndex, + B)); + } // This is the first use or definition of a mangled name. If there is a // deferred decl with this name, remember that we need to emit it at the end @@ -1214,9 +1376,14 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, llvm::Constant * CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name, - llvm::Attributes ExtraAttrs) { - return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false, - ExtraAttrs); + llvm::AttributeSet ExtraAttrs) { + llvm::Constant *C + = GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false, + ExtraAttrs); + if (llvm::Function *F = dyn_cast<llvm::Function>(C)) + if (F->empty()) + F->setCallingConv(getRuntimeCC()); + return C; } /// isTypeConstant - Determine whether an object of this type can be emitted @@ -1294,8 +1461,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, GV->setConstant(isTypeConstant(D->getType(), false)); // Set linkage and visibility in case we never see a definition. - NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility(); - if (LV.linkage() != ExternalLinkage) { + LinkageInfo LV = D->getLinkageAndVisibility(); + if (LV.getLinkage() != ExternalLinkage) { // Don't set internal linkage on declarations. } else { if (D->hasAttr<DLLImportAttr>()) @@ -1304,8 +1471,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); // Set visibility on a declaration only if it's explicit. - if (LV.visibilityExplicit()) - GV->setVisibility(GetLLVMVisibility(LV.visibility())); + if (LV.isVisibilityExplicit()) + GV->setVisibility(GetLLVMVisibility(LV.getVisibility())); } if (D->isThreadSpecified()) @@ -1403,80 +1570,6 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) { EmitGlobalVarDefinition(D); } -void CodeGenModule::EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired) { - if (DefinitionRequired) - getCXXABI().EmitVTables(Class); -} - -llvm::GlobalVariable::LinkageTypes -CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { - if (RD->getLinkage() != ExternalLinkage) - return llvm::GlobalVariable::InternalLinkage; - - if (const CXXMethodDecl *KeyFunction - = RD->getASTContext().getKeyFunction(RD)) { - // If this class has a key function, use that to determine the linkage of - // the vtable. - const FunctionDecl *Def = 0; - if (KeyFunction->hasBody(Def)) - KeyFunction = cast<CXXMethodDecl>(Def); - - switch (KeyFunction->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ExplicitSpecialization: - // When compiling with optimizations turned on, we emit all vtables, - // even if the key function is not defined in the current translation - // unit. If this is the case, use available_externally linkage. - if (!Def && CodeGenOpts.OptimizationLevel) - return llvm::GlobalVariable::AvailableExternallyLinkage; - - if (KeyFunction->isInlined()) - return !Context.getLangOpts().AppleKext ? - llvm::GlobalVariable::LinkOnceODRLinkage : - llvm::Function::InternalLinkage; - - return llvm::GlobalVariable::ExternalLinkage; - - case TSK_ImplicitInstantiation: - return !Context.getLangOpts().AppleKext ? - llvm::GlobalVariable::LinkOnceODRLinkage : - llvm::Function::InternalLinkage; - - case TSK_ExplicitInstantiationDefinition: - return !Context.getLangOpts().AppleKext ? - llvm::GlobalVariable::WeakODRLinkage : - llvm::Function::InternalLinkage; - - case TSK_ExplicitInstantiationDeclaration: - // FIXME: Use available_externally linkage. However, this currently - // breaks LLVM's build due to undefined symbols. - // return llvm::GlobalVariable::AvailableExternallyLinkage; - return !Context.getLangOpts().AppleKext ? - llvm::GlobalVariable::LinkOnceODRLinkage : - llvm::Function::InternalLinkage; - } - } - - if (Context.getLangOpts().AppleKext) - return llvm::Function::InternalLinkage; - - switch (RD->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ExplicitSpecialization: - case TSK_ImplicitInstantiation: - // FIXME: Use available_externally linkage. However, this currently - // breaks LLVM's build due to undefined symbols. - // return llvm::GlobalVariable::AvailableExternallyLinkage; - case TSK_ExplicitInstantiationDeclaration: - return llvm::GlobalVariable::LinkOnceODRLinkage; - - case TSK_ExplicitInstantiationDefinition: - return llvm::GlobalVariable::WeakODRLinkage; - } - - llvm_unreachable("Invalid TemplateSpecializationKind!"); -} - CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const { return Context.toCharUnitsFromBits( TheDataLayout.getTypeStoreSizeInBits(Ty)); @@ -1523,7 +1616,7 @@ CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D, D->getDeclContext()), D->getLocStart(), D->getLocation(), name, arrayType, sourceInfo, - SC_Static, SC_Static); + SC_Static); // Now clone the InitListExpr to initialize the array instead. // Incredible hack: we want to use the existing InitListExpr here, so we need @@ -1739,7 +1832,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // If we are compiling with ASan, add metadata indicating dynamically // initialized globals. - if (LangOpts.SanitizeAddress && NeedsGlobalCtor) { + if (SanOpts.Address && NeedsGlobalCtor) { llvm::Module &M = getModule(); llvm::NamedMDNode *DynamicInitializers = @@ -1785,105 +1878,139 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, return llvm::GlobalVariable::ExternalLinkage; } -/// ReplaceUsesOfNonProtoTypeWithRealFunction - This function is called when we -/// implement a function with no prototype, e.g. "int foo() {}". If there are -/// existing call uses of the old function in the module, this adjusts them to -/// call the new function directly. -/// -/// This is not just a cleanup: the always_inline pass requires direct calls to -/// functions to be able to inline them. If there is a bitcast in the way, it -/// won't inline them. Instcombine normally deletes these calls, but it isn't -/// run at -O0. -static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, - llvm::Function *NewFn) { - // If we're redefining a global as a function, don't transform it. - llvm::Function *OldFn = dyn_cast<llvm::Function>(Old); - if (OldFn == 0) return; - - llvm::Type *NewRetTy = NewFn->getReturnType(); - SmallVector<llvm::Value*, 4> ArgList; - - for (llvm::Value::use_iterator UI = OldFn->use_begin(), E = OldFn->use_end(); - UI != E; ) { - // TODO: Do invokes ever occur in C code? If so, we should handle them too. - llvm::Value::use_iterator I = UI++; // Increment before the CI is erased. - llvm::CallInst *CI = dyn_cast<llvm::CallInst>(*I); - if (!CI) continue; // FIXME: when we allow Invoke, just do CallSite CS(*I) - llvm::CallSite CS(CI); - if (!CI || !CS.isCallee(I)) continue; - - // If the return types don't match exactly, and if the call isn't dead, then - // we can't transform this call. - if (CI->getType() != NewRetTy && !CI->use_empty()) +/// Replace the uses of a function that was declared with a non-proto type. +/// We want to silently drop extra arguments from call sites +static void replaceUsesOfNonProtoConstant(llvm::Constant *old, + llvm::Function *newFn) { + // Fast path. + if (old->use_empty()) return; + + llvm::Type *newRetTy = newFn->getReturnType(); + SmallVector<llvm::Value*, 4> newArgs; + + for (llvm::Value::use_iterator ui = old->use_begin(), ue = old->use_end(); + ui != ue; ) { + llvm::Value::use_iterator use = ui++; // Increment before the use is erased. + llvm::User *user = *use; + + // Recognize and replace uses of bitcasts. Most calls to + // unprototyped functions will use bitcasts. + if (llvm::ConstantExpr *bitcast = dyn_cast<llvm::ConstantExpr>(user)) { + if (bitcast->getOpcode() == llvm::Instruction::BitCast) + replaceUsesOfNonProtoConstant(bitcast, newFn); + continue; + } + + // Recognize calls to the function. + llvm::CallSite callSite(user); + if (!callSite) continue; + if (!callSite.isCallee(use)) continue; + + // If the return types don't match exactly, then we can't + // transform this call unless it's dead. + if (callSite->getType() != newRetTy && !callSite->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.hasAttributes()) - AttrVec.push_back(llvm:: - AttributeWithIndex::get(llvm::AttrListPtr::ReturnIndex, - RAttrs)); - - // If the function was passed too few arguments, don't transform. If extra - // arguments were passed, we silently drop them. If any of the types - // mismatch, we don't transform. - unsigned ArgNo = 0; - bool DontTransform = false; - for (llvm::Function::arg_iterator AI = NewFn->arg_begin(), - E = NewFn->arg_end(); AI != E; ++AI, ++ArgNo) { - if (CS.arg_size() == ArgNo || - CS.getArgument(ArgNo)->getType() != AI->getType()) { - DontTransform = true; + // Get the call site's attribute list. + SmallVector<llvm::AttributeSet, 8> newAttrs; + llvm::AttributeSet oldAttrs = callSite.getAttributes(); + + // Collect any return attributes from the call. + if (oldAttrs.hasAttributes(llvm::AttributeSet::ReturnIndex)) + newAttrs.push_back( + llvm::AttributeSet::get(newFn->getContext(), + oldAttrs.getRetAttributes())); + + // If the function was passed too few arguments, don't transform. + unsigned newNumArgs = newFn->arg_size(); + if (callSite.arg_size() < newNumArgs) continue; + + // If extra arguments were passed, we silently drop them. + // If any of the types mismatch, we don't transform. + unsigned argNo = 0; + bool dontTransform = false; + for (llvm::Function::arg_iterator ai = newFn->arg_begin(), + ae = newFn->arg_end(); ai != ae; ++ai, ++argNo) { + if (callSite.getArgument(argNo)->getType() != ai->getType()) { + dontTransform = true; break; } // Add any parameter attributes. - llvm::Attributes PAttrs = AttrList.getParamAttributes(ArgNo + 1); - if (PAttrs.hasAttributes()) - AttrVec.push_back(llvm::AttributeWithIndex::get(ArgNo + 1, PAttrs)); + if (oldAttrs.hasAttributes(argNo + 1)) + newAttrs. + push_back(llvm:: + AttributeSet::get(newFn->getContext(), + oldAttrs.getParamAttributes(argNo + 1))); } - if (DontTransform) + if (dontTransform) continue; - llvm::Attributes FnAttrs = AttrList.getFnAttributes(); - if (FnAttrs.hasAttributes()) - AttrVec.push_back(llvm:: - AttributeWithIndex::get(llvm::AttrListPtr::FunctionIndex, - FnAttrs)); + if (oldAttrs.hasAttributes(llvm::AttributeSet::FunctionIndex)) + newAttrs.push_back(llvm::AttributeSet::get(newFn->getContext(), + oldAttrs.getFnAttributes())); // Okay, we can transform this. Create the new call instruction and copy // over the required information. - ArgList.append(CS.arg_begin(), CS.arg_begin() + ArgNo); - llvm::CallInst *NewCall = llvm::CallInst::Create(NewFn, ArgList, "", CI); - ArgList.clear(); - if (!NewCall->getType()->isVoidTy()) - NewCall->takeName(CI); - NewCall->setAttributes(llvm::AttrListPtr::get(OldFn->getContext(), AttrVec)); - NewCall->setCallingConv(CI->getCallingConv()); + newArgs.append(callSite.arg_begin(), callSite.arg_begin() + argNo); + + llvm::CallSite newCall; + if (callSite.isCall()) { + newCall = llvm::CallInst::Create(newFn, newArgs, "", + callSite.getInstruction()); + } else { + llvm::InvokeInst *oldInvoke = + cast<llvm::InvokeInst>(callSite.getInstruction()); + newCall = llvm::InvokeInst::Create(newFn, + oldInvoke->getNormalDest(), + oldInvoke->getUnwindDest(), + newArgs, "", + callSite.getInstruction()); + } + newArgs.clear(); // for the next iteration + + if (!newCall->getType()->isVoidTy()) + newCall->takeName(callSite.getInstruction()); + newCall.setAttributes( + llvm::AttributeSet::get(newFn->getContext(), newAttrs)); + newCall.setCallingConv(callSite.getCallingConv()); // Finally, remove the old call, replacing any uses with the new one. - if (!CI->use_empty()) - CI->replaceAllUsesWith(NewCall); + if (!callSite->use_empty()) + callSite->replaceAllUsesWith(newCall.getInstruction()); // Copy debug location attached to CI. - if (!CI->getDebugLoc().isUnknown()) - NewCall->setDebugLoc(CI->getDebugLoc()); - CI->eraseFromParent(); + if (!callSite->getDebugLoc().isUnknown()) + newCall->setDebugLoc(callSite->getDebugLoc()); + callSite->eraseFromParent(); } } +/// ReplaceUsesOfNonProtoTypeWithRealFunction - This function is called when we +/// implement a function with no prototype, e.g. "int foo() {}". If there are +/// existing call uses of the old function in the module, this adjusts them to +/// call the new function directly. +/// +/// This is not just a cleanup: the always_inline pass requires direct calls to +/// functions to be able to inline them. If there is a bitcast in the way, it +/// won't inline them. Instcombine normally deletes these calls, but it isn't +/// run at -O0. +static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, + llvm::Function *NewFn) { + // If we're redefining a global as a function, don't transform it. + if (!isa<llvm::Function>(Old)) return; + + replaceUsesOfNonProtoConstant(Old, NewFn); +} + void CodeGenModule::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { TemplateSpecializationKind TSK = VD->getTemplateSpecializationKind(); // If we have a definition, this might be a deferred decl. If the // instantiation is explicit, make sure we emit it at the end. if (VD->getDefinition() && TSK == TSK_ExplicitInstantiationDefinition) GetAddrOfGlobalVar(VD); + + EmitTopLevelDecl(VD); } void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { @@ -1921,10 +2048,14 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { OldFn->setName(StringRef()); llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty)); - // If this is an implementation of a function without a prototype, try to - // replace any existing uses of the function (which may be calls) with uses - // of the new function - if (D->getType()->isFunctionNoProtoType()) { + // This might be an implementation of a function without a + // prototype, in which case, try to do special replacement of + // calls which match the new prototype. The really key thing here + // is that we also potentially drop arguments from the call site + // so as to make a direct call, which makes the inliner happier + // and suppresses a number of optimizer warnings (!) about + // dropping arguments. + if (!OldFn->use_empty()) { ReplaceUsesOfNonProtoTypeWithRealFunction(OldFn, NewFn); OldFn->removeDeadConstantUsers(); } @@ -2131,7 +2262,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { llvm::Constant *C = 0; if (isUTF16) { ArrayRef<uint16_t> Arr = - llvm::makeArrayRef<uint16_t>((uint16_t*)Entry.getKey().data(), + llvm::makeArrayRef<uint16_t>(reinterpret_cast<uint16_t*>( + const_cast<char *>(Entry.getKey().data())), Entry.getKey().size() / 2); C = llvm::ConstantDataArray::get(VMContext, Arr); } else { @@ -2644,7 +2776,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::TypeAliasTemplate: case Decl::NamespaceAlias: case Decl::Block: - case Decl::Import: + case Decl::Empty: break; case Decl::CXXConstructor: // Skip function templates @@ -2691,9 +2823,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { ObjCRuntime->GenerateClass(OMD); // Emit global variable debug information. if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->getOrCreateInterfaceType(getContext().getObjCInterfaceType(OMD->getClassInterface()), - OMD->getLocation()); - + if (getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) + DI->getOrCreateInterfaceType(getContext().getObjCInterfaceType( + OMD->getClassInterface()), OMD->getLocation()); break; } case Decl::ObjCMethod: { @@ -2725,6 +2857,20 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; } + case Decl::Import: { + ImportDecl *Import = cast<ImportDecl>(D); + + // Ignore import declarations that come from imported modules. + if (clang::Module *Owner = Import->getOwningModule()) { + if (getLangOpts().CurrentModule.empty() || + Owner->getTopLevelModule()->Name == getLangOpts().CurrentModule) + break; + } + + ImportedModules.insert(Import->getImportedModule()); + break; + } + default: // Make sure we handled everything we should, every other kind is a // non-top-level decl. FIXME: Would be nice to have an isTopLevelDeclKind @@ -2828,7 +2974,7 @@ llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid, 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])); + else assert(isHexDigit(Uuidstr[i])); } llvm::APInt Field0(32, StringRef(Uuidstr , 8), 16); |