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 | ee4ab93906027c054088fb248c030d8dd238ddf9 (patch) | |
| tree | 7de36fcf9b8bb0a523abcbf0c01d1334640eda0d /clang/lib/CodeGen | |
| parent | c8042323e1b2e24222ab603bfb6488ce3bb1ce60 (diff) | |
| download | bcm5719-llvm-ee4ab93906027c054088fb248c030d8dd238ddf9.tar.gz bcm5719-llvm-ee4ab93906027c054088fb248c030d8dd238ddf9.zip | |
For pass-by-value record arguments to functions emit a forward decl
instead of the entire class definition.
llvm-svn: 149474
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 67 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.h | 11 |
2 files changed, 75 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 2ddfd310835..78096d2918b 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/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/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index e33b2825112..c2a28fd8e3c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/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); |

