aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2016-04-12 01:05:35 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2016-04-12 01:05:35 +0000
commit278199f615d9f9e224e5033b9558c6ed974cbf37 (patch)
treeed03369bae73053077296d212482ab279c4ee013 /llvm/lib/AsmParser/LLParser.cpp
parentb40d14f3d56e9b0f1bc41f6123586d09ccd6d305 (diff)
downloadllvm-278199f615d9f9e224e5033b9558c6ed974cbf37.zip
llvm-278199f615d9f9e224e5033b9558c6ed974cbf37.tar.gz
llvm-278199f615d9f9e224e5033b9558c6ed974cbf37.tar.bz2
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
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp39
1 files changed, 39 insertions, 0 deletions
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 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
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 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
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: ::=