DI: Rewrite the DIBuilder local variable API

Replace the general `createLocalVariable()` with two more specific
functions: `createParameterVariable()` and `createAutoVariable()`, and
rewrite the documentation.

Besides cleaning up the API, this avoids exposing the fake DWARF tags
`DW_TAG_arg_variable` and `DW_TAG_auto_variable` to frontends, and is
preparation for removing them completely.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243764 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-07-31 17:55:53 +00:00
parent 3f2cb5c959
commit aa50fa7c2f
6 changed files with 67 additions and 34 deletions

View File

@ -84,13 +84,18 @@ LLVMMetadataRef LLVMDIBuilderCreateFunction(
} }
LLVMMetadataRef LLVMDIBuilderCreateLocalVariable( LLVMMetadataRef LLVMDIBuilderCreateLocalVariable(
LLVMDIBuilderRef Dref, unsigned Tag, LLVMMetadataRef Scope, LLVMDIBuilderRef Dref, unsigned, LLVMMetadataRef Scope,
const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty,
int AlwaysPreserve, unsigned Flags, unsigned ArgNo) { int AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
DIBuilder *D = unwrap(Dref); DIBuilder *D = unwrap(Dref);
return wrap(D->createLocalVariable( // FIXME: Update the Go bindings to match the DIBuilder API.
Tag, unwrap<DIScope>(Scope), Name, unwrap<DIFile>(File), Line, if (ArgNo)
unwrap<DIType>(Ty), AlwaysPreserve, Flags, ArgNo)); return wrap(D->createParameterVariable(
unwrap<DIScope>(Scope), Name, ArgNo, unwrap<DIFile>(File), Line,
unwrap<DIType>(Ty), AlwaysPreserve, Flags));
return wrap(D->createAutoVariable(unwrap<DIScope>(Scope), Name,
unwrap<DIFile>(File), Line,
unwrap<DIType>(Ty), AlwaysPreserve, Flags));
} }
LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref, LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,

View File

@ -395,9 +395,8 @@ argument allocas in ``PrototypeAST::CreateArgumentAllocas``.
DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); DIScope *Scope = KSDbgInfo.LexicalBlocks.back();
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(),
KSDbgInfo.TheCU.getDirectory()); KSDbgInfo.TheCU.getDirectory());
DILocalVariable D = DBuilder->createLocalVariable( DILocalVariable D = DBuilder->createParameterVariable(
dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line, Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true);
KSDbgInfo.getDoubleTy(), true, 0, Idx + 1);
Instruction *Call = DBuilder->insertDeclare( Instruction *Call = DBuilder->insertDeclare(
Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock()); Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock());

View File

@ -1253,9 +1253,8 @@ void PrototypeAST::CreateArgumentAllocas(Function *F) {
DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); DIScope *Scope = KSDbgInfo.LexicalBlocks.back();
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
KSDbgInfo.TheCU->getDirectory()); KSDbgInfo.TheCU->getDirectory());
DILocalVariable *D = DBuilder->createLocalVariable( DILocalVariable *D = DBuilder->createParameterVariable(
dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line, Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true);
KSDbgInfo.getDoubleTy(), true, 0, Idx + 1);
DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
DebugLoc::get(Line, 0, Scope), DebugLoc::get(Line, 0, Scope),

View File

@ -457,26 +457,36 @@ namespace llvm {
unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val, unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val,
MDNode *Decl = nullptr); MDNode *Decl = nullptr);
/// Create a new descriptor for the specified /// Create a new descriptor for an auto variable. This is a local variable
/// local variable. /// that is not a subprogram parameter.
/// \param Tag Dwarf TAG. Usually DW_TAG_auto_variable or ///
/// DW_TAG_arg_variable. /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually
/// \param Scope Variable scope. /// leads to a \a DISubprogram.
/// \param Name Variable name. ///
/// \param File File where this variable is defined. /// If \c AlwaysPreserve, this variable will be referenced from its
/// \param LineNo Line number. /// containing subprogram, and will survive some optimizations.
/// \param Ty Variable Type DILocalVariable *createAutoVariable(DIScope *Scope, StringRef Name,
/// \param AlwaysPreserve Boolean. Set to true if debug info for this DIFile *File, unsigned LineNo,
/// variable should be preserved in optimized build. DIType *Ty,
/// \param Flags Flags, e.g. artificial variable.
/// \param ArgNo If this variable is an argument then this argument's
/// number. 1 indicates 1st argument.
DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope,
StringRef Name, DIFile *File,
unsigned LineNo, DIType *Ty,
bool AlwaysPreserve = false, bool AlwaysPreserve = false,
unsigned Flags = 0, unsigned Flags = 0);
unsigned ArgNo = 0);
/// Create a new descriptor for a parameter variable.
///
/// \c Scope must be a \a DILocalScope, and thus its scope chain eventually
/// leads to a \a DISubprogram.
///
/// \c ArgNo is the index (starting from \c 1) of this variable in the
/// subprogram parameters. \c ArgNo should not conflict with other
/// parameters of the same subprogram.
///
/// If \c AlwaysPreserve, this variable will be referenced from its
/// containing subprogram, and will survive some optimizations.
DILocalVariable *createParameterVariable(DIScope *Scope, StringRef Name,
unsigned ArgNo, DIFile *File,
unsigned LineNo, DIType *Ty,
bool AlwaysPreserve = false,
unsigned Flags = 0);
/// Create a new descriptor for the specified /// Create a new descriptor for the specified
/// variable which has a complex address expression for its address. /// variable which has a complex address expression for its address.

View File

@ -602,15 +602,18 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
.release(); .release();
} }
DILocalVariable *DIBuilder::createLocalVariable( static DILocalVariable *createLocalVariable(
unsigned Tag, DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, LLVMContext &VMContext,
DIType *Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) { DenseMap<MDNode *, std::vector<TrackingMDNodeRef>> &PreservedVariables,
DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
unsigned LineNo, DIType *Ty, bool AlwaysPreserve, unsigned Flags) {
// FIXME: Why getNonCompileUnitScope()? // FIXME: Why getNonCompileUnitScope()?
// FIXME: Why is "!Context" okay here? // FIXME: Why is "!Context" okay here?
// FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT // FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT
// the only valid scopes)? // the only valid scopes)?
DIScope *Context = getNonCompileUnitScope(Scope); DIScope *Context = getNonCompileUnitScope(Scope);
dwarf::Tag Tag = ArgNo ? dwarf::DW_TAG_arg_variable : dwarf::DW_TAG_auto_variable;
auto *Node = DILocalVariable::get( auto *Node = DILocalVariable::get(
VMContext, Tag, cast_or_null<DILocalScope>(Context), Name, File, LineNo, VMContext, Tag, cast_or_null<DILocalScope>(Context), Name, File, LineNo,
DITypeRef::get(Ty), ArgNo, Flags); DITypeRef::get(Ty), ArgNo, Flags);
@ -625,6 +628,23 @@ DILocalVariable *DIBuilder::createLocalVariable(
return Node; return Node;
} }
DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name,
DIFile *File, unsigned LineNo,
DIType *Ty, bool AlwaysPreserve,
unsigned Flags) {
return createLocalVariable(VMContext, PreservedVariables, Scope, Name,
/* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve,
Flags);
}
DILocalVariable *DIBuilder::createParameterVariable(
DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
unsigned LineNo, DIType *Ty, bool AlwaysPreserve, unsigned Flags) {
assert(ArgNo && "Expected non-zero argument number for parameter");
return createLocalVariable(VMContext, PreservedVariables, Scope, Name, ArgNo,
File, LineNo, Ty, AlwaysPreserve, Flags);
}
DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) { DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
return DIExpression::get(VMContext, Addr); return DIExpression::get(VMContext, Addr);
} }

View File

@ -255,8 +255,8 @@ protected:
auto *IntType = auto *IntType =
DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed); DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed);
auto *E = DBuilder.createExpression(); auto *E = DBuilder.createExpression();
auto *Variable = DBuilder.createLocalVariable( auto *Variable =
dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true); DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true);
auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram); auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
DBuilder.insertDeclare(Alloca, Variable, E, DL, Store); DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL, DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,