diff options
author | Eric Christopher <echristo@apple.com> | 2012-02-01 06:07:23 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2012-02-01 06:07:23 +0000 |
commit | 0086a5b44af6384b369f8660da69cf2775d09733 (patch) | |
tree | ed984432659c588377a3ab7d87e90bbfb344703d /lib/CodeGen/CGDebugInfo.cpp | |
parent | 7b48a2986345480241f3b8209f71bb21b0530b4f (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.cpp | 67 |
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. |