diff options
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 227 |
1 files changed, 171 insertions, 56 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 41f8721468..3656602c3d 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1,9 +1,8 @@ //===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -373,7 +372,7 @@ CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const { SourceManager &SM = CGM.getContext().getSourceManager(); bool Invalid; - llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid); + const llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid); if (Invalid) return None; @@ -451,8 +450,8 @@ CGDebugInfo::createFile(StringRef FileName, for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt) llvm::sys::path::append(DirBuf, *CurDirIt); if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) { - // The common prefix only the root; stripping it would cause - // LLVM diagnostic locations to be more confusing. + // Don't strip the common prefix if it is only the root "/" + // since that would make LLVM diagnostic locations confusing. Dir = {}; File = RemappedFile; } else { @@ -916,6 +915,11 @@ static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM, if (!needsTypeIdentifier(TD, CGM, TheCU)) return Identifier; + if (const auto *RD = dyn_cast<CXXRecordDecl>(TD)) + if (RD->getDefinition()) + if (RD->isDynamicClass() && + CGM.getVTableLinkage(RD) == llvm::GlobalValue::ExternalLinkage) + return Identifier; // TODO: This is using the RTTI name. Is there a better way to get // a unique string for a type? @@ -1726,31 +1730,37 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, QualType T = TA.getParamTypeForDecl().getDesugaredType(CGM.getContext()); llvm::DIType *TTy = getOrCreateType(T, Unit); llvm::Constant *V = nullptr; - const CXXMethodDecl *MD; - // Variable pointer template parameters have a value that is the address - // of the variable. - if (const auto *VD = dyn_cast<VarDecl>(D)) - V = CGM.GetAddrOfGlobalVar(VD); - // Member function pointers have special support for building them, though - // this is currently unsupported in LLVM CodeGen. - else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->isInstance()) - V = CGM.getCXXABI().EmitMemberFunctionPointer(MD); - else if (const auto *FD = dyn_cast<FunctionDecl>(D)) - V = CGM.GetAddrOfFunction(FD); - // Member data pointers have special handling too to compute the fixed - // offset within the object. - else if (const auto *MPT = dyn_cast<MemberPointerType>(T.getTypePtr())) { - // These five lines (& possibly the above member function pointer - // handling) might be able to be refactored to use similar code in - // CodeGenModule::getMemberPointerConstant - uint64_t fieldOffset = CGM.getContext().getFieldOffset(D); - CharUnits chars = - CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset); - V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars); + // Skip retrieve the value if that template parameter has cuda device + // attribute, i.e. that value is not available at the host side. + if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice || + !D->hasAttr<CUDADeviceAttr>()) { + const CXXMethodDecl *MD; + // Variable pointer template parameters have a value that is the address + // of the variable. + if (const auto *VD = dyn_cast<VarDecl>(D)) + V = CGM.GetAddrOfGlobalVar(VD); + // Member function pointers have special support for building them, + // though this is currently unsupported in LLVM CodeGen. + else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->isInstance()) + V = CGM.getCXXABI().EmitMemberFunctionPointer(MD); + else if (const auto *FD = dyn_cast<FunctionDecl>(D)) + V = CGM.GetAddrOfFunction(FD); + // Member data pointers have special handling too to compute the fixed + // offset within the object. + else if (const auto *MPT = + dyn_cast<MemberPointerType>(T.getTypePtr())) { + // These five lines (& possibly the above member function pointer + // handling) might be able to be refactored to use similar code in + // CodeGenModule::getMemberPointerConstant + uint64_t fieldOffset = CGM.getContext().getFieldOffset(D); + CharUnits chars = + CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset); + V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars); + } + V = V->stripPointerCasts(); } TemplateParams.push_back(DBuilder.createTemplateValueParameter( - TheCU, Name, TTy, - cast_or_null<llvm::Constant>(V->stripPointerCasts()))); + TheCU, Name, TTy, cast_or_null<llvm::Constant>(V))); } break; case TemplateArgument::NullPtr: { QualType T = TA.getNullPtrType(); @@ -1817,32 +1827,24 @@ CGDebugInfo::CollectFunctionTemplateParams(const FunctionDecl *FD, } llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL, - llvm::DIFile *Unit) { - if (auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL)) { - auto T = TS->getSpecializedTemplateOrPartial(); - auto TA = TS->getTemplateArgs().asArray(); - // Collect parameters for a partial specialization - if (T.is<VarTemplatePartialSpecializationDecl *>()) { - const TemplateParameterList *TList = - T.get<VarTemplatePartialSpecializationDecl *>() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - - // Collect parameters for an explicit specialization - if (T.is<VarTemplateDecl *>()) { - const TemplateParameterList *TList = T.get<VarTemplateDecl *>() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - } - return llvm::DINodeArray(); + llvm::DIFile *Unit) { + // Always get the full list of parameters, not just the ones from the + // specialization. A partial specialization may have fewer parameters than + // there are arguments. + auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL); + if (!TS) + return llvm::DINodeArray(); + VarTemplateDecl *T = TS->getSpecializedTemplate(); + const TemplateParameterList *TList = T->getTemplateParameters(); + auto TA = TS->getTemplateArgs().asArray(); + return CollectTemplateParams(TList, TA, Unit); } llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams( const ClassTemplateSpecializationDecl *TSpecial, llvm::DIFile *Unit) { - // Always get the full list of parameters, not just the ones from - // the specialization. + // Always get the full list of parameters, not just the ones from the + // specialization. A partial specialization may have fewer parameters than + // there are arguments. TemplateParameterList *TPList = TSpecial->getSpecializedTemplate()->getTemplateParameters(); const TemplateArgumentList &TAList = TSpecial->getTemplateArgs(); @@ -1875,6 +1877,58 @@ StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) { return internString("_vptr$", RD->getNameAsString()); } +StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD, + DynamicInitKind StubKind, + llvm::Function *InitFn) { + // If we're not emitting codeview, use the mangled name. For Itanium, this is + // arbitrary. + if (!CGM.getCodeGenOpts().EmitCodeView) + return InitFn->getName(); + + // Print the normal qualified name for the variable, then break off the last + // NNS, and add the appropriate other text. Clang always prints the global + // variable name without template arguments, so we can use rsplit("::") and + // then recombine the pieces. + SmallString<128> QualifiedGV; + StringRef Quals; + StringRef GVName; + { + llvm::raw_svector_ostream OS(QualifiedGV); + VD->printQualifiedName(OS, getPrintingPolicy()); + std::tie(Quals, GVName) = OS.str().rsplit("::"); + if (GVName.empty()) + std::swap(Quals, GVName); + } + + SmallString<128> InitName; + llvm::raw_svector_ostream OS(InitName); + if (!Quals.empty()) + OS << Quals << "::"; + + switch (StubKind) { + case DynamicInitKind::NoStub: + llvm_unreachable("not an initializer"); + case DynamicInitKind::Initializer: + OS << "`dynamic initializer for '"; + break; + case DynamicInitKind::AtExit: + OS << "`dynamic atexit destructor for '"; + break; + } + + OS << GVName; + + // Add any template specialization args. + if (const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) { + printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(), + getPrintingPolicy()); + } + + OS << '\''; + + return internString(OS.str()); +} + void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit, SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DICompositeType *RecordTy) { @@ -1954,6 +2008,20 @@ llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D, return T; } +void CGDebugInfo::addHeapAllocSiteMetadata(llvm::Instruction *CI, + QualType D, + SourceLocation Loc) { + llvm::MDNode *node; + if (D.getTypePtr()->isVoidPointerType()) { + node = llvm::MDNode::get(CGM.getLLVMContext(), None); + } else { + QualType PointeeTy = D.getTypePtr()->getPointeeType(); + node = getOrCreateType(PointeeTy, getOrCreateFile(Loc)); + } + + CI->setMetadata("heapallocsite", node); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2297,7 +2365,14 @@ CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod, } bool IsRootModule = M ? !M->Parent : true; - if (CreateSkeletonCU && IsRootModule) { + // When a module name is specified as -fmodule-name, that module gets a + // clang::Module object, but it won't actually be built or imported; it will + // be textual. + if (CreateSkeletonCU && IsRootModule && Mod.getASTFile().empty() && M) + assert(StringRef(M->Name).startswith(CGM.getLangOpts().ModuleName) && + "clang module without ASTFile must be specified by -fmodule-name"); + + if (CreateSkeletonCU && IsRootModule && !Mod.getASTFile().empty()) { // PCH files don't have a signature field in the control block, // but LLVM detects skeleton CUs by looking for a non-zero DWO id. // We use the lower 64 bits for debug info. @@ -2314,6 +2389,7 @@ CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod, Signature); DIB.finalize(); } + llvm::DIModule *Parent = IsRootModule ? nullptr : getOrCreateModuleRef( @@ -3021,9 +3097,9 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { else Flags |= llvm::DINode::FlagTypePassByValue; - // Record if a C++ record is trivial type. - if (CXXRD->isTrivial()) - Flags |= llvm::DINode::FlagTrivial; + // Record if a C++ record is non-trivial type. + if (!CXXRD->isTrivial()) + Flags |= llvm::DINode::FlagNonTrivial; } llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType( @@ -3443,6 +3519,11 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, } else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) { Name = getObjCMethodName(OMD); Flags |= llvm::DINode::FlagPrototyped; + } else if (isa<VarDecl>(D) && + GD.getDynamicInitKind() != DynamicInitKind::NoStub) { + // This is a global initializer or atexit destructor for a global variable. + Name = getDynamicInitializerName(cast<VarDecl>(D), GD.getDynamicInitKind(), + Fn); } else { // Use llvm function name. Name = Fn->getName(); @@ -3863,6 +3944,32 @@ CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage, return EmitDeclare(VD, Storage, llvm::None, Builder); } +void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) { + assert(DebugKind >= codegenoptions::LimitedDebugInfo); + assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); + + if (D->hasAttr<NoDebugAttr>()) + return; + + auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back()); + llvm::DIFile *Unit = getOrCreateFile(D->getLocation()); + + // Get location information. + unsigned Line = getLineNumber(D->getLocation()); + unsigned Column = getColumnNumber(D->getLocation()); + + StringRef Name = D->getName(); + + // Create the descriptor for the label. + auto *L = + DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize); + + // Insert an llvm.dbg.label into the current block. + DBuilder.insertLabel(L, + llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt), + Builder.GetInsertBlock()); +} + llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy, llvm::DIType *Ty) { llvm::DIType *CachedTy = getTypeOrNull(QualTy); @@ -4207,6 +4314,14 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, SmallVector<int64_t, 4> Expr; unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(D->getType()); + if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) { + if (D->hasAttr<CUDASharedAttr>()) + AddressSpace = + CGM.getContext().getTargetAddressSpace(LangAS::cuda_shared); + else if (D->hasAttr<CUDAConstantAttr>()) + AddressSpace = + CGM.getContext().getTargetAddressSpace(LangAS::cuda_constant); + } AppendAddressSpaceXDeref(AddressSpace, Expr); GVE = DBuilder.createGlobalVariableExpression( |