summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorBob Haarman <llvm@inglorion.net>2016-10-25 22:19:32 +0000
committerBob Haarman <llvm@inglorion.net>2016-10-25 22:19:32 +0000
commitdff36738d1710288f7ab50460e5dc584be033951 (patch)
tree10449963cc807fe3522c6a9f9486566da76bcf09 /clang/lib/CodeGen
parent2e64b8b79e635295ab1614088a49883063c4541b (diff)
downloadbcm5719-llvm-dff36738d1710288f7ab50460e5dc584be033951.tar.gz
bcm5719-llvm-dff36738d1710288f7ab50460e5dc584be033951.zip
[codeview] emit debug info for indirect virtual base classes
Summary: Fixes PR28281. MSVC lists indirect virtual base classes in the field list of a class. This change makes Clang emit the information necessary for LLVM to emit such records. Reviewers: rnk, ruiu, zturner Differential Revision: https://reviews.llvm.org/D25579 llvm-svn: 285132
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp37
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h12
2 files changed, 40 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 9b623d7443c..6a6b83e3314 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -13,9 +13,9 @@
#include "CGDebugInfo.h"
#include "CGBlocks.h"
-#include "CGRecordLayout.h"
#include "CGCXXABI.h"
#include "CGObjCRuntime.h"
+#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/ASTContext.h"
@@ -31,6 +31,7 @@
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PreprocessorOptions.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Constants.h"
@@ -1380,13 +1381,33 @@ void CGDebugInfo::CollectCXXMemberFunctions(
void CGDebugInfo::CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile *Unit,
SmallVectorImpl<llvm::Metadata *> &EltTys,
llvm::DIType *RecordTy) {
- const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
- for (const auto &BI : RD->bases()) {
- llvm::DINode::DIFlags BFlags = llvm::DINode::FlagZero;
- uint64_t BaseOffset;
+ llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> SeenTypes;
+ CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->bases(), SeenTypes,
+ llvm::DINode::FlagZero);
+
+ // If we are generating CodeView debug info, we also need to emit records for
+ // indirect virtual base classes.
+ if (CGM.getCodeGenOpts().EmitCodeView) {
+ CollectCXXBasesAux(RD, Unit, EltTys, RecordTy, RD->vbases(), SeenTypes,
+ llvm::DINode::FlagIndirectVirtualBase);
+ }
+}
+void CGDebugInfo::CollectCXXBasesAux(
+ const CXXRecordDecl *RD, llvm::DIFile *Unit,
+ SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy,
+ const CXXRecordDecl::base_class_const_range &Bases,
+ llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
+ llvm::DINode::DIFlags StartingFlags) {
+ const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+ for (const auto &BI : Bases) {
const auto *Base =
cast<CXXRecordDecl>(BI.getType()->getAs<RecordType>()->getDecl());
+ if (!SeenTypes.insert(Base).second)
+ continue;
+ auto *BaseTy = getOrCreateType(BI.getType(), Unit);
+ llvm::DINode::DIFlags BFlags = StartingFlags;
+ uint64_t BaseOffset;
if (BI.isVirtual()) {
if (CGM.getTarget().getCXXABI().isItaniumFamily()) {
@@ -1401,15 +1422,15 @@ void CGDebugInfo::CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile *Unit,
BaseOffset =
4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base);
}
- BFlags = llvm::DINode::FlagVirtual;
+ BFlags |= llvm::DINode::FlagVirtual;
} else
BaseOffset = CGM.getContext().toBits(RL.getBaseClassOffset(Base));
// FIXME: Inconsistent units for BaseOffset. It is in bytes when
// BI->isVirtual() and bits when not.
BFlags |= getAccessFlag(BI.getAccessSpecifier(), RD);
- llvm::DIType *DTy = DBuilder.createInheritance(
- RecordTy, getOrCreateType(BI.getType(), Unit), BaseOffset, BFlags);
+ llvm::DIType *DTy =
+ DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset, BFlags);
EltTys.push_back(DTy);
}
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index d2af9be9b6c..f43261a47d2 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -15,12 +15,14 @@
#define LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H
#include "CGBuilder.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
@@ -32,7 +34,6 @@ class MDNode;
}
namespace clang {
-class CXXMethodDecl;
class ClassTemplateSpecializationDecl;
class GlobalDecl;
class ModuleMap;
@@ -218,6 +219,15 @@ class CGDebugInfo {
SmallVectorImpl<llvm::Metadata *> &EltTys,
llvm::DIType *RecordTy);
+ /// Helper function for CollectCXXBases.
+ /// Adds debug info entries for types in Bases that are not in SeenTypes.
+ void CollectCXXBasesAux(const CXXRecordDecl *RD, llvm::DIFile *Unit,
+ SmallVectorImpl<llvm::Metadata *> &EltTys,
+ llvm::DIType *RecordTy,
+ const CXXRecordDecl::base_class_const_range &Bases,
+ llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
+ llvm::DINode::DIFlags StartingFlags);
+
/// A helper function to collect template parameters.
llvm::DINodeArray CollectTemplateParams(const TemplateParameterList *TPList,
ArrayRef<TemplateArgument> TAList,
OpenPOWER on IntegriCloud