Merge "Record SourceLocation in exportables."
diff --git a/slang_rs_export_foreach.cpp b/slang_rs_export_foreach.cpp
index 619bd7a..3b14aff 100644
--- a/slang_rs_export_foreach.cpp
+++ b/slang_rs_export_foreach.cpp
@@ -314,7 +314,7 @@
 
   slangAssert(!Name.empty() && "Function must have a name");
 
-  FE = new RSExportForEach(Context, Name);
+  FE = new RSExportForEach(Context, Name, FD->getLocation());
 
   if (!FE->validateAndConstructParams(Context, FD)) {
     return nullptr;
@@ -424,7 +424,7 @@
 RSExportForEach *RSExportForEach::CreateDummyRoot(RSContext *Context) {
   slangAssert(Context);
   llvm::StringRef Name = "root";
-  RSExportForEach *FE = new RSExportForEach(Context, Name);
+  RSExportForEach *FE = new RSExportForEach(Context, Name, clang::SourceLocation());
   FE->mDummyRoot = true;
   return FE;
 }
diff --git a/slang_rs_export_foreach.h b/slang_rs_export_foreach.h
index 67b3a5c..eb973f5 100644
--- a/slang_rs_export_foreach.h
+++ b/slang_rs_export_foreach.h
@@ -68,8 +68,8 @@
   bool mDummyRoot;
 
   // TODO(all): Add support for LOD/face when we have them
-  RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
-    : RSExportable(Context, RSExportable::EX_FOREACH),
+  RSExportForEach(RSContext *Context, const llvm::StringRef &Name, clang::SourceLocation Loc)
+    : RSExportable(Context, RSExportable::EX_FOREACH, Loc),
       mName(Name.data(), Name.size()), mParamPacketType(nullptr),
       mOutType(nullptr), numParams(0), mSignatureMetadata(0),
       mOut(nullptr), mUsrData(nullptr), mSpecialParameterSignatureMetadata(0),
diff --git a/slang_rs_export_func.h b/slang_rs_export_func.h
index 3c0804d..b6c4f01 100644
--- a/slang_rs_export_func.h
+++ b/slang_rs_export_func.h
@@ -33,10 +33,6 @@
   class StructType;
 }
 
-namespace clang {
-  class FunctionDecl;
-}   // namespace clang
-
 namespace slang {
 
 class RSContext;
@@ -52,7 +48,7 @@
 
   RSExportFunc(RSContext *Context, const llvm::StringRef &Name,
                const clang::FunctionDecl *FD)
-    : RSExportable(Context, RSExportable::EX_FUNC),
+    : RSExportable(Context, RSExportable::EX_FUNC, FD->getLocation()),
       mName(Name.data(), Name.size()),
       mMangledName(),
       mShouldMangle(false),
diff --git a/slang_rs_export_reduce.h b/slang_rs_export_reduce.h
index 491bf19..ea00b63 100644
--- a/slang_rs_export_reduce.h
+++ b/slang_rs_export_reduce.h
@@ -85,7 +85,7 @@
                  const llvm::StringRef &NameCombiner,
                  const llvm::StringRef &NameOutConverter,
                  const llvm::StringRef &NameHalter)
-    : RSExportable(Context, RSExportable::EX_REDUCE),
+    : RSExportable(Context, RSExportable::EX_REDUCE, Location),
       mLocation(Location),
       mNameReduce(NameReduce),
       mNameInitializer(NameInitializer),
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp
index fb307a9..21f85a0 100644
--- a/slang_rs_export_type.cpp
+++ b/slang_rs_export_type.cpp
@@ -944,8 +944,8 @@
 
 RSExportType::RSExportType(RSContext *Context,
                            ExportClass Class,
-                           const llvm::StringRef &Name)
-    : RSExportable(Context, RSExportable::EX_TYPE),
+                           const llvm::StringRef &Name, clang::SourceLocation Loc)
+    : RSExportable(Context, RSExportable::EX_TYPE, Loc),
       mClass(Class),
       // Make a copy on Name since memory stored @Name is either allocated in
       // ASTContext or allocated in GetTypeName which will be destroyed later.
@@ -1506,6 +1506,7 @@
   RSExportRecordType *ERT =
       new RSExportRecordType(Context,
                              TypeName,
+                             RD->getLocation(),
                              RD->hasAttr<clang::PackedAttr>(),
                              mIsArtificial,
                              RL->getDataSize().getQuantity(),
diff --git a/slang_rs_export_type.h b/slang_rs_export_type.h
index fcdd9cd..57d0973 100644
--- a/slang_rs_export_type.h
+++ b/slang_rs_export_type.h
@@ -217,7 +217,8 @@
  protected:
   RSExportType(RSContext *Context,
                ExportClass Class,
-               const llvm::StringRef &Name);
+               const llvm::StringRef &Name,
+               clang::SourceLocation Loc = clang::SourceLocation());
 
   // Let's make it private since there're some prerequisites to call this
   // function.
@@ -638,11 +639,12 @@
 
   RSExportRecordType(RSContext *Context,
                      const llvm::StringRef &Name,
+                     clang::SourceLocation Loc,
                      bool IsPacked,
                      bool IsArtificial,
                      size_t StoreSize,
                      size_t AllocSize)
-      : RSExportType(Context, ExportClassRecord, Name),
+      : RSExportType(Context, ExportClassRecord, Name, Loc),
         mIsPacked(IsPacked),
         mIsArtificial(IsArtificial),
         mStoreSize(StoreSize),
diff --git a/slang_rs_export_var.cpp b/slang_rs_export_var.cpp
index 2da2baf..a2b4c68 100644
--- a/slang_rs_export_var.cpp
+++ b/slang_rs_export_var.cpp
@@ -29,7 +29,7 @@
 RSExportVar::RSExportVar(RSContext *Context,
                          const clang::VarDecl *VD,
                          const RSExportType *ET)
-    : RSExportable(Context, RSExportable::EX_VAR),
+    : RSExportable(Context, RSExportable::EX_VAR, VD->getLocation()),
       mName(VD->getName().data(), VD->getName().size()),
       mET(ET),
       mIsConst(false),
diff --git a/slang_rs_exportable.h b/slang_rs_exportable.h
index f6d97a7..7ea982b 100644
--- a/slang_rs_exportable.h
+++ b/slang_rs_exportable.h
@@ -17,6 +17,7 @@
 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORTABLE_H_  // NOLINT
 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORTABLE_H_
 
+#include "clang/Basic/SourceLocation.h"
 #include "slang_rs_context.h"
 
 namespace slang {
@@ -36,24 +37,29 @@
 
   Kind mK;
 
+  clang::SourceLocation mLoc;
+
  protected:
-  RSExportable(RSContext *Context, RSExportable::Kind K)
+  RSExportable(RSContext *Context, RSExportable::Kind K, clang::SourceLocation Loc)
       : mContext(Context),
-        mK(K) {
+        mK(K),
+        mLoc(Loc) {
     Context->newExportable(this);
   }
 
  public:
-  inline Kind getKind() const { return mK; }
+  Kind getKind() const { return mK; }
+
+  clang::SourceLocation getLocation() const { return mLoc; }
 
   // When keep() is invoked, mKeep will set to true and the associated RSContext
   // won't free this RSExportable object in its destructor. The deallocation
   // responsibility is then transferred to the object who invoked this function.
   // Return false if the exportable is kept or failed to keep.
   virtual bool keep();
-  inline bool isKeep() const { return (mContext == nullptr); }
+  bool isKeep() const { return (mContext == nullptr); }
 
-  inline RSContext *getRSContext() const { return mContext; }
+  RSContext *getRSContext() const { return mContext; }
 
   virtual ~RSExportable() { }
 };