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(
LLVMDIBuilderRef Dref, unsigned Tag, LLVMMetadataRef Scope,
LLVMDIBuilderRef Dref, unsigned, LLVMMetadataRef Scope,
const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty,
int AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
DIBuilder *D = unwrap(Dref);
return wrap(D->createLocalVariable(
Tag, unwrap<DIScope>(Scope), Name, unwrap<DIFile>(File), Line,
unwrap<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
// FIXME: Update the Go bindings to match the DIBuilder API.
if (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,

View File

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

View File

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

View File

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

View File

@ -602,15 +602,18 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
.release();
}
DILocalVariable *DIBuilder::createLocalVariable(
unsigned Tag, DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo,
DIType *Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
static DILocalVariable *createLocalVariable(
LLVMContext &VMContext,
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 is "!Context" okay here?
// FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT
// the only valid scopes)?
DIScope *Context = getNonCompileUnitScope(Scope);
dwarf::Tag Tag = ArgNo ? dwarf::DW_TAG_arg_variable : dwarf::DW_TAG_auto_variable;
auto *Node = DILocalVariable::get(
VMContext, Tag, cast_or_null<DILocalScope>(Context), Name, File, LineNo,
DITypeRef::get(Ty), ArgNo, Flags);
@ -625,6 +628,23 @@ DILocalVariable *DIBuilder::createLocalVariable(
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) {
return DIExpression::get(VMContext, Addr);
}

View File

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