summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorMatthias Gehre <M.Gehre@gmx.de>2019-07-25 17:50:51 +0000
committerMatthias Gehre <M.Gehre@gmx.de>2019-07-25 17:50:51 +0000
commitd293cbd5fd44549bb48314499bc3b266d8967249 (patch)
treeab6670feffca7c33388bc45e9dba4f3aa4bef18b /clang/lib/Parse/ParseDecl.cpp
parent393094859e45f7a6ccbade1c919dee2c2e2f3a7e (diff)
downloadbcm5719-llvm-d293cbd5fd44549bb48314499bc3b266d8967249.tar.gz
bcm5719-llvm-d293cbd5fd44549bb48314499bc3b266d8967249.zip
Add lifetime categories attributes
Summary: This is the first part of work announced in "[RFC] Adding lifetime analysis to clang" [0], i.e. the addition of the [[gsl::Owner(T)]] and [[gsl::Pointer(T)]] attributes, which will enable user-defined types to participate in the lifetime analysis (which will be part of the next PR). The type `T` here is called "DerefType" in the paper, and denotes the type that an Owner owns and a Pointer points to. E.g. `std::vector<int>` should be annotated with `[[gsl::Owner(int)]]` and a `std::vector<int>::iterator` with `[[gsl::Pointer(int)]]`. [0] http://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html Reviewers: gribozavr Subscribers: xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D63954 llvm-svn: 367040
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 73b4f50fda4..3cf1f82943c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -335,6 +335,7 @@ unsigned Parser::ParseAttributeArgsCommon(
ConsumeParen();
bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier(*AttrName);
+ bool AttributeIsTypeArgAttr = attributeIsTypeArgAttr(*AttrName);
// Interpret "kw_this" as an identifier if the attributed requests it.
if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
@@ -360,6 +361,7 @@ unsigned Parser::ParseAttributeArgsCommon(
ArgExprs.push_back(ParseIdentifierLoc());
}
+ ParsedType TheParsedType;
if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
// Eat the comma.
if (!ArgExprs.empty())
@@ -372,8 +374,17 @@ unsigned Parser::ParseAttributeArgsCommon(
Tok.setKind(tok::identifier);
ExprResult ArgExpr;
- if (Tok.is(tok::identifier) &&
- attributeHasVariadicIdentifierArg(*AttrName)) {
+ if (AttributeIsTypeArgAttr) {
+ TypeResult T = ParseTypeName();
+ if (T.isInvalid()) {
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return 0;
+ }
+ if (T.isUsable())
+ TheParsedType = T.get();
+ break; // FIXME: Multiple type arguments are not implemented.
+ } else if (Tok.is(tok::identifier) &&
+ attributeHasVariadicIdentifierArg(*AttrName)) {
ArgExprs.push_back(ParseIdentifierLoc());
} else {
bool Uneval = attributeParsedArgsUnevaluated(*AttrName);
@@ -397,14 +408,20 @@ unsigned Parser::ParseAttributeArgsCommon(
SourceLocation RParen = Tok.getLocation();
if (!ExpectAndConsume(tok::r_paren)) {
SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
- Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
- ArgExprs.data(), ArgExprs.size(), Syntax);
+
+ if (AttributeIsTypeArgAttr && !TheParsedType.get().isNull()) {
+ Attrs.addNewTypeAttr(AttrName, SourceRange(AttrNameLoc, RParen),
+ ScopeName, ScopeLoc, TheParsedType, Syntax);
+ } else {
+ Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
+ ArgExprs.data(), ArgExprs.size(), Syntax);
+ }
}
if (EndLoc)
*EndLoc = RParen;
- return static_cast<unsigned>(ArgExprs.size());
+ return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.get().isNull());
}
/// Parse the arguments to a parameterized GNU attribute or
OpenPOWER on IntegriCloud