[PATCH] D75827: Add new `attribute push` matcher `function(is_definition)`

Johannes Doerfert via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 8 10:07:39 PDT 2020


jdoerfert created this revision.
jdoerfert added reviewers: erichkeane, aaron.ballman.
Herald added a subscriber: bollu.
Herald added a project: clang.

This can also be used as a subject for attributes.

TODO: Tests are missing.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75827

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/Sema/SemaDeclAttr.cpp


Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -7690,6 +7690,26 @@
   }
 }
 
+namespace {
+/// The `attribute push` matcher `function(is_definition)` needs to know if a
+/// function declaration is a definition but we might check before the relevant
+/// parts have been parsed. This RAII helper will set the `WillHaveBody` flag
+/// if appropriate to make the matcher possible.
+struct MarkDeclerationsForParamMatcherRAII {
+  FunctionDecl *FD;
+  bool OldWillHaveBody;
+  MarkDeclerationsForParamMatcherRAII(FunctionDecl *FD, const Declarator &PD)
+      : FD(FD), OldWillHaveBody(FD && FD->willHaveBody()) {
+    if (FD && PD.isFunctionDefinition())
+      FD->setWillHaveBody(true);
+  }
+  ~MarkDeclerationsForParamMatcherRAII() {
+    if (FD)
+      FD->setWillHaveBody(OldWillHaveBody);
+  }
+};
+} // namespace
+
 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
 /// it, apply them to D.  This is a bit tricky because PD can have attributes
 /// specified in many different places, and we need to find and apply them all.
@@ -7710,7 +7730,10 @@
   ProcessDeclAttributeList(S, D, PD.getAttributes());
 
   // Apply additional attributes specified by '#pragma clang attribute'.
-  AddPragmaAttributes(S, D);
+  {
+    MarkDeclerationsForParamMatcherRAII MDFPM(dyn_cast<FunctionDecl>(D), PD);
+    AddPragmaAttributes(S, D);
+  }
 }
 
 /// Is the given declaration allowed to use a forbidden type?
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -101,6 +101,10 @@
                     [{!S->isStatic() && !S->isConst()}],
                     "non-static non-const member functions">;
 
+def FunctionDefinition : SubsetSubject<Function,
+                                       [{S->isThisDeclarationADefinition()}],
+                                       "function definition">;
+
 def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
                                        [{S->isInstanceMethod()}],
                                        "Objective-C instance methods">;
@@ -417,8 +421,11 @@
 def SubRuleForCXXMethod : AttrSubjectMatcherSubRule<"is_member", [CXXMethod]> {
   let LangOpts = [CPlusPlus];
 }
+// function(is_definition)
+def SubRuleForFunctionDefiniton
+    : AttrSubjectMatcherSubRule<"is_definition", [FunctionDefinition]> {}
 def SubjectMatcherForFunction : AttrSubjectMatcherRule<"function", [Function], [
-  SubRuleForCXXMethod
+  SubRuleForCXXMethod, SubRuleForFunctionDefiniton
 ]>;
 // hasType is abstract, it should be used with one of the sub-rules.
 def SubjectMatcherForType : AttrSubjectMatcherRule<"hasType", [], [


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75827.249004.patch
Type: text/x-patch
Size: 2860 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200308/74897df0/attachment.bin>


More information about the cfe-commits mailing list