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 | |
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')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 67 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 11 |
2 files changed, 75 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. diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index e33b282511..c2a28fd8e3 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -73,6 +73,9 @@ class CGDebugInfo { llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache; llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache; + /// Helper functions for getOrCreateLimitedType. + llvm::DIType CreateLimitedType(const RecordType *Ty); + /// Helper functions for getOrCreateType. llvm::DIType CreateType(const BuiltinType *Ty); llvm::DIType CreateType(const ComplexType *Ty); @@ -257,9 +260,17 @@ private: /// necessary. llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F); + /// getOrCreateLimitedType - Get the type from the cache or create a flat + /// limited type. + llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F); + /// CreateTypeNode - Create type metadata for a source language type. llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F); + /// CreateLimitedTypeNode - Create type metadata for a source language type, + /// but create as little as possible. + llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F); + /// CreateMemberType - Create new member and increase Offset by FType's size. llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType, StringRef Name, uint64_t *Offset); |