simon_tatham created this revision. simon_tatham added reviewers: dmgreen, miyuki, ostannard. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This allows you to declare a function with a name of your choice (say `foo`), but have clang treat it as if it were a builtin function (say `__builtin_foo`), by writing static __inline__ __attribute__((__clang_builtin(__builtin_foo))) int foo(args); I'm intending to use this for the ACLE intrinsics for MVE, which have to be polymorphic on their argument types and also implemented by builtins. This commit itself just introduces the new attribute, and doesn't use it for anything. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D67159 Files: clang/include/clang/Basic/Attr.td clang/lib/AST/Decl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Misc/pragma-attribute-supported-attributes-list.test Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test =================================================================== --- clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -36,6 +36,7 @@ // CHECK-NEXT: Callback (SubjectMatchRule_function) // CHECK-NEXT: Capability (SubjectMatchRule_record, SubjectMatchRule_type_alias) // CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function) +// CHECK-NEXT: ClangBuiltinOverride (SubjectMatchRule_function) // CHECK-NEXT: Cold (SubjectMatchRule_function) // CHECK-NEXT: Common (SubjectMatchRule_variable) // CHECK-NEXT: Constructor (SubjectMatchRule_function) Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -5041,6 +5041,13 @@ AL.getAttributeSpellingListIndex())); } +static void handleClangBuiltinOverrideAttribute(Sema &S, Decl *D, + const ParsedAttr &AL) { + D->addAttr(::new (S.Context) ClangBuiltinOverrideAttr( + AL.getRange(), S.Context, AL.getArgAsIdent(0)->Ident, + AL.getAttributeSpellingListIndex())); +} + //===----------------------------------------------------------------------===// // Checker-specific attribute handlers. //===----------------------------------------------------------------------===// @@ -7430,6 +7437,10 @@ case ParsedAttr::AT_MSAllocator: handleMSAllocatorAttr(S, D, AL); break; + + case ParsedAttr::AT_ClangBuiltinOverride: + handleClangBuiltinOverrideAttribute(S, D, AL); + break; } } Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -3075,10 +3075,18 @@ /// functions as their wrapped builtins. This shouldn't be done in general, but /// it's useful in Sema to diagnose calls to wrappers based on their semantics. unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { - if (!getIdentifier()) - return 0; + unsigned BuiltinID; + + if (hasAttr<ClangBuiltinOverrideAttr>()) { + IdentifierInfo *II = getAttr<ClangBuiltinOverrideAttr>()->getBuiltinName(); + BuiltinID = II->getBuiltinID(); + } else { + if (!getIdentifier()) + return 0; + + BuiltinID = getIdentifier()->getBuiltinID(); + } - unsigned BuiltinID = getIdentifier()->getBuiltinID(); if (!BuiltinID) return 0; @@ -3102,7 +3110,8 @@ // If the function is marked "overloadable", it has a different mangled name // and is not the C library function. - if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>()) + if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() && + !hasAttr<ClangBuiltinOverrideAttr>()) return 0; if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -593,6 +593,12 @@ let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } +def ClangBuiltinOverride : Attr { + let Spellings = [GCC<"__clang_builtin">]; + let Args = [IdentifierArgument<"BuiltinName">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [Undocumented]; +} def Aligned : InheritableAttr { let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test =================================================================== --- clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -36,6 +36,7 @@ // CHECK-NEXT: Callback (SubjectMatchRule_function) // CHECK-NEXT: Capability (SubjectMatchRule_record, SubjectMatchRule_type_alias) // CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function) +// CHECK-NEXT: ClangBuiltinOverride (SubjectMatchRule_function) // CHECK-NEXT: Cold (SubjectMatchRule_function) // CHECK-NEXT: Common (SubjectMatchRule_variable) // CHECK-NEXT: Constructor (SubjectMatchRule_function) Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -5041,6 +5041,13 @@ AL.getAttributeSpellingListIndex())); } +static void handleClangBuiltinOverrideAttribute(Sema &S, Decl *D, + const ParsedAttr &AL) { + D->addAttr(::new (S.Context) ClangBuiltinOverrideAttr( + AL.getRange(), S.Context, AL.getArgAsIdent(0)->Ident, + AL.getAttributeSpellingListIndex())); +} + //===----------------------------------------------------------------------===// // Checker-specific attribute handlers. //===----------------------------------------------------------------------===// @@ -7430,6 +7437,10 @@ case ParsedAttr::AT_MSAllocator: handleMSAllocatorAttr(S, D, AL); break; + + case ParsedAttr::AT_ClangBuiltinOverride: + handleClangBuiltinOverrideAttribute(S, D, AL); + break; } } Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -3075,10 +3075,18 @@ /// functions as their wrapped builtins. This shouldn't be done in general, but /// it's useful in Sema to diagnose calls to wrappers based on their semantics. unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { - if (!getIdentifier()) - return 0; + unsigned BuiltinID; + + if (hasAttr<ClangBuiltinOverrideAttr>()) { + IdentifierInfo *II = getAttr<ClangBuiltinOverrideAttr>()->getBuiltinName(); + BuiltinID = II->getBuiltinID(); + } else { + if (!getIdentifier()) + return 0; + + BuiltinID = getIdentifier()->getBuiltinID(); + } - unsigned BuiltinID = getIdentifier()->getBuiltinID(); if (!BuiltinID) return 0; @@ -3102,7 +3110,8 @@ // If the function is marked "overloadable", it has a different mangled name // and is not the C library function. - if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>()) + if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() && + !hasAttr<ClangBuiltinOverrideAttr>()) return 0; if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -593,6 +593,12 @@ let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } +def ClangBuiltinOverride : Attr { + let Spellings = [GCC<"__clang_builtin">]; + let Args = [IdentifierArgument<"BuiltinName">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [Undocumented]; +} def Aligned : InheritableAttr { let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits