]> granicus.if.org Git - clang/commitdiff
[XRay][clang] Support capturing the implicit `this` argument to C++ class member...
authorDean Michael Berris <dberris@google.com>
Fri, 16 Jun 2017 03:22:09 +0000 (03:22 +0000)
committerDean Michael Berris <dberris@google.com>
Fri, 16 Jun 2017 03:22:09 +0000 (03:22 +0000)
Summary:
Before this change, we couldn't capture the `this` pointer that's
implicitly the first argument of class member functions. There are some
interesting things we can do with capturing even just this single
argument for zero-argument member functions.

Reviewers: rnk, pelikan

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D34052

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305544 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclAttr.cpp
test/Sema/xray-log-args-class.cpp [new file with mode: 0644]

index 6c492fac9eb9d8d6847241a4c47962bbe5d6a576..b43642f5493b3acbae89878e17405311965bd52e 100644 (file)
@@ -313,8 +313,8 @@ static bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range,
 /// \returns true if IdxExpr is a valid index.
 template <typename AttrInfo>
 static bool checkFunctionOrMethodParameterIndex(
-    Sema &S, const Decl *D, const AttrInfo& Attr,
-    unsigned AttrArgNum, const Expr *IdxExpr, uint64_t &Idx) {
+    Sema &S, const Decl *D, const AttrInfo &Attr, unsigned AttrArgNum,
+    const Expr *IdxExpr, uint64_t &Idx, bool AllowImplicitThis = false) {
   assert(isFunctionOrMethodOrBlock(D));
 
   // In C++ the implicit 'this' function parameter also counts.
@@ -341,7 +341,7 @@ static bool checkFunctionOrMethodParameterIndex(
     return false;
   }
   Idx--; // Convert to zero-based.
-  if (HasImplicitThisParam) {
+  if (HasImplicitThisParam && !AllowImplicitThis) {
     if (Idx == 0) {
       S.Diag(getAttrLoc(Attr),
              diag::err_attribute_invalid_implicit_this_argument)
@@ -4604,14 +4604,16 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
 static void handleXRayLogArgsAttr(Sema &S, Decl *D,
                                   const AttributeList &Attr) {
   uint64_t ArgCount;
+
   if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, Attr.getArgAsExpr(0),
-                                           ArgCount))
+                                           ArgCount,
+                                           true /* AllowImplicitThis*/))
     return;
 
   // ArgCount isn't a parameter index [0;n), it's a count [1;n] - hence + 1.
   D->addAttr(::new (S.Context)
-             XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount,
-             Attr.getAttributeSpellingListIndex()));
+                 XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount,
+                                 Attr.getAttributeSpellingListIndex()));
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Sema/xray-log-args-class.cpp b/test/Sema/xray-log-args-class.cpp
new file mode 100644 (file)
index 0000000..10da93f
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
+
+class Class {
+  [[clang::xray_always_instrument, clang::xray_log_args(1)]] void Method();
+  [[clang::xray_log_args(-1)]] void Invalid(); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
+  [[clang::xray_log_args("invalid")]] void InvalidStringArg(); // expected-error {{'xray_log_args'}}
+};