1 /*
2  * Copyright 2010, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FUNC_H_  // NOLINT
18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FUNC_H_
19 
20 #include <list>
21 #include <string>
22 
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/Support/raw_ostream.h"
25 
26 #include "clang/AST/Decl.h"
27 
28 #include "slang_assert.h"
29 #include "slang_rs_export_type.h"
30 #include "slang_rs_exportable.h"
31 
32 namespace llvm {
33   class StructType;
34 }
35 
36 namespace clang {
37   class FunctionDecl;
38 }   // namespace clang
39 
40 namespace slang {
41 
42 class RSContext;
43 
44 class RSExportFunc : public RSExportable {
45   friend class RSContext;
46 
47  private:
48   std::string mName;
49   std::string mMangledName;
50   bool mShouldMangle;
51   RSExportRecordType *mParamPacketType;
52 
RSExportFunc(RSContext * Context,const llvm::StringRef & Name,const clang::FunctionDecl * FD)53   RSExportFunc(RSContext *Context, const llvm::StringRef &Name,
54                const clang::FunctionDecl *FD)
55     : RSExportable(Context, RSExportable::EX_FUNC),
56       mName(Name.data(), Name.size()),
57       mMangledName(),
58       mShouldMangle(false),
59       mParamPacketType(nullptr) {
60 
61     mShouldMangle = Context->getMangleContext().shouldMangleDeclName(FD);
62 
63     if (mShouldMangle) {
64       llvm::raw_string_ostream BufStm(mMangledName);
65       Context->getMangleContext().mangleName(FD, BufStm);
66       BufStm.flush();
67     }
68   }
69 
70  public:
71   static RSExportFunc *Create(RSContext *Context,
72                               const clang::FunctionDecl *FD);
73 
74   typedef RSExportRecordType::const_field_iterator const_param_iterator;
75 
params_begin()76   inline const_param_iterator params_begin() const {
77     slangAssert((mParamPacketType != nullptr) &&
78                 "Get parameter from export function having no parameter!");
79     return mParamPacketType->fields_begin();
80   }
params_end()81   inline const_param_iterator params_end() const {
82     slangAssert((mParamPacketType != nullptr) &&
83                 "Get parameter from export function having no parameter!");
84     return mParamPacketType->fields_end();
85   }
86 
87   inline const std::string &getName(bool mangle = true) const {
88     return (mShouldMangle && mangle) ? mMangledName : mName;
89   }
90 
hasParam()91   inline bool hasParam() const
92     { return (mParamPacketType && !mParamPacketType->getFields().empty()); }
getNumParameters()93   inline size_t getNumParameters() const
94     { return ((mParamPacketType) ? mParamPacketType->getFields().size() : 0); }
95 
getParamPacketType()96   inline const RSExportRecordType *getParamPacketType() const
97     { return mParamPacketType; }
98 
99   // Check whether the given ParamsPacket type (in LLVM type) is "size
100   // equivalent" to the one obtained from getParamPacketType(). If the @Params
101   // is nullptr, means there must be no any parameters.
102   bool checkParameterPacketType(llvm::StructType *ParamTy) const;
103 };  // RSExportFunc
104 
105 
106 }   // namespace slang
107 
108 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FUNC_H_  NOLINT
109