wsmoses updated this revision to Diff 206751.
wsmoses added a comment.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

Actually upload full patch so far (and not just the last commit).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63845/new/

https://reviews.llvm.org/D63845

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/utils/TableGen/ClangAttrEmitter.cpp
  llvm/include/llvm/IR/Attributes.h
  llvm/lib/IR/Attributes.cpp
  llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp

Index: llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
===================================================================
--- llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
+++ llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp
@@ -24,48 +24,6 @@
                              "example -force-attribute=foo:noinline. This "
                              "option can be specified multiple times."));
 
-static Attribute::AttrKind parseAttrKind(StringRef Kind) {
-  return StringSwitch<Attribute::AttrKind>(Kind)
-      .Case("alwaysinline", Attribute::AlwaysInline)
-      .Case("builtin", Attribute::Builtin)
-      .Case("cold", Attribute::Cold)
-      .Case("convergent", Attribute::Convergent)
-      .Case("inlinehint", Attribute::InlineHint)
-      .Case("jumptable", Attribute::JumpTable)
-      .Case("minsize", Attribute::MinSize)
-      .Case("naked", Attribute::Naked)
-      .Case("nobuiltin", Attribute::NoBuiltin)
-      .Case("noduplicate", Attribute::NoDuplicate)
-      .Case("noimplicitfloat", Attribute::NoImplicitFloat)
-      .Case("noinline", Attribute::NoInline)
-      .Case("nonlazybind", Attribute::NonLazyBind)
-      .Case("noredzone", Attribute::NoRedZone)
-      .Case("noreturn", Attribute::NoReturn)
-      .Case("nocf_check", Attribute::NoCfCheck)
-      .Case("norecurse", Attribute::NoRecurse)
-      .Case("nounwind", Attribute::NoUnwind)
-      .Case("optforfuzzing", Attribute::OptForFuzzing)
-      .Case("optnone", Attribute::OptimizeNone)
-      .Case("optsize", Attribute::OptimizeForSize)
-      .Case("readnone", Attribute::ReadNone)
-      .Case("readonly", Attribute::ReadOnly)
-      .Case("argmemonly", Attribute::ArgMemOnly)
-      .Case("returns_twice", Attribute::ReturnsTwice)
-      .Case("safestack", Attribute::SafeStack)
-      .Case("shadowcallstack", Attribute::ShadowCallStack)
-      .Case("sanitize_address", Attribute::SanitizeAddress)
-      .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
-      .Case("sanitize_memory", Attribute::SanitizeMemory)
-      .Case("sanitize_thread", Attribute::SanitizeThread)
-      .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening)
-      .Case("ssp", Attribute::StackProtect)
-      .Case("sspreq", Attribute::StackProtectReq)
-      .Case("sspstrong", Attribute::StackProtectStrong)
-      .Case("strictfp", Attribute::StrictFP)
-      .Case("uwtable", Attribute::UWTable)
-      .Default(Attribute::None);
-}
-
 /// If F has any forced attributes given on the command line, add them.
 static void addForcedAttributes(Function &F) {
   for (auto &S : ForceAttributes) {
@@ -73,7 +31,7 @@
     if (KV.first != F.getName())
       continue;
 
-    auto Kind = parseAttrKind(KV.second);
+    auto Kind = Attribute::parseAttrKind(KV.second);
     if (Kind == Attribute::None) {
       LLVM_DEBUG(dbgs() << "ForcedAttribute: " << KV.second
                         << " unknown or not handled!\n");
Index: llvm/lib/IR/Attributes.cpp
===================================================================
--- llvm/lib/IR/Attributes.cpp
+++ llvm/lib/IR/Attributes.cpp
@@ -479,6 +479,48 @@
   llvm_unreachable("Unknown attribute");
 }
 
+Attribute::AttrKind Attribute::parseAttrKind(StringRef Kind) {
+  return StringSwitch<Attribute::AttrKind>(Kind)
+      .Case("alwaysinline", Attribute::AlwaysInline)
+      .Case("builtin", Attribute::Builtin)
+      .Case("cold", Attribute::Cold)
+      .Case("convergent", Attribute::Convergent)
+      .Case("inlinehint", Attribute::InlineHint)
+      .Case("jumptable", Attribute::JumpTable)
+      .Case("minsize", Attribute::MinSize)
+      .Case("naked", Attribute::Naked)
+      .Case("nobuiltin", Attribute::NoBuiltin)
+      .Case("noduplicate", Attribute::NoDuplicate)
+      .Case("noimplicitfloat", Attribute::NoImplicitFloat)
+      .Case("noinline", Attribute::NoInline)
+      .Case("nonlazybind", Attribute::NonLazyBind)
+      .Case("noredzone", Attribute::NoRedZone)
+      .Case("noreturn", Attribute::NoReturn)
+      .Case("nocf_check", Attribute::NoCfCheck)
+      .Case("norecurse", Attribute::NoRecurse)
+      .Case("nounwind", Attribute::NoUnwind)
+      .Case("optforfuzzing", Attribute::OptForFuzzing)
+      .Case("optnone", Attribute::OptimizeNone)
+      .Case("optsize", Attribute::OptimizeForSize)
+      .Case("readnone", Attribute::ReadNone)
+      .Case("readonly", Attribute::ReadOnly)
+      .Case("argmemonly", Attribute::ArgMemOnly)
+      .Case("returns_twice", Attribute::ReturnsTwice)
+      .Case("safestack", Attribute::SafeStack)
+      .Case("shadowcallstack", Attribute::ShadowCallStack)
+      .Case("sanitize_address", Attribute::SanitizeAddress)
+      .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
+      .Case("sanitize_memory", Attribute::SanitizeMemory)
+      .Case("sanitize_thread", Attribute::SanitizeThread)
+      .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening)
+      .Case("ssp", Attribute::StackProtect)
+      .Case("sspreq", Attribute::StackProtectReq)
+      .Case("sspstrong", Attribute::StackProtectStrong)
+      .Case("strictfp", Attribute::StrictFP)
+      .Case("uwtable", Attribute::UWTable)
+      .Default(Attribute::None);
+}
+
 bool Attribute::operator<(Attribute A) const {
   if (!pImpl && !A.pImpl) return false;
   if (!pImpl) return true;
Index: llvm/include/llvm/IR/Attributes.h
===================================================================
--- llvm/include/llvm/IR/Attributes.h
+++ llvm/include/llvm/IR/Attributes.h
@@ -192,6 +192,8 @@
   static Attribute fromRawPointer(void *RawPtr) {
     return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr));
   }
+
+  static Attribute::AttrKind parseAttrKind(StringRef Kind);
 };
 
 // Specialized opaque value conversions.
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -1290,6 +1290,8 @@
     Ptr = llvm::make_unique<VariadicParamIdxArgument>(Arg, Attr);
   else if (ArgName == "VariadicParamOrParamIdxArgument")
     Ptr = llvm::make_unique<VariadicParamOrParamIdxArgument>(Arg, Attr);
+  else if (ArgName == "ParamOrParamIdxArgument")
+    Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "int");
   else if (ArgName == "ParamIdxArgument")
     Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx");
   else if (ArgName == "VariadicIdentifierArgument")
@@ -2184,6 +2186,7 @@
          llvm::StringSwitch<bool>(
              Arg->getSuperClasses().back().first->getName())
              .Case("VariadicParamOrParamIdxArgument", true)
+             .Case("ParamOrParamIdxArgument", true)
              .Default(false);
 }
 
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3456,20 +3456,9 @@
     D->addAttr(NewAttr);
 }
 
-/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
-static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  // The index that identifies the callback callee is mandatory.
-  if (AL.getNumArgs() == 0) {
-    S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
-        << AL.getRange();
-    return;
-  }
-
-  bool HasImplicitThisParam = isInstanceMethod(D);
-  int32_t NumArgs = getFunctionOrMethodNumParams(D);
-
-  FunctionDecl *FD = D->getAsFunction();
-  assert(FD && "Expected a function declaration!");
+static int32_t getParamFromNameOrIndex(Sema &S, FunctionDecl *FD, const ParsedAttr &AL, unsigned I) {
+  bool HasImplicitThisParam = isInstanceMethod(FD);
+  int32_t NumArgs = getFunctionOrMethodNumParams(FD);
 
   llvm::StringMap<int> NameIdxMapping;
   NameIdxMapping["__"] = -1;
@@ -3482,8 +3471,6 @@
 
   auto UnknownName = NameIdxMapping.end();
 
-  SmallVector<int, 8> EncodingIndices;
-  for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
     SourceRange SR;
     int32_t ArgIdx;
 
@@ -3493,7 +3480,7 @@
       if (It == UnknownName) {
         S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
             << IdLoc->Ident << IdLoc->Loc;
-        return;
+        return -1;
       }
 
       SR = SourceRange(IdLoc->Loc);
@@ -3506,14 +3493,14 @@
                                false)) {
         S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
             << AL << (I + 1) << IdxExpr->getSourceRange();
-        return;
+        return -1;
       }
 
       // Check oob, excluding the special values, 0 and -1.
       if (ArgIdx < -1 || ArgIdx > NumArgs) {
         S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
             << AL << (I + 1) << IdxExpr->getSourceRange();
-        return;
+        return -1;
       }
 
       SR = IdxExpr->getSourceRange();
@@ -3524,7 +3511,7 @@
     if (ArgIdx == 0 && !HasImplicitThisParam) {
       S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
           << (I + 1) << SR;
-      return;
+      return -1;
     }
 
     // Adjust for the case we do not have an implicit "this" parameter. In this
@@ -3532,9 +3519,31 @@
     if (!HasImplicitThisParam && ArgIdx > 0)
       ArgIdx -= 1;
 
+    return ArgIdx;
+}
+
+/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
+static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // The index that identifies the callback callee is mandatory.
+  if (AL.getNumArgs() == 0) {
+    S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
+        << AL.getRange();
+    return;
+  }
+
+
+  FunctionDecl *FD = D->getAsFunction();
+  assert(FD && "Expected a function declaration!");
+
+
+  SmallVector<int, 8> EncodingIndices;
+  for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
+    int32_t ArgIdx = getParamFromNameOrIndex(S, FD, AL, I);
+    if (ArgIdx == -1) return;
     EncodingIndices.push_back(ArgIdx);
   }
 
+  bool HasImplicitThisParam = isInstanceMethod(FD);
   int CalleeIdx = EncodingIndices.front();
   // Check if the callee index is proper, thus not "this" and not "unknown".
   // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
@@ -3737,6 +3746,42 @@
   D->addAttr(::new (Context) AlignValueAttr(TmpAttr));
 }
 
+template <typename AttrType>
+static void handleSimpleIntStringAttribute(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // check the attribute arguments.
+  if (AL.getNumArgs() != 2) {
+    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
+    return;
+  }
+
+  Expr *E = AL.getArgAsExpr(0);
+
+  FunctionDecl *FD = D->getAsFunction();
+  assert(FD && "Expected a function declaration!");
+
+  int32_t ArgIdx = getParamFromNameOrIndex(S, FD, AL, 0);
+  StringRef Str;
+  S.checkStringLiteralArgumentAttr(AL, 1, Str);
+  
+  D->addAttr(::new (S.Context) AttrType(AL.getRange(), S.Context, ArgIdx, Str,
+                                         AL.getAttributeSpellingListIndex()));
+}
+
+template <typename AttrType>
+static void handleSimpleStringAttribute(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // check the attribute arguments.
+  if (AL.getNumArgs() != 1) {
+    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
+    return;
+  }
+
+  StringRef Str;
+  S.checkStringLiteralArgumentAttr(AL, 0, Str);
+  
+  D->addAttr(::new (S.Context) AttrType(AL.getRange(), S.Context, Str,
+                                         AL.getAttributeSpellingListIndex()));
+}
+
 static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   // check the attribute arguments.
   if (AL.getNumArgs() > 1) {
@@ -6618,6 +6663,15 @@
     S.Diag(AL.getLoc(), diag::err_stmt_attribute_invalid_on_decl)
         << AL << D->getLocation();
     break;
+  case ParsedAttr::AT_LLVMFN:
+    handleSimpleStringAttribute<LLVMFNAttr>(S, D, AL);
+    break;
+  case ParsedAttr::AT_LLVMARG:
+    handleSimpleIntStringAttribute<LLVMARGAttr>(S, D, AL);
+    break;
+  case ParsedAttr::AT_LLVMRET:
+    handleSimpleStringAttribute<LLVMRETAttr>(S, D, AL);
+    break;
   case ParsedAttr::AT_Interrupt:
     handleInterruptAttr(S, D, AL);
     break;
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -730,6 +730,36 @@
       SanOpts.Mask &= ~SanitizerKind::CFIUnrelatedCast;
   }
 
+  if (D) {
+    for(auto a: D->attrs()) {
+        if (auto atr = dyn_cast<LLVMFNAttr>(a)) {
+            Fn->addFnAttr(atr->getAttrName());
+        }
+        if (auto atr = dyn_cast<LLVMARGAttr>(a)) {
+            std::pair<StringRef, StringRef> attributeandvalue = atr->getAttrName().split('=');
+            unsigned index = llvm::AttributeList::FirstArgIndex + atr->getParamIndex(); //.getLLVMIndex();
+            llvm::Attribute::AttrKind attrkind = llvm::Attribute::parseAttrKind(attributeandvalue.first);
+            if (attrkind != llvm::Attribute::None) {
+                assert(attributeandvalue.second.size() == 0);
+                Fn->addParamAttr(index, llvm::Attribute::get(Fn->getContext(), attrkind));
+            }
+            else
+                Fn->addParamAttr(index, llvm::Attribute::get(Fn->getContext(), attributeandvalue.first, attributeandvalue.second));
+        }
+        if (auto atr = dyn_cast<LLVMRETAttr>(a)) {
+            std::pair<StringRef, StringRef> attributeandvalue = atr->getAttrName().split('=');
+            unsigned index = llvm::AttributeList::ReturnIndex;
+            llvm::Attribute::AttrKind attrkind = llvm::Attribute::parseAttrKind(attributeandvalue.first);
+            if (attrkind != llvm::Attribute::None) {
+                assert(attributeandvalue.second.size() == 0);
+                Fn->addParamAttr(index, llvm::Attribute::get(Fn->getContext(), attrkind));
+            }
+            else
+                Fn->addParamAttr(index, llvm::Attribute::get(Fn->getContext(), attributeandvalue.first, attributeandvalue.second));
+        }
+    }
+  }
+
   // Apply xray attributes to the function (as a string, for now)
   if (D) {
     if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -187,6 +187,9 @@
 // A list of identifiers matching parameters or ParamIdx indices.
 class VariadicParamOrParamIdxArgument<string name> : Argument<name, 1>;
 
+// Like VariadicParamOrParamIdxArgument but for a single function parameter index.
+class ParamOrParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>;
+
 // Like VariadicParamIdxArgument but for a single function parameter index.
 class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>;
 
@@ -1631,6 +1634,24 @@
   let Documentation = [AllocAlignDocs];
 }
 
+def LLVMFN : InheritableAttr {
+  let Spellings = [GCC<"LLVMFN">];
+  let Args = [StringArgument<"AttrName">];
+  let Documentation = [Undocumented];
+}
+
+def LLVMARG : InheritableAttr {
+  let Spellings = [GCC<"LLVMARG">];
+  let Args = [ParamOrParamIdxArgument<"ParamIndex">, StringArgument<"AttrName">];
+  let Documentation = [Undocumented];
+}
+
+def LLVMRET : InheritableAttr {
+  let Spellings = [GCC<"LLVMRET">];
+  let Args = [StringArgument<"AttrName">];
+  let Documentation = [Undocumented];
+}
+
 def NoReturn : InheritableAttr {
   let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
   // FIXME: Does GCC allow this on the function instead?
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to