[DebugInfo] Expose Fortran array debug info attributes through DIBuilder.

The support of a few debug info attributes specifically for Fortran
arrays have been added to LLVM recently, but there's no way to take
advantage of them through DIBuilder. This patch extends
DIBuilder::createArrayType to enable the settings of those attributes.

Patch by Chih-Ping Chen!

Differential Revision: https://reviews.llvm.org/D89817
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp
index 900823a..f49ceee 100644
--- a/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/llvm/unittests/IR/DebugInfoTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -185,4 +186,44 @@
   EXPECT_TRUE(isa<UndefValue>(DVIs[0]->getValue()));
 }
 
+TEST(DIBuilder, CreateFortranArrayTypeWithAttributes) {
+  LLVMContext Ctx;
+  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
+  DIBuilder DIB(*M);
+
+  DISubrange *Subrange = DIB.getOrCreateSubrange(1,1);
+  SmallVector<Metadata*, 4> Subranges;
+  Subranges.push_back(Subrange);
+  DINodeArray Subscripts = DIB.getOrCreateArray(Subranges);
+
+  auto getDIExpression = [&DIB](int offset) {
+    SmallVector<uint64_t, 4> ops;
+    ops.push_back(llvm::dwarf::DW_OP_push_object_address);
+    DIExpression::appendOffset(ops, offset);
+    ops.push_back(llvm::dwarf::DW_OP_deref);
+
+    return DIB.createExpression(ops);
+  };
+
+  DIFile *F = DIB.createFile("main.c", "/");
+  DICompileUnit *CU = DIB.createCompileUnit(
+      dwarf::DW_LANG_C, DIB.createFile("main.c", "/"), "llvm-c", true, "", 0);
+
+  DIVariable *DataLocation =
+      DIB.createTempGlobalVariableFwdDecl(CU, "dl", "_dl", F, 1, nullptr, true);
+  DIExpression *Associated = getDIExpression(1);
+  DIExpression *Allocated = getDIExpression(2);
+  DIExpression *Rank = DIB.createConstantValueExpression(3);
+
+  DICompositeType *ArrayType = DIB.createArrayType(0, 0, nullptr, Subscripts,
+                                                   DataLocation, Associated,
+                                                   Allocated, Rank);
+
+  EXPECT_TRUE(isa_and_nonnull<DICompositeType>(ArrayType));
+  EXPECT_EQ(ArrayType->getRawDataLocation(), DataLocation);
+  EXPECT_EQ(ArrayType->getRawAssociated(), Associated);
+  EXPECT_EQ(ArrayType->getRawAllocated(), Allocated);
+  EXPECT_EQ(ArrayType->getRawRank(), Rank);
+}
+
 } // end namespace