DI: Rewrite the DIBuilder local variable API
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 31 Jul 2015 17:55:53 +0000 (17:55 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 31 Jul 2015 17:55:53 +0000 (17:55 +0000)
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

bindings/go/llvm/DIBuilderBindings.cpp
docs/tutorial/LangImpl8.rst
examples/Kaleidoscope/Chapter8/toy.cpp
include/llvm/IR/DIBuilder.h
lib/IR/DIBuilder.cpp
unittests/Transforms/Utils/Cloning.cpp

index df5885de25c49e2d958a71c664057befeba9af3a..627c09131aa50ab65cd1d781d1307652cf6c24d4 100644 (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,
index 88224bb92f07f78263d84ce1ca2a3613ec5736fc..24c4d171f8590f08c7961c90861de30bb14827f0 100644 (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());
index 72e5089177b7c3f3ddda22f18a129b382dbdf487..f525ac7a1b0a5681eae99920e15bf85976d0dc7a 100644 (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),
index 0137a096e9706b2fd2c7a0db29903f8c454d0576..8aca266ce77b2f964c1f64db2dda3a5f71304135 100644 (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.
index 28a8d567c22316a444a82dfc9202b24ca77a53a2..7a4c520396542cfc7b3cd20b804921a0b1fd5516 100644 (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);
 }
index e2671499e812aa433c9ed75a2741b92ddd7f8f16..3ceb84c42c7e519ef90a1bb3145efada9dc28084 100644 (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,