aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
authorEric Christopher <echristo@apple.com>2012-02-01 06:07:23 +0000
committerEric Christopher <echristo@apple.com>2012-02-01 06:07:23 +0000
commit0086a5b44af6384b369f8660da69cf2775d09733 (patch)
treeed984432659c588377a3ab7d87e90bbfb344703d /lib/CodeGen/CGDebugInfo.cpp
parent7b48a2986345480241f3b8209f71bb21b0530b4f (diff)
For pass-by-value record arguments to functions emit a forward decl
instead of the entire class definition. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149474 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp67
1 files changed, 64 insertions, 3 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 2ddfd31083..78096d2918 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -671,8 +671,12 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
if (isa<FunctionNoProtoType>(Ty))
EltTys.push_back(DBuilder.createUnspecifiedParameter());
else if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
- for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
- EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
+ for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) {
+ if (CGM.getCodeGenOpts().LimitDebugInfo)
+ EltTys.push_back(getOrCreateLimitedType(FTP->getArgType(i), Unit));
+ else
+ EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
+ }
}
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -681,7 +685,6 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
return DbgTy;
}
-
void CGDebugInfo::
CollectRecordStaticVars(const RecordDecl *RD, llvm::DIType FwdDecl) {
@@ -1646,6 +1649,64 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
return Res;
}
+/// getOrCreateLimitedType - Get the type from the cache or create a new
+/// limited type if necessary.
+llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty,
+ llvm::DIFile Unit) {
+ if (Ty.isNull())
+ return llvm::DIType();
+
+ // Unwrap the type as needed for debug information.
+ Ty = UnwrapTypeForDebugInfo(Ty);
+
+ llvm::DIType T = getTypeOrNull(Ty);
+ if (T.Verify()) return T;
+
+ // Otherwise create the type.
+ llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);
+
+ // And update the type cache.
+ TypeCache[Ty.getAsOpaquePtr()] = Res;
+ return Res;
+}
+
+// TODO: Not safe to use for inner types or for fields. Currently only
+// used for by value arguments to functions anything else needs to be
+// audited carefully.
+llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
+ RecordDecl *RD = Ty->getDecl();
+
+ // For templated records we want the full type information and
+ // our forward decls don't handle this correctly.
+ if (isa<ClassTemplateSpecializationDecl>(RD))
+ return CreateType(Ty);
+
+ llvm::DIDescriptor RDContext
+ = createContextChain(cast<Decl>(RD->getDeclContext()));
+
+ return createRecordFwdDecl(RD, RDContext);
+}
+
+/// CreateLimitedTypeNode - Create a new debug type node, but only forward
+/// declare composite types that haven't been processed yet.
+llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) {
+
+ // Work out details of type.
+ switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+ #include "clang/AST/TypeNodes.def"
+ llvm_unreachable("Dependent types cannot show up in debug information");
+
+ case Type::Record:
+ return CreateLimitedType(cast<RecordType>(Ty));
+ default:
+ return CreateTypeNode(Ty, Unit);
+ }
+}
+
/// CreateTypeNode - Create a new debug type node.
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
// Handle qualifiers, which recursively handles what they refer to.