diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 44 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.h | 11 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 7 |
3 files changed, 53 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index ddcb931e46c..f6bb9168ab5 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2097,6 +2097,17 @@ llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType, return Ty; } +llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { + if (const TypeDecl *RD = dyn_cast<TypeDecl>(D)) + return CreatePointeeType(QualType(RD->getTypeForDecl(), 0), llvm::DIFile()); + llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator I = + DeclCache.find(D->getCanonicalDecl()); + if (I == DeclCache.end()) + return llvm::DIDescriptor(); + llvm::Value *V = I->second; + return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V)); +} + /// getFunctionDeclaration - Return debug info descriptor to describe method /// declaration for the given method definition. llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { @@ -2265,6 +2276,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, getLineNumber(CurLoc), Flags, CGM.getLangOpts().Optimize, Fn, TParamsArray, SPDecl); + if (HasDecl) + DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(SP))); // Push function on region stack. llvm::MDNode *SPN = SP; @@ -2875,10 +2888,11 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, LinkageName = StringRef(); llvm::DIDescriptor DContext = getContextDescriptor(dyn_cast<Decl>(D->getDeclContext())); - DBuilder.createStaticVariable(DContext, DeclName, LinkageName, + llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), Var->hasInternalLinkage(), Var, getStaticDataMemberDeclaration(D)); + DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV))); } /// EmitGlobalVariable - Emit information about an objective-c interface. @@ -2923,22 +2937,38 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, // Do not use DIGlobalVariable for enums. if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type) return; - DBuilder.createStaticVariable(Unit, Name, Name, Unit, + llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init, getStaticDataMemberDeclaration(VD)); + DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV))); +} + +llvm::DIScope CGDebugInfo::getCurrentContextDescriptor(const Decl *D) { + if (!LexicalBlockStack.empty()) + return llvm::DIScope(LexicalBlockStack.back()); + return getContextDescriptor(D); } void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { - llvm::DIScope Scope = - LexicalBlockStack.empty() - ? getContextDescriptor(cast<Decl>(UD.getDeclContext())) - : llvm::DIScope(LexicalBlockStack.back()); DBuilder.createImportedModule( - Scope, getOrCreateNameSpace(UD.getNominatedNamespace()), + getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())), + getOrCreateNameSpace(UD.getNominatedNamespace()), getLineNumber(UD.getLocation())); } +void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { + assert(UD.shadow_size() && + "We shouldn't be codegening an invalid UsingDecl containing no decls"); + // Emitting one decl is sufficient - debuggers can detect that this is an + // overloaded name & provide lookup for all the overloads. + const UsingShadowDecl &USD = **UD.shadow_begin(); + if (llvm::DIDescriptor Target = getDeclarationOrDefinition(USD.getUnderlyingDecl())) + DBuilder.createImportedDeclaration( + getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target, + getLineNumber(USD.getLocation())); +} + /// getOrCreateNamesSpace - Return namespace descriptor for the given /// namespace decl. llvm::DINameSpace diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 4080492a1c6..e61a50eeb41 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -35,6 +35,7 @@ namespace clang { class ObjCIvarDecl; class ClassTemplateSpecializationDecl; class GlobalDecl; + class UsingDecl; namespace CodeGen { class CodeGenModule; @@ -94,6 +95,7 @@ class CGDebugInfo { llvm::DenseMap<const char *, llvm::WeakVH> DIFileCache; llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache; + llvm::DenseMap<const Decl *, llvm::WeakVH> DeclCache; llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache; llvm::DenseMap<const Decl *, llvm::WeakVH> StaticDataMemberCache; @@ -265,6 +267,9 @@ public: /// \brief - Emit C++ using directive. void EmitUsingDirective(const UsingDirectiveDecl &UD); + /// \brief - Emit C++ using declaration. + void EmitUsingDecl(const UsingDecl &UD); + /// getOrCreateRecordType - Emit record type's standalone debug info. llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L); @@ -286,6 +291,8 @@ private: /// getContextDescriptor - Get context info for the decl. llvm::DIScope getContextDescriptor(const Decl *Decl); + llvm::DIScope getCurrentContextDescriptor(const Decl *Decl); + /// createRecordFwdDecl - Create a forward decl for a RecordType in a given /// context. llvm::DIType createRecordFwdDecl(const RecordDecl *, llvm::DIDescriptor); @@ -329,6 +336,10 @@ private: llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType, StringRef Name, uint64_t *Offset); + /// \brief Retrieve the DIDescriptor, if any, for the canonical form of this + /// declaration. + llvm::DIDescriptor getDeclarationOrDefinition(const Decl *D); + /// getFunctionDeclaration - Return debug info descriptor to describe method /// declaration for the given method definition. llvm::DISubprogram getFunctionDeclaration(const Decl *D); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 3ce6dec6a53..41f84091892 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -72,14 +72,13 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Block: case Decl::Captured: case Decl::ClassScopeFunctionSpecialization: + case Decl::UsingShadow: llvm_unreachable("Declaration should not be in declstmts!"); case Decl::Function: // void X(); case Decl::Record: // struct/union/class X; case Decl::Enum: // enum X; case Decl::EnumConstant: // enum ? { X = ? } case Decl::CXXRecord: // struct/union/class X; [C++] - case Decl::Using: // using X; [C++] - case Decl::UsingShadow: case Decl::NamespaceAlias: case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label: // __label__ x; @@ -89,6 +88,10 @@ void CodeGenFunction::EmitDecl(const Decl &D) { // None of these decls require codegen support. return; + case Decl::Using: // using X; [C++] + if (CGDebugInfo *DI = getDebugInfo()) + DI->EmitUsingDecl(cast<UsingDecl>(D)); + return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D)); |