diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp | 710 |
1 files changed, 458 insertions, 252 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp index 5df8519..0607a51 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -13,6 +13,7 @@ #include "CGDebugInfo.h" #include "CGBlocks.h" +#include "CGRecordLayout.h" #include "CGCXXABI.h" #include "CGObjCRuntime.h" #include "CodeGenFunction.h" @@ -168,10 +169,10 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context, } // Check namespace. - if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context)) + if (const auto *NSDecl = dyn_cast<NamespaceDecl>(Context)) return getOrCreateNameSpace(NSDecl); - if (const RecordDecl *RDecl = dyn_cast<RecordDecl>(Context)) + if (const auto *RDecl = dyn_cast<RecordDecl>(Context)) if (!RDecl->isDependentType()) return getOrCreateType(CGM.getContext().getTypeDeclType(RDecl), getOrCreateMainFile()); @@ -184,30 +185,32 @@ StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) { FunctionTemplateSpecializationInfo *Info = FD->getTemplateSpecializationInfo(); - if (!Info && FII && !CGM.getCodeGenOpts().EmitCodeView) + // Emit the unqualified name in normal operation. LLVM and the debugger can + // compute the fully qualified name from the scope chain. If we're only + // emitting line table info, there won't be any scope chains, so emit the + // fully qualified name here so that stack traces are more accurate. + // FIXME: Do this when emitting DWARF as well as when emitting CodeView after + // evaluating the size impact. + bool UseQualifiedName = DebugKind == codegenoptions::DebugLineTablesOnly && + CGM.getCodeGenOpts().EmitCodeView; + + if (!Info && FII && !UseQualifiedName) return FII->getName(); - // Otherwise construct human readable name for debug info. SmallString<128> NS; llvm::raw_svector_ostream OS(NS); PrintingPolicy Policy(CGM.getLangOpts()); - - if (CGM.getCodeGenOpts().EmitCodeView) { - // Print a fully qualified name like MSVC would. - Policy.MSVCFormatting = true; - FD->printQualifiedName(OS, Policy); - } else { - // Print the unqualified name with some template arguments. This is what - // DWARF-based debuggers expect. + Policy.MSVCFormatting = CGM.getCodeGenOpts().EmitCodeView; + if (!UseQualifiedName) FD->printName(OS); - // Add any template specialization args. - if (Info) { - const TemplateArgumentList *TArgs = Info->TemplateArguments; - const TemplateArgument *Args = TArgs->data(); - unsigned NumArgs = TArgs->size(); - TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, NumArgs, - Policy); - } + else + FD->printQualifiedName(OS, Policy); + + // Add any template specialization args. + if (Info) { + const TemplateArgumentList *TArgs = Info->TemplateArguments; + TemplateSpecializationType::PrintTemplateArgumentList(OS, TArgs->asArray(), + Policy); } // Copy this name on the side and use its reference. @@ -219,21 +222,18 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) { llvm::raw_svector_ostream OS(MethodName); OS << (OMD->isInstanceMethod() ? '-' : '+') << '['; const DeclContext *DC = OMD->getDeclContext(); - if (const ObjCImplementationDecl *OID = - dyn_cast<const ObjCImplementationDecl>(DC)) { + if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) { OS << OID->getName(); - } else if (const ObjCInterfaceDecl *OID = - dyn_cast<const ObjCInterfaceDecl>(DC)) { + } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) { OS << OID->getName(); - } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(DC)) { + } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) { if (OC->IsClassExtension()) { OS << OC->getClassInterface()->getName(); } else { - OS << ((const NamedDecl *)OC)->getIdentifier()->getNameStart() << '(' + OS << OC->getIdentifier()->getNameStart() << '(' << OC->getIdentifier()->getNameStart() << ')'; } - } else if (const ObjCCategoryImplDecl *OCD = - dyn_cast<const ObjCCategoryImplDecl>(DC)) { + } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) { OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '(' << OCD->getIdentifier()->getNameStart() << ')'; } else if (isa<ObjCProtocolDecl>(DC)) { @@ -254,20 +254,56 @@ StringRef CGDebugInfo::getSelectorName(Selector S) { } StringRef CGDebugInfo::getClassName(const RecordDecl *RD) { - // quick optimization to avoid having to intern strings that are already - // stored reliably elsewhere - if (!isa<ClassTemplateSpecializationDecl>(RD)) - return RD->getName(); - - SmallString<128> Name; - { + if (isa<ClassTemplateSpecializationDecl>(RD)) { + SmallString<128> Name; llvm::raw_svector_ostream OS(Name); RD->getNameForDiagnostic(OS, CGM.getContext().getPrintingPolicy(), /*Qualified*/ false); + + // Copy this name on the side and use its reference. + return internString(Name); } - // Copy this name on the side and use its reference. - return internString(Name); + // quick optimization to avoid having to intern strings that are already + // stored reliably elsewhere + if (const IdentifierInfo *II = RD->getIdentifier()) + return II->getName(); + + // The CodeView printer in LLVM wants to see the names of unnamed types: it is + // used to reconstruct the fully qualified type names. + if (CGM.getCodeGenOpts().EmitCodeView) { + if (const TypedefNameDecl *D = RD->getTypedefNameForAnonDecl()) { + assert(RD->getDeclContext() == D->getDeclContext() && + "Typedef should not be in another decl context!"); + assert(D->getDeclName().getAsIdentifierInfo() && + "Typedef was not named!"); + return D->getDeclName().getAsIdentifierInfo()->getName(); + } + + if (CGM.getLangOpts().CPlusPlus) { + StringRef Name; + + ASTContext &Context = CGM.getContext(); + if (const DeclaratorDecl *DD = Context.getDeclaratorForUnnamedTagDecl(RD)) + // Anonymous types without a name for linkage purposes have their + // declarator mangled in if they have one. + Name = DD->getName(); + else if (const TypedefNameDecl *TND = + Context.getTypedefNameForUnnamedTagDecl(RD)) + // Anonymous types without a name for linkage purposes have their + // associate typedef mangled in if they have one. + Name = TND->getName(); + + if (!Name.empty()) { + SmallString<256> UnnamedType("<unnamed-type-"); + UnnamedType += Name; + UnnamedType += '>'; + return internString(UnnamedType); + } + } + } + + return StringRef(); } llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) { @@ -383,6 +419,8 @@ void CGDebugInfo::CreateCompileUnit() { LangTag = llvm::dwarf::DW_LANG_C_plus_plus; } else if (LO.ObjC1) { LangTag = llvm::dwarf::DW_LANG_ObjC; + } else if (LO.RenderScript) { + LangTag = llvm::dwarf::DW_LANG_GOOGLE_RenderScript; } else if (LO.C99) { LangTag = llvm::dwarf::DW_LANG_C99; } else { @@ -396,16 +434,27 @@ void CGDebugInfo::CreateCompileUnit() { if (LO.ObjC1) RuntimeVers = LO.ObjCRuntime.isNonFragile() ? 2 : 1; + llvm::DICompileUnit::DebugEmissionKind EmissionKind; + switch (DebugKind) { + case codegenoptions::NoDebugInfo: + case codegenoptions::LocTrackingOnly: + EmissionKind = llvm::DICompileUnit::NoDebug; + break; + case codegenoptions::DebugLineTablesOnly: + EmissionKind = llvm::DICompileUnit::LineTablesOnly; + break; + case codegenoptions::LimitedDebugInfo: + case codegenoptions::FullDebugInfo: + EmissionKind = llvm::DICompileUnit::FullDebug; + break; + } + // Create new compile unit. // FIXME - Eliminate TheCU. TheCU = DBuilder.createCompileUnit( LangTag, remapDIPath(MainFileName), remapDIPath(getCurrentDirname()), Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, - CGM.getCodeGenOpts().SplitDwarfFile, - DebugKind <= CodeGenOptions::DebugLineTablesOnly - ? llvm::DIBuilder::LineTablesOnly - : llvm::DIBuilder::FullDebug, - 0 /* DWOid */, DebugKind != CodeGenOptions::LocTrackingOnly); + CGM.getCodeGenOpts().SplitDwarfFile, EmissionKind, 0 /* DWOid */); } llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { @@ -463,39 +512,11 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { return SelTy; } - case BuiltinType::OCLImage1d: - return getOrCreateStructPtrType("opencl_image1d_t", OCLImage1dDITy); - case BuiltinType::OCLImage1dArray: - return getOrCreateStructPtrType("opencl_image1d_array_t", - OCLImage1dArrayDITy); - case BuiltinType::OCLImage1dBuffer: - return getOrCreateStructPtrType("opencl_image1d_buffer_t", - OCLImage1dBufferDITy); - case BuiltinType::OCLImage2d: - return getOrCreateStructPtrType("opencl_image2d_t", OCLImage2dDITy); - case BuiltinType::OCLImage2dArray: - return getOrCreateStructPtrType("opencl_image2d_array_t", - OCLImage2dArrayDITy); - case BuiltinType::OCLImage2dDepth: - return getOrCreateStructPtrType("opencl_image2d_depth_t", - OCLImage2dDepthDITy); - case BuiltinType::OCLImage2dArrayDepth: - return getOrCreateStructPtrType("opencl_image2d_array_depth_t", - OCLImage2dArrayDepthDITy); - case BuiltinType::OCLImage2dMSAA: - return getOrCreateStructPtrType("opencl_image2d_msaa_t", - OCLImage2dMSAADITy); - case BuiltinType::OCLImage2dArrayMSAA: - return getOrCreateStructPtrType("opencl_image2d_array_msaa_t", - OCLImage2dArrayMSAADITy); - case BuiltinType::OCLImage2dMSAADepth: - return getOrCreateStructPtrType("opencl_image2d_msaa_depth_t", - OCLImage2dMSAADepthDITy); - case BuiltinType::OCLImage2dArrayMSAADepth: - return getOrCreateStructPtrType("opencl_image2d_array_msaa_depth_t", - OCLImage2dArrayMSAADepthDITy); - case BuiltinType::OCLImage3d: - return getOrCreateStructPtrType("opencl_image3d_t", OCLImage3dDITy); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", \ + SingletonId); +#include "clang/Basic/OpenCLImageTypes.def" case BuiltinType::OCLSampler: return DBuilder.createBasicType( "opencl_sampler_t", CGM.getContext().getTypeSize(BT), @@ -545,7 +566,13 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { case BuiltinType::Half: case BuiltinType::Float: case BuiltinType::LongDouble: + case BuiltinType::Float128: case BuiltinType::Double: + // FIXME: For targets where long double and __float128 have the same size, + // they are currently indistinguishable in the debugger without some + // special treatment. However, there is currently no consensus on encoding + // and this should be updated once a DWARF encoding exists for distinct + // floating point types of the same size. Encoding = llvm::dwarf::DW_ATE_float; break; } @@ -660,10 +687,6 @@ static SmallString<256> getUniqueTagTypeName(const TagType *Ty, if (!hasCXXMangling(TD, TheCU) || !TD->isExternallyVisible()) return FullName; - // Microsoft Mangler does not have support for mangleCXXRTTIName yet. - if (CGM.getTarget().getCXXABI().isMicrosoft()) - return FullName; - // TODO: This is using the RTTI name. Is there a better way to get // a unique string for a type? llvm::raw_svector_ostream Out(FullName); @@ -817,10 +840,10 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, /*qualified*/ false); TemplateSpecializationType::PrintTemplateArgumentList( - OS, Ty->getArgs(), Ty->getNumArgs(), + OS, Ty->template_arguments(), CGM.getContext().getPrintingPolicy()); - TypeAliasDecl *AliasDecl = cast<TypeAliasTemplateDecl>( + auto *AliasDecl = cast<TypeAliasTemplateDecl>( Ty->getTemplateName().getAsTemplateDecl())->getTemplatedDecl(); SourceLocation Loc = AliasDecl->getLocation(); @@ -842,6 +865,39 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, getDeclContextDescriptor(Ty->getDecl())); } +static unsigned getDwarfCC(CallingConv CC) { + switch (CC) { + case CC_C: + // Avoid emitting DW_AT_calling_convention if the C convention was used. + return 0; + + case CC_X86StdCall: + return llvm::dwarf::DW_CC_BORLAND_stdcall; + case CC_X86FastCall: + return llvm::dwarf::DW_CC_BORLAND_msfastcall; + case CC_X86ThisCall: + return llvm::dwarf::DW_CC_BORLAND_thiscall; + case CC_X86VectorCall: + return llvm::dwarf::DW_CC_LLVM_vectorcall; + case CC_X86Pascal: + return llvm::dwarf::DW_CC_BORLAND_pascal; + + // FIXME: Create new DW_CC_ codes for these calling conventions. + case CC_X86_64Win64: + case CC_X86_64SysV: + case CC_AAPCS: + case CC_AAPCS_VFP: + case CC_IntelOclBicc: + case CC_SpirFunction: + case CC_OpenCLKernel: + case CC_Swift: + case CC_PreserveMost: + case CC_PreserveAll: + return 0; + } + return 0; +} + llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, llvm::DIFile *Unit) { SmallVector<llvm::Metadata *, 16> EltTys; @@ -853,15 +909,16 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, // otherwise emit it as a variadic function. if (isa<FunctionNoProtoType>(Ty)) EltTys.push_back(DBuilder.createUnspecifiedParameter()); - else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) { - for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i) - EltTys.push_back(getOrCreateType(FPT->getParamType(i), Unit)); + else if (const auto *FPT = dyn_cast<FunctionProtoType>(Ty)) { + for (const QualType &ParamType : FPT->param_types()) + EltTys.push_back(getOrCreateType(ParamType, Unit)); if (FPT->isVariadic()) EltTys.push_back(DBuilder.createUnspecifiedParameter()); } llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys); - return DBuilder.createSubroutineType(EltTypeArray); + return DBuilder.createSubroutineType(EltTypeArray, 0, + getDwarfCC(Ty->getCallConv())); } /// Convert an AccessSpecifier into the corresponding DINode flag. @@ -890,10 +947,38 @@ static unsigned getAccessFlag(AccessSpecifier Access, const RecordDecl *RD) { llvm_unreachable("unexpected access enumerator"); } -llvm::DIType *CGDebugInfo::createFieldType( - StringRef name, QualType type, uint64_t sizeInBitsOverride, - SourceLocation loc, AccessSpecifier AS, uint64_t offsetInBits, - llvm::DIFile *tunit, llvm::DIScope *scope, const RecordDecl *RD) { +llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl, + llvm::DIScope *RecordTy, + const RecordDecl *RD) { + StringRef Name = BitFieldDecl->getName(); + QualType Ty = BitFieldDecl->getType(); + SourceLocation Loc = BitFieldDecl->getLocation(); + llvm::DIFile *VUnit = getOrCreateFile(Loc); + llvm::DIType *DebugType = getOrCreateType(Ty, VUnit); + + // Get the location for the field. + llvm::DIFile *File = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); + + const CGBitFieldInfo &BitFieldInfo = + CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl); + uint64_t SizeInBits = BitFieldInfo.Size; + assert(SizeInBits > 0 && "found named 0-width bitfield"); + unsigned AlignInBits = CGM.getContext().getTypeAlign(Ty); + uint64_t StorageOffsetInBits = + CGM.getContext().toBits(BitFieldInfo.StorageOffset); + uint64_t OffsetInBits = StorageOffsetInBits + BitFieldInfo.Offset; + unsigned Flags = getAccessFlag(BitFieldDecl->getAccess(), RD); + return DBuilder.createBitFieldMemberType( + RecordTy, Name, File, Line, SizeInBits, AlignInBits, OffsetInBits, + StorageOffsetInBits, Flags, DebugType); +} + +llvm::DIType * +CGDebugInfo::createFieldType(StringRef name, QualType type, SourceLocation loc, + AccessSpecifier AS, uint64_t offsetInBits, + llvm::DIFile *tunit, llvm::DIScope *scope, + const RecordDecl *RD) { llvm::DIType *debugType = getOrCreateType(type, tunit); // Get the location for the field. @@ -906,9 +991,6 @@ llvm::DIType *CGDebugInfo::createFieldType( TypeInfo TI = CGM.getContext().getTypeInfo(type); SizeInBits = TI.Width; AlignInBits = TI.Align; - - if (sizeInBitsOverride) - SizeInBits = sizeInBitsOverride; } unsigned flags = getAccessFlag(AS, RD); @@ -930,19 +1012,15 @@ void CGDebugInfo::CollectRecordLambdaFields( I != E; ++I, ++Field, ++fieldno) { const LambdaCapture &C = *I; if (C.capturesVariable()) { + SourceLocation Loc = C.getLocation(); + assert(!Field->isBitField() && "lambdas don't have bitfield members!"); VarDecl *V = C.getCapturedVar(); - llvm::DIFile *VUnit = getOrCreateFile(C.getLocation()); StringRef VName = V->getName(); - uint64_t SizeInBitsOverride = 0; - if (Field->isBitField()) { - SizeInBitsOverride = Field->getBitWidthValue(CGM.getContext()); - assert(SizeInBitsOverride && "found named 0-width bitfield"); - } - llvm::DIType *fieldType = createFieldType( - VName, Field->getType(), SizeInBitsOverride, C.getLocation(), - Field->getAccess(), layout.getFieldOffset(fieldno), VUnit, RecordTy, - CXXDecl); - elements.push_back(fieldType); + llvm::DIFile *VUnit = getOrCreateFile(Loc); + llvm::DIType *FieldType = createFieldType( + VName, Field->getType(), Loc, Field->getAccess(), + layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl); + elements.push_back(FieldType); } else if (C.capturesThis()) { // TODO: Need to handle 'this' in some way by probably renaming the // this of the lambda class and having a field member of 'this' or @@ -952,7 +1030,7 @@ void CGDebugInfo::CollectRecordLambdaFields( llvm::DIFile *VUnit = getOrCreateFile(f->getLocation()); QualType type = f->getType(); llvm::DIType *fieldType = createFieldType( - "this", type, 0, f->getLocation(), f->getAccess(), + "this", type, f->getLocation(), f->getAccess(), layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl); elements.push_back(fieldType); @@ -1000,24 +1078,23 @@ void CGDebugInfo::CollectRecordNormalField( if (name.empty() && !type->isRecordType()) return; - uint64_t SizeInBitsOverride = 0; + llvm::DIType *FieldType; if (field->isBitField()) { - SizeInBitsOverride = field->getBitWidthValue(CGM.getContext()); - assert(SizeInBitsOverride && "found named 0-width bitfield"); + FieldType = createBitFieldType(field, RecordTy, RD); + } else { + FieldType = + createFieldType(name, type, field->getLocation(), field->getAccess(), + OffsetInBits, tunit, RecordTy, RD); } - llvm::DIType *fieldType = - createFieldType(name, type, SizeInBitsOverride, field->getLocation(), - field->getAccess(), OffsetInBits, tunit, RecordTy, RD); - - elements.push_back(fieldType); + elements.push_back(FieldType); } void CGDebugInfo::CollectRecordFields( const RecordDecl *record, llvm::DIFile *tunit, SmallVectorImpl<llvm::Metadata *> &elements, llvm::DICompositeType *RecordTy) { - const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(record); + const auto *CXXDecl = dyn_cast<CXXRecordDecl>(record); if (CXXDecl && CXXDecl->isLambda()) CollectRecordLambdaFields(CXXDecl, elements, RecordTy); @@ -1031,6 +1108,8 @@ void CGDebugInfo::CollectRecordFields( // the corresponding declarations in the source program. for (const auto *I : record->decls()) if (const auto *V = dyn_cast<VarDecl>(I)) { + if (V->hasAttr<NoDebugAttr>()) + continue; // Reuse the existing static member declaration if one exists auto MI = StaticDataMemberCache.find(V->getCanonicalDecl()); if (MI != StaticDataMemberCache.end()) { @@ -1112,13 +1191,14 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType( if (Func->getExtProtoInfo().RefQualifier == RQ_RValue) Flags |= llvm::DINode::FlagRValueReference; - return DBuilder.createSubroutineType(EltTypeArray, Flags); + return DBuilder.createSubroutineType(EltTypeArray, Flags, + getDwarfCC(Func->getCallConv())); } /// isFunctionLocalClass - Return true if CXXRecordDecl is defined /// inside a function. static bool isFunctionLocalClass(const CXXRecordDecl *RD) { - if (const CXXRecordDecl *NRD = dyn_cast<CXXRecordDecl>(RD->getDeclContext())) + if (const auto *NRD = dyn_cast<CXXRecordDecl>(RD->getDeclContext())) return isFunctionLocalClass(NRD); if (isa<FunctionDecl>(RD->getDeclContext())) return true; @@ -1136,6 +1216,11 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( // Since a single ctor/dtor corresponds to multiple functions, it doesn't // make sense to give a single ctor/dtor a linkage name. StringRef MethodLinkageName; + // FIXME: 'isFunctionLocalClass' seems like an arbitrary/unintentional + // property to use here. It may've been intended to model "is non-external + // type" but misses cases of non-function-local but non-external classes such + // as those in anonymous namespaces as well as the reverse - external types + // that are function local, such as those in (non-local) inline functions. if (!IsCtorOrDtor && !isFunctionLocalClass(Method->getParent())) MethodLinkageName = CGM.getMangledName(Method); @@ -1151,6 +1236,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( llvm::DIType *ContainingType = nullptr; unsigned Virtuality = 0; unsigned VIndex = 0; + unsigned Flags = 0; + int ThisAdjustment = 0; if (Method->isVirtual()) { if (Method->isPure()) @@ -1158,26 +1245,45 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( else Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual; - // It doesn't make sense to give a virtual destructor a vtable index, - // since a single destructor has two entries in the vtable. - // FIXME: Add proper support for debug info for virtual calls in - // the Microsoft ABI, where we may use multiple vptrs to make a vftable - // lookup if we have multiple or virtual inheritance. - if (!isa<CXXDestructorDecl>(Method) && - !CGM.getTarget().getCXXABI().isMicrosoft()) - VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method); + if (CGM.getTarget().getCXXABI().isItaniumFamily()) { + // It doesn't make sense to give a virtual destructor a vtable index, + // since a single destructor has two entries in the vtable. + if (!isa<CXXDestructorDecl>(Method)) + VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method); + } else { + // Emit MS ABI vftable information. There is only one entry for the + // deleting dtor. + const auto *DD = dyn_cast<CXXDestructorDecl>(Method); + GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method); + MicrosoftVTableContext::MethodVFTableLocation ML = + CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); + VIndex = ML.Index; + + // CodeView only records the vftable offset in the class that introduces + // the virtual method. This is possible because, unlike Itanium, the MS + // C++ ABI does not include all virtual methods from non-primary bases in + // the vtable for the most derived class. For example, if C inherits from + // A and B, C's primary vftable will not include B's virtual methods. + if (Method->begin_overridden_methods() == Method->end_overridden_methods()) + Flags |= llvm::DINode::FlagIntroducedVirtual; + + // The 'this' adjustment accounts for both the virtual and non-virtual + // portions of the adjustment. Presumably the debugger only uses it when + // it knows the dynamic type of an object. + ThisAdjustment = CGM.getCXXABI() + .getVirtualFunctionPrologueThisAdjustment(GD) + .getQuantity(); + } ContainingType = RecordTy; } - unsigned Flags = 0; if (Method->isImplicit()) Flags |= llvm::DINode::FlagArtificial; Flags |= getAccessFlag(Method->getAccess(), Method->getParent()); - if (const CXXConstructorDecl *CXXC = dyn_cast<CXXConstructorDecl>(Method)) { + if (const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) { if (CXXC->isExplicit()) Flags |= llvm::DINode::FlagExplicit; - } else if (const CXXConversionDecl *CXXC = - dyn_cast<CXXConversionDecl>(Method)) { + } else if (const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) { if (CXXC->isExplicit()) Flags |= llvm::DINode::FlagExplicit; } @@ -1191,9 +1297,9 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit); llvm::DISubprogram *SP = DBuilder.createMethod( RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine, - MethodTy, /*isLocalToUnit=*/false, - /* isDefinition=*/false, Virtuality, VIndex, ContainingType, Flags, - CGM.getLangOpts().Optimize, TParamsArray.get()); + MethodTy, /*isLocalToUnit=*/false, /*isDefinition=*/false, Virtuality, + VIndex, ThisAdjustment, ContainingType, Flags, CGM.getLangOpts().Optimize, + TParamsArray.get()); SPCache[Method->getCanonicalDecl()].reset(SP); @@ -1246,7 +1352,7 @@ void CGDebugInfo::CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile *Unit, unsigned BFlags = 0; uint64_t BaseOffset; - const CXXRecordDecl *Base = + const auto *Base = cast<CXXRecordDecl>(BI.getType()->getAs<RecordType>()->getDecl()); if (BI.isVirtual()) { @@ -1334,8 +1440,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, llvm::Constant *V = nullptr; // Special case member data pointer null values since they're actually -1 // instead of zero. - if (const MemberPointerType *MPT = - dyn_cast<MemberPointerType>(T.getTypePtr())) + if (const auto *MPT = dyn_cast<MemberPointerType>(T.getTypePtr())) // But treat member function pointers as simple zero integers because // it's easier than having a special case in LLVM's CodeGen. If LLVM // CodeGen grows handling for values of non-null member function @@ -1346,7 +1451,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, if (!V) V = llvm::ConstantInt::get(CGM.Int8Ty, 0); TemplateParams.push_back(DBuilder.createTemplateValueParameter( - TheCU, Name, TTy, cast<llvm::Constant>(V))); + TheCU, Name, TTy, V)); } break; case TemplateArgument::Template: TemplateParams.push_back(DBuilder.createTemplateTemplateParameter( @@ -1367,7 +1472,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, assert(V && "Expression in template argument isn't constant"); llvm::DIType *TTy = getOrCreateType(T, Unit); TemplateParams.push_back(DBuilder.createTemplateValueParameter( - TheCU, Name, TTy, cast<llvm::Constant>(V->stripPointerCasts()))); + TheCU, Name, TTy, V->stripPointerCasts())); } break; // And the following should never occur: case TemplateArgument::TemplateExpansion: @@ -1446,7 +1551,7 @@ void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit, llvm::DIType *CGDebugInfo::getOrCreateRecordType(QualType RTy, SourceLocation Loc) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc)); return T; } @@ -1458,22 +1563,17 @@ llvm::DIType *CGDebugInfo::getOrCreateInterfaceType(QualType D, llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D, SourceLocation Loc) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); assert(!D.isNull() && "null type"); llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc)); assert(T && "could not create debug info for type"); - // Composite types with UIDs were already retained by DIBuilder - // because they are only referenced by name in the IR. - if (auto *CTy = dyn_cast<llvm::DICompositeType>(T)) - if (!CTy->getIdentifier().empty()) - return T; RetainedTypes.push_back(D.getAsOpaquePtr()); return T; } void CGDebugInfo::completeType(const EnumDecl *ED) { - if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; QualType Ty = CGM.getContext().getEnumType(ED); void *TyPtr = Ty.getAsOpaquePtr(); @@ -1486,16 +1586,16 @@ void CGDebugInfo::completeType(const EnumDecl *ED) { } void CGDebugInfo::completeType(const RecordDecl *RD) { - if (DebugKind > CodeGenOptions::LimitedDebugInfo || + if (DebugKind > codegenoptions::LimitedDebugInfo || !CGM.getLangOpts().CPlusPlus) completeRequiredType(RD); } void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { - if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; - if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) + if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) if (CXXDecl->isDynamicClass()) return; @@ -1509,7 +1609,7 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { } void CGDebugInfo::completeClassData(const RecordDecl *RD) { - if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; QualType Ty = CGM.getContext().getRecordType(RD); void *TyPtr = Ty.getAsOpaquePtr(); @@ -1523,23 +1623,38 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) { static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I, CXXRecordDecl::method_iterator End) { - for (; I != End; ++I) - if (FunctionDecl *Tmpl = I->getInstantiatedFromMemberFunction()) + for (CXXMethodDecl *MD : llvm::make_range(I, End)) + if (FunctionDecl *Tmpl = MD->getInstantiatedFromMemberFunction()) if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() && - !I->getMemberSpecializationInfo()->isExplicitSpecialization()) + !MD->getMemberSpecializationInfo()->isExplicitSpecialization()) return true; return false; } -static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind, - bool DebugTypeExtRefs, - const RecordDecl *RD, +/// Does a type definition exist in an imported clang module? +static bool isDefinedInClangModule(const RecordDecl *RD) { + if (!RD || !RD->isFromASTFile()) + return false; + if (!RD->isExternallyVisible() && RD->getName().empty()) + return false; + if (auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) { + assert(CXXDecl->isCompleteDefinition() && "incomplete record definition"); + if (CXXDecl->getTemplateSpecializationKind() != TSK_Undeclared) + // Make sure the instantiation is actually in a module. + if (CXXDecl->field_begin() != CXXDecl->field_end()) + return CXXDecl->field_begin()->isFromASTFile(); + } + + return true; +} + +static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind, + bool DebugTypeExtRefs, const RecordDecl *RD, const LangOptions &LangOpts) { - // Does the type exist in an imported clang module? - if (DebugTypeExtRefs && RD->isFromASTFile() && RD->getDefinition()) - return true; + if (DebugTypeExtRefs && isDefinedInClangModule(RD->getDefinition())) + return true; - if (DebugKind > CodeGenOptions::LimitedDebugInfo) + if (DebugKind > codegenoptions::LimitedDebugInfo) return false; if (!LangOpts.CPlusPlus) @@ -1548,7 +1663,7 @@ static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind, if (!RD->isCompleteDefinitionRequired()) return true; - const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); + const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD); if (!CXXDecl) return false; @@ -1557,8 +1672,7 @@ static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind, return true; TemplateSpecializationKind Spec = TSK_Undeclared; - if (const ClassTemplateSpecializationDecl *SD = - dyn_cast<ClassTemplateSpecializationDecl>(RD)) + if (const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) Spec = SD->getSpecializationKind(); if (Spec == TSK_ExplicitInstantiationDeclaration && @@ -1600,7 +1714,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { if (!D || !D->isCompleteDefinition()) return FwdDecl; - if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) + if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) CollectContainingType(CXXDecl, FwdDecl); // Push the struct on region stack. @@ -1615,7 +1729,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { // gdb tests will depend on a certain ordering at printout. The debug // information offsets are still correct if we merge them all together // though. - const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); + const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD); if (CXXDecl) { CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl); CollectVTableInfo(CXXDecl, DefUnit, EltTys); @@ -1676,8 +1790,11 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, if (!ID) return nullptr; - // Return a forward declaration if this type was imported from a clang module. - if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition()) + // Return a forward declaration if this type was imported from a clang module, + // and this is not the compile unit with the implementation of the type (which + // may contain hidden ivars). + if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition() && + !ID->getImplementation()) return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, ID->getName(), getDeclContextDescriptor(ID), Unit, 0); @@ -1739,11 +1856,14 @@ CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod, bool IsRootModule = M ? !M->Parent : true; if (CreateSkeletonCU && IsRootModule) { + // 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. + uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL; llvm::DIBuilder DIB(CGM.getModule()); DIB.createCompileUnit(TheCU->getSourceLanguage(), Mod.getModuleName(), Mod.getPath(), TheCU->getProducer(), true, StringRef(), 0, Mod.getASTFile(), - llvm::DIBuilder::FullDebug, Mod.getSignature()); + llvm::DICompileUnit::FullDebug, Signature); DIB.finalize(); } llvm::DIModule *Parent = @@ -1942,7 +2062,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) { uint64_t Align; // FIXME: make getTypeAlign() aware of VLAs and incomplete array types - if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) { + if (const auto *VAT = dyn_cast<VariableArrayType>(Ty)) { Size = 0; Align = CGM.getContext().getTypeAlign(CGM.getContext().getBaseElementType(VAT)); @@ -1975,7 +2095,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) { // int x[0]; // }; int64_t Count = -1; // Count == -1 is an unbounded array. - if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty)) + if (const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) Count = CAT->getSize().getZExtValue(); // FIXME: Verify this is right for VLAs. @@ -2003,12 +2123,35 @@ llvm::DIType *CGDebugInfo::CreateType(const RValueReferenceType *Ty, llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty, llvm::DIFile *U) { - uint64_t Size = - !Ty->isIncompleteType() ? CGM.getContext().getTypeSize(Ty) : 0; + unsigned Flags = 0; + uint64_t Size = 0; + + if (!Ty->isIncompleteType()) { + Size = CGM.getContext().getTypeSize(Ty); + + // Set the MS inheritance model. There is no flag for the unspecified model. + if (CGM.getTarget().getCXXABI().isMicrosoft()) { + switch (Ty->getMostRecentCXXRecordDecl()->getMSInheritanceModel()) { + case MSInheritanceAttr::Keyword_single_inheritance: + Flags |= llvm::DINode::FlagSingleInheritance; + break; + case MSInheritanceAttr::Keyword_multiple_inheritance: + Flags |= llvm::DINode::FlagMultipleInheritance; + break; + case MSInheritanceAttr::Keyword_virtual_inheritance: + Flags |= llvm::DINode::FlagVirtualInheritance; + break; + case MSInheritanceAttr::Keyword_unspecified_inheritance: + break; + } + } + } + llvm::DIType *ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U); if (Ty->isMemberDataPointerType()) return DBuilder.createMemberPointerType( - getOrCreateType(Ty->getPointeeType(), U), ClassType, Size); + getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, /*Align=*/0, + Flags); const FunctionProtoType *FPT = Ty->getPointeeType()->getAs<FunctionProtoType>(); @@ -2016,7 +2159,7 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty, getOrCreateInstanceMethodType(CGM.getContext().getPointerType(QualType( Ty->getClass(), FPT->getTypeQuals())), FPT, U), - ClassType, Size); + ClassType, Size, /*Align=*/0, Flags); } llvm::DIType *CGDebugInfo::CreateType(const AtomicType *Ty, llvm::DIFile *U) { @@ -2048,13 +2191,23 @@ llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) { // If this is just a forward declaration, construct an appropriately // marked node and just return it. if (isImportedFromModule || !ED->getDefinition()) { + // Note that it is possible for enums to be created as part of + // their own declcontext. In this case a FwdDecl will be created + // twice. This doesn't cause a problem because both FwdDecls are + // entered into the ReplaceMap: finalize() will replace the first + // FwdDecl with the second and then replace the second with + // complete type. llvm::DIScope *EDContext = getDeclContextDescriptor(ED); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); + llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( + llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); + unsigned Line = getLineNumber(ED->getLocation()); StringRef EDName = ED->getName(); llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line, 0, Size, Align, llvm::DINode::FlagFwdDecl, FullName); + ReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(Ty), std::make_tuple(static_cast<llvm::Metadata *>(RetTy))); @@ -2168,7 +2321,7 @@ llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) { void CGDebugInfo::completeTemplateDefinition( const ClassTemplateSpecializationDecl &SD) { - if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; completeClassData(&SD); @@ -2220,8 +2373,12 @@ llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) { // option. FullSourceLoc Loc(D->getLocation(), CGM.getContext().getSourceManager()); if (Module *M = ClangModuleMap->inferModuleFromLocation(Loc)) { + // This is a (sub-)module. auto Info = ExternalASTSource::ASTSourceDescriptor(*M); return getOrCreateModuleRef(Info, /*SkeletonCU=*/false); + } else { + // This the precompiled header being built. + return getOrCreateModuleRef(PCHDescriptor, /*SkeletonCU=*/false); } } @@ -2369,11 +2526,34 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align, 0, FullName); + // Elements of composite types usually have back to the type, creating + // uniquing cycles. Distinct nodes are more efficient. + switch (RealDecl->getTag()) { + default: + llvm_unreachable("invalid composite type tag"); + + case llvm::dwarf::DW_TAG_array_type: + case llvm::dwarf::DW_TAG_enumeration_type: + // Array elements and most enumeration elements don't have back references, + // so they don't tend to be involved in uniquing cycles and there is some + // chance of merging them when linking together two modules. Only make + // them distinct if they are ODR-uniqued. + if (FullName.empty()) + break; + + case llvm::dwarf::DW_TAG_structure_type: + case llvm::dwarf::DW_TAG_union_type: + case llvm::dwarf::DW_TAG_class_type: + // Immediatley resolve to a distinct node. + RealDecl = + llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl)); + break; + } + RegionMap[Ty->getDecl()].reset(RealDecl); TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl); - if (const ClassTemplateSpecializationDecl *TSpecial = - dyn_cast<ClassTemplateSpecializationDecl>(RD)) + if (const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD)) DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(), CollectCXXTemplateParams(TSpecial, DefUnit)); return RealDecl; @@ -2420,7 +2600,7 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit, llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray, unsigned &Flags) { - const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); + const auto *FD = cast<FunctionDecl>(GD.getDecl()); Name = getFunctionName(FD); // Use mangled name as linkage name for C/C++ functions. if (FD->hasPrototype()) { @@ -2430,13 +2610,12 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit, // No need to replicate the linkage name if it isn't different from the // subprogram name, no need to have it at all unless coverage is enabled or // debug is set to more than just line tables. - if (LinkageName == Name || - (!CGM.getCodeGenOpts().EmitGcovArcs && - !CGM.getCodeGenOpts().EmitGcovNotes && - DebugKind <= CodeGenOptions::DebugLineTablesOnly)) + if (LinkageName == Name || (!CGM.getCodeGenOpts().EmitGcovArcs && + !CGM.getCodeGenOpts().EmitGcovNotes && + DebugKind <= codegenoptions::DebugLineTablesOnly)) LinkageName = StringRef(); - if (DebugKind >= CodeGenOptions::LimitedDebugInfo) { + if (DebugKind >= codegenoptions::LimitedDebugInfo) { if (const NamespaceDecl *NSDecl = dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext())) FDContext = getOrCreateNameSpace(NSDecl); @@ -2513,15 +2692,15 @@ CGDebugInfo::getFunctionForwardDeclaration(const FunctionDecl *FD) { SmallVector<QualType, 16> ArgTypes; for (const ParmVarDecl *Parm: FD->parameters()) ArgTypes.push_back(Parm->getType()); - QualType FnType = - CGM.getContext().getFunctionType(FD->getReturnType(), ArgTypes, - FunctionProtoType::ExtProtoInfo()); + CallingConv CC = FD->getType()->castAs<FunctionType>()->getCallConv(); + QualType FnType = CGM.getContext().getFunctionType( + FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC)); llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl( DContext, Name, LinkageName, Unit, Line, getOrCreateFunctionType(FD, FnType, Unit), !FD->isExternallyVisible(), /* isDefinition = */ false, 0, Flags, CGM.getLangOpts().Optimize, TParamsArray.get(), getFunctionDeclaration(FD)); - const FunctionDecl *CanonDecl = cast<FunctionDecl>(FD->getCanonicalDecl()); + const auto *CanonDecl = cast<FunctionDecl>(FD->getCanonicalDecl()); FwdDeclReplaceMap.emplace_back(std::piecewise_construct, std::make_tuple(CanonDecl), std::make_tuple(SP)); @@ -2553,7 +2732,7 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { // we would otherwise do to get a type for a pointee. (forward declarations in // limited debug info, full definitions (if the type definition is available) // in unlimited debug info) - if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) + if (const auto *TD = dyn_cast<TypeDecl>(D)) return getOrCreateType(CGM.getContext().getTypeDeclType(TD), getOrCreateFile(TD->getLocation())); auto I = DeclCache.find(D->getCanonicalDecl()); @@ -2563,7 +2742,7 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { // No definition for now. Emit a forward definition that might be // merged with a potential upcoming definition. - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) + if (const auto *FD = dyn_cast<FunctionDecl>(D)) return getFunctionForwardDeclaration(FD); else if (const auto *VD = dyn_cast<VarDecl>(D)) return getGlobalVariableForwardDeclaration(VD); @@ -2572,10 +2751,10 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { } llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) { - if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (!D || DebugKind <= codegenoptions::DebugLineTablesOnly) return nullptr; - const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); + const auto *FD = dyn_cast<FunctionDecl>(D); if (!FD) return nullptr; @@ -2584,8 +2763,7 @@ llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) { auto MI = SPCache.find(FD->getCanonicalDecl()); if (MI == SPCache.end()) { - if (const CXXMethodDecl *MD = - dyn_cast<CXXMethodDecl>(FD->getCanonicalDecl())) { + if (const auto *MD = dyn_cast<CXXMethodDecl>(FD->getCanonicalDecl())) { return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), cast<llvm::DICompositeType>(S)); } @@ -2612,14 +2790,18 @@ llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) { llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F) { - if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (!D || DebugKind <= codegenoptions::DebugLineTablesOnly) // Create fake but valid subroutine type. Otherwise -verify would fail, and // subprogram DIE will miss DW_AT_decl_file and DW_AT_decl_line fields. return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray(None)); - if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) + if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) return getOrCreateMethodType(Method, F); - if (const ObjCMethodDecl *OMethod = dyn_cast<ObjCMethodDecl>(D)) { + + const auto *FTy = FnType->getAs<FunctionType>(); + CallingConv CC = FTy ? FTy->getCallConv() : CallingConv::CC_C; + + if (const auto *OMethod = dyn_cast<ObjCMethodDecl>(D)) { // Add "self" and "_cmd" SmallVector<llvm::Metadata *, 16> Elts; @@ -2645,28 +2827,28 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D, Elts.push_back(DBuilder.createArtificialType( getOrCreateType(CGM.getContext().getObjCSelType(), F))); // Get rest of the arguments. - for (const auto *PI : OMethod->params()) + for (const auto *PI : OMethod->parameters()) Elts.push_back(getOrCreateType(PI->getType(), F)); // Variadic methods need a special marker at the end of the type list. if (OMethod->isVariadic()) Elts.push_back(DBuilder.createUnspecifiedParameter()); llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts); - return DBuilder.createSubroutineType(EltTypeArray); + return DBuilder.createSubroutineType(EltTypeArray, 0, getDwarfCC(CC)); } // Handle variadic function types; they need an additional // unspecified parameter. - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (const auto *FD = dyn_cast<FunctionDecl>(D)) if (FD->isVariadic()) { SmallVector<llvm::Metadata *, 16> EltTys; EltTys.push_back(getOrCreateType(FD->getReturnType(), F)); - if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FnType)) - for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i) - EltTys.push_back(getOrCreateType(FPT->getParamType(i), F)); + if (const auto *FPT = dyn_cast<FunctionProtoType>(FnType)) + for (QualType ParamType : FPT->param_types()) + EltTys.push_back(getOrCreateType(ParamType, F)); EltTys.push_back(DBuilder.createUnspecifiedParameter()); llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys); - return DBuilder.createSubroutineType(EltTypeArray); + return DBuilder.createSubroutineType(EltTypeArray, 0, getDwarfCC(CC)); } return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F)); @@ -2691,7 +2873,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, if (!HasDecl) { // Use llvm function name. LinkageName = Fn->getName(); - } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) { // If there is a subprogram for this function available then use it. auto FI = SPCache.find(FD->getCanonicalDecl()); if (FI != SPCache.end()) { @@ -2704,7 +2886,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, } collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext, TParamsArray, Flags); - } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { + } else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) { Name = getObjCMethodName(OMD); Flags |= llvm::DINode::FlagPrototyped; } else { @@ -2712,7 +2894,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, Name = Fn->getName(); Flags |= llvm::DINode::FlagPrototyped; } - if (!Name.empty() && Name[0] == '\01') + if (Name.startswith("\01")) Name = Name.substr(1); if (!HasDecl || D->isImplicit()) { @@ -2731,7 +2913,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, // are emitted as CU level entities by the backend. llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), Fn->hasInternalLinkage(), + getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(), true /*definition*/, ScopeLine, Flags, CGM.getLangOpts().Optimize, TParamsArray.get(), getFunctionDeclaration(D)); Fn->setSubprogram(SP); @@ -2739,7 +2921,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, // code for the initialization of globals. Do not record these decls // as they will overwrite the actual VarDecl Decl in the cache. if (HasDecl && isa<FunctionDecl>(D)) - DeclCache[D->getCanonicalDecl()].reset(static_cast<llvm::Metadata *>(SP)); + DeclCache[D->getCanonicalDecl()].reset(SP); // Push the function onto the lexical block stack. LexicalBlockStack.emplace_back(SP); @@ -2765,7 +2947,7 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, // If there is a DISubprogram for this function available then use it. collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext, TParamsArray, Flags); - } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) { + } else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) { Name = getObjCMethodName(OMD); Flags |= llvm::DINode::FlagPrototyped; } else { @@ -2783,11 +2965,11 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, unsigned LineNo = getLineNumber(Loc); unsigned ScopeLine = 0; - DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), - false /*internalLinkage*/, true /*definition*/, - ScopeLine, Flags, CGM.getLangOpts().Optimize, - TParamsArray.get(), getFunctionDeclaration(D)); + DBuilder.retainType(DBuilder.createFunction( + FDContext, Name, LinkageName, Unit, LineNo, + getOrCreateFunctionType(D, FnType, Unit), false /*internalLinkage*/, + false /*definition*/, ScopeLine, Flags, CGM.getLangOpts().Optimize, + TParamsArray.get(), getFunctionDeclaration(D))); } void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) { @@ -2820,7 +3002,7 @@ void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, Builder.SetCurrentDebugLocation(llvm::DebugLoc::get( getLineNumber(Loc), getColumnNumber(Loc), LexicalBlockStack.back())); - if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; // Create a new lexical block and push it on the stack. @@ -2834,7 +3016,7 @@ void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder, // Provide an entry in the line table for the end of the block. EmitLocation(Builder, Loc); - if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) + if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; LexicalBlockStack.pop_back(); @@ -2896,8 +3078,7 @@ llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, CGM.getTarget().getPointerAlign(0))) { CharUnits FieldOffsetInBytes = CGM.getContext().toCharUnitsFromBits(FieldOffset); - CharUnits AlignedOffsetInBytes = - FieldOffsetInBytes.RoundUpToAlignment(Align); + CharUnits AlignedOffsetInBytes = FieldOffsetInBytes.alignTo(Align); CharUnits NumPaddingBytes = AlignedOffsetInBytes - FieldOffsetInBytes; if (NumPaddingBytes.isPositive()) { @@ -2930,8 +3111,10 @@ llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage, llvm::Optional<unsigned> ArgNo, CGBuilderTy &Builder) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); + if (VD->hasAttr<NoDebugAttr>()) + return; bool Unwritten = VD->isImplicit() || (isa<Decl>(VD->getDeclContext()) && @@ -2969,7 +3152,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage, // otherwise it is 'self' or 'this'. if (isa<ImplicitParamDecl>(VD) && ArgNo && *ArgNo == 1) Flags |= llvm::DINode::FlagObjectPointer; - if (llvm::Argument *Arg = dyn_cast<llvm::Argument>(Storage)) + if (auto *Arg = dyn_cast<llvm::Argument>(Storage)) if (Arg->getType()->isPointerTy() && !Arg->hasByValAttr() && !VD->getType()->isPointerType()) Expr.push_back(llvm::dwarf::DW_OP_deref); @@ -3005,10 +3188,10 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage, return; } else if (isa<VariableArrayType>(VD->getType())) Expr.push_back(llvm::dwarf::DW_OP_deref); - } else if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) { + } else if (const auto *RT = dyn_cast<RecordType>(VD->getType())) { // If VD is an anonymous union then Storage represents value for // all union fields. - const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); + const auto *RD = cast<RecordDecl>(RT->getDecl()); if (RD->isUnion() && RD->isAnonymousStructOrUnion()) { // GDB has trouble finding local variables in anonymous unions, so we emit // artifical local variables for each of the members. @@ -3056,7 +3239,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage, void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage, CGBuilderTy &Builder) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); EmitDeclare(VD, Storage, llvm::None, Builder); } @@ -3071,11 +3254,13 @@ llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy, void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable( const VarDecl *VD, llvm::Value *Storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, llvm::Instruction *InsertPoint) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); if (Builder.GetInsertBlock() == nullptr) return; + if (VD->hasAttr<NoDebugAttr>()) + return; bool isByRef = VD->hasAttr<BlocksAttr>(); @@ -3139,7 +3324,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable( void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); EmitDeclare(VD, AI, ArgNo, Builder); } @@ -3158,7 +3343,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, unsigned ArgNo, llvm::Value *LocalAddr, CGBuilderTy &Builder) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); ASTContext &C = CGM.getContext(); const BlockDecl *blockDecl = block.getBlockDecl(); @@ -3175,25 +3360,25 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, CGM.getDataLayout().getStructLayout(block.StructureType); SmallVector<llvm::Metadata *, 16> fields; - fields.push_back(createFieldType("__isa", C.VoidPtrTy, 0, loc, AS_public, + fields.push_back(createFieldType("__isa", C.VoidPtrTy, loc, AS_public, blockLayout->getElementOffsetInBits(0), tunit, tunit)); - fields.push_back(createFieldType("__flags", C.IntTy, 0, loc, AS_public, + fields.push_back(createFieldType("__flags", C.IntTy, loc, AS_public, blockLayout->getElementOffsetInBits(1), tunit, tunit)); - fields.push_back(createFieldType("__reserved", C.IntTy, 0, loc, AS_public, + fields.push_back(createFieldType("__reserved", C.IntTy, loc, AS_public, blockLayout->getElementOffsetInBits(2), tunit, tunit)); auto *FnTy = block.getBlockExpr()->getFunctionType(); auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar()); - fields.push_back(createFieldType("__FuncPtr", FnPtrType, 0, loc, AS_public, + fields.push_back(createFieldType("__FuncPtr", FnPtrType, loc, AS_public, blockLayout->getElementOffsetInBits(3), tunit, tunit)); fields.push_back(createFieldType( "__descriptor", C.getPointerType(block.NeedsCopyDispose ? C.getBlockDescriptorExtendedType() : C.getBlockDescriptorType()), - 0, loc, AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit)); + loc, AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit)); // We want to sort the captures by offset, not because DWARF // requires this, but because we're paranoid about debuggers. @@ -3227,19 +3412,22 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, // Sort by offset. llvm::array_pod_sort(chunks.begin(), chunks.end()); - for (SmallVectorImpl<BlockLayoutChunk>::iterator i = chunks.begin(), - e = chunks.end(); - i != e; ++i) { - uint64_t offsetInBits = i->OffsetInBits; - const BlockDecl::Capture *capture = i->Capture; + for (const BlockLayoutChunk &Chunk : chunks) { + uint64_t offsetInBits = Chunk.OffsetInBits; + const BlockDecl::Capture *capture = Chunk.Capture; // If we have a null capture, this must be the C++ 'this' capture. if (!capture) { - const CXXMethodDecl *method = - cast<CXXMethodDecl>(blockDecl->getNonClosureContext()); - QualType type = method->getThisType(C); + QualType type; + if (auto *Method = + cast_or_null<CXXMethodDecl>(blockDecl->getNonClosureContext())) + type = Method->getThisType(C); + else if (auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->getParent())) + type = QualType(RDecl->getTypeForDecl(), 0); + else + llvm_unreachable("unexpected block declcontext"); - fields.push_back(createFieldType("this", type, 0, loc, AS_public, + fields.push_back(createFieldType("this", type, loc, AS_public, offsetInBits, tunit, tunit)); continue; } @@ -3259,7 +3447,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, DBuilder.createMemberType(tunit, name, tunit, line, PtrInfo.Width, PtrInfo.Align, offsetInBits, 0, fieldType); } else { - fieldType = createFieldType(name, variable->getType(), 0, loc, AS_public, + fieldType = createFieldType(name, variable->getType(), loc, AS_public, offsetInBits, tunit, tunit); } fields.push_back(fieldType); @@ -3328,8 +3516,7 @@ llvm::DIGlobalVariable *CGDebugInfo::CollectAnonRecordDecls( // Ignore unnamed fields, but recurse into anonymous records. if (FieldName.empty()) { - const RecordType *RT = dyn_cast<RecordType>(Field->getType()); - if (RT) + if (const auto *RT = dyn_cast<RecordType>(Field->getType())) GV = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName, Var, DContext); continue; @@ -3337,14 +3524,16 @@ llvm::DIGlobalVariable *CGDebugInfo::CollectAnonRecordDecls( // Use VarDecl's Tag, Scope and Line number. GV = DBuilder.createGlobalVariable(DContext, FieldName, LinkageName, Unit, LineNo, FieldTy, - Var->hasInternalLinkage(), Var, nullptr); + Var->hasLocalLinkage(), Var, nullptr); } return GV; } void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, const VarDecl *D) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); + if (D->hasAttr<NoDebugAttr>()) + return; // Create global variable debug descriptor. llvm::DIFile *Unit = nullptr; llvm::DIScope *DContext = nullptr; @@ -3368,21 +3557,23 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, } else { GV = DBuilder.createGlobalVariable( DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), - Var->hasInternalLinkage(), Var, + Var->hasLocalLinkage(), Var, getOrCreateStaticDataMemberDeclarationOrNull(D)); } - DeclCache[D->getCanonicalDecl()].reset(static_cast<llvm::Metadata *>(GV)); + DeclCache[D->getCanonicalDecl()].reset(GV); } void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init) { - assert(DebugKind >= CodeGenOptions::LimitedDebugInfo); + assert(DebugKind >= codegenoptions::LimitedDebugInfo); + if (VD->hasAttr<NoDebugAttr>()) + return; // Create the descriptor for the variable. llvm::DIFile *Unit = getOrCreateFile(VD->getLocation()); StringRef Name = VD->getName(); llvm::DIType *Ty = getOrCreateType(VD->getType(), Unit); - if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(VD)) { - const EnumDecl *ED = cast<EnumDecl>(ECD->getDeclContext()); + if (const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) { + const auto *ED = cast<EnumDecl>(ECD->getDeclContext()); assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?"); Ty = getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit); } @@ -3400,6 +3591,9 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, auto *RD = cast<RecordDecl>(VarD->getDeclContext()); getDeclContextDescriptor(VarD); // Ensure that the type is retained even though it's otherwise unreferenced. + // + // FIXME: This is probably unnecessary, since Ty should reference RD + // through its scope. RetainedTypes.push_back( CGM.getContext().getRecordType(RD).getAsOpaquePtr()); return; @@ -3423,7 +3617,7 @@ llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) { } void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { - if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) + if (CGM.getCodeGenOpts().getDebugInfo() < codegenoptions::LimitedDebugInfo) return; const NamespaceDecl *NSDecl = UD.getNominatedNamespace(); if (!NSDecl->isAnonymousNamespace() || @@ -3436,13 +3630,23 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { } void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { - if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) + if (CGM.getCodeGenOpts().getDebugInfo() < codegenoptions::LimitedDebugInfo) return; assert(UD.shadow_size() && "We shouldn't be codegening an invalid UsingDecl containing no decls"); // Emitting one decl is sufficient - debuggers can detect that this is an // overloaded name & provide lookup for all the overloads. const UsingShadowDecl &USD = **UD.shadow_begin(); + + // FIXME: Skip functions with undeduced auto return type for now since we + // don't currently have the plumbing for separate declarations & definitions + // of free functions and mismatched types (auto in the declaration, concrete + // return type in the definition) + if (const auto *FD = dyn_cast<FunctionDecl>(USD.getUnderlyingDecl())) + if (const auto *AT = + FD->getType()->getAs<FunctionProtoType>()->getContainedAutoType()) + if (AT->getDeducedType().isNull()) + return; if (llvm::DINode *Target = getDeclarationOrDefinition(USD.getUnderlyingDecl())) DBuilder.createImportedDeclaration( @@ -3451,6 +3655,8 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { } void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) { + if (CGM.getCodeGenOpts().getDebuggerTuning() != llvm::DebuggerKind::LLDB) + return; if (Module *M = ID.getImportedModule()) { auto Info = ExternalASTSource::ASTSourceDescriptor(*M); DBuilder.createImportedDeclaration( @@ -3462,13 +3668,13 @@ void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) { llvm::DIImportedEntity * CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { - if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) + if (CGM.getCodeGenOpts().getDebugInfo() < codegenoptions::LimitedDebugInfo) return nullptr; auto &VH = NamespaceAliasCache[&NA]; if (VH) return cast<llvm::DIImportedEntity>(VH); llvm::DIImportedEntity *R; - if (const NamespaceAliasDecl *Underlying = + if (const auto *Underlying = dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace())) // This could cache & dedup here rather than relying on metadata deduping. R = DBuilder.createImportedDeclaration( @@ -3557,7 +3763,7 @@ void CGDebugInfo::finalize() { } void CGDebugInfo::EmitExplicitCastType(QualType Ty) { - if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) + if (CGM.getCodeGenOpts().getDebugInfo() < codegenoptions::LimitedDebugInfo) return; if (auto *DieTy = getOrCreateType(Ty, getOrCreateMainFile())) |