Fix resetting the DataLayout in a Module.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 25 Feb 2014 22:23:04 +0000 (22:23 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 25 Feb 2014 22:23:04 +0000 (22:23 +0000)
No tool does this currently, but as everything else in a module we should be
able to change its DataLayout.

Most of the fix is in DataLayout to make sure it can be reset properly.

The test uses Module::setDataLayout since the fact that we mutate a DataLayout
is an implementation detail. The module could hold a OwningPtr<DataLayout> and
the DataLayout itself could be immutable.

Thanks to Philip Reames for pushing me in the right direction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202198 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/DataLayout.h
lib/IR/DataLayout.cpp
lib/IR/Module.cpp
unittests/IR/IRBuilderTest.cpp

index f9ab9cf94c8e86ad422816216a93cd2d97eb7a7e..046553dc1a27c2b9060ee1ecc8df66b12a3578f7 100644 (file)
@@ -110,7 +110,7 @@ private:
 
   /// Alignments - Where the primitive type alignment data is stored.
   ///
-  /// @sa init().
+  /// @sa reset().
   /// @note Could support multiple size pointer alignments, e.g., 32-bit
   /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now,
   /// we don't.
@@ -161,30 +161,35 @@ private:
   /// malformed.
   void parseSpecifier(StringRef LayoutDescription);
 
+  // Free all internal data structures.
+  void clear();
+
 public:
-  /// Constructs a DataLayout from a specification string. See init().
-  explicit DataLayout(StringRef LayoutDescription) { init(LayoutDescription); }
+  /// Constructs a DataLayout from a specification string. See reset().
+  explicit DataLayout(StringRef LayoutDescription) : LayoutMap(0) {
+    reset(LayoutDescription);
+  }
 
   /// Initialize target data from properties stored in the module.
   explicit DataLayout(const Module *M);
 
-  DataLayout(const DataLayout &DL) { *this = DL; }
+  DataLayout(const DataLayout &DL) : LayoutMap(0) { *this = DL; }
 
   DataLayout &operator=(const DataLayout &DL) {
+    clear();
     LittleEndian = DL.isLittleEndian();
     StackNaturalAlign = DL.StackNaturalAlign;
     ManglingMode = DL.ManglingMode;
     LegalIntWidths = DL.LegalIntWidths;
     Alignments = DL.Alignments;
     Pointers = DL.Pointers;
-    LayoutMap = 0;
     return *this;
   }
 
   ~DataLayout();  // Not virtual, do not subclass this class
 
   /// Parse a data layout string (with fallback to default values).
-  void init(StringRef LayoutDescription);
+  void reset(StringRef LayoutDescription);
 
   /// Layout endianness...
   bool isLittleEndian() const { return LittleEndian; }
index d60c79f52e86bdde23486a8eb9538f9e96195103..ccdaec5e554f465acd806ccd39afe18f027a1e3b 100644 (file)
@@ -176,7 +176,9 @@ static const LayoutAlignElem DefaultAlignments[] = {
   { AGGREGATE_ALIGN, 0, 0, 8 }   // struct
 };
 
-void DataLayout::init(StringRef Desc) {
+void DataLayout::reset(StringRef Desc) {
+  clear();
+
   LayoutMap = 0;
   LittleEndian = false;
   StackNaturalAlign = 0;
@@ -344,12 +346,12 @@ void DataLayout::parseSpecifier(StringRef Desc) {
   }
 }
 
-DataLayout::DataLayout(const Module *M) {
+DataLayout::DataLayout(const Module *M) : LayoutMap(0) {
   const DataLayout *Other = M->getDataLayout();
   if (Other)
     *this = *Other;
   else
-    init("");
+    reset("");
 }
 
 void
@@ -469,8 +471,16 @@ public:
 
 } // end anonymous namespace
 
+void DataLayout::clear() {
+  LegalIntWidths.clear();
+  Alignments.clear();
+  Pointers.clear();
+  delete static_cast<StructLayoutMap *>(LayoutMap);
+  LayoutMap = 0;
+}
+
 DataLayout::~DataLayout() {
-  delete static_cast<StructLayoutMap*>(LayoutMap);
+  clear();
 }
 
 const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
index 739f8888f96a46283b8584334eb5fbe18891566e..4204c8ef5fcd378b88f26c02c09d479834e623d7 100644 (file)
@@ -339,17 +339,21 @@ void Module::addModuleFlag(MDNode *Node) {
 }
 
 void Module::setDataLayout(StringRef Desc) {
+  DL.reset(Desc);
+
   if (Desc.empty()) {
     DataLayoutStr = "";
   } else {
-    DL.init(Desc);
     DataLayoutStr = DL.getStringRepresentation();
+    // DataLayoutStr is now equivalent to Desc, but since the representation
+    // is not unique, they may not be identical.
   }
 }
 
 void Module::setDataLayout(const DataLayout *Other) {
   if (!Other) {
     DataLayoutStr = "";
+    DL.reset("");
   } else {
     DL = *Other;
     DataLayoutStr = DL.getStringRepresentation();
index a0a72e82ed8ad72ceb675abda10535451c279195..e6db8c66df0a9f5397bf42b08324de22a180f432 100644 (file)
@@ -108,6 +108,14 @@ TEST_F(IRBuilderTest, LandingPadName) {
   EXPECT_EQ(LP->getName(), "LP");
 }
 
+TEST_F(IRBuilderTest, DataLayout) {
+  OwningPtr<Module> M(new Module("test", Ctx));
+  M->setDataLayout("e-n32");
+  EXPECT_TRUE(M->getDataLayout()->isLegalInteger(32));
+  M->setDataLayout("e");
+  EXPECT_FALSE(M->getDataLayout()->isLegalInteger(32));
+}
+
 TEST_F(IRBuilderTest, GetIntTy) {
   IRBuilder<> Builder(BB);
   IntegerType *Ty1 = Builder.getInt1Ty();