From ad24ad4c741cad0fe79d6e4a74edc58d592a0f90 Mon Sep 17 00:00:00 2001
From: Rafael Espindola <rafael.espindola@gmail.com>
Date: Thu, 13 Jun 2013 18:34:17 +0000
Subject: [PATCH] Allow clang to build __clear_cache on ARM.

__clear_cache is special. It needs no signature, but is a real function in
compiler_rt or libgcc.

Patch by Andrew Turner.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183926 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/Builtins.def        | 2 ++
 include/clang/Basic/Builtins.h          | 7 +++++++
 include/clang/Basic/BuiltinsAArch64.def | 2 +-
 include/clang/Basic/BuiltinsARM.def     | 2 +-
 lib/Sema/SemaDecl.cpp                   | 3 ++-
 test/Sema/builtin-clear_cache.c         | 5 +++++
 6 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 test/Sema/builtin-clear_cache.c

diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 247ffde019b..3dd25b4ebf3 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -70,6 +70,8 @@
 //  f -> this is a libc/libm function without the '__builtin_' prefix. It can
 //       be followed by ':headername:' to state which header this function
 //       comes from.
+//  i -> this is a runtime library implemented function without the
+//       '__builtin_' prefix. It will be implemented in compiter-rt or libgcc.
 //  p:N: -> this is a printf-like function whose Nth argument is the format
 //          string.
 //  P:N: -> similar to the p:N: attribute, but the function is like vprintf
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 77c0461f106..eb156519ae8 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -130,6 +130,13 @@ public:
     return strchr(GetRecord(ID).Attributes, 'f') != 0;
   }
 
+  /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
+  /// function, such as "__clear_cache", where we know the signature a
+  /// priori.
+  bool isPredefinedRuntimeFunction(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'i') != 0;
+  }
+
   /// \brief Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
     return strchr(GetRecord(ID).Attributes, 't') != 0;
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index 9e9f6d0875d..768e4bb26c7 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -15,4 +15,4 @@
 // The format of this database matches clang/Basic/Builtins.def.
 
 // In libgcc
-BUILTIN(__clear_cache, "vv*v*", "")
+BUILTIN(__clear_cache, "vv*v*", "i")
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index fad9007e04b..2f2993fc6ae 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -15,7 +15,7 @@
 // The format of this database matches clang/Basic/Builtins.def.
 
 // In libgcc
-BUILTIN(__clear_cache, "vv*v*", "")
+BUILTIN(__clear_cache, "vv*v*", "i")
 BUILTIN(__builtin_thread_pointer, "v*", "")
 
 // Saturating arithmetic
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 00471816eb9..e43a318804d 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8687,7 +8687,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
 
   // Builtin functions cannot be defined.
   if (unsigned BuiltinID = FD->getBuiltinID()) {
-    if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
+    if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID) &&
+        !Context.BuiltinInfo.isPredefinedRuntimeFunction(BuiltinID)) {
       Diag(FD->getLocation(), diag::err_builtin_definition) << FD;
       FD->setInvalidDecl();
     }
diff --git a/test/Sema/builtin-clear_cache.c b/test/Sema/builtin-clear_cache.c
new file mode 100644
index 00000000000..e21aad79d12
--- /dev/null
+++ b/test/Sema/builtin-clear_cache.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple armv7-none-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+void __clear_cache(void *a, void *b) {}
-- 
GitLab