Provide a placement new taking an ASTContext argument.
This allows more concise syntax when allocating an object using the ASTContext's allocator.
Convert a few allocations to this operator to for test purposes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62623 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 32aa915..9ae6c85 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -550,9 +550,48 @@
FieldDecl *Field,
bool OutermostType = false,
bool EncodingProperty = false) const;
-
+
};
-
+
} // end namespace clang
+// operator new and delete aren't allowed inside namespaces.
+// The throw specifications are mandated by the standard.
+/// @brief Placement new for using the ASTContext's allocator.
+///
+/// This placement form of operator new uses the ASTContext's allocator for
+/// obtaining memory. It is a non-throwing new, which means that it returns
+/// null on error. (If that is what the allocator does. The current does, so if
+/// this ever changes, this operator will have to be changed, too.)
+/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
+/// @code
+/// // Default alignment (16)
+/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
+/// // Specific alignment
+/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.getAllocator().Deallocate(Ptr)
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The ASTContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the allocator
+/// supports it, which the current one doesn't).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new(size_t Bytes, clang::ASTContext &C,
+ size_t Alignment = 16) throw () {
+ return C.getAllocator().Allocate(Bytes, Alignment);
+}
+/// @brief Placement delete companion to the new above.
+///
+/// This operator is just a companion to the new above. There is no way of
+/// invoking it directly; see the new operator for more details. This operator
+/// is called implicitly by the compiler if a placement new expression using
+/// the ASTContext throws in the object constructor.
+inline void operator delete(void *Ptr, clang::ASTContext &C, size_t = 16)
+ throw () {
+ C.getAllocator().Deallocate(Ptr);
+}
+
#endif
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8a8fb73..b332b55 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -864,9 +864,9 @@
QualType type = getLangOptions().CPlusPlus ? Context.CharTy : Context.IntTy;
- void *Mem = Context.getAllocator().Allocate<CharacterLiteral>();
- return Owned(new (Mem) CharacterLiteral(Literal.getValue(), Literal.isWide(),
- type, Tok.getLocation()));
+ return Owned(new (Context) CharacterLiteral(Literal.getValue(),
+ Literal.isWide(),
+ type, Tok.getLocation()));
}
Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
@@ -908,9 +908,8 @@
// isExact will be set by GetFloatValue().
bool isExact = false;
- void *Mem = Context.getAllocator().Allocate<FloatingLiteral>();
- Res = new (Mem) FloatingLiteral(Literal.GetFloatValue(Format, &isExact),
- &isExact, Ty, Tok.getLocation());
+ Res = new (Context) FloatingLiteral(Literal.GetFloatValue(Format, &isExact),
+ &isExact, Ty, Tok.getLocation());
} else if (!Literal.isIntegerLiteral()) {
return ExprError();
@@ -997,8 +996,7 @@
if (ResultVal.getBitWidth() != Width)
ResultVal.trunc(Width);
}
- void *Mem = Context.getAllocator().Allocate<IntegerLiteral>();
- Res = new (Mem) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+ Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
}
// If this is an imaginary literal, create the ImaginaryLiteral wrapper.