diff options
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 501 |
1 files changed, 328 insertions, 173 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 1a9080604a79..7e9e86763af9 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -248,6 +248,7 @@ PrintingPolicy CGDebugInfo::getPrintingPolicy() const { PP.PrintCanonicalTypes = true; PP.UsePreferredNames = false; PP.AlwaysIncludeTypeForTemplateArgument = true; + PP.UseEnumerators = false; // Apply -fdebug-prefix-map. PP.Callbacks = &PrintCB; @@ -424,16 +425,16 @@ CGDebugInfo::createFile(StringRef FileName, SmallString<128> DirBuf; SmallString<128> FileBuf; if (llvm::sys::path::is_absolute(RemappedFile)) { - // Strip the common prefix (if it is more than just "/") from current - // directory and FileName for a more space-efficient encoding. + // Strip the common prefix (if it is more than just "/" or "C:\") from + // current directory and FileName for a more space-efficient encoding. auto FileIt = llvm::sys::path::begin(RemappedFile); auto FileE = llvm::sys::path::end(RemappedFile); auto CurDirIt = llvm::sys::path::begin(CurDir); auto CurDirE = llvm::sys::path::end(CurDir); for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt) llvm::sys::path::append(DirBuf, *CurDirIt); - if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) { - // Don't strip the common prefix if it is only the root "/" + if (llvm::sys::path::root_path(DirBuf) == DirBuf) { + // Don't strip the common prefix if it is only the root ("/" or "C:\") // since that would make LLVM diagnostic locations confusing. Dir = {}; File = RemappedFile; @@ -444,7 +445,8 @@ CGDebugInfo::createFile(StringRef FileName, File = FileBuf; } } else { - Dir = CurDir; + if (!llvm::sys::path::is_absolute(FileName)) + Dir = CurDir; File = RemappedFile; } llvm::DIFile *F = DBuilder.createFile(File, Dir, CSInfo, Source); @@ -517,8 +519,9 @@ void CGDebugInfo::CreateCompileUnit() { // a relative path, so we look into the actual file entry for the main // file to determine the real absolute path for the file. std::string MainFileDir; - if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { - MainFileDir = std::string(MainFile->getDir()->getName()); + if (Optional<FileEntryRef> MainFile = + SM.getFileEntryRefForID(SM.getMainFileID())) { + MainFileDir = std::string(MainFile->getDir().getName()); if (!llvm::sys::path::is_absolute(MainFileName)) { llvm::SmallString<1024> MainFileDirSS(MainFileDir); llvm::sys::path::append(MainFileDirSS, MainFileName); @@ -927,28 +930,8 @@ static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q) { return (llvm::dwarf::Tag)0; } -// Strip MacroQualifiedTypeLoc and AttributedTypeLoc -// as their corresponding types will be ignored -// during code generation. Stripping them allows -// to maintain proper TypeLoc for a given type -// during code generation. -static TypeLoc StripMacroAttributed(TypeLoc TL) { - if (!TL) - return TL; - - while (true) { - if (auto MTL = TL.getAs<MacroQualifiedTypeLoc>()) - TL = MTL.getInnerLoc(); - else if (auto ATL = TL.getAs<AttributedTypeLoc>()) - TL = ATL.getModifiedLoc(); - else - break; - } - return TL; -} - -llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, + llvm::DIFile *Unit) { QualifierCollector Qc; const Type *T = Qc.strip(Ty); @@ -962,15 +945,7 @@ llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit, return getOrCreateType(QualType(T, 0), Unit); } - QualType NextTy = Qc.apply(CGM.getContext(), T); - TypeLoc NextTL; - if (NextTy.hasQualifiers()) - NextTL = TL; - else if (TL) { - if (auto QTL = TL.getAs<QualifiedTypeLoc>()) - NextTL = StripMacroAttributed(QTL.getNextTypeLoc()); - } - auto *FromTy = getOrCreateType(NextTy, Unit, NextTL); + auto *FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit); // No need to fill in the Name, Line, Size, Alignment, Offset in case of // CVR derived types. @@ -1014,10 +989,10 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty, Ty->getPointeeType(), Unit); } -llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, + llvm::DIFile *Unit) { return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, - Ty->getPointeeType(), Unit, TL); + Ty->getPointeeType(), Unit); } /// \return whether a C++ mangling exists for the type defined by TD. @@ -1158,8 +1133,7 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty, QualType PointeeTy, - llvm::DIFile *Unit, - TypeLoc TL) { + llvm::DIFile *Unit) { // Bit size, align and offset of the type. // Size is always the size of a pointer. We can't use getTypeSize here // because that does not return the correct value for references. @@ -1169,52 +1143,32 @@ llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag, Optional<unsigned> DWARFAddressSpace = CGM.getTarget().getDWARFAddressSpace(AddressSpace); - llvm::DINodeArray Annotations = nullptr; - TypeLoc NextTL; - if (TL) { - SmallVector<llvm::Metadata *, 4> Annots; - NextTL = TL.getNextTypeLoc(); - if (NextTL) { - // Traverse all MacroQualifiedTypeLoc, QualifiedTypeLoc and - // AttributedTypeLoc type locations so we can collect - // BTFTypeTag attributes for this pointer. - while (true) { - if (auto MTL = NextTL.getAs<MacroQualifiedTypeLoc>()) { - NextTL = MTL.getInnerLoc(); - } else if (auto QTL = NextTL.getAs<QualifiedTypeLoc>()) { - NextTL = QTL.getNextTypeLoc(); - } else if (auto ATL = NextTL.getAs<AttributedTypeLoc>()) { - if (const auto *A = ATL.getAttrAs<BTFTypeTagAttr>()) { - StringRef BTFTypeTag = A->getBTFTypeTag(); - if (!BTFTypeTag.empty()) { - llvm::Metadata *Ops[2] = { - llvm::MDString::get(CGM.getLLVMContext(), - StringRef("btf_type_tag")), - llvm::MDString::get(CGM.getLLVMContext(), BTFTypeTag)}; - Annots.insert(Annots.begin(), - llvm::MDNode::get(CGM.getLLVMContext(), Ops)); - } - } - NextTL = ATL.getModifiedLoc(); - } else { - break; - } - } + SmallVector<llvm::Metadata *, 4> Annots; + auto *BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy); + while (BTFAttrTy) { + StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag(); + if (!Tag.empty()) { + llvm::Metadata *Ops[2] = { + llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_type_tag")), + llvm::MDString::get(CGM.getLLVMContext(), Tag)}; + Annots.insert(Annots.begin(), + llvm::MDNode::get(CGM.getLLVMContext(), Ops)); } - - NextTL = StripMacroAttributed(TL.getNextTypeLoc()); - if (Annots.size() > 0) - Annotations = DBuilder.getOrCreateArray(Annots); + BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->getWrappedType()); } + llvm::DINodeArray Annotations = nullptr; + if (Annots.size() > 0) + Annotations = DBuilder.getOrCreateArray(Annots); + if (Tag == llvm::dwarf::DW_TAG_reference_type || Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit), Size, Align, DWARFAddressSpace); else - return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit, NextTL), - Size, Align, DWARFAddressSpace, - StringRef(), Annotations); + return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, + Align, DWARFAddressSpace, StringRef(), + Annotations); } llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name, @@ -1331,11 +1285,8 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { - TypeLoc TL; - if (const TypeSourceInfo *TSI = Ty->getDecl()->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); llvm::DIType *Underlying = - getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, TL); + getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); if (Ty->getDecl()->hasAttr<NoDebugAttr>()) return Underlying; @@ -1375,6 +1326,7 @@ static unsigned getDwarfCC(CallingConv CC) { return llvm::dwarf::DW_CC_LLVM_X86_64SysV; case CC_AAPCS: case CC_AArch64VectorCall: + case CC_AArch64SVEPCS: return llvm::dwarf::DW_CC_LLVM_AAPCS; case CC_AAPCS_VFP: return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP; @@ -1383,6 +1335,7 @@ static unsigned getDwarfCC(CallingConv CC) { case CC_SpirFunction: return llvm::dwarf::DW_CC_LLVM_SpirFunction; case CC_OpenCLKernel: + case CC_AMDGPUKernelCall: return llvm::dwarf::DW_CC_LLVM_OpenCLKernel; case CC_Swift: return llvm::dwarf::DW_CC_LLVM_Swift; @@ -1409,7 +1362,7 @@ static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func) { } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, - llvm::DIFile *Unit, TypeLoc TL) { + llvm::DIFile *Unit) { const auto *FPT = dyn_cast<FunctionProtoType>(Ty); if (FPT) { if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit)) @@ -1421,12 +1374,7 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, SmallVector<llvm::Metadata *, 16> EltTys; // Add the result type at least. - TypeLoc RetTL; - if (TL) { - if (auto FTL = TL.getAs<FunctionTypeLoc>()) - RetTL = FTL.getReturnLoc(); - } - EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit, RetTL)); + EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit)); llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; // Set up remainder of arguments if there is a prototype. @@ -1435,30 +1383,8 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, EltTys.push_back(DBuilder.createUnspecifiedParameter()); } else { Flags = getRefFlags(FPT); - bool DoneWithTL = false; - if (TL) { - if (auto FTL = TL.getAs<FunctionTypeLoc>()) { - DoneWithTL = true; - unsigned Idx = 0; - unsigned FTL_NumParams = FTL.getNumParams(); - for (const QualType &ParamType : FPT->param_types()) { - TypeLoc ParamTL; - if (Idx < FTL_NumParams) { - if (ParmVarDecl *Param = FTL.getParam(Idx)) { - if (const TypeSourceInfo *TSI = Param->getTypeSourceInfo()) - ParamTL = TSI->getTypeLoc(); - } - } - EltTys.push_back(getOrCreateType(ParamType, Unit, ParamTL)); - Idx++; - } - } - } - - if (!DoneWithTL) { - for (const QualType &ParamType : FPT->param_types()) - EltTys.push_back(getOrCreateType(ParamType, Unit)); - } + for (const QualType &ParamType : FPT->param_types()) + EltTys.push_back(getOrCreateType(ParamType, Unit)); if (FPT->isVariadic()) EltTys.push_back(DBuilder.createUnspecifiedParameter()); } @@ -1529,13 +1455,11 @@ llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl, Flags, DebugType, Annotations); } -llvm::DIType * -CGDebugInfo::createFieldType(StringRef name, QualType type, SourceLocation loc, - AccessSpecifier AS, uint64_t offsetInBits, - uint32_t AlignInBits, llvm::DIFile *tunit, - llvm::DIScope *scope, const RecordDecl *RD, - llvm::DINodeArray Annotations, TypeLoc TL) { - llvm::DIType *debugType = getOrCreateType(type, tunit, TL); +llvm::DIType *CGDebugInfo::createFieldType( + StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS, + uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit, + llvm::DIScope *scope, const RecordDecl *RD, llvm::DINodeArray Annotations) { + llvm::DIType *debugType = getOrCreateType(type, tunit); // Get the location for the field. llvm::DIFile *file = getOrCreateFile(loc); @@ -1643,12 +1567,9 @@ void CGDebugInfo::CollectRecordNormalField( } else { auto Align = getDeclAlignIfRequired(field, CGM.getContext()); llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field); - TypeLoc TL; - if (const TypeSourceInfo *TSI = field->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - FieldType = createFieldType(name, type, field->getLocation(), - field->getAccess(), OffsetInBits, Align, tunit, - RecordTy, RD, Annotations, TL); + FieldType = + createFieldType(name, type, field->getLocation(), field->getAccess(), + OffsetInBits, Align, tunit, RecordTy, RD, Annotations); } elements.push_back(FieldType); @@ -1725,7 +1646,7 @@ void CGDebugInfo::CollectRecordFields( llvm::DISubroutineType * CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, llvm::DIFile *Unit, bool decl) { - const FunctionProtoType *Func = Method->getType()->getAs<FunctionProtoType>(); + const auto *Func = Method->getType()->castAs<FunctionProtoType>(); if (Method->isStatic()) return cast_or_null<llvm::DISubroutineType>( getOrCreateType(QualType(Func, 0), Unit)); @@ -1760,9 +1681,17 @@ CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr, SmallVector<llvm::Metadata *, 16> Elts; // First element is always return type. For 'void' functions it is NULL. QualType temp = Func->getReturnType(); - if (temp->getTypeClass() == Type::Auto && decl) - Elts.push_back(CreateType(cast<AutoType>(temp))); - else + if (temp->getTypeClass() == Type::Auto && decl) { + const AutoType *AT = cast<AutoType>(temp); + + // It may be tricky in some cases to link the specification back the lambda + // call operator and so we skip emitting "auto" for lambdas. This is + // consistent with gcc as well. + if (AT->isDeduced() && ThisPtr->getPointeeCXXRecordDecl()->isLambda()) + Elts.push_back(getOrCreateType(AT->getDeducedType(), Unit)); + else + Elts.push_back(CreateType(AT)); + } else Elts.push_back(Args[0]); // "this" pointer is always first argument. @@ -3035,6 +2964,23 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIType *CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile *Unit) { + if (Ty->isExtVectorBoolType()) { + // Boolean ext_vector_type(N) are special because their real element type + // (bits of bit size) is not their Clang element type (_Bool of size byte). + // For now, we pretend the boolean vector were actually a vector of bytes + // (where each byte represents 8 bits of the actual vector). + // FIXME Debug info should actually represent this proper as a vector mask + // type. + auto &Ctx = CGM.getContext(); + uint64_t Size = CGM.getContext().getTypeSize(Ty); + uint64_t NumVectorBytes = Size / Ctx.getCharWidth(); + + // Construct the vector of 'char' type. + QualType CharVecTy = Ctx.getVectorType(Ctx.CharTy, NumVectorBytes, + VectorType::GenericVector); + return CreateType(CharVecTy->getAs<VectorType>(), Unit); + } + llvm::DIType *ElementTy = getOrCreateType(Ty->getElementType(), Unit); int64_t Count = Ty->getNumElements(); @@ -3348,6 +3294,9 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) { case Type::Attributed: T = cast<AttributedType>(T)->getEquivalentType(); break; + case Type::BTFTagAttributed: + T = cast<BTFTagAttributedType>(T)->getWrappedType(); + break; case Type::Elaborated: T = cast<ElaboratedType>(T)->getNamedType(); break; @@ -3409,8 +3358,7 @@ void CGDebugInfo::completeUnusedClass(const CXXRecordDecl &D) { RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr()); } -llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) { if (Ty.isNull()) return nullptr; @@ -3427,7 +3375,7 @@ llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit, if (auto *T = getTypeOrNull(Ty)) return T; - llvm::DIType *Res = CreateTypeNode(Ty, Unit, TL); + llvm::DIType *Res = CreateTypeNode(Ty, Unit); void *TyPtr = Ty.getAsOpaquePtr(); // And update the type cache. @@ -3471,11 +3419,10 @@ llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) { return nullptr; } -llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) { // Handle qualifiers, which recursively handles what they refer to. if (Ty.hasLocalQualifiers()) - return CreateQualifiedType(Ty, Unit, TL); + return CreateQualifiedType(Ty, Unit); // Work out details of type. switch (Ty->getTypeClass()) { @@ -3504,7 +3451,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit, case Type::Complex: return CreateType(cast<ComplexType>(Ty)); case Type::Pointer: - return CreateType(cast<PointerType>(Ty), Unit, TL); + return CreateType(cast<PointerType>(Ty), Unit); case Type::BlockPointer: return CreateType(cast<BlockPointerType>(Ty), Unit); case Type::Typedef: @@ -3515,7 +3462,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit, return CreateEnumType(cast<EnumType>(Ty)); case Type::FunctionProto: case Type::FunctionNoProto: - return CreateType(cast<FunctionType>(Ty), Unit, TL); + return CreateType(cast<FunctionType>(Ty), Unit); case Type::ConstantArray: case Type::VariableArray: case Type::IncompleteArray: @@ -3542,6 +3489,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit, case Type::Auto: case Type::Attributed: + case Type::BTFTagAttributed: case Type::Adjusted: case Type::Decayed: case Type::DeducedTemplateSpecialization: @@ -3615,7 +3563,11 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { return getOrCreateRecordFwdDecl(Ty, RDContext); uint64_t Size = CGM.getContext().getTypeSize(Ty); - auto Align = getDeclAlignIfRequired(D, CGM.getContext()); + // __attribute__((aligned)) can increase or decrease alignment *except* on a + // struct or struct member, where it only increases alignment unless 'packed' + // is also specified. To handle this case, the `getTypeAlignIfRequired` needs + // to be used. + auto Align = getTypeAlignIfRequired(Ty, CGM.getContext()); SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU); @@ -3908,6 +3860,17 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { auto N = I->second; if (auto *GVE = dyn_cast_or_null<llvm::DIGlobalVariableExpression>(N)) return GVE->getVariable(); + return cast<llvm::DINode>(N); + } + + // Search imported declaration cache if it is already defined + // as imported declaration. + auto IE = ImportedDeclCache.find(D->getCanonicalDecl()); + + if (IE != ImportedDeclCache.end()) { + auto N = IE->second; + if (auto *GVE = dyn_cast_or_null<llvm::DIImportedEntity>(N)) + return cast<llvm::DINode>(GVE); return dyn_cast_or_null<llvm::DINode>(N); } @@ -4064,12 +4027,7 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D, getDwarfCC(CC)); } - TypeLoc TL; - if (const auto *FD = dyn_cast<FunctionDecl>(D)) { - if (const TypeSourceInfo *TSI = FD->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - } - return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F, TL)); + return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F)); } QualType @@ -4328,7 +4286,7 @@ void CGDebugInfo::AppendAddressSpaceXDeref( return; Expr.push_back(llvm::dwarf::DW_OP_constu); - Expr.push_back(DWARFAddressSpace.getValue()); + Expr.push_back(*DWARFAddressSpace); Expr.push_back(llvm::dwarf::DW_OP_swap); Expr.push_back(llvm::dwarf::DW_OP_xderef); } @@ -4471,12 +4429,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, uint64_t XOffset = 0; if (VD->hasAttr<BlocksAttr>()) Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType; - else { - TypeLoc TL; - if (const TypeSourceInfo *TSI = VD->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - Ty = getOrCreateType(VD->getType(), Unit, TL); - } + else + Ty = getOrCreateType(VD->getType(), Unit); // If there is no debug info for this type then do not emit debug info // for this variable. @@ -4635,11 +4589,103 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, return D; } +llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD, + llvm::Value *Storage, + llvm::Optional<unsigned> ArgNo, + CGBuilderTy &Builder, + const bool UsePointerValue) { + assert(CGM.getCodeGenOpts().hasReducedDebugInfo()); + assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); + if (BD->hasAttr<NoDebugAttr>()) + return nullptr; + + // Skip the tuple like case, we don't handle that here + if (isa<DeclRefExpr>(BD->getBinding())) + return nullptr; + + llvm::DIFile *Unit = getOrCreateFile(BD->getLocation()); + llvm::DIType *Ty = getOrCreateType(BD->getType(), Unit); + + // If there is no debug info for this type then do not emit debug info + // for this variable. + if (!Ty) + return nullptr; + + auto Align = getDeclAlignIfRequired(BD, CGM.getContext()); + unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(BD->getType()); + + SmallVector<uint64_t, 3> Expr; + AppendAddressSpaceXDeref(AddressSpace, Expr); + + // Clang stores the sret pointer provided by the caller in a static alloca. + // Use DW_OP_deref to tell the debugger to load the pointer and treat it as + // the address of the variable. + if (UsePointerValue) { + assert(!llvm::is_contained(Expr, llvm::dwarf::DW_OP_deref) && + "Debug info already contains DW_OP_deref."); + Expr.push_back(llvm::dwarf::DW_OP_deref); + } + + unsigned Line = getLineNumber(BD->getLocation()); + unsigned Column = getColumnNumber(BD->getLocation()); + StringRef Name = BD->getName(); + auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back()); + // Create the descriptor for the variable. + llvm::DILocalVariable *D = DBuilder.createAutoVariable( + Scope, Name, Unit, Line, Ty, CGM.getLangOpts().Optimize, + llvm::DINode::FlagZero, Align); + + if (const MemberExpr *ME = dyn_cast<MemberExpr>(BD->getBinding())) { + if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) { + const unsigned fieldIndex = FD->getFieldIndex(); + const clang::CXXRecordDecl *parent = + (const CXXRecordDecl *)FD->getParent(); + const ASTRecordLayout &layout = + CGM.getContext().getASTRecordLayout(parent); + const uint64_t fieldOffset = layout.getFieldOffset(fieldIndex); + + if (fieldOffset != 0) { + Expr.push_back(llvm::dwarf::DW_OP_plus_uconst); + Expr.push_back( + CGM.getContext().toCharUnitsFromBits(fieldOffset).getQuantity()); + } + } + } else if (const ArraySubscriptExpr *ASE = + dyn_cast<ArraySubscriptExpr>(BD->getBinding())) { + if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ASE->getIdx())) { + const uint64_t value = IL->getValue().getZExtValue(); + const uint64_t typeSize = CGM.getContext().getTypeSize(BD->getType()); + + if (value != 0) { + Expr.push_back(llvm::dwarf::DW_OP_plus_uconst); + Expr.push_back(CGM.getContext() + .toCharUnitsFromBits(value * typeSize) + .getQuantity()); + } + } + } + + // Insert an llvm.dbg.declare into the current block. + DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), + llvm::DILocation::get(CGM.getLLVMContext(), Line, + Column, Scope, CurInlinedAt), + Builder.GetInsertBlock()); + + return D; +} + llvm::DILocalVariable * CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage, CGBuilderTy &Builder, const bool UsePointerValue) { assert(CGM.getCodeGenOpts().hasReducedDebugInfo()); + + if (auto *DD = dyn_cast<DecompositionDecl>(VD)) + for (auto *B : DD->bindings()) { + EmitDeclare(B, Storage, llvm::None, Builder, + VD->getType()->isReferenceType()); + } + return EmitDeclare(VD, Storage, llvm::None, Builder, UsePointerValue); } @@ -4975,6 +5021,52 @@ llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls( return GVE; } +static bool ReferencesAnonymousEntity(ArrayRef<TemplateArgument> Args); +static bool ReferencesAnonymousEntity(RecordType *RT) { + // Unnamed classes/lambdas can't be reconstituted due to a lack of column + // info we produce in the DWARF, so we can't get Clang's full name back. + // But so long as it's not one of those, it doesn't matter if some sub-type + // of the record (a template parameter) can't be reconstituted - because the + // un-reconstitutable type itself will carry its own name. + const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); + if (!RD) + return false; + if (!RD->getIdentifier()) + return true; + auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD); + if (!TSpecial) + return false; + return ReferencesAnonymousEntity(TSpecial->getTemplateArgs().asArray()); +} +static bool ReferencesAnonymousEntity(ArrayRef<TemplateArgument> Args) { + return llvm::any_of(Args, [&](const TemplateArgument &TA) { + switch (TA.getKind()) { + case TemplateArgument::Pack: + return ReferencesAnonymousEntity(TA.getPackAsArray()); + case TemplateArgument::Type: { + struct ReferencesAnonymous + : public RecursiveASTVisitor<ReferencesAnonymous> { + bool RefAnon = false; + bool VisitRecordType(RecordType *RT) { + if (ReferencesAnonymousEntity(RT)) { + RefAnon = true; + return false; + } + return true; + } + }; + ReferencesAnonymous RT; + RT.TraverseType(TA.getAsType()); + if (RT.RefAnon) + return true; + break; + } + default: + break; + } + return false; + }); +} namespace { struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> { bool Reconstitutable = true; @@ -4986,6 +5078,15 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> { Reconstitutable = false; return false; } + bool VisitType(Type *T) { + // _BitInt(N) isn't reconstitutable because the bit width isn't encoded in + // the DWARF, only the byte width. + if (T->isBitIntType()) { + Reconstitutable = false; + return false; + } + return true; + } bool TraverseEnumType(EnumType *ET) { // Unnamed enums can't be reconstituted due to a lack of column info we // produce in the DWARF, so we can't get Clang's full name back. @@ -4994,24 +5095,21 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> { Reconstitutable = false; return false; } + if (!ED->isExternallyVisible()) { + Reconstitutable = false; + return false; + } } return true; } bool VisitFunctionProtoType(FunctionProtoType *FT) { // noexcept is not encoded in DWARF, so the reversi Reconstitutable &= !isNoexceptExceptionSpec(FT->getExceptionSpecType()); + Reconstitutable &= !FT->getNoReturnAttr(); return Reconstitutable; } - bool TraverseRecordType(RecordType *RT) { - // Unnamed classes/lambdas can't be reconstituted due to a lack of column - // info we produce in the DWARF, so we can't get Clang's full name back. - // But so long as it's not one of those, it doesn't matter if some sub-type - // of the record (a template parameter) can't be reconstituted - because the - // un-reconstitutable type itself will carry its own name. - const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); - if (!RD) - return true; - if (RD->isLambda() || !RD->getIdentifier()) { + bool VisitRecordType(RecordType *RT) { + if (ReferencesAnonymousEntity(RT)) { Reconstitutable = false; return false; } @@ -5035,6 +5133,10 @@ std::string CGDebugInfo::GetName(const Decl *D, bool Qualified) const { return Name; codegenoptions::DebugTemplateNamesKind TemplateNamesKind = CGM.getCodeGenOpts().getDebugSimpleTemplateNames(); + + if (!CGM.getCodeGenOpts().hasReducedDebugInfo()) + TemplateNamesKind = codegenoptions::DebugTemplateNamesKind::Full; + Optional<TemplateArgs> Args; bool IsOperatorOverload = false; // isa<CXXConversionDecl>(ND); @@ -5080,7 +5182,8 @@ std::string CGDebugInfo::GetName(const Decl *D, bool Qualified) const { // harder to parse back into a large integer, etc - so punting on // this for now. Re-parsing the integers back into APInt is probably // feasible some day. - return TA.getAsIntegral().getBitWidth() <= 64; + return TA.getAsIntegral().getBitWidth() <= 64 && + IsReconstitutableType(TA.getIntegralType()); case TemplateArgument::Type: return IsReconstitutableType(TA.getAsType()); default: @@ -5123,7 +5226,7 @@ std::string CGDebugInfo::GetName(const Decl *D, bool Qualified) const { TemplateNamesKind == codegenoptions::DebugTemplateNamesKind::Mangled; // check if it's a template if (Mangled) - OS << "_STN"; + OS << "_STN|"; OS << ND->getDeclName(); std::string EncodedOriginalName; @@ -5200,14 +5303,10 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, } AppendAddressSpaceXDeref(AddressSpace, Expr); - TypeLoc TL; - if (const TypeSourceInfo *TSI = D->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D); GVE = DBuilder.createGlobalVariableExpression( - DContext, DeclName, LinkageName, Unit, LineNo, - getOrCreateType(T, Unit, TL), Var->hasLocalLinkage(), true, + DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), + Var->hasLocalLinkage(), true, Expr.empty() ? nullptr : DBuilder.createExpression(Expr), getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters, Align, Annotations); @@ -5320,6 +5419,62 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, Var->addDebugInfo(GVE); } +void CGDebugInfo::EmitGlobalAlias(const llvm::GlobalValue *GV, + const GlobalDecl GD) { + + assert(GV); + + if (!CGM.getCodeGenOpts().hasReducedDebugInfo()) + return; + + const auto *D = cast<ValueDecl>(GD.getDecl()); + if (D->hasAttr<NoDebugAttr>()) + return; + + auto AliaseeDecl = CGM.getMangledNameDecl(GV->getName()); + llvm::DINode *DI; + + if (!AliaseeDecl) + // FIXME: Aliasee not declared yet - possibly declared later + // For example, + // + // 1 extern int newname __attribute__((alias("oldname"))); + // 2 int oldname = 1; + // + // No debug info would be generated for 'newname' in this case. + // + // Fix compiler to generate "newname" as imported_declaration + // pointing to the DIE of "oldname". + return; + if (!(DI = getDeclarationOrDefinition( + AliaseeDecl.getCanonicalDecl().getDecl()))) + return; + + llvm::DIScope *DContext = getDeclContextDescriptor(D); + auto Loc = D->getLocation(); + + llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration( + DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName()); + + // Record this DIE in the cache for nested declaration reference. + ImportedDeclCache[GD.getCanonicalDecl().getDecl()].reset(ImportDI); +} + +void CGDebugInfo::AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, + const StringLiteral *S) { + SourceLocation Loc = S->getStrTokenLoc(0); + PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc); + if (!PLoc.isValid()) + return; + + llvm::DIFile *File = getOrCreateFile(Loc); + llvm::DIGlobalVariableExpression *Debug = + DBuilder.createGlobalVariableExpression( + nullptr, StringRef(), StringRef(), getOrCreateFile(Loc), + getLineNumber(Loc), getOrCreateType(S->getType(), File), true); + GV->addDebugInfo(Debug); +} + llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) { if (!LexicalBlockStack.empty()) return LexicalBlockStack.back(); |
