From: Sebastian Redl Date: Tue, 20 Jan 2009 22:23:13 +0000 (+0000) Subject: Provide a placement new taking an ASTContext argument. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e91b3bc1624ec877862e5d276f1b6f5026fe71e3;p=clang 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 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(); - 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(); - 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(); - 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.