summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-05-15 17:49:20 +0000
committerJohn McCall <rjmccall@apple.com>2011-05-15 17:49:20 +0000
commit53ffd3714f7d312448bb904d69ae255479db5c2a (patch)
treed7c455dfdef128e93b9fafa6e8bff849d4471045
parent49c0bd2a251c851640b67d5f5de2b3ee598b640c (diff)
downloadbcm5719-llvm-53ffd3714f7d312448bb904d69ae255479db5c2a.tar.gz
bcm5719-llvm-53ffd3714f7d312448bb904d69ae255479db5c2a.zip
Add a method for checking whether a function is one of the reserved global
placement allocation or deallocation functions. These functions cannot be replaced by the user and are exempt from the normal requirements on allocation functions (e.g. that they must return unaliased memory). llvm-svn: 131386
-rw-r--r--clang/include/clang/AST/Decl.h19
-rw-r--r--clang/lib/AST/Decl.cpp32
2 files changed, 45 insertions, 6 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 6ca14ce8749..e1dad644c99 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -1644,10 +1644,25 @@ public:
bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
- /// \brief Determines whether this is a function "main", which is
- /// the entry point into an executable program.
+ /// \brief Determines whether this function is "main", which is the
+ /// entry point into an executable program.
bool isMain() const;
+ /// \brief Determines whether this operator new or delete is one
+ /// of the reserved global placement operators:
+ /// void *operator new(size_t, void *);
+ /// void *operator new[](size_t, void *);
+ /// void operator delete(void *, void *);
+ /// void operator delete[](void *, void *);
+ /// These functions have special behavior under [new.delete.placement]:
+ /// These functions are reserved, a C++ program may not define
+ /// functions that displace the versions in the Standard C++ library.
+ /// The provisions of [basic.stc.dynamic] do not apply to these
+ /// reserved placement forms of operator new and operator delete.
+ ///
+ /// This function must be an allocation or deallocation function.
+ bool isReservedGlobalPlacementOperator() const;
+
/// \brief Determines whether this function is a function with
/// external, C linkage.
bool isExternC() const;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index d4df017383d..1e98998002f 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1475,10 +1475,34 @@ void FunctionDecl::setPure(bool P) {
}
bool FunctionDecl::isMain() const {
- ASTContext &Context = getASTContext();
- return !Context.getLangOptions().Freestanding &&
- getDeclContext()->getRedeclContext()->isTranslationUnit() &&
- getIdentifier() && getIdentifier()->isStr("main");
+ const TranslationUnitDecl *tunit =
+ dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
+ return tunit &&
+ tunit->getASTContext().getLangOptions().Freestanding &&
+ getIdentifier() &&
+ getIdentifier()->isStr("main");
+}
+
+bool FunctionDecl::isReservedGlobalPlacementOperator() const {
+ assert(getDeclName().getNameKind() == DeclarationName::CXXOperatorName);
+ assert(getDeclName().getCXXOverloadedOperator() == OO_New ||
+ getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ getDeclName().getCXXOverloadedOperator() == OO_Array_New ||
+ getDeclName().getCXXOverloadedOperator() == OO_Array_Delete);
+
+ if (isa<CXXRecordDecl>(getDeclContext())) return false;
+ assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+
+ const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
+ if (proto->getNumArgs() != 2 || proto->isVariadic()) return false;
+
+ ASTContext &Context =
+ cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
+ ->getASTContext();
+
+ // The result type and first argument type are constant across all
+ // these operators. The second argument must be exactly void*.
+ return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy);
}
bool FunctionDecl::isExternC() const {
OpenPOWER on IntegriCloud