This revision was automatically updated to reflect the committed changes.
dberris marked an inline comment as done.
Closed by commit rL299041: [XRay] Add -fxray-{always,never}-instrument= flags 
to clang (authored by dberris).

Changed prior to commit:
  https://reviews.llvm.org/D30388?vs=92766&id=93428#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D30388

Files:
  cfe/trunk/include/clang/AST/ASTContext.h
  cfe/trunk/include/clang/Basic/LangOptions.def
  cfe/trunk/include/clang/Basic/LangOptions.h
  cfe/trunk/include/clang/Basic/XRayLists.h
  cfe/trunk/include/clang/Driver/Options.td
  cfe/trunk/include/clang/Driver/ToolChain.h
  cfe/trunk/include/clang/Driver/XRayArgs.h
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/Basic/CMakeLists.txt
  cfe/trunk/lib/Basic/LangOptions.cpp
  cfe/trunk/lib/Basic/XRayLists.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.h
  cfe/trunk/lib/Driver/CMakeLists.txt
  cfe/trunk/lib/Driver/ToolChain.cpp
  cfe/trunk/lib/Driver/ToolChains/Clang.cpp
  cfe/trunk/lib/Driver/XRayArgs.cpp
  cfe/trunk/lib/Frontend/CompilerInvocation.cpp
  cfe/trunk/test/CodeGen/xray-always-instrument.cpp

Index: cfe/trunk/lib/Basic/XRayLists.cpp
===================================================================
--- cfe/trunk/lib/Basic/XRayLists.cpp
+++ cfe/trunk/lib/Basic/XRayLists.cpp
@@ -0,0 +1,53 @@
+//===--- XRayFunctionFilter.cpp - XRay automatic-attribution --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided filters for always/never XRay instrumenting certain functions.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/XRayLists.h"
+
+using namespace clang;
+
+XRayFunctionFilter::XRayFunctionFilter(
+    ArrayRef<std::string> AlwaysInstrumentPaths,
+    ArrayRef<std::string> NeverInstrumentPaths, SourceManager &SM)
+    : AlwaysInstrument(
+          llvm::SpecialCaseList::createOrDie(AlwaysInstrumentPaths)),
+      NeverInstrument(llvm::SpecialCaseList::createOrDie(NeverInstrumentPaths)),
+      SM(SM) {}
+
+XRayFunctionFilter::ImbueAttribute
+XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const {
+  // First apply the always instrument list, than if it isn't an "always" see
+  // whether it's treated as a "never" instrument function.
+  if (AlwaysInstrument->inSection("fun", FunctionName))
+    return ImbueAttribute::ALWAYS;
+  if (NeverInstrument->inSection("fun", FunctionName))
+    return ImbueAttribute::NEVER;
+  return ImbueAttribute::NONE;
+}
+
+XRayFunctionFilter::ImbueAttribute
+XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename,
+                                               StringRef Category) const {
+  if (AlwaysInstrument->inSection("src", Filename, Category))
+    return ImbueAttribute::ALWAYS;
+  if (NeverInstrument->inSection("src", Filename, Category))
+    return ImbueAttribute::NEVER;
+  return ImbueAttribute::NONE;
+}
+
+XRayFunctionFilter::ImbueAttribute
+XRayFunctionFilter::shouldImbueLocation(SourceLocation Loc,
+                                        StringRef Category) const {
+  if (!Loc.isValid())
+    return ImbueAttribute::NONE;
+  return this->shouldImbueFunctionsInFile(SM.getFilename(SM.getFileLoc(Loc)),
+                                          Category);
+}
Index: cfe/trunk/lib/Basic/LangOptions.cpp
===================================================================
--- cfe/trunk/lib/Basic/LangOptions.cpp
+++ cfe/trunk/lib/Basic/LangOptions.cpp
@@ -33,6 +33,8 @@
   // sanitizer options (this affects __has_feature(address_sanitizer) etc).
   Sanitize.clear();
   SanitizerBlacklistFiles.clear();
+  XRayAlwaysInstrumentFiles.clear();
+  XRayNeverInstrumentFiles.clear();
 
   CurrentModule.clear();
   IsHeaderFile = false;
Index: cfe/trunk/lib/Basic/CMakeLists.txt
===================================================================
--- cfe/trunk/lib/Basic/CMakeLists.txt
+++ cfe/trunk/lib/Basic/CMakeLists.txt
@@ -90,6 +90,7 @@
   VersionTuple.cpp
   VirtualFileSystem.cpp
   Warnings.cpp
+  XRayLists.cpp
   ${version_inc}
   )
 
Index: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp
@@ -2307,6 +2307,14 @@
   Opts.SanitizeAddressFieldPadding =
       getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
   Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
+
+  // -fxray-{always,never}-instrument= filenames.
+  Opts.XRayInstrument =
+      Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false);
+  Opts.XRayAlwaysInstrumentFiles =
+      Args.getAllArgValues(OPT_fxray_always_instrument);
+  Opts.XRayNeverInstrumentFiles =
+      Args.getAllArgValues(OPT_fxray_never_instrument);
 }
 
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
@@ -786,9 +786,10 @@
                       llvm::utostr(LogArgs->getArgumentCount()));
       }
     } else {
-      Fn->addFnAttr(
-          "xray-instruction-threshold",
-          llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+      if (!CGM.imbueXRayAttrs(Fn, Loc))
+        Fn->addFnAttr(
+            "xray-instruction-threshold",
+            llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
     }
   }
 
Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp
@@ -1489,6 +1489,30 @@
   return false;
 }
 
+bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
+                                   StringRef Category) const {
+  if (!LangOpts.XRayInstrument)
+    return false;
+  const auto &XRayFilter = getContext().getXRayFilter();
+  using ImbueAttr = XRayFunctionFilter::ImbueAttribute;
+  auto Attr = XRayFunctionFilter::ImbueAttribute::NONE;
+  if (Loc.isValid())
+    Attr = XRayFilter.shouldImbueLocation(Loc, Category);
+  if (Attr == ImbueAttr::NONE)
+    Attr = XRayFilter.shouldImbueFunction(Fn->getName());
+  switch (Attr) {
+  case ImbueAttr::NONE:
+    return false;
+  case ImbueAttr::ALWAYS:
+    Fn->addFnAttr("function-instrument", "xray-always");
+    break;
+  case ImbueAttr::NEVER:
+    Fn->addFnAttr("function-instrument", "xray-never");
+    break;
+  }
+  return true;
+}
+
 bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) {
   // Never defer when EmitAllDecls is specified.
   if (LangOpts.EmitAllDecls)
Index: cfe/trunk/lib/CodeGen/CodeGenModule.h
===================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h
@@ -28,6 +28,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SanitizerBlacklist.h"
+#include "clang/Basic/XRayLists.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -1125,6 +1126,12 @@
                               QualType Ty,
                               StringRef Category = StringRef()) const;
 
+  /// Imbue XRay attributes to a function, applying the always/never attribute
+  /// lists in the process. Returns true if we did imbue attributes this way,
+  /// false otherwise.
+  bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
+                      StringRef Category = StringRef()) const;
+
   SanitizerMetadata *getSanitizerMetadata() {
     return SanitizerMD.get();
   }
Index: cfe/trunk/lib/Driver/CMakeLists.txt
===================================================================
--- cfe/trunk/lib/Driver/CMakeLists.txt
+++ cfe/trunk/lib/Driver/CMakeLists.txt
@@ -58,6 +58,7 @@
   ToolChains/WebAssembly.cpp
   ToolChains/XCore.cpp
   Types.cpp
+  XRayArgs.cpp
 
   DEPENDS
   ClangDriverOptions
Index: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp
@@ -27,6 +27,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/XRayArgs.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
@@ -2818,37 +2819,6 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
 
-  if (Args.hasFlag(options::OPT_fxray_instrument,
-                   options::OPT_fnoxray_instrument, false)) {
-    const char *const XRayInstrumentOption = "-fxray-instrument";
-    if (Triple.getOS() == llvm::Triple::Linux)
-      switch (Triple.getArch()) {
-      case llvm::Triple::x86_64:
-      case llvm::Triple::arm:
-      case llvm::Triple::aarch64:
-      case llvm::Triple::ppc64le:
-      case llvm::Triple::mips:
-      case llvm::Triple::mipsel:
-      case llvm::Triple::mips64:
-      case llvm::Triple::mips64el:
-        // Supported.
-        break;
-      default:
-        D.Diag(diag::err_drv_clang_unsupported)
-            << (std::string(XRayInstrumentOption) + " on " + Triple.str());
-      }
-    else
-      D.Diag(diag::err_drv_clang_unsupported)
-          << (std::string(XRayInstrumentOption) + " on non-Linux target OS");
-    CmdArgs.push_back(XRayInstrumentOption);
-    if (const Arg *A =
-            Args.getLastArg(options::OPT_fxray_instruction_threshold_,
-                            options::OPT_fxray_instruction_threshold_EQ)) {
-      CmdArgs.push_back("-fxray-instruction-threshold");
-      CmdArgs.push_back(A->getValue());
-    }
-  }
-
   addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
 
   // Add runtime flag for PS4 when PGO or Coverage are enabled.
@@ -3238,6 +3208,9 @@
   const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
   Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType);
 
+  const XRayArgs &XRay = getToolChain().getXRayArgs();
+  XRay.addArgs(getToolChain(), Args, CmdArgs, InputType);
+
   if (getToolChain().SupportsProfiling())
     Args.AddLastArg(CmdArgs, options::OPT_pg);
 
Index: cfe/trunk/lib/Driver/ToolChain.cpp
===================================================================
--- cfe/trunk/lib/Driver/ToolChain.cpp
+++ cfe/trunk/lib/Driver/ToolChain.cpp
@@ -19,6 +19,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/XRayArgs.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -100,6 +101,12 @@
   return *SanitizerArguments.get();
 }
 
+const XRayArgs& ToolChain::getXRayArgs() const {
+  if (!XRayArguments.get())
+    XRayArguments.reset(new XRayArgs(*this, Args));
+  return *XRayArguments.get();
+}
+
 namespace {
 struct DriverSuffix {
   const char *Suffix;
Index: cfe/trunk/lib/Driver/XRayArgs.cpp
===================================================================
--- cfe/trunk/lib/Driver/XRayArgs.cpp
+++ cfe/trunk/lib/Driver/XRayArgs.cpp
@@ -0,0 +1,113 @@
+//===--- XRayArgs.cpp - Arguments for XRay --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Driver/XRayArgs.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SpecialCaseList.h"
+
+using namespace clang;
+using namespace clang::driver;
+using namespace llvm::opt;
+
+namespace {
+constexpr char XRayInstrumentOption[] = "-fxray-instrument";
+constexpr char XRayInstructionThresholdOption[] =
+    "-fxray-instruction-threshold=";
+constexpr char XRayAlwaysInstrumentOption[] = "-fxray-always-instrument=";
+constexpr char XRayNeverInstrumentOption[] = "-fxray-never-instrument=";
+} // namespace
+
+XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
+  const Driver &D = TC.getDriver();
+  const llvm::Triple &Triple = TC.getTriple();
+  if (Args.hasFlag(options::OPT_fxray_instrument,
+                   options::OPT_fnoxray_instrument, false)) {
+    if (Triple.getOS() == llvm::Triple::Linux)
+      switch (Triple.getArch()) {
+      case llvm::Triple::x86_64:
+      case llvm::Triple::arm:
+      case llvm::Triple::aarch64:
+      case llvm::Triple::ppc64le:
+      case llvm::Triple::mips:
+      case llvm::Triple::mipsel:
+      case llvm::Triple::mips64:
+      case llvm::Triple::mips64el:
+        break;
+      default:
+        D.Diag(diag::err_drv_clang_unsupported)
+            << (std::string(XRayInstrumentOption) + " on " + Triple.str());
+      }
+    else
+      D.Diag(diag::err_drv_clang_unsupported)
+          << (std::string(XRayInstrumentOption) + " on non-Linux target OS");
+    XRayInstrument = true;
+    if (const Arg *A =
+            Args.getLastArg(options::OPT_fxray_instruction_threshold_,
+                            options::OPT_fxray_instruction_threshold_EQ)) {
+      StringRef S = A->getValue();
+      if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
+        D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+    }
+
+    // Validate the always/never attribute files. We also make sure that they
+    // are treated as actual dependencies.
+    for (const auto &Filename :
+         Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
+      if (llvm::sys::fs::exists(Filename)) {
+        AlwaysInstrumentFiles.push_back(Filename);
+        ExtraDeps.push_back(Filename);
+      } else
+        D.Diag(clang::diag::err_drv_no_such_file) << Filename;
+    }
+
+    for (const auto &Filename :
+         Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
+      if (llvm::sys::fs::exists(Filename)) {
+        NeverInstrumentFiles.push_back(Filename);
+        ExtraDeps.push_back(Filename);
+      } else
+        D.Diag(clang::diag::err_drv_no_such_file) << Filename;
+    }
+  }
+}
+
+void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
+                       ArgStringList &CmdArgs, types::ID InputType) const {
+  if (!XRayInstrument)
+    return;
+
+  CmdArgs.push_back(XRayInstrumentOption);
+  CmdArgs.push_back(Args.MakeArgString(XRayInstructionThresholdOption +
+                                       std::to_string(InstructionThreshold)));
+
+  for (const auto &Always : AlwaysInstrumentFiles) {
+    SmallString<64> AlwaysInstrumentOpt(XRayAlwaysInstrumentOption);
+    AlwaysInstrumentOpt += Always;
+    CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
+  }
+
+  for (const auto &Never : NeverInstrumentFiles) {
+    SmallString<64> NeverInstrumentOpt(XRayNeverInstrumentOption);
+    NeverInstrumentOpt += Never;
+    CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
+  }
+
+  for (const auto &Dep : ExtraDeps) {
+    SmallString<64> ExtraDepOpt("-fdepfile-entry=");
+    ExtraDepOpt += Dep;
+    CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
+  }
+}
Index: cfe/trunk/lib/AST/ASTContext.cpp
===================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp
+++ cfe/trunk/lib/AST/ASTContext.cpp
@@ -748,6 +748,8 @@
       ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr),
       TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts),
       SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
+      XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
+                                        LangOpts.XRayNeverInstrumentFiles, SM)),
       AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
       PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
       BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr),
Index: cfe/trunk/include/clang/Driver/ToolChain.h
===================================================================
--- cfe/trunk/include/clang/Driver/ToolChain.h
+++ cfe/trunk/include/clang/Driver/ToolChain.h
@@ -44,6 +44,7 @@
   class RegisterEffectiveTriple;
   class SanitizerArgs;
   class Tool;
+  class XRayArgs;
 
 /// ToolChain - Access to tools for a single platform.
 class ToolChain {
@@ -94,6 +95,7 @@
   Tool *getOffloadBundler() const;
 
   mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
+  mutable std::unique_ptr<XRayArgs> XRayArguments;
 
   /// The effective clang triple for the current Job.
   mutable llvm::Triple EffectiveTriple;
@@ -177,6 +179,8 @@
 
   const SanitizerArgs& getSanitizerArgs() const;
 
+  const XRayArgs& getXRayArgs() const;
+
   // Returns the Arg * that explicitly turned on/off rtti, or nullptr.
   const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; }
 
Index: cfe/trunk/include/clang/Driver/Options.td
===================================================================
--- cfe/trunk/include/clang/Driver/Options.td
+++ cfe/trunk/include/clang/Driver/Options.td
@@ -962,6 +962,15 @@
   JoinedOrSeparate<["-"], "fxray-instruction-threshold">,
   Group<f_Group>, Flags<[CC1Option]>;
 
+def fxray_always_instrument :
+  JoinedOrSeparate<["-"], "fxray-always-instrument=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">;
+def fxray_never_instrument :
+  JoinedOrSeparate<["-"], "fxray-never-instrument=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
+
 def flat__namespace : Flag<["-"], "flat_namespace">;
 def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
 def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
Index: cfe/trunk/include/clang/Driver/XRayArgs.h
===================================================================
--- cfe/trunk/include/clang/Driver/XRayArgs.h
+++ cfe/trunk/include/clang/Driver/XRayArgs.h
@@ -0,0 +1,38 @@
+//===--- XRayArgs.h - Arguments for XRay ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_DRIVER_XRAYARGS_H
+#define LLVM_CLANG_DRIVER_XRAYARGS_H
+
+#include "clang/Driver/Types.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+
+namespace clang {
+namespace driver {
+
+class ToolChain;
+
+class XRayArgs {
+  std::vector<std::string> AlwaysInstrumentFiles;
+  std::vector<std::string> NeverInstrumentFiles;
+  std::vector<std::string> ExtraDeps;
+  bool XRayInstrument = false;
+  int InstructionThreshold = 200;
+
+public:
+  /// Parses the XRay arguments from an argument list.
+  XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
+  void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
+               llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // LLVM_CLANG_DRIVER_XRAYARGS_H
Index: cfe/trunk/include/clang/AST/ASTContext.h
===================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h
+++ cfe/trunk/include/clang/AST/ASTContext.h
@@ -39,6 +39,7 @@
 #include "clang/Basic/SanitizerBlacklist.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
+#include "clang/Basic/XRayLists.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -475,6 +476,10 @@
   /// entities should not be instrumented.
   std::unique_ptr<SanitizerBlacklist> SanitizerBL;
 
+  /// \breif Function filtering mehcanism to determine whether a given function
+  /// should be imbued with the XRay "always" or "never" attributes.
+  std::unique_ptr<XRayFunctionFilter> XRayFilter;
+
   /// \brief The allocator used to create AST objects.
   ///
   /// AST objects are never destructed; rather, all memory associated with the
@@ -657,6 +662,10 @@
     return *SanitizerBL;
   }
 
+  const XRayFunctionFilter &getXRayFilter() const {
+    return *XRayFilter;
+  }
+
   DiagnosticsEngine &getDiagnostics() const;
 
   FullSourceLoc getFullLoc(SourceLocation Loc) const {
Index: cfe/trunk/include/clang/Basic/LangOptions.h
===================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h
+++ cfe/trunk/include/clang/Basic/LangOptions.h
@@ -102,6 +102,16 @@
   /// (files, functions, variables) should not be instrumented.
   std::vector<std::string> SanitizerBlacklistFiles;
 
+  /// \brief Paths to the XRay "always instrument" files specifying which
+  /// objects (files, functions, variables) should be imbued with the XRay
+  /// "always instrument" attribute.
+  std::vector<std::string> XRayAlwaysInstrumentFiles;
+
+  /// \brief Paths to the XRay "never instrument" files specifying which
+  /// objects (files, functions, variables) should be imbued with the XRay
+  /// "never instrument" attribute.
+  std::vector<std::string> XRayNeverInstrumentFiles;
+
   clang::ObjCRuntime ObjCRuntime;
 
   std::string ObjCConstantStringClass;
Index: cfe/trunk/include/clang/Basic/LangOptions.def
===================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.def
+++ cfe/trunk/include/clang/Basic/LangOptions.def
@@ -263,6 +263,8 @@
                                            "field padding (0: none, 1:least "
                                            "aggressive, 2: more aggressive)")
 
+LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
+
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
Index: cfe/trunk/include/clang/Basic/XRayLists.h
===================================================================
--- cfe/trunk/include/clang/Basic/XRayLists.h
+++ cfe/trunk/include/clang/Basic/XRayLists.h
@@ -0,0 +1,54 @@
+//===--- XRayLists.h - XRay automatic attribution ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided filters for always/never XRay instrumenting certain functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_XRAYLISTS_H
+#define LLVM_CLANG_BASIC_XRAYLISTS_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace clang {
+
+class XRayFunctionFilter {
+  std::unique_ptr<llvm::SpecialCaseList> AlwaysInstrument;
+  std::unique_ptr<llvm::SpecialCaseList> NeverInstrument;
+  SourceManager &SM;
+
+public:
+  XRayFunctionFilter(ArrayRef<std::string> AlwaysInstrumentPaths,
+                     ArrayRef<std::string> NeverInstrumentPaths,
+                     SourceManager &SM);
+
+  enum class ImbueAttribute {
+    NONE,
+    ALWAYS,
+    NEVER,
+  };
+
+  ImbueAttribute shouldImbueFunction(StringRef FunctionName) const;
+
+  ImbueAttribute
+  shouldImbueFunctionsInFile(StringRef Filename,
+                             StringRef Category = StringRef()) const;
+
+  ImbueAttribute shouldImbueLocation(SourceLocation Loc,
+                                     StringRef Category = StringRef()) const;
+};
+
+} // namespace clang
+
+#endif
Index: cfe/trunk/test/CodeGen/xray-always-instrument.cpp
===================================================================
--- cfe/trunk/test/CodeGen/xray-always-instrument.cpp
+++ cfe/trunk/test/CodeGen/xray-always-instrument.cpp
@@ -0,0 +1,15 @@
+// RUN: echo "fun:*foo*" > %t.always-instrument
+// RUN: echo "src:*xray-always-instrument.cpp" >> %t.always-instrument
+// RUN: %clang_cc1 -fxray-instrument -x c++ -std=c++11 -fxray-always-instrument=%t.always-instrument -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+void foo() {}
+
+[[clang::xray_never_instrument]] void bar() {}
+
+void baz() {}
+
+// CHECK: define void @_Z3foov() #[[ALWAYSATTR:[0-9]+]] {
+// CHECK: define void @_Z3barv() #[[NEVERATTR:[0-9]+]] {
+// CHECK: define void @_Z3bazv() #[[ALWAYSATTR:[0-9]+]] {
+// CHECK: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// CHECK: attributes #[[NEVERATTR]] = {{.*}} "function-instrument"="xray-never" {{.*}}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to