diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 29 |
2 files changed, 41 insertions, 4 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index dae4af8bb24..66446626c2e 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3115,10 +3115,17 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); } /// 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 (const auto *AMAA = getAttr<ArmMveAliasAttr>()) { + BuiltinID = AMAA->getBuiltinName()->getBuiltinID(); + } else { + if (!getIdentifier()) + return 0; + + BuiltinID = getIdentifier()->getBuiltinID(); + } - unsigned BuiltinID = getIdentifier()->getBuiltinID(); if (!BuiltinID) return 0; @@ -3142,7 +3149,8 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { // 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<ArmMveAliasAttr>()) return 0; if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index b2be6245a81..cebb1c642b9 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -23,6 +23,7 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" @@ -4830,6 +4831,30 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex())); } +static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName) { + // FIXME: this will be filled in by Tablegen which isn't written yet + return false; +} + +static void handleArmMveAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!AL.isArgIdent(0)) { + S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) + << AL << 1 << AANT_ArgumentIdentifier; + return; + } + + IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident; + unsigned BuiltinID = Ident->getBuiltinID(); + + if (!ArmMveAliasValid(BuiltinID, + cast<FunctionDecl>(D)->getIdentifier()->getName())) { + S.Diag(AL.getLoc(), diag::err_attribute_arm_mve_alias); + return; + } + + D->addAttr(::new (S.Context) ArmMveAliasAttr(S.Context, AL, Ident)); +} + //===----------------------------------------------------------------------===// // Checker-specific attribute handlers. //===----------------------------------------------------------------------===// @@ -7160,6 +7185,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_MSAllocator: handleMSAllocatorAttr(S, D, AL); break; + + case ParsedAttr::AT_ArmMveAlias: + handleArmMveAliasAttr(S, D, AL); + break; } } |