wsmoses created this revision. wsmoses added a reviewer: jdoerfert. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This (work in progress) diff adds three new attributes to clang (__attribute__((LLVMFN(string))), __attribute__((LLVMARG(paramidx, string))), __attribute__((LLVMRET(paramidx, string))) ) for passing attributes down to LLVM. This is useful for allowing users, tools, or test cases to specify LLVM attributes that may not have a representation in clang. Repository: rG LLVM Github Monorepo 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
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" @@ -3746,12 +3755,15 @@ } Expr *E = AL.getArgAsExpr(0); - ParamIdx Idx; - checkFunctionOrMethodParameterIndex(S, D, AL, 0, E, Idx); + + 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, Idx, Str, + D->addAttr(::new (S.Context) AttrType(AL.getRange(), S.Context, ArgIdx, Str, AL.getAttributeSpellingListIndex())); } Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -737,7 +737,7 @@ } if (auto atr = dyn_cast<LLVMARGAttr>(a)) { std::pair<StringRef, StringRef> attributeandvalue = atr->getAttrName().split('='); - unsigned index = llvm::AttributeList::FirstArgIndex + atr->getParamIndex().getLLVMIndex(); + 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); 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>; @@ -1639,7 +1642,7 @@ def LLVMARG : InheritableAttr { let Spellings = [GCC<"LLVMARG">]; - let Args = [ParamIdxArgument<"ParamIndex">, StringArgument<"AttrName">]; + let Args = [ParamOrParamIdxArgument<"ParamIndex">, StringArgument<"AttrName">]; let Documentation = [Undocumented]; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits