diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index f9ab9cf94c8..046553dc1a2 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -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; } diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp index d60c79f52e8..ccdaec5e554 100644 --- a/lib/IR/DataLayout.cpp +++ b/lib/IR/DataLayout.cpp @@ -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(LayoutMap); + LayoutMap = 0; +} + DataLayout::~DataLayout() { - delete static_cast(LayoutMap); + clear(); } const StructLayout *DataLayout::getStructLayout(StructType *Ty) const { diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 739f8888f96..4204c8ef5fc 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -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(); diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp index a0a72e82ed8..e6db8c66df0 100644 --- a/unittests/IR/IRBuilderTest.cpp +++ b/unittests/IR/IRBuilderTest.cpp @@ -108,6 +108,14 @@ TEST_F(IRBuilderTest, LandingPadName) { EXPECT_EQ(LP->getName(), "LP"); } +TEST_F(IRBuilderTest, DataLayout) { + OwningPtr 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();