llvm-project/clang/lib/CodeGen/CGDebugInfo.h

486 lines
20 KiB
C
Raw Normal View History

//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the source-level debug info generator for llvm translation.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H
#define LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H
#include "CGBuilder.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class MDNode;
}
namespace clang {
class CXXMethodDecl;
class VarDecl;
class ObjCInterfaceDecl;
class ObjCIvarDecl;
class ClassTemplateSpecializationDecl;
class GlobalDecl;
class UsingDecl;
namespace CodeGen {
class CodeGenModule;
class CodeGenFunction;
class CGBlockInfo;
/// \brief This class gathers all debug information during compilation
/// and is responsible for emitting to llvm globals or pass directly to
/// the backend.
class CGDebugInfo {
friend class ArtificialLocation;
friend class SaveAndRestoreLocation;
CodeGenModule &CGM;
const CodeGenOptions::DebugInfoKind DebugKind;
llvm::DIBuilder DBuilder;
llvm::DICompileUnit TheCU;
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
SourceLocation CurLoc;
llvm::DIType VTablePtrType;
llvm::DIType ClassTy;
llvm::DICompositeType ObjTy;
llvm::DIType SelTy;
llvm::DIType OCLImage1dDITy, OCLImage1dArrayDITy, OCLImage1dBufferDITy;
llvm::DIType OCLImage2dDITy, OCLImage2dArrayDITy;
llvm::DIType OCLImage3dDITy;
llvm::DIType OCLEventDITy;
llvm::DIType BlockLiteralGeneric;
2013-05-16 08:52:23 +08:00
/// \brief Cache of previously constructed Types.
llvm::DenseMap<const void *, llvm::TrackingMDRef> TypeCache;
struct ObjCInterfaceCacheEntry {
const ObjCInterfaceType *Type;
llvm::DIType Decl;
llvm::DIFile Unit;
ObjCInterfaceCacheEntry(const ObjCInterfaceType *Type, llvm::DIType Decl,
llvm::DIFile Unit)
: Type(Type), Decl(Decl), Unit(Unit) {}
};
/// \brief Cache of previously constructed interfaces
/// which may change.
llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
/// \brief list of interfaces we want to keep even if orphaned.
std::vector<void *> RetainedTypes;
/// \brief Cache of forward declared types to RAUW at the end of
/// compilation.
std::vector<std::pair<const TagType *, llvm::TrackingMDRef>> ReplaceMap;
/// \brief Cache of replaceable forward declarartions (functions and
/// variables) to RAUW at the end of compilation.
std::vector<std::pair<const DeclaratorDecl *, llvm::TrackingMDRef>>
FwdDeclReplaceMap;
// LexicalBlockStack - Keep track of our current nested lexical block.
std::vector<llvm::TrackingMDNodeRef> LexicalBlockStack;
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> RegionMap;
// FnBeginRegionCount - Keep track of LexicalBlockStack counter at the
// beginning of a function. This is used to pop unbalanced regions at
// the end of a function.
std::vector<unsigned> FnBeginRegionCount;
/// \brief This is a storage for names that are
/// constructed on demand. For example, C++ destructors, C++ operators etc..
llvm::BumpPtrAllocator DebugInfoNames;
StringRef CWDName;
llvm::DenseMap<const char *, llvm::TrackingMDRef> DIFileCache;
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPCache;
/// \brief Cache declarations relevant to DW_TAG_imported_declarations (C++
/// using declarations) that aren't covered by other more specific caches.
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NameSpaceCache;
llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
NamespaceAliasCache;
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> StaticDataMemberCache;
/// Helper functions for getOrCreateType.
unsigned Checksum(const ObjCInterfaceDecl *InterfaceDecl);
llvm::DIType CreateType(const BuiltinType *Ty);
llvm::DIType CreateType(const ComplexType *Ty);
llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg);
llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg);
llvm::DIType CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Fg);
llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
llvm::DIFile F);
llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const RecordType *Tyg);
llvm::DIType CreateTypeDefinition(const RecordType *Ty);
llvm::DICompositeType CreateLimitedType(const RecordType *Ty);
void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);
llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
llvm::DIType CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const RValueReferenceType *Ty, llvm::DIFile Unit);
llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
llvm::DIType CreateEnumType(const EnumType *Ty);
llvm::DIType CreateTypeDefinition(const EnumType *Ty);
llvm::DIType CreateSelfType(const QualType &QualTy, llvm::DIType Ty);
llvm::DIType getTypeOrNull(const QualType);
llvm::DICompositeType getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DIFile F);
llvm::DICompositeType getOrCreateInstanceMethodType(
QualType ThisPtr, const FunctionProtoType *Func, llvm::DIFile Unit);
llvm::DICompositeType getOrCreateFunctionType(const Decl *D, QualType FnType,
llvm::DIFile F);
llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N);
llvm::DIType getOrCreateTypeDeclaration(QualType PointeeTy, llvm::DIFile F);
llvm::DIType CreatePointerLikeType(llvm::dwarf::Tag Tag,
const Type *Ty, QualType PointeeTy,
llvm::DIFile F);
llvm::Value *getCachedInterfaceTypeOrNull(const QualType Ty);
llvm::DIType getOrCreateStructPtrType(StringRef Name, llvm::DIType &Cache);
llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,
llvm::DIFile F,
llvm::DIType RecordTy);
2013-05-16 08:52:23 +08:00
void CollectCXXMemberFunctions(const CXXRecordDecl *Decl, llvm::DIFile F,
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DIType T);
void CollectCXXBases(const CXXRecordDecl *Decl, llvm::DIFile F,
SmallVectorImpl<llvm::Metadata *> &EltTys,
llvm::DIType RecordTy);
2013-05-16 08:52:23 +08:00
llvm::DIArray
CollectTemplateParams(const TemplateParameterList *TPList,
ArrayRef<TemplateArgument> TAList,
llvm::DIFile Unit);
llvm::DIArray
CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit);
2013-05-16 08:52:23 +08:00
llvm::DIArray
CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,
llvm::DIFile F);
llvm::DIType createFieldType(StringRef name, QualType type,
uint64_t sizeInBitsOverride, SourceLocation loc,
AccessSpecifier AS,
uint64_t offsetInBits,
llvm::DIFile tunit,
llvm::DIScope scope,
const RecordDecl* RD = nullptr);
// Helpers for collecting fields of a record.
void CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DIType RecordTy);
llvm::DIDerivedType CreateRecordStaticField(const VarDecl *Var,
llvm::DIType RecordTy,
const RecordDecl* RD);
void CollectRecordNormalField(const FieldDecl *Field, uint64_t OffsetInBits,
llvm::DIFile F,
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DIType RecordTy, const RecordDecl *RD);
void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DICompositeType RecordTy);
void CollectVTableInfo(const CXXRecordDecl *Decl, llvm::DIFile F,
SmallVectorImpl<llvm::Metadata *> &EltTys);
// CreateLexicalBlock - Create a new lexical block node and push it on
// the stack.
void CreateLexicalBlock(SourceLocation Loc);
2013-05-16 08:52:23 +08:00
public:
CGDebugInfo(CodeGenModule &CGM);
~CGDebugInfo();
void finalize();
/// \brief Update the current source location. If \arg loc is
/// invalid it is ignored.
void setLocation(SourceLocation Loc);
/// \brief Emit metadata to indicate a change in line/column
/// information in the source file.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
/// \brief Emit a call to llvm.dbg.function.start to indicate
/// start of a new function.
/// \param Loc The location of the function header.
/// \param ScopeLoc The location of the function body.
void EmitFunctionStart(GlobalDecl GD,
SourceLocation Loc, SourceLocation ScopeLoc,
QualType FnType, llvm::Function *Fn,
CGBuilderTy &Builder);
/// \brief Constructs the debug code for exiting a function.
void EmitFunctionEnd(CGBuilderTy &Builder);
/// \brief Emit metadata to indicate the beginning of a
/// new lexical block and push the block onto the stack.
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc);
/// \brief Emit metadata to indicate the end of a new lexical
/// block and pop the current block.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc);
/// \brief Emit call to llvm.dbg.declare for an automatic
/// variable declaration.
void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
CGBuilderTy &Builder);
/// \brief Emit call to llvm.dbg.declare for an
/// imported variable declaration in a block.
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable,
llvm::Value *storage,
CGBuilderTy &Builder,
const CGBlockInfo &blockInfo,
llvm::Instruction *InsertPoint = 0);
/// \brief Emit call to llvm.dbg.declare for an argument
/// variable declaration.
void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
unsigned ArgNo, CGBuilderTy &Builder);
/// \brief Emit call to
/// llvm.dbg.declare for the block-literal argument to a block
/// invocation function.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
llvm::Value *Arg, unsigned ArgNo,
llvm::Value *LocalAddr,
CGBuilderTy &Builder);
/// \brief Emit information about a global variable.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
/// \brief Emit global variable's debug info.
void EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init);
/// \brief Emit C++ using directive.
void EmitUsingDirective(const UsingDirectiveDecl &UD);
/// \brief Emit the type explicitly casted to.
void EmitExplicitCastType(QualType Ty);
/// \brief Emit C++ using declaration.
void EmitUsingDecl(const UsingDecl &UD);
/// \brief Emit C++ namespace alias.
llvm::DIImportedEntity EmitNamespaceAlias(const NamespaceAliasDecl &NA);
/// \brief Emit record type's standalone debug info.
llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L);
/// \brief Emit an objective c interface type standalone
/// debug info.
llvm::DIType getOrCreateInterfaceType(QualType Ty,
SourceLocation Loc);
void completeType(const EnumDecl *ED);
void completeType(const RecordDecl *RD);
void completeRequiredType(const RecordDecl *RD);
void completeClassData(const RecordDecl *RD);
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
private:
/// \brief Emit call to llvm.dbg.declare for a variable declaration.
/// Tag accepts custom types DW_TAG_arg_variable and DW_TAG_auto_variable,
/// otherwise would be of type llvm::dwarf::Tag.
void EmitDeclare(const VarDecl *decl, llvm::dwarf::LLVMConstants Tag,
llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder);
2013-05-16 08:52:23 +08:00
// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.
// See BuildByRefType.
llvm::DIType EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
uint64_t *OffSet);
/// \brief Get context info for the decl.
llvm::DIScope getContextDescriptor(const Decl *Decl);
llvm::DIScope getCurrentContextDescriptor(const Decl *Decl);
/// \brief Create a forward decl for a RecordType in a given context.
llvm::DICompositeType getOrCreateRecordFwdDecl(const RecordType *,
llvm::DIDescriptor);
2013-05-16 08:52:23 +08:00
/// \brief Create a set of decls for the context chain.
llvm::DIDescriptor createContextChain(const Decl *Decl);
/// \brief Return current directory name.
StringRef getCurrentDirname();
/// \brief Create new compile unit.
void CreateCompileUnit();
/// \brief Get the file debug info descriptor for the input
/// location.
llvm::DIFile getOrCreateFile(SourceLocation Loc);
/// \brief Get the file info for main compile unit.
llvm::DIFile getOrCreateMainFile();
/// \brief Get the type from the cache or create a new type if
/// necessary.
llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile Fg);
/// \brief Get the type from the cache or create a new
/// partial type if necessary.
llvm::DIType getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile F);
/// \brief Create type metadata for a source language type.
llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile Fg);
/// \brief return the underlying ObjCInterfaceDecl
/// if Ty is an ObjCInterface or a pointer to one.
ObjCInterfaceDecl* getObjCInterfaceDecl(QualType Ty);
/// \brief Create new member and increase Offset by FType's size.
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);
/// \brief Return debug info descriptor to describe method
/// declaration for the given method definition.
llvm::DISubprogram getFunctionDeclaration(const Decl *D);
/// Return debug info descriptor to describe in-class static data member
/// declaration for the given out-of-class definition.
llvm::DIDerivedType
getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);
/// \brief Create a DISubprogram describing the forward
/// decalration represented in the given FunctionDecl.
llvm::DISubprogram getFunctionForwardDeclaration(const FunctionDecl *FD);
/// \brief Create a DIGlobalVariable describing the forward
/// decalration represented in the given VarDecl.
llvm::DIGlobalVariable getGlobalVariableForwardDeclaration(const VarDecl *VD);
/// Return a global variable that represents one of the collection of
/// global variables created for an anonmyous union.
llvm::DIGlobalVariable
CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile Unit, unsigned LineNo,
StringRef LinkageName, llvm::GlobalVariable *Var,
llvm::DIDescriptor DContext);
/// \brief Get function name for the given FunctionDecl. If the
/// name is constructed on demand (e.g. C++ destructor) then the name
/// is stored on the side.
StringRef getFunctionName(const FunctionDecl *FD);
/// \brief Returns the unmangled name of an Objective-C method.
2013-05-16 08:52:23 +08:00
/// This is the display name for the debugging info.
StringRef getObjCMethodName(const ObjCMethodDecl *FD);
/// \brief Return selector name. This is used for debugging
/// info.
StringRef getSelectorName(Selector S);
/// \brief Get class name including template argument list.
StringRef getClassName(const RecordDecl *RD);
/// \brief Get vtable name for the given Class.
StringRef getVTableName(const CXXRecordDecl *Decl);
/// \brief Get line number for the location. If location is invalid
/// then use current location.
unsigned getLineNumber(SourceLocation Loc);
/// \brief Get column number for the location. If location is
/// invalid then use current location.
/// \param Force Assume DebugColumnInfo option is true.
unsigned getColumnNumber(SourceLocation Loc, bool Force=false);
/// \brief Collect various properties of a FunctionDecl.
/// \param GD A GlobalDecl whose getDecl() must return a FunctionDecl.
void collectFunctionDeclProps(GlobalDecl GD,
llvm::DIFile Unit,
StringRef &Name, StringRef &LinkageName,
llvm::DIDescriptor &FDContext,
llvm::DIArray &TParamsArray,
unsigned &Flags);
/// \brief Collect various properties of a VarDecl.
void collectVarDeclProps(const VarDecl *VD, llvm::DIFile &Unit,
unsigned &LineNo, QualType &T,
StringRef &Name, StringRef &LinkageName,
llvm::DIDescriptor &VDContext);
/// \brief Allocate a copy of \p A using the DebugInfoNames allocator
/// and return a reference to it. If multiple arguments are given the strings
/// are concatenated.
StringRef internString(StringRef A, StringRef B = StringRef()) {
char *Data = DebugInfoNames.Allocate<char>(A.size() + B.size());
std::memcpy(Data, A.data(), A.size());
std::memcpy(Data + A.size(), B.data(), B.size());
return StringRef(Data, A.size() + B.size());
}
};
/// A scoped helper to set the current debug location to the specified location
/// or preferred location of the specified Expr.
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
class ApplyDebugLocation {
DebugInfo: Use the preferred location rather than the start location for expression line info This causes things like assignment to refer to the '=' rather than the LHS when attributing the store instruction, for example. There were essentially 3 options for this: * The beginning of an expression (this was the behavior prior to this commit). This meant that stepping through subexpressions would bounce around from subexpressions back to the start of the outer expression, etc. (eg: x + y + z would go x, y, x, z, x (the repeated 'x's would be where the actual addition occurred)). * The end of an expression. This seems to be what GCC does /mostly/, and certainly this for function calls. This has the advantage that progress is always 'forwards' (never jumping backwards - except for independent subexpressions if they're evaluated in interesting orders, etc). "x + y + z" would go "x y z" with the additions occurring at y and z after the respective loads. The problem with this is that the user would still have to think fairly hard about precedence to realize which subexpression is being evaluated or which operator overload is being called in, say, an asan backtrace. * The preferred location or 'exprloc'. In this case you get sort of what you'd expect, though it's a bit confusing in its own way due to going 'backwards'. In this case the locations would be: "x y + z +" in lovely postfix arithmetic order. But this does mean that if the op+ were an operator overload, say, and in a backtrace, the backtrace will point to the exact '+' that's being called, not to the end of one of its operands. (actually the operator overload case doesn't work yet for other reasons, but that's being fixed - but this at least gets scalar/complex assignments and other plain operators right) llvm-svn: 227027
2015-01-25 09:19:10 +08:00
private:
void init(SourceLocation TemporaryLocation);
protected:
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
llvm::DebugLoc OriginalLocation;
CodeGenFunction &CGF;
public:
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
ApplyDebugLocation(CodeGenFunction &CGF,
SourceLocation TemporaryLocation = SourceLocation());
DebugInfo: Use the preferred location rather than the start location for expression line info This causes things like assignment to refer to the '=' rather than the LHS when attributing the store instruction, for example. There were essentially 3 options for this: * The beginning of an expression (this was the behavior prior to this commit). This meant that stepping through subexpressions would bounce around from subexpressions back to the start of the outer expression, etc. (eg: x + y + z would go x, y, x, z, x (the repeated 'x's would be where the actual addition occurred)). * The end of an expression. This seems to be what GCC does /mostly/, and certainly this for function calls. This has the advantage that progress is always 'forwards' (never jumping backwards - except for independent subexpressions if they're evaluated in interesting orders, etc). "x + y + z" would go "x y z" with the additions occurring at y and z after the respective loads. The problem with this is that the user would still have to think fairly hard about precedence to realize which subexpression is being evaluated or which operator overload is being called in, say, an asan backtrace. * The preferred location or 'exprloc'. In this case you get sort of what you'd expect, though it's a bit confusing in its own way due to going 'backwards'. In this case the locations would be: "x y + z +" in lovely postfix arithmetic order. But this does mean that if the op+ were an operator overload, say, and in a backtrace, the backtrace will point to the exact '+' that's being called, not to the end of one of its operands. (actually the operator overload case doesn't work yet for other reasons, but that's being fixed - but this at least gets scalar/complex assignments and other plain operators right) llvm-svn: 227027
2015-01-25 09:19:10 +08:00
ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E);
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc);
~ApplyDebugLocation();
};
/// \brief An RAII object that temporarily switches to
/// an artificial debug location that has a valid scope, but no line
/// information. This is useful when emitting compiler-generated
/// helper functions that have no source location associated with
/// them. The DWARF specification allows the compiler to use the
/// special line number 0 to indicate code that can not be attributed
/// to any source location.
///
/// This is necessary because passing an empty SourceLocation to
/// CGDebugInfo::setLocation() will result in the last valid location
/// being reused.
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
class ArtificialLocation : public ApplyDebugLocation {
public:
Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits). Several pieces of code were relying on implicit debug location setting which usually lead to incorrect line information anyway. So I've fixed those (in r225955 and r225845) separately which should pave the way for this commit to be cleanly reapplied. The reason these implicit dependencies resulted in crashes with this patch is that the debug location would no longer implicitly leak from one place to another, but be set back to invalid. Once a call with no/invalid location was emitted, if that call was ever inlined it could produce invalid debugloc chains and assert during LLVM's codegen. There may be further cases of such bugs in this patch - they're hard to flush out with regression testing, so I'll keep an eye out for reports and investigate/fix them ASAP if they come up. Original commit message: Reapply "DebugInfo: Generalize debug info location handling" Originally committed in r224385 and reverted in r224441 due to concerns this change might've introduced a crash. Turns out this change fixes the crash introduced by one of my earlier more specific location handling changes (those specific fixes are reverted by this patch, in favor of the more general solution). Recommitted in r224941 and reverted in r224970 after it caused a crash when building compiler-rt. Looks to be due to this change zeroing out the debug location when emitting default arguments (which were meant to inherit their outer expression's location) thus creating call instructions without locations - these create problems for inlining and must not be created. That is fixed and tested in this version of the change. Original commit message: This is a more scalable (fixed in mostly one place, rather than many places that will need constant improvement/maintenance) solution to several commits I've made recently to increase source fidelity for subexpressions. This resetting had to be done at the DebugLoc level (not the SourceLocation level) to preserve scoping information (if the resetting was done with CGDebugInfo::EmitLocation, it would've caused the tail end of an expression's codegen to end up in a potentially different scope than the start, even though it was at the same source location). The drawback to this is that it might leave CGDebugInfo out of sync. Ideally CGDebugInfo shouldn't have a duplicate sense of the current SourceLocation, but for now it seems it does... - I don't think I'm going to tackle removing that just now. I expect this'll probably cause some more buildbot fallout & I'll investigate that as it comes up. Also these sort of improvements might be starting to show a weakness/bug in LLVM's line table handling: we don't correctly emit is_stmt for statements, we just put it on every line table entry. This means one statement split over multiple lines appears as multiple 'statements' and two statements on one line (without column info) are treated as one statement. I don't think we have any IR representation of statements that would help us distinguish these cases and identify the beginning of each statement - so that might be something we need to add (possibly to the lexical scope chain - a scope for each statement). This does cause some problems for GDB and possibly other DWARF consumers. llvm-svn: 225956
2015-01-14 15:38:27 +08:00
ArtificialLocation(CodeGenFunction &CGF);
};
} // namespace CodeGen
} // namespace clang
#endif