diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp | 723 |
1 files changed, 423 insertions, 300 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp index 0b03a3c..792fbfc 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -35,7 +35,9 @@ #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/CallingConv.h" @@ -67,25 +69,23 @@ static CGCXXABI &createCXXABI(CodeGenModule &CGM) { llvm_unreachable("invalid C++ ABI kind"); } - CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, llvm::Module &M, const llvm::DataLayout &TD, DiagnosticsEngine &diags) - : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M), - Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()), - ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0), - TheTargetCodeGenInfo(0), Types(*this), VTables(*this), - ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0), - DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0), - RRData(0), CFConstantStringClassRef(0), - ConstantStringClassRef(0), NSConstantStringType(0), - NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), - BlockObjectAssign(0), BlockObjectDispose(0), - BlockDescriptorType(0), GenericBlockLiteralType(0), - LifetimeStartFn(0), LifetimeEndFn(0), - SanitizerBlacklist(CGO.SanitizerBlacklistFile), - SanOpts(SanitizerBlacklist.isIn(M) ? - SanitizerOptions::Disabled : LangOpts.Sanitize) { + : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M), + Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()), + ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0), + TheTargetCodeGenInfo(0), Types(*this), VTables(*this), ObjCRuntime(0), + OpenCLRuntime(0), CUDARuntime(0), DebugInfo(0), ARCData(0), + NoObjCARCExceptionsMetadata(0), RRData(0), CFConstantStringClassRef(0), + ConstantStringClassRef(0), NSConstantStringType(0), + NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0), + BlockObjectDispose(0), BlockDescriptorType(0), GenericBlockLiteralType(0), + LifetimeStartFn(0), LifetimeEndFn(0), + SanitizerBlacklist( + llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)), + SanOpts(SanitizerBlacklist->isIn(M) ? SanitizerOptions::Disabled + : LangOpts.Sanitize) { // Initialize the type cache. llvm::LLVMContext &LLVMContext = M.getContext(); @@ -172,8 +172,71 @@ void CodeGenModule::createCUDARuntime() { CUDARuntime = CreateNVCUDARuntime(*this); } +void CodeGenModule::applyReplacements() { + for (ReplacementsTy::iterator I = Replacements.begin(), + E = Replacements.end(); + I != E; ++I) { + StringRef MangledName = I->first(); + llvm::Constant *Replacement = I->second; + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + if (!Entry) + continue; + llvm::Function *OldF = cast<llvm::Function>(Entry); + llvm::Function *NewF = dyn_cast<llvm::Function>(Replacement); + if (!NewF) { + llvm::ConstantExpr *CE = cast<llvm::ConstantExpr>(Replacement); + assert(CE->getOpcode() == llvm::Instruction::BitCast || + CE->getOpcode() == llvm::Instruction::GetElementPtr); + NewF = dyn_cast<llvm::Function>(CE->getOperand(0)); + } + + // Replace old with new, but keep the old order. + OldF->replaceAllUsesWith(Replacement); + if (NewF) { + NewF->removeFromParent(); + OldF->getParent()->getFunctionList().insertAfter(OldF, NewF); + } + OldF->eraseFromParent(); + } +} + +void CodeGenModule::checkAliases() { + bool Error = false; + for (std::vector<GlobalDecl>::iterator I = Aliases.begin(), + E = Aliases.end(); I != E; ++I) { + const GlobalDecl &GD = *I; + const ValueDecl *D = cast<ValueDecl>(GD.getDecl()); + const AliasAttr *AA = D->getAttr<AliasAttr>(); + StringRef MangledName = getMangledName(GD); + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry); + llvm::GlobalValue *GV = Alias->getAliasedGlobal(); + if (GV->isDeclaration()) { + Error = true; + getDiags().Report(AA->getLocation(), diag::err_alias_to_undefined); + } else if (!Alias->resolveAliasedGlobal(/*stopOnWeak*/ false)) { + Error = true; + getDiags().Report(AA->getLocation(), diag::err_cyclic_alias); + } + } + if (!Error) + return; + + for (std::vector<GlobalDecl>::iterator I = Aliases.begin(), + E = Aliases.end(); I != E; ++I) { + const GlobalDecl &GD = *I; + StringRef MangledName = getMangledName(GD); + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry); + Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType())); + Alias->eraseFromParent(); + } +} + void CodeGenModule::Release() { EmitDeferred(); + applyReplacements(); + checkAliases(); EmitCXXGlobalInitFunc(); EmitCXXGlobalDtorFunc(); EmitCXXThreadLocalInitFunc(); @@ -186,9 +249,23 @@ void CodeGenModule::Release() { EmitStaticExternCAliases(); EmitLLVMUsed(); - if (CodeGenOpts.Autolink && Context.getLangOpts().Modules) { + if (CodeGenOpts.Autolink && + (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) { EmitModuleLinkOptions(); } + if (CodeGenOpts.DwarfVersion) + // We actually want the latest version when there are conflicts. + // We can change from Warning to Latest if such mode is supported. + getModule().addModuleFlag(llvm::Module::Warning, "Dwarf Version", + CodeGenOpts.DwarfVersion); + if (DebugInfo) + // We support a single version in the linked module: error out when + // modules do not have the same version. We are going to implement dropping + // debug info when the version number is not up-to-date. Once that is + // done, the bitcode linker is not going to see modules with different + // version numbers. + getModule().addModuleFlag(llvm::Module::Error, "Debug Info Version", + llvm::DEBUG_METADATA_VERSION); SimplifyPersonality(); @@ -200,6 +277,8 @@ void CodeGenModule::Release() { if (DebugInfo) DebugInfo->finalize(); + + EmitVersionIdentMetadata(); } void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { @@ -239,14 +318,14 @@ llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O); } -/// Decorate the instruction with a TBAA tag. For scalar TBAA, the tag -/// is the same as the type. For struct-path aware TBAA, the tag -/// is different from the type: base type, access type and offset. +/// Decorate the instruction with a TBAA tag. For both scalar TBAA +/// and struct-path aware TBAA, the tag has the same format: +/// base type, access type and offset. /// When ConvertTypeToTag is true, we create a tag based on the scalar type. void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo, bool ConvertTypeToTag) { - if (ConvertTypeToTag && TBAA && CodeGenOpts.StructPathTBAA) + if (ConvertTypeToTag && TBAA) Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAA->getTBAAScalarTagInfo(TBAAInfo)); else @@ -260,10 +339,7 @@ void CodeGenModule::Error(SourceLocation loc, StringRef error) { /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified stmt yet. -void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, - bool OmitOnError) { - if (OmitOnError && getDiags().hasErrorOccurred()) - return; +void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type) { unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "cannot compile this %0 yet"); std::string Msg = Type; @@ -273,10 +349,7 @@ void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified decl yet. -void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type, - bool OmitOnError) { - if (OmitOnError && getDiags().hasErrorOccurred()) - return; +void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type) { unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "cannot compile this %0 yet"); std::string Msg = Type; @@ -428,9 +501,6 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) { getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out); else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND)) getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out); - else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND)) - getCXXABI().getMangleContext().mangleBlock(BD, Out, - dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl())); else getCXXABI().getMangleContext().mangleName(ND, Out); @@ -508,7 +578,14 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) { } llvm::GlobalValue::LinkageTypes -CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { +CodeGenModule::getFunctionLinkage(GlobalDecl GD) { + const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); + + if (isa<CXXDestructorDecl>(D) && + getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D), + GD.getDtorType())) + return llvm::Function::LinkOnceODRLinkage; + GVALinkage Linkage = getContext().GetGVALinkageForFunction(D); if (Linkage == GVA_Internal) @@ -597,61 +674,66 @@ static bool hasUnwindExceptions(const LangOptions &LangOpts) { void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F) { + llvm::AttrBuilder B; + if (CodeGenOpts.UnwindTables) - F->setHasUWTable(); + B.addAttribute(llvm::Attribute::UWTable); if (!hasUnwindExceptions(LangOpts)) - F->addFnAttr(llvm::Attribute::NoUnwind); + B.addAttribute(llvm::Attribute::NoUnwind); if (D->hasAttr<NakedAttr>()) { // Naked implies noinline: we should not be inlining such functions. - F->addFnAttr(llvm::Attribute::Naked); - F->addFnAttr(llvm::Attribute::NoInline); + B.addAttribute(llvm::Attribute::Naked); + B.addAttribute(llvm::Attribute::NoInline); + } else if (D->hasAttr<NoInlineAttr>()) { + B.addAttribute(llvm::Attribute::NoInline); + } else if ((D->hasAttr<AlwaysInlineAttr>() || + D->hasAttr<ForceInlineAttr>()) && + !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::NoInline)) { + // (noinline wins over always_inline, and we can't specify both in IR) + B.addAttribute(llvm::Attribute::AlwaysInline); } - 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>() || D->hasAttr<ForceInlineAttr>()) && - !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::Attribute::OptimizeForSize); + if (D->hasAttr<ColdAttr>()) { + B.addAttribute(llvm::Attribute::OptimizeForSize); + B.addAttribute(llvm::Attribute::Cold); + } if (D->hasAttr<MinSizeAttr>()) - F->addFnAttr(llvm::Attribute::MinSize); - - if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) - F->setUnnamedAddr(true); - - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) - if (MD->isVirtual()) - F->setUnnamedAddr(true); + B.addAttribute(llvm::Attribute::MinSize); if (LangOpts.getStackProtector() == LangOptions::SSPOn) - F->addFnAttr(llvm::Attribute::StackProtect); + B.addAttribute(llvm::Attribute::StackProtect); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) - F->addFnAttr(llvm::Attribute::StackProtectReq); + B.addAttribute(llvm::Attribute::StackProtectReq); // Add sanitizer attributes if function is not blacklisted. - if (!SanitizerBlacklist.isIn(*F)) { + 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); + B.addAttribute(llvm::Attribute::SanitizeAddress); // Same for ThreadSanitizer and __attribute__((no_sanitize_thread)) if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) { - F->addFnAttr(llvm::Attribute::SanitizeThread); + B.addAttribute(llvm::Attribute::SanitizeThread); } // Same for MemorySanitizer and __attribute__((no_sanitize_memory)) if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>()) - F->addFnAttr(llvm::Attribute::SanitizeMemory); + B.addAttribute(llvm::Attribute::SanitizeMemory); } + F->addAttributes(llvm::AttributeSet::FunctionIndex, + llvm::AttributeSet::get( + F->getContext(), llvm::AttributeSet::FunctionIndex, B)); + + if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) + F->setUnnamedAddr(true); + else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) + if (MD->isVirtual()) + F->setUnnamedAddr(true); + unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); if (alignment) F->setAlignment(alignment); @@ -706,6 +788,14 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, if (!IsIncompleteFunction) SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F); + if (getCXXABI().HasThisReturn(GD)) { + assert(!F->arg_empty() && + F->arg_begin()->getType() + ->canLosslesslyBitCastTo(F->getReturnType()) && + "unexpected this return"); + F->addAttribute(1, llvm::Attribute::Returned); + } + // Only a few attributes are set on declarations; these may later be // overridden by a definition. @@ -727,6 +817,12 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, if (const SectionAttr *SA = FD->getAttr<SectionAttr>()) F->setSection(SA->getName()); + + // A replaceable global allocation function does not act like a builtin by + // default, only if it is invoked by a new-expression or delete-expression. + if (FD->isReplaceableGlobalAllocationFunction()) + F->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::NoBuiltin); } void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { @@ -762,31 +858,48 @@ void CodeGenModule::EmitLLVMUsed() { GV->setSection("llvm.metadata"); } +void CodeGenModule::AppendLinkerOptions(StringRef Opts) { + llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opts); + LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); +} + +void CodeGenModule::AddDetectMismatch(StringRef Name, StringRef Value) { + llvm::SmallString<32> Opt; + getTargetCodeGenInfo().getDetectMismatchOption(Name, Value, Opt); + llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opt); + LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); +} + +void CodeGenModule::AddDependentLib(StringRef Lib) { + llvm::SmallString<24> Opt; + getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt); + llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opt); + LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); +} + /// \brief Add link options implied by the given module, including modules /// it depends on, using a postorder walk. -static void addLinkOptionsPostorder(llvm::LLVMContext &Context, +static void addLinkOptionsPostorder(CodeGenModule &CGM, 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); + addLinkOptionsPostorder(CGM, 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); + addLinkOptionsPostorder(CGM, Mod->Imports[I-1], Metadata, Visited); } // Add linker options to link against the libraries/frameworks // described by this module. + llvm::LLVMContext &Context = CGM.getLLVMContext(); 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. + // Link against a framework. Frameworks are currently Darwin only, so we + // don't to ask TargetCodeGenInfo for the spelling of the linker option. if (Mod->LinkLibraries[I-1].IsFramework) { llvm::Value *Args[2] = { llvm::MDString::get(Context, "-framework"), @@ -798,9 +911,10 @@ static void addLinkOptionsPostorder(llvm::LLVMContext &Context, } // Link against a library. - llvm::Value *OptString - = llvm::MDString::get(Context, - "-l" + Mod->LinkLibraries[I-1].Library); + llvm::SmallString<24> Opt; + CGM.getTargetCodeGenInfo().getDependentLibraryOption( + Mod->LinkLibraries[I-1].Library, Opt); + llvm::Value *OptString = llvm::MDString::get(Context, Opt); Metadata.push_back(llvm::MDNode::get(Context, OptString)); } } @@ -824,8 +938,7 @@ void CodeGenModule::EmitModuleLinkOptions() { // 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(); + clang::Module *Mod = Stack.pop_back_val(); bool AnyChildren = false; @@ -852,20 +965,23 @@ void CodeGenModule::EmitModuleLinkOptions() { } // Add link options for all of the imported modules in reverse topological - // order. + // order. We don't do anything to try to order import link flags with respect + // to linker options inserted by things like #pragma comment(). 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); + addLinkOptionsPostorder(*this, *M, MetadataArgs, Visited); } std::reverse(MetadataArgs.begin(), MetadataArgs.end()); + LinkerOptionsMetadata.append(MetadataArgs.begin(), MetadataArgs.end()); // Add the linker options metadata flag. getModule().addModuleFlag(llvm::Module::AppendUnique, "Linker Options", - llvm::MDNode::get(getLLVMContext(), MetadataArgs)); + llvm::MDNode::get(getLLVMContext(), + LinkerOptionsMetadata)); } void CodeGenModule::EmitDeferred() { @@ -928,9 +1044,9 @@ void CodeGenModule::EmitGlobalAnnotations() { } llvm::Constant *CodeGenModule::EmitAnnotationString(StringRef Str) { - llvm::StringMap<llvm::Constant*>::iterator i = AnnotationStrings.find(Str); - if (i != AnnotationStrings.end()) - return i->second; + llvm::Constant *&AStr = AnnotationStrings[Str]; + if (AStr) + return AStr; // Not found yet, create a new global. llvm::Constant *s = llvm::ConstantDataArray::getString(getLLVMContext(), Str); @@ -938,7 +1054,7 @@ llvm::Constant *CodeGenModule::EmitAnnotationString(StringRef Str) { true, llvm::GlobalValue::PrivateLinkage, s, ".str"); gv->setSection(AnnotationSection); gv->setUnnamedAddr(true); - AnnotationStrings[Str] = gv; + AStr = gv; return gv; } @@ -998,18 +1114,9 @@ llvm::Constant *CodeGenModule::GetAddrOfUuidDescriptor( const CXXUuidofExpr* E) { // Sema has verified that IIDSource has a __declspec(uuid()), and that its // well-formed. - StringRef Uuid; - if (E->isTypeOperand()) - Uuid = CXXUuidofExpr::GetUuidAttrOfType(E->getTypeOperand())->getGuid(); - else { - // Special case: __uuidof(0) means an all-zero GUID. - Expr *Op = E->getExprOperand(); - if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) - Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid(); - else - Uuid = "00000000-0000-0000-0000-000000000000"; - } - std::string Name = "__uuid_" + Uuid.str(); + StringRef Uuid = E->getUuidAsStringRef(Context); + std::string Name = "_GUID_" + Uuid.lower(); + std::replace(Name.begin(), Name.end(), '-', '_'); // Look for an existing global. if (llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name)) @@ -1018,22 +1125,9 @@ llvm::Constant *CodeGenModule::GetAddrOfUuidDescriptor( llvm::Constant *Init = EmitUuidofInitializer(Uuid, E->getType()); assert(Init && "failed to initialize as constant"); - // GUIDs are assumed to be 16 bytes, spread over 4-2-2-8 bytes. However, the - // first field is declared as "long", which for many targets is 8 bytes. - // Those architectures are not supported. (With the MS abi, long is always 4 - // bytes.) - llvm::Type *GuidType = getTypes().ConvertType(E->getType()); - if (Init->getType() != GuidType) { - DiagnosticsEngine &Diags = getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "__uuidof codegen is not supported on this architecture"); - Diags.Report(E->getExprLoc(), DiagID) << E->getSourceRange(); - Init = llvm::UndefValue::get(GuidType); - } - - llvm::GlobalVariable *GV = new llvm::GlobalVariable(getModule(), GuidType, - /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Init, Name); - GV->setUnnamedAddr(true); + llvm::GlobalVariable *GV = new llvm::GlobalVariable( + getModule(), Init->getType(), + /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name); return GV; } @@ -1203,9 +1297,10 @@ CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) { } bool -CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { - if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) +CodeGenModule::shouldEmitFunction(GlobalDecl GD) { + if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage) return true; + const FunctionDecl *F = cast<FunctionDecl>(GD.getDecl()); if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>()) return false; @@ -1217,6 +1312,23 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { return !isTriviallyRecursive(F); } +/// If the type for the method's class was generated by +/// CGDebugInfo::createContextChain(), the cache contains only a +/// limited DIType without any declarations. Since EmitFunctionStart() +/// needs to find the canonical declaration for each method, we need +/// to construct the complete type prior to emitting the method. +void CodeGenModule::CompleteDIClassType(const CXXMethodDecl* D) { + if (!D->isInstance()) + return; + + if (CGDebugInfo *DI = getModuleDebugInfo()) + if (getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) { + const PointerType *ThisPtr = + cast<PointerType>(D->getThisType(getContext())); + DI->getOrCreateRecordType(ThisPtr->getPointeeType(), D->getLocation()); + } +} + void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { const ValueDecl *D = cast<ValueDecl>(GD.getDecl()); @@ -1224,13 +1336,14 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { Context.getSourceManager(), "Generating code for declaration"); - if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + if (isa<FunctionDecl>(D)) { // At -O0, don't generate IR for functions with available_externally // linkage. - if (!shouldEmitFunction(Function)) + if (!shouldEmitFunction(GD)) return; if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { + CompleteDIClassType(Method); // Make sure to emit the definition(s) before we emit the thunks. // This is necessary for the generation of certain thunks. if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method)) @@ -1265,13 +1378,15 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { llvm::Constant * CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, - GlobalDecl D, bool ForVTable, + GlobalDecl GD, bool ForVTable, llvm::AttributeSet ExtraAttrs) { + const Decl *D = GD.getDecl(); + // Lookup the entry, lazily creating it if necessary. llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (Entry) { if (WeakRefReferences.erase(Entry)) { - const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl()); + const FunctionDecl *FD = cast_or_null<FunctionDecl>(D); if (FD && !FD->hasAttr<WeakAttr>()) Entry->setLinkage(llvm::Function::ExternalLinkage); } @@ -1283,6 +1398,14 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo()); } + // All MSVC dtors other than the base dtor are linkonce_odr and delegate to + // each other bottoming out with the base dtor. Therefore we emit non-base + // dtors on usage, even if there is no dtor definition in the TU. + if (D && isa<CXXDestructorDecl>(D) && + getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D), + GD.getDtorType())) + DeferredDeclsToEmit.push_back(GD); + // This function doesn't have a complete type (for example, the return // type is an incomplete struct). Use a fake type instead, and make // sure not to try to set attributes. @@ -1300,8 +1423,8 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, llvm::Function::ExternalLinkage, MangledName, &getModule()); assert(F->getName() == MangledName && "name was uniqued!"); - if (D.getDecl()) - SetFunctionAttributes(D, F, IsIncompleteFunction); + if (D) + SetFunctionAttributes(GD, F, IsIncompleteFunction); if (ExtraAttrs.hasAttributes(llvm::AttributeSet::FunctionIndex)) { llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeSet::FunctionIndex); F->addAttributes(llvm::AttributeSet::FunctionIndex, @@ -1320,6 +1443,12 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, DeferredDeclsToEmit.push_back(DDI->second); DeferredDecls.erase(DDI); + // Otherwise, if this is a sized deallocation function, emit a weak definition + // for it at the end of the translation unit. + } else if (D && cast<FunctionDecl>(D) + ->getCorrespondingUnsizedGlobalDeallocationFunction()) { + DeferredDeclsToEmit.push_back(GD); + // Otherwise, there are cases we have to worry about where we're // using a declaration for which we must emit a definition but where // we might not find a top-level definition: @@ -1331,18 +1460,18 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, // // We also don't emit a definition for a function if it's going to be an entry // in a vtable, unless it's already marked as used. - } else if (getLangOpts().CPlusPlus && D.getDecl()) { + } else if (getLangOpts().CPlusPlus && D) { // Look for a declaration that's lexically in a record. - const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl()); + const FunctionDecl *FD = cast<FunctionDecl>(D); FD = FD->getMostRecentDecl(); do { if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) { if (FD->isImplicit() && !ForVTable) { assert(FD->isUsed() && "Sema didn't mark implicit function as used!"); - DeferredDeclsToEmit.push_back(D.getWithDecl(FD)); + DeferredDeclsToEmit.push_back(GD.getWithDecl(FD)); break; } else if (FD->doesThisDeclarationHaveABody()) { - DeferredDeclsToEmit.push_back(D.getWithDecl(FD)); + DeferredDeclsToEmit.push_back(GD.getWithDecl(FD)); break; } } @@ -1436,6 +1565,9 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, return Entry; // Make sure the result is of the correct type. + if (Entry->getType()->getAddressSpace() != Ty->getAddressSpace()) + return llvm::ConstantExpr::getAddrSpaceCast(Entry, Ty); + return llvm::ConstantExpr::getBitCast(Entry, Ty); } @@ -1483,12 +1615,19 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, CXXThreadLocals.push_back(std::make_pair(D, GV)); setTLSMode(GV, *D); } + + // If required by the ABI, treat declarations of static data members with + // inline initializers as definitions. + if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() && + D->isStaticDataMember() && D->hasInit() && + !D->isThisDeclarationADefinition()) + EmitGlobalVarDefinition(D); } if (AddrSpace != Ty->getAddressSpace()) - return llvm::ConstantExpr::getBitCast(GV, Ty); - else - return GV; + return llvm::ConstantExpr::getAddrSpaceCast(GV, Ty); + + return GV; } @@ -1581,125 +1720,6 @@ CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const { TheDataLayout.getTypeStoreSizeInBits(Ty)); } -llvm::Constant * -CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D, - const Expr *rawInit) { - ArrayRef<ExprWithCleanups::CleanupObject> cleanups; - if (const ExprWithCleanups *withCleanups = - dyn_cast<ExprWithCleanups>(rawInit)) { - cleanups = withCleanups->getObjects(); - rawInit = withCleanups->getSubExpr(); - } - - const InitListExpr *init = dyn_cast<InitListExpr>(rawInit); - if (!init || !init->initializesStdInitializerList() || - init->getNumInits() == 0) - return 0; - - ASTContext &ctx = getContext(); - unsigned numInits = init->getNumInits(); - // FIXME: This check is here because we would otherwise silently miscompile - // nested global std::initializer_lists. Better would be to have a real - // implementation. - for (unsigned i = 0; i < numInits; ++i) { - const InitListExpr *inner = dyn_cast<InitListExpr>(init->getInit(i)); - if (inner && inner->initializesStdInitializerList()) { - ErrorUnsupported(inner, "nested global std::initializer_list"); - return 0; - } - } - - // Synthesize a fake VarDecl for the array and initialize that. - QualType elementType = init->getInit(0)->getType(); - llvm::APInt numElements(ctx.getTypeSize(ctx.getSizeType()), numInits); - QualType arrayType = ctx.getConstantArrayType(elementType, numElements, - ArrayType::Normal, 0); - - IdentifierInfo *name = &ctx.Idents.get(D->getNameAsString() + "__initlist"); - TypeSourceInfo *sourceInfo = ctx.getTrivialTypeSourceInfo( - arrayType, D->getLocation()); - VarDecl *backingArray = VarDecl::Create(ctx, const_cast<DeclContext*>( - D->getDeclContext()), - D->getLocStart(), D->getLocation(), - name, arrayType, sourceInfo, - SC_Static); - backingArray->setTSCSpec(D->getTSCSpec()); - - // Now clone the InitListExpr to initialize the array instead. - // Incredible hack: we want to use the existing InitListExpr here, so we need - // to tell it that it no longer initializes a std::initializer_list. - ArrayRef<Expr*> Inits(const_cast<InitListExpr*>(init)->getInits(), - init->getNumInits()); - Expr *arrayInit = new (ctx) InitListExpr(ctx, init->getLBraceLoc(), Inits, - init->getRBraceLoc()); - arrayInit->setType(arrayType); - - if (!cleanups.empty()) - arrayInit = ExprWithCleanups::Create(ctx, arrayInit, cleanups); - - backingArray->setInit(arrayInit); - - // Emit the definition of the array. - EmitGlobalVarDefinition(backingArray); - - // Inspect the initializer list to validate it and determine its type. - // FIXME: doing this every time is probably inefficient; caching would be nice - RecordDecl *record = init->getType()->castAs<RecordType>()->getDecl(); - RecordDecl::field_iterator field = record->field_begin(); - if (field == record->field_end()) { - ErrorUnsupported(D, "weird std::initializer_list"); - return 0; - } - QualType elementPtr = ctx.getPointerType(elementType.withConst()); - // Start pointer. - if (!ctx.hasSameType(field->getType(), elementPtr)) { - ErrorUnsupported(D, "weird std::initializer_list"); - return 0; - } - ++field; - if (field == record->field_end()) { - ErrorUnsupported(D, "weird std::initializer_list"); - return 0; - } - bool isStartEnd = false; - if (ctx.hasSameType(field->getType(), elementPtr)) { - // End pointer. - isStartEnd = true; - } else if(!ctx.hasSameType(field->getType(), ctx.getSizeType())) { - ErrorUnsupported(D, "weird std::initializer_list"); - return 0; - } - - // Now build an APValue representing the std::initializer_list. - APValue initListValue(APValue::UninitStruct(), 0, 2); - APValue &startField = initListValue.getStructField(0); - APValue::LValuePathEntry startOffsetPathEntry; - startOffsetPathEntry.ArrayIndex = 0; - startField = APValue(APValue::LValueBase(backingArray), - CharUnits::fromQuantity(0), - llvm::makeArrayRef(startOffsetPathEntry), - /*IsOnePastTheEnd=*/false, 0); - - if (isStartEnd) { - APValue &endField = initListValue.getStructField(1); - APValue::LValuePathEntry endOffsetPathEntry; - endOffsetPathEntry.ArrayIndex = numInits; - endField = APValue(APValue::LValueBase(backingArray), - ctx.getTypeSizeInChars(elementType) * numInits, - llvm::makeArrayRef(endOffsetPathEntry), - /*IsOnePastTheEnd=*/true, 0); - } else { - APValue &sizeField = initListValue.getStructField(1); - sizeField = APValue(llvm::APSInt(numElements)); - } - - // Emit the constant for the initializer_list. - llvm::Constant *llvmInit = - EmitConstantValueForMemory(initListValue, D->getType()); - assert(llvmInit && "failed to initialize as constant"); - return llvmInit; -} - unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D, unsigned AddrSpace) { if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) { @@ -1726,12 +1746,12 @@ void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D, return; // Must have internal linkage and an ordinary name. - if (!D->getIdentifier() || D->getLinkage() != InternalLinkage) + if (!D->getIdentifier() || D->getFormalLinkage() != InternalLinkage) return; // Must be in an extern "C" context. Entities declared directly within // a record are not extern "C" even if the record is in such a context. - const SomeDecl *First = D->getFirstDeclaration(); + const SomeDecl *First = D->getFirstDecl(); if (First->getDeclContext()->isRecord() || !First->isInExternCContext()) return; @@ -1770,18 +1790,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type"); Init = EmitNullConstant(D->getType()); } else { - // If this is a std::initializer_list, emit the special initializer. - Init = MaybeEmitGlobalStdInitializerListInitializer(D, InitExpr); - // An empty init list will perform zero-initialization, which happens - // to be exactly what we want. - // FIXME: It does so in a global constructor, which is *not* what we - // want. + initializedGlobalDecl = GlobalDecl(D); + Init = EmitConstantInit(*InitDecl); if (!Init) { - initializedGlobalDecl = GlobalDecl(D); - Init = EmitConstantInit(*InitDecl); - } - if (!Init) { QualType T = InitExpr->getType(); if (D->getType()->isReferenceType()) T = D->getType(); @@ -1808,7 +1820,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // Strip off a bitcast if we got one back. if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) { assert(CE->getOpcode() == llvm::Instruction::BitCast || - // all zero index gep. + CE->getOpcode() == llvm::Instruction::AddrSpaceCast || + // All zero index gep. CE->getOpcode() == llvm::Instruction::GetElementPtr); Entry = CE->getOperand(0); } @@ -1860,8 +1873,16 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // Set the llvm linkage type as appropriate. llvm::GlobalValue::LinkageTypes Linkage = - GetLLVMLinkageVarDefinition(D, GV); + GetLLVMLinkageVarDefinition(D, GV->isConstant()); GV->setLinkage(Linkage); + + // If required by the ABI, give definitions of static data members with inline + // initializers linkonce_odr linkage. + if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() && + D->isStaticDataMember() && InitExpr && + !InitDecl->isThisDeclarationADefinition()) + GV->setLinkage(llvm::GlobalVariable::LinkOnceODRLinkage); + if (Linkage == llvm::GlobalVariable::CommonLinkage) // common vars aren't constant even if declared const. GV->setConstant(false); @@ -1891,8 +1912,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { } llvm::GlobalValue::LinkageTypes -CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, - llvm::GlobalVariable *GV) { +CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) { GVALinkage Linkage = getContext().GetGVALinkageForVariable(D); if (Linkage == GVA_Internal) return llvm::Function::InternalLinkage; @@ -1900,8 +1920,14 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, return llvm::Function::DLLImportLinkage; else if (D->hasAttr<DLLExportAttr>()) return llvm::Function::DLLExportLinkage; - else if (D->hasAttr<WeakAttr>()) { - if (GV->isConstant()) + else if (D->hasAttr<SelectAnyAttr>()) { + // selectany symbols are externally visible, so use weak instead of + // linkonce. MSVC optimizes away references to const selectany globals, so + // all definitions should be the same and ODR linkage should be used. + // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx + return llvm::GlobalVariable::WeakODRLinkage; + } else if (D->hasAttr<WeakAttr>()) { + if (isConstant) return llvm::GlobalVariable::WeakODRLinkage; else return llvm::GlobalVariable::WeakAnyLinkage; @@ -2077,6 +2103,10 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { Entry = CE->getOperand(0); } + if (!cast<llvm::GlobalValue>(Entry)->isDeclaration()) { + getDiags().Report(D->getLocation(), diag::err_duplicate_mangled_name); + return; + } if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != Ty) { llvm::GlobalValue *OldFn = cast<llvm::GlobalValue>(Entry); @@ -2126,7 +2156,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { // want to propagate this information down (e.g. to local static // declarations). llvm::Function *Fn = cast<llvm::Function>(Entry); - setFunctionLinkage(D, Fn); + setFunctionLinkage(GD, Fn); // FIXME: this is redundant with part of SetFunctionDefinitionAttributes setGlobalVisibility(Fn, D); @@ -2159,6 +2189,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { if (Entry && !Entry->isDeclaration()) return; + Aliases.push_back(GD); + llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); // Create a reference to the named value. This ensures that it is emitted @@ -2624,11 +2656,16 @@ static llvm::GlobalVariable *GenerateStringLiteral(StringRef str, llvm::Constant *C = llvm::ConstantDataArray::getString(CGM.getLLVMContext(), str, false); + // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. + unsigned AddrSpace = 0; + if (CGM.getLangOpts().OpenCL) + AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_constant); + // Create a global variable for this string - llvm::GlobalVariable *GV = - new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant, - llvm::GlobalValue::PrivateLinkage, - C, GlobalName); + llvm::GlobalVariable *GV = new llvm::GlobalVariable( + CGM.getModule(), C->getType(), constant, + llvm::GlobalValue::PrivateLinkage, C, GlobalName, 0, + llvm::GlobalVariable::NotThreadLocal, AddrSpace); GV->setAlignment(Alignment); GV->setUnnamedAddr(true); return GV; @@ -2684,6 +2721,74 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str, return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment); } +llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary( + const MaterializeTemporaryExpr *E, const Expr *Init) { + assert((E->getStorageDuration() == SD_Static || + E->getStorageDuration() == SD_Thread) && "not a global temporary"); + const VarDecl *VD = cast<VarDecl>(E->getExtendingDecl()); + + // If we're not materializing a subobject of the temporary, keep the + // cv-qualifiers from the type of the MaterializeTemporaryExpr. + QualType MaterializedType = Init->getType(); + if (Init == E->GetTemporaryExpr()) + MaterializedType = E->getType(); + + llvm::Constant *&Slot = MaterializedGlobalTemporaryMap[E]; + if (Slot) + return Slot; + + // FIXME: If an externally-visible declaration extends multiple temporaries, + // we need to give each temporary the same name in every translation unit (and + // we also need to make the temporaries externally-visible). + SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out); + Out.flush(); + + APValue *Value = 0; + if (E->getStorageDuration() == SD_Static) { + // We might have a cached constant initializer for this temporary. Note + // that this might have a different value from the value computed by + // evaluating the initializer if the surrounding constant expression + // modifies the temporary. + Value = getContext().getMaterializedTemporaryValue(E, false); + if (Value && Value->isUninit()) + Value = 0; + } + + // Try evaluating it now, it might have a constant initializer. + Expr::EvalResult EvalResult; + if (!Value && Init->EvaluateAsRValue(EvalResult, getContext()) && + !EvalResult.hasSideEffects()) + Value = &EvalResult.Val; + + llvm::Constant *InitialValue = 0; + bool Constant = false; + llvm::Type *Type; + if (Value) { + // The temporary has a constant initializer, use it. + InitialValue = EmitConstantValue(*Value, MaterializedType, 0); + Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value); + Type = InitialValue->getType(); + } else { + // No initializer, the initialization will be provided when we + // initialize the declaration which performed lifetime extension. + Type = getTypes().ConvertTypeForMem(MaterializedType); + } + + // Create a global variable for this lifetime-extended temporary. + llvm::GlobalVariable *GV = + new llvm::GlobalVariable(getModule(), Type, Constant, + llvm::GlobalValue::PrivateLinkage, + InitialValue, Name.c_str()); + GV->setAlignment( + getContext().getTypeAlignInChars(MaterializedType).getQuantity()); + if (VD->getTLSKind()) + setTLSMode(GV, *VD); + Slot = GV; + return GV; +} + /// EmitObjCPropertyImplementations - Emit information for synthesized /// properties for an implementation. void CodeGenModule::EmitObjCPropertyImplementations(const @@ -2767,8 +2872,13 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) { /// 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) + I != E; ++I) { + if (const VarDecl *VD = dyn_cast<VarDecl>(*I)) + if (VD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization && + VD->getTemplateSpecializationKind() != TSK_Undeclared) + continue; EmitTopLevelDecl(*I); + } } // EmitLinkageSpec - Emit all declarations in a linkage spec. @@ -2795,12 +2905,6 @@ void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) { /// 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; @@ -2816,8 +2920,12 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { EmitGlobal(cast<FunctionDecl>(D)); break; - + case Decl::Var: + // Skip variable templates + if (cast<VarDecl>(D)->getDescribedVarTemplate()) + return; + case Decl::VarTemplateSpecialization: EmitGlobal(cast<VarDecl>(D)); break; @@ -2834,12 +2942,17 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::UsingShadow: case Decl::Using: case Decl::ClassTemplate: + case Decl::VarTemplate: + case Decl::VarTemplatePartialSpecialization: case Decl::FunctionTemplate: case Decl::TypeAliasTemplate: - case Decl::NamespaceAlias: case Decl::Block: case Decl::Empty: break; + case Decl::NamespaceAlias: + if (CGDebugInfo *DI = getModuleDebugInfo()) + DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D)); + return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getModuleDebugInfo()) DI->EmitUsingDirective(cast<UsingDirectiveDecl>(*D)); @@ -2850,12 +2963,12 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { cast<FunctionDecl>(D)->isLateTemplateParsed()) return; - EmitCXXConstructors(cast<CXXConstructorDecl>(D)); + getCXXABI().EmitCXXConstructors(cast<CXXConstructorDecl>(D)); break; case Decl::CXXDestructor: if (cast<FunctionDecl>(D)->isLateTemplateParsed()) return; - EmitCXXDestructors(cast<CXXDestructorDecl>(D)); + getCXXABI().EmitCXXDestructors(cast<CXXDestructorDecl>(D)); break; case Decl::StaticAssert: @@ -3032,6 +3145,18 @@ void CodeGenFunction::EmitDeclMetadata() { } } +void CodeGenModule::EmitVersionIdentMetadata() { + llvm::NamedMDNode *IdentMetadata = + TheModule.getOrInsertNamedMetadata("llvm.ident"); + std::string Version = getClangFullVersion(); + llvm::LLVMContext &Ctx = TheModule.getContext(); + + llvm::Value *IdentNode[] = { + llvm::MDString::get(Ctx, Version) + }; + IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode)); +} + void CodeGenModule::EmitCoverageFile() { if (!getCodeGenOpts().CoverageFile.empty()) { if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) { @@ -3054,26 +3179,24 @@ llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid, // 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(isHexDigit(Uuidstr[i])); + for (unsigned i = 0; i < 36; ++i) { + if (i == 8 || i == 13 || i == 18 || i == 23) assert(Uuid[i] == '-'); + else assert(isHexDigit(Uuid[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); - static const int Field3ValueOffsets[] = { 19, 21, 24, 26, 28, 30, 32, 34 }; - - 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( - llvm::APInt(8, StringRef(Uuidstr + Field3ValueOffsets[t], 2), 16))); - - return EmitConstantValue(InitStruct, GuidType); + + const unsigned Field3ValueOffsets[8] = { 19, 21, 24, 26, 28, 30, 32, 34 }; + + llvm::Constant *Field3[8]; + for (unsigned Idx = 0; Idx < 8; ++Idx) + Field3[Idx] = llvm::ConstantInt::get( + Int8Ty, Uuid.substr(Field3ValueOffsets[Idx], 2), 16); + + llvm::Constant *Fields[4] = { + llvm::ConstantInt::get(Int32Ty, Uuid.substr(0, 8), 16), + llvm::ConstantInt::get(Int16Ty, Uuid.substr(9, 4), 16), + llvm::ConstantInt::get(Int16Ty, Uuid.substr(14, 4), 16), + llvm::ConstantArray::get(llvm::ArrayType::get(Int8Ty, 8), Field3) + }; + + return llvm::ConstantStruct::getAnon(Fields); } |