Add support for language-specific address spaces.  On top of that,
add support for the OpenCL __private, __local, __constant and
__global address spaces, as well as the __read_only, _read_write and
__write_only image access specifiers.  Patch originally by ARM;
language-specific address space support by myself.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127915 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index ad69f0f..68a12bb 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_ASTCONTEXT_H
 #define LLVM_CLANG_AST_ASTCONTEXT_H
 
+#include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/OperatorKinds.h"
@@ -311,6 +312,9 @@
   llvm::OwningPtr<CXXABI> ABI;
   CXXABI *createCXXABI(const TargetInfo &T);
 
+  /// \brief The logical -> physical address space map.
+  const LangAS::Map &AddrSpaceMap;
+
   friend class ASTDeclReader;
 
 public:
@@ -1295,6 +1299,21 @@
   QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
                                              QualType typeDomain) const;
 
+  unsigned getTargetAddressSpace(QualType T) const {
+    return getTargetAddressSpace(T.getQualifiers());
+  }
+
+  unsigned getTargetAddressSpace(Qualifiers Q) const {
+    return getTargetAddressSpace(Q.getAddressSpace());
+  }
+
+  unsigned getTargetAddressSpace(unsigned AS) const {
+    if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
+      return AS;
+    else
+      return AddrSpaceMap[AS - LangAS::Offset];
+  }
+
 private:
   // Helper for integer ordering
   unsigned getIntegerRank(const Type *T) const;
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
new file mode 100644
index 0000000..d44a9c3
--- /dev/null
+++ b/include/clang/Basic/AddressSpaces.h
@@ -0,0 +1,44 @@
+//===--- AddressSpaces.h - Language-specific address spaces -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides definitions for the various language-specific address
+//  spaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
+#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
+
+namespace clang {
+
+namespace LangAS {
+
+/// This enum defines the set of possible language-specific address spaces.
+/// It uses a high starting offset so as not to conflict with any address
+/// space used by a target.
+enum ID {
+  Offset = 0xFFFF00,
+
+  opencl_global = Offset,
+  opencl_local,
+  opencl_constant,
+
+  Last,
+  Count = Last-Offset
+};
+
+/// The type of a lookup table which maps from language-specific address spaces
+/// to target-specific ones.
+typedef unsigned Map[Count];
+
+}
+
+}
+
+#endif
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index ebdcdde..433f42e 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -124,6 +124,8 @@
   unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT
   // FIXME: This is just a temporary option, for testing purposes.
   unsigned NoBitFieldTypeAlign : 1;
+  unsigned FakeAddressSpaceMap : 1; // Use a fake address space map, for
+                                    // testing languages such as OpenCL.
 
   unsigned MRTD : 1;            // -mrtd calling convention
 
diff --git a/include/clang/Basic/OpenCL.h b/include/clang/Basic/OpenCL.h
new file mode 100644
index 0000000..6f9785f
--- /dev/null
+++ b/include/clang/Basic/OpenCL.h
@@ -0,0 +1,28 @@
+//===--- OpenCL.h - OpenCL enums --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines some OpenCL-specific enums.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPENCL_H
+#define LLVM_CLANG_BASIC_OPENCL_H
+
+namespace clang {
+
+/// Names for the OpenCL image access qualifiers (OpenCL 1.1 6.6).
+enum OpenCLImageAccess {
+  CLIA_read_only = 1,
+  CLIA_write_only = 2,
+  CLIA_read_write = 3
+};
+
+}
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index b9087f2..fd9e373 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/DataTypes.h"
+#include "clang/Basic/AddressSpaces.h"
 #include <cassert>
 #include <vector>
 #include <string>
@@ -78,6 +79,7 @@
   const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
   unsigned char RegParmMax, SSERegParmMax;
   TargetCXXABI CXXABI;
+  const LangAS::Map *AddrSpaceMap;
 
   unsigned HasAlignMac68kSupport : 1;
   unsigned RealTypeUsesObjCFPRet : 3;
@@ -530,6 +532,11 @@
   virtual const char *getStaticInitSectionSpecifier() const {
     return 0;
   }
+
+  const LangAS::Map &getAddressSpaceMap() const {
+    return *AddrSpaceMap;
+  }
+
 protected:
   virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
     return PointerWidth;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index c7d9524..6fa4bf9 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -252,7 +252,7 @@
 KEYWORD(namespace                   , KEYCXX)
 KEYWORD(new                         , KEYCXX)
 KEYWORD(operator                    , KEYCXX)
-KEYWORD(private                     , KEYCXX)
+KEYWORD(private                     , KEYCXX|KEYOPENCL)
 KEYWORD(protected                   , KEYCXX)
 KEYWORD(public                      , KEYCXX)
 KEYWORD(reinterpret_cast            , KEYCXX)
@@ -350,6 +350,19 @@
 KEYWORD(__kernel                    , KEYOPENCL)
 ALIAS("kernel", __kernel            , KEYOPENCL)
 KEYWORD(vec_step                    , KEYOPENCL)
+KEYWORD(__private                   , KEYOPENCL)
+KEYWORD(__global                    , KEYOPENCL)
+KEYWORD(__local                     , KEYOPENCL)
+KEYWORD(__constant                  , KEYOPENCL)
+ALIAS("global", __global            , KEYOPENCL)
+ALIAS("local", __local              , KEYOPENCL)
+ALIAS("constant", __constant        , KEYOPENCL)
+KEYWORD(__read_only                 , KEYOPENCL)
+KEYWORD(__write_only                , KEYOPENCL)
+KEYWORD(__read_write                , KEYOPENCL)
+ALIAS("read_only", __read_only      , KEYOPENCL)
+ALIAS("write_only", __write_only    , KEYOPENCL)
+ALIAS("read_write", __read_write    , KEYOPENCL)
 
 // Borland Extensions.
 KEYWORD(__pascal                    , KEYALL)
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index bb8759e..4188234 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -513,6 +513,8 @@
   HelpText<"Ignore bit-field types when aligning structures">;
 def traditional_cpp : Flag<"-traditional-cpp">,
   HelpText<"Enable some traditional CPP emulation">;
+def ffake_address_space_map : Flag<"-ffake-address-space-map">,
+  HelpText<"Use a fake address space map; OpenCL testing purposes only">;
 
 //===----------------------------------------------------------------------===//
 // Header Search Options
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index bd39cdb..b9af05e 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1546,6 +1546,7 @@
   void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
   void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
   void ParseOpenCLAttributes(ParsedAttributes &attrs);
+  void ParseOpenCLQualifiers(DeclSpec &DS);
 
   void ParseTypeofSpecifier(DeclSpec &DS);
   void ParseDecltypeSpecifier(DeclSpec &DS);
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 10b859e..382e504 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -18,6 +18,7 @@
 #include "llvm/Support/Allocator.h"
 #include "clang/Sema/Ownership.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/AST/Expr.h"
 #include <cassert>
 
 namespace clang {
@@ -76,6 +77,13 @@
                                 declspec, cxx0x);
         return Mem;
       }
+
+    AttributeList* CreateIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
+                                          SourceLocation TokLoc, int Arg) {
+      Expr* IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t)Arg),
+                                          C.IntTy, TokLoc);
+      return Create( Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
+    }
   };
   
   enum Kind {             // Please keep this list alphabetized.
@@ -135,6 +143,7 @@
     AT_ns_consumed,             // Clang-specific.
     AT_ns_consumes_self,        // Clang-specific.
     AT_objc_gc,
+    AT_opencl_image_access,     // OpenCL-specific.
     AT_opencl_kernel_function,  // OpenCL-specific.
     AT_overloadable,       // Clang-specific.
     AT_ownership_holds,    // Clang-specific.