[cfe-commits] r82678 - in /cfe/trunk/lib/AST: RecordLayoutBuilder.cpp RecordLayoutBuilder.h
Anders Carlsson
andersca at mac.com
Wed Sep 23 20:13:30 PDT 2009
Author: andersca
Date: Wed Sep 23 22:13:30 2009
New Revision: 82678
URL: http://llvm.org/viewvc/llvm-project?rev=82678&view=rev
Log:
Scaffolding for supporting empty bases/fields.
Modified:
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=82678&r1=82677&r2=82678&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Sep 23 22:13:30 2009
@@ -219,8 +219,18 @@
}
}
-void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD,
- bool IsVirtualBase) {
+bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
+ uint64_t Offset) const {
+ // FIXME: Implement.
+ return true;
+}
+
+void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
+ uint64_t Offset) {
+ // FIXME: Implement.
+}
+
+uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
if (!Bases.empty()) {
assert(BaseInfo.getDataSize() > 0 &&
@@ -229,15 +239,32 @@
unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
uint64_t BaseSize = BaseInfo.getNonVirtualSize();
-
+
// Round up the current record size to the base's alignment boundary.
- Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1);
+ uint64_t Offset = llvm::RoundUpToAlignment(Size, BaseAlign);
+
+ // Reserve space for this base.
+ Size = Offset + BaseSize;
+
+ // Remember the next available offset.
+ NextOffset = Size;
+
+ // Remember max struct/class alignment.
+ UpdateAlignment(BaseAlign);
+
+ return Offset;
+}
+
+void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD,
+ bool IsVirtualBase) {
+ // Layout the base.
+ unsigned Offset = LayoutBase(RD);
// Add base class offsets.
if (IsVirtualBase)
- VBases.push_back(std::make_pair(RD, Size));
+ VBases.push_back(std::make_pair(RD, Offset));
else
- Bases.push_back(std::make_pair(RD, Size));
+ Bases.push_back(std::make_pair(RD, Offset));
#if 0
// And now add offsets for all our primary virtual bases as well, so
@@ -254,15 +281,6 @@
L = &Ctx.getASTRecordLayout(PB);
}
#endif
-
- // Reserve space for this base.
- Size += BaseSize;
-
- // Remember the next available offset.
- NextOffset = Size;
-
- // Remember max struct/class alignment.
- UpdateAlignment(BaseAlign);
}
void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
@@ -408,7 +426,7 @@
FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
// Round up the current record size to the field's alignment boundary.
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+ FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
}
// Place this field at the current location.
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=82678&r1=82677&r2=82678&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Wed Sep 23 22:13:30 2009
@@ -13,6 +13,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/DataTypes.h"
+#include <map>
namespace clang {
class ASTContext;
@@ -53,6 +54,10 @@
/// primary base classes for some other direct or indirect base class.
llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases;
+ /// EmptyClassOffsets - A map from offsets to empty record decls.
+ typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy;
+ EmptyClassOffsetsTy EmptyClassOffsets;
+
ASTRecordLayoutBuilder(ASTContext &Ctx);
void Layout(const RecordDecl *D);
@@ -79,6 +84,10 @@
bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
+ /// LayoutBase - Will lay out a base and return the offset where it was
+ /// placed, in bits.
+ uint64_t LayoutBase(const CXXRecordDecl *RD);
+
void LayoutVtable(const CXXRecordDecl *RD);
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);
@@ -88,6 +97,18 @@
llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
+ /// canPlaceRecordAtOffset - Return whether a record (either a base class
+ /// or a field) can be placed at the given offset.
+ /// Returns false if placing the record will result in two components
+ /// (direct or indirect) of the same type having the same offset.
+ bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
+
+ /// UpdateEmptyClassOffsets - Called after a record (either a base class
+ /// or a field) has been placed at the given offset. Will update the
+ /// EmptyClassOffsets map if the class is empty or has any empty bases or
+ /// fields.
+ void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset);
+
/// FinishLayout - Finalize record layout. Adjust record size based on the
/// alignment.
void FinishLayout();
More information about the cfe-commits
mailing list