Add the allocsize attribute to LLVM.
`allocsize` is a function attribute that allows users to request that
LLVM treat arbitrary functions as allocation functions.
This patch makes LLVM accept the `allocsize` attribute, and makes
`@llvm.objectsize` recognize said attribute.
The review for this was split into two patches for ease of reviewing:
D18974 and D14933. As promised on the revisions, I'm landing both
patches as a single commit.
Differential Revision: http://reviews.llvm.org/D14933
llvm-svn: 266032
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index db87fa7..e0ce50d 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -14,6 +14,7 @@
#include "LLParser.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
@@ -1051,6 +1052,15 @@
B.addStackAlignmentAttr(Alignment);
continue;
}
+ case lltok::kw_allocsize: {
+ unsigned ElemSizeArg;
+ Optional<unsigned> NumElemsArg;
+ // inAttrGrp doesn't matter; we only support allocsize(a[, b])
+ if (parseAllocSizeArguments(ElemSizeArg, NumElemsArg))
+ return true;
+ B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
+ continue;
+ }
case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break;
case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
@@ -1790,6 +1800,35 @@
return false;
}
+bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
+ Optional<unsigned> &HowManyArg) {
+ Lex.Lex();
+
+ auto StartParen = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return Error(StartParen, "expected '('");
+
+ if (ParseUInt32(BaseSizeArg))
+ return true;
+
+ if (EatIfPresent(lltok::comma)) {
+ auto HowManyAt = Lex.getLoc();
+ unsigned HowMany;
+ if (ParseUInt32(HowMany))
+ return true;
+ if (HowMany == BaseSizeArg)
+ return Error(HowManyAt,
+ "'allocsize' indices can't refer to the same parameter");
+ HowManyArg = HowMany;
+ } else
+ HowManyArg = None;
+
+ auto EndParen = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return Error(EndParen, "expected ')'");
+ return false;
+}
+
/// ParseScopeAndOrdering
/// if isAtomic: ::= 'singlethread'? AtomicOrdering
/// else: ::=