diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-20 22:23:13 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-20 22:23:13 +0000 |
commit | e91b3bc1624ec877862e5d276f1b6f5026fe71e3 (patch) | |
tree | ed6229bed30c0ffe838146bb25b80d619913593c | |
parent | 09abfea5b6fbe8ac98b2943034e53ab13b0acd07 (diff) |
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
-rw-r--r-- | include/clang/AST/ASTContext.h | 43 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 14 |
2 files changed, 47 insertions, 10 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 32aa9157aa..9ae6c85e91 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -550,9 +550,48 @@ private: 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 8a8fb731c7..b332b557a8 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -864,9 +864,9 @@ Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) { 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 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { // 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 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { 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. |