diff options
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 97 |
1 files changed, 69 insertions, 28 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index f6ee7ee26d4b..7c63743f3b43 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -314,7 +314,9 @@ StringRef CGDebugInfo::getClassName(const RecordDecl *RD) { if (isa<ClassTemplateSpecializationDecl>(RD)) { SmallString<128> Name; llvm::raw_svector_ostream OS(Name); - RD->getNameForDiagnostic(OS, getPrintingPolicy(), + PrintingPolicy PP = getPrintingPolicy(); + PP.PrintCanonicalTypes = true; + RD->getNameForDiagnostic(OS, PP, /*Qualified*/ false); // Copy this name on the side and use its reference. @@ -537,11 +539,11 @@ void CGDebugInfo::CreateCompileUnit() { // file to determine the real absolute path for the file. std::string MainFileDir; if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { - MainFileDir = remapDIPath(MainFile->getDir()->getName()); - if (MainFileDir != ".") { + MainFileDir = MainFile->getDir()->getName(); + if (!llvm::sys::path::is_absolute(MainFileName)) { llvm::SmallString<1024> MainFileDirSS(MainFileDir); llvm::sys::path::append(MainFileDirSS, MainFileName); - MainFileName = MainFileDirSS.str(); + MainFileName = llvm::sys::path::remove_leading_dotslash(MainFileDirSS); } // If the main file name provided is identical to the input file name, and // if the input file is a preprocessed source, use the module name for @@ -561,6 +563,10 @@ void CGDebugInfo::CreateCompileUnit() { if (LO.CPlusPlus) { if (LO.ObjC) LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus; + else if (LO.CPlusPlus14) + LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14; + else if (LO.CPlusPlus11) + LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11; else LangTag = llvm::dwarf::DW_LANG_C_plus_plus; } else if (LO.ObjC) { @@ -697,6 +703,22 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { case BuiltinType::Id: \ return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty); #include "clang/Basic/OpenCLExtensionTypes.def" + // TODO: real support for SVE types requires more infrastructure + // to be added first. The types have a variable length and are + // represented in debug info as types whose length depends on a + // target-specific pseudo register. +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" + { + unsigned DiagID = CGM.getDiags().getCustomDiagID( + DiagnosticsEngine::Error, + "cannot yet generate debug info for SVE type '%0'"); + auto Name = BT->getName(CGM.getContext().getPrintingPolicy()); + CGM.getDiags().Report(DiagID) << Name; + // Return something safe. + return CreateType(cast<const BuiltinType>(CGM.getContext().IntTy)); + } case BuiltinType::UChar: case BuiltinType::Char_U: @@ -862,6 +884,8 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { switch (TheCU->getSourceLanguage()) { case llvm::dwarf::DW_LANG_C_plus_plus: + case llvm::dwarf::DW_LANG_C_plus_plus_11: + case llvm::dwarf::DW_LANG_C_plus_plus_14: return true; case llvm::dwarf::DW_LANG_ObjC_plus_plus: return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); @@ -1583,6 +1607,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( ContainingType = RecordTy; } + if (Method->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; if (Method->isStatic()) Flags |= llvm::DINode::FlagStaticMember; if (Method->isImplicit()) @@ -1637,7 +1663,7 @@ void CGDebugInfo::CollectCXXMemberFunctions( if (!Method || Method->isImplicit() || Method->hasAttr<NoDebugAttr>()) continue; - if (Method->getType()->getAs<FunctionProtoType>()->getContainedAutoType()) + if (Method->getType()->castAs<FunctionProtoType>()->getContainedAutoType()) continue; // Reuse the existing member function declaration if it exists. @@ -1677,7 +1703,7 @@ void CGDebugInfo::CollectCXXBasesAux( const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); for (const auto &BI : Bases) { const auto *Base = - cast<CXXRecordDecl>(BI.getType()->getAs<RecordType>()->getDecl()); + cast<CXXRecordDecl>(BI.getType()->castAs<RecordType>()->getDecl()); if (!SeenTypes.insert(Base).second) continue; auto *BaseTy = getOrCreateType(BI.getType(), Unit); @@ -1769,6 +1795,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset); V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars); } + assert(V && "Failed to find template parameter pointer"); V = V->stripPointerCasts(); } TemplateParams.push_back(DBuilder.createTemplateValueParameter( @@ -2695,6 +2722,8 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty, break; case MSInheritanceAttr::Keyword_unspecified_inheritance: break; + case MSInheritanceAttr::SpellingNotCalculated: + llvm_unreachable("Spelling not yet calculated"); } } } @@ -2978,7 +3007,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) { #define ABSTRACT_TYPE(Class, Base) #define NON_CANONICAL_TYPE(Class, Base) #define DEPENDENT_TYPE(Class, Base) case Type::Class: -#include "clang/AST/TypeNodes.def" +#include "clang/AST/TypeNodes.inc" llvm_unreachable("Dependent types cannot show up in debug information"); case Type::ExtVector: @@ -3105,7 +3134,8 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU); - // Explicitly record the calling convention for C++ records. + // Explicitly record the calling convention and export symbols for C++ + // records. auto Flags = llvm::DINode::FlagZero; if (auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) { if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect) @@ -3116,6 +3146,10 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { // Record if a C++ record is non-trivial type. if (!CXXRD->isTrivial()) Flags |= llvm::DINode::FlagNonTrivial; + + // Record exports it symbols to the containing structure. + if (CXXRD->isAnonymousStructOrUnion()) + Flags |= llvm::DINode::FlagExportSymbols; } llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType( @@ -3247,8 +3281,8 @@ void CGDebugInfo::collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit, llvm::APInt ConstVal(32, 1); QualType ET = CGM.getContext().getAsArrayType(T)->getElementType(); - T = CGM.getContext().getConstantArrayType(ET, ConstVal, ArrayType::Normal, - 0); + T = CGM.getContext().getConstantArrayType(ET, ConstVal, nullptr, + ArrayType::Normal, 0); } Name = VD->getName(); @@ -3298,13 +3332,13 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD, unsigned Line = getLineNumber(Loc); collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray, Flags); - auto *FD = dyn_cast<FunctionDecl>(GD.getDecl()); + auto *FD = cast<FunctionDecl>(GD.getDecl()); // Build function type. SmallVector<QualType, 16> ArgTypes; - if (FD) - for (const ParmVarDecl *Parm : FD->parameters()) - ArgTypes.push_back(Parm->getType()); + for (const ParmVarDecl *Parm : FD->parameters()) + ArgTypes.push_back(Parm->getType()); + CallingConv CC = FD->getType()->castAs<FunctionType>()->getCallConv(); QualType FnType = CGM.getContext().getFunctionType( FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC)); @@ -3677,8 +3711,7 @@ void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke, const FunctionDecl *CalleeDecl) { auto &CGOpts = CGM.getCodeGenOpts(); if (!CGOpts.EnableDebugEntryValues || !CGM.getLangOpts().Optimize || - !CallOrInvoke || - CGM.getCodeGenOpts().getDebugInfo() < codegenoptions::LimitedDebugInfo) + !CallOrInvoke) return; auto *Func = CallOrInvoke->getCalledFunction(); @@ -3844,8 +3877,8 @@ CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, if (NumPaddingBytes.isPositive()) { llvm::APInt pad(32, NumPaddingBytes.getQuantity()); - FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy, - pad, ArrayType::Normal, 0); + FType = CGM.getContext().getConstantArrayType( + CGM.getContext().CharTy, pad, nullptr, ArrayType::Normal, 0); EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset)); } } @@ -4417,19 +4450,27 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { StringRef Name = VD->getName(); llvm::DIType *Ty = getOrCreateType(VD->getType(), Unit); - // Do not use global variables for enums, unless in CodeView. if (const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) { const auto *ED = cast<EnumDecl>(ECD->getDeclContext()); assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?"); - (void)ED; - - // If CodeView, emit enums as global variables, unless they are defined - // inside a class. We do this because MSVC doesn't emit S_CONSTANTs for - // enums in classes, and because it is difficult to attach this scope - // information to the global variable. - if (!CGM.getCodeGenOpts().EmitCodeView || - isa<RecordDecl>(ED->getDeclContext())) + + if (CGM.getCodeGenOpts().EmitCodeView) { + // If CodeView, emit enums as global variables, unless they are defined + // inside a class. We do this because MSVC doesn't emit S_CONSTANTs for + // enums in classes, and because it is difficult to attach this scope + // information to the global variable. + if (isa<RecordDecl>(ED->getDeclContext())) + return; + } else { + // If not CodeView, emit DW_TAG_enumeration_type if necessary. For + // example: for "enum { ZERO };", a DW_TAG_enumeration_type is created the + // first time `ZERO` is referenced in a function. + llvm::DIType *EDTy = + getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit); + assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type); + (void)EDTy; return; + } } llvm::DIScope *DContext = nullptr; @@ -4524,7 +4565,7 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { // return type in the definition) if (const auto *FD = dyn_cast<FunctionDecl>(USD.getUnderlyingDecl())) if (const auto *AT = - FD->getType()->getAs<FunctionProtoType>()->getContainedAutoType()) + FD->getType()->castAs<FunctionProtoType>()->getContainedAutoType()) if (AT->getDeducedType().isNull()) return; if (llvm::DINode *Target = |