forked from OSchip/llvm-project
[XRay] [clang] Allow logging the first argument of a function call.
Summary: Functions with the "xray_log_args" attribute will tell LLVM to emit a special XRay sled for compiler-rt to copy any call arguments to your logging handler. Reviewers: dberris Reviewed By: dberris Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D29704 llvm-svn: 296999
This commit is contained in:
parent
7e8eea429f
commit
418da3fe80
|
@ -450,6 +450,15 @@ def XRayInstrument : InheritableAttr {
|
|||
let Documentation = [XRayDocs];
|
||||
}
|
||||
|
||||
def XRayLogArgs : InheritableAttr {
|
||||
let Spellings = [GNU<"xray_log_args">, CXX11<"clang", "xray_log_args">];
|
||||
let Subjects = SubjectList<
|
||||
[CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
|
||||
>;
|
||||
let Args = [UnsignedArgument<"ArgumentCount">];
|
||||
let Documentation = [XRayDocs];
|
||||
}
|
||||
|
||||
def TLSModel : InheritableAttr {
|
||||
let Spellings = [GCC<"tls_model">];
|
||||
let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
|
||||
|
|
|
@ -2862,13 +2862,15 @@ See the RenderScript_ documentation for more information.
|
|||
|
||||
def XRayDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument)";
|
||||
let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args)";
|
||||
let Content = [{
|
||||
``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching.
|
||||
|
||||
Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points.
|
||||
|
||||
If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise.
|
||||
|
||||
``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported.
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -779,6 +779,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
|
|||
Fn->addFnAttr("function-instrument", "xray-always");
|
||||
if (XRayAttr->neverXRayInstrument())
|
||||
Fn->addFnAttr("function-instrument", "xray-never");
|
||||
if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) {
|
||||
Fn->addFnAttr("xray-log-args",
|
||||
llvm::utostr(LogArgs->getArgumentCount()));
|
||||
}
|
||||
} else {
|
||||
Fn->addFnAttr(
|
||||
"xray-instruction-threshold",
|
||||
|
|
|
@ -4424,6 +4424,19 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
|
|||
Attr.getAttributeSpellingListIndex()));
|
||||
}
|
||||
|
||||
static void handleXRayLogArgsAttr(Sema &S, Decl *D,
|
||||
const AttributeList &Attr) {
|
||||
uint64_t ArgCount;
|
||||
if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, Attr.getArgAsExpr(0),
|
||||
ArgCount))
|
||||
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()));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Checker-specific attribute handlers.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -6285,6 +6298,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case AttributeList::AT_XRayInstrument:
|
||||
handleSimpleAttribute<XRayInstrumentAttr>(S, D, Attr);
|
||||
break;
|
||||
case AttributeList::AT_XRayLogArgs:
|
||||
handleXRayLogArgsAttr(S, D, Attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// RUN: %clang_cc1 %s -fxray-instrument -std=c++11 -x c++ -emit-llvm -o - -triple x86_64-unknown-linux-gnu | FileCheck %s
|
||||
|
||||
// Make sure that the LLVM attribute for XRay-annotated functions do show up.
|
||||
[[clang::xray_always_instrument,clang::xray_log_args(1)]] void foo(int a) {
|
||||
// CHECK: define void @_Z3fooi(i32 %a) #0
|
||||
};
|
||||
|
||||
[[clang::xray_log_args(1)]] void bar(int a) {
|
||||
// CHECK: define void @_Z3bari(i32 %a) #1
|
||||
};
|
||||
|
||||
// CHECK: #0 = {{.*}}"function-instrument"="xray-always"{{.*}}"xray-log-args"="1"
|
||||
// CHECK-NOT: #1 = {{.*}}"xray-log-args"="1"
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
|
||||
void foo(int) __attribute__((xray_log_args(1)));
|
||||
struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
|
||||
|
||||
void fop() __attribute__((xray_log_args(1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
|
||||
|
||||
void foq() __attribute__((xray_log_args(-1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
|
||||
|
||||
void fos() __attribute__((xray_log_args(0))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
|
||||
void foo [[clang::xray_log_args(1)]] (int);
|
||||
struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
|
||||
|
||||
void fop [[clang::xray_log_args(1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
|
||||
|
||||
void foq [[clang::xray_log_args(-1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
|
||||
|
||||
void fos [[clang::xray_log_args(0)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
|
Loading…
Reference in New Issue