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 slang {
37 
38 class RSContext;
39 
40 class RSExportFunc : public RSExportable {
41   friend class RSContext;
42 
43  private:
44   std::string mName;
45   std::string mMangledName;
46   bool mShouldMangle;
47   RSExportRecordType *mParamPacketType;
48 
RSExportFunc(RSContext * Context,const llvm::StringRef & Name,const clang::FunctionDecl * FD)49   RSExportFunc(RSContext *Context, const llvm::StringRef &Name,
50                const clang::FunctionDecl *FD)
51     : RSExportable(Context, RSExportable::EX_FUNC, FD->getLocation()),
52       mName(Name.data(), Name.size()),
53       mMangledName(),
54       mShouldMangle(false),
55       mParamPacketType(nullptr) {
56 
57     mShouldMangle = Context->getMangleContext().shouldMangleDeclName(FD);
58 
59     if (mShouldMangle) {
60       llvm::raw_string_ostream BufStm(mMangledName);
61       Context->getMangleContext().mangleName(FD, BufStm);
62       BufStm.flush();
63     }
64   }
65 
66  public:
67   static RSExportFunc *Create(RSContext *Context,
68                               const clang::FunctionDecl *FD);
69 
70   typedef RSExportRecordType::const_field_iterator const_param_iterator;
71 
params_begin()72   inline const_param_iterator params_begin() const {
73     slangAssert((mParamPacketType != nullptr) &&
74                 "Get parameter from export function having no parameter!");
75     return mParamPacketType->fields_begin();
76   }
params_end()77   inline const_param_iterator params_end() const {
78     slangAssert((mParamPacketType != nullptr) &&
79                 "Get parameter from export function having no parameter!");
80     return mParamPacketType->fields_end();
81   }
82 
83   inline const std::string &getName(bool mangle = true) const {
84     return (mShouldMangle && mangle) ? mMangledName : mName;
85   }
86 
hasParam()87   inline bool hasParam() const
88     { return (mParamPacketType && !mParamPacketType->getFields().empty()); }
getNumParameters()89   inline size_t getNumParameters() const
90     { return ((mParamPacketType) ? mParamPacketType->getFields().size() : 0); }
91 
getParamPacketType()92   inline const RSExportRecordType *getParamPacketType() const
93     { return mParamPacketType; }
94 
95   // Check whether the given ParamsPacket type (in LLVM type) is "size
96   // equivalent" to the one obtained from getParamPacketType(). If the @Params
97   // is nullptr, means there must be no any parameters.
98   bool checkParameterPacketType(llvm::StructType *ParamTy) const;
99 };  // RSExportFunc
100 
101 
102 }   // namespace slang
103 
104 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FUNC_H_  NOLINT
105