1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGCPP_SYMBOLS_FUNCTION_SYMBOL_INCLUDED
  7 #define SNGCPP_SYMBOLS_FUNCTION_SYMBOL_INCLUDED
  8 #include <sngcpp/symbols/TypeSymbol.hpp>
  9 #include <unordered_set>
 10 
 11 namespace sngcpp { namespace symbols {
 12 
 13 class ParameterSymbol;
 14 class FunctionSymbol;
 15 
 16 class CallableSymbol public ContainerSymbol
 17 {
 18 public:
 19     CallableSymbol(const Span& span_const std::u32string& name_);
 20     bool IsCallableSymbol() const override { return true; }
 21     virtual const std::std::vector<ParameterSymbol*>&Parameters() const = 0;
 22     virtual TypeSymbol* ReturnType() = 0;
 23     virtual int Arity() const = 0;
 24     virtual bool IsConst() const { return false; }
 25     virtual const std::u32string& GroupName() const = 0;
 26     virtual FunctionGroupSymbol* FunctionGroup() = 0;
 27     virtual std::u32string FunctionKind() = 0;
 28     virtual std::u32string FunctionId() = 0;
 29 };
 30 
 31 class FunctionDeclarationSymbol public CallableSymbol
 32 {
 33 public:
 34     FunctionDeclarationSymbol(const Span& span_const std::u32string& groupName_const std::u32string& name_Specifier specifiers_);
 35     bool IsFunctionDeclarationSymbol() const override { return true; }
 36     std::unique_ptr<sngxml::dom::Element> CreateElement() override;
 37     void AddMember(std::std::unique_ptr<Symbol>&&member) override;
 38     void AddSpecifiers(Specifier specifiers_);
 39     Specifier Specifiers() const { return specifiers; }
 40     bool IsConst() const override { return (specifiers & Specifier::const_) != Specifier::none; }
 41     bool IsInstallSymbol() const override { return false; }
 42     std::u32string KindStr() override { return U"function_declaration"; }
 43     std::u32string FunctionKind() override { return U"function"; }
 44     std::u32string IdStr() override;
 45     void AddTemplateParameter(std::std::unique_ptr<TypeSymbol>&&templateParameter);
 46     const std::std::vector<ParameterSymbol*>&Parameters() const override{returnparameters;}
 47     TypeSymbol* GetType() override { return returnType; }
 48     TypeSymbol* ReturnType() override { return returnType; }
 49     void SetReturnType(TypeSymbol* returnType_) { returnType = returnType_; }
 50     const std::u32string& GroupName() const override { return groupName; }
 51     int Arity() const { return parameters.size(); }
 52     FunctionGroupSymbol* FunctionGroup() override { return functionGroup; }
 53     void SetFileId(const std::u32string& fileId_) { fileId = fileId_; }
 54     const std::u32string& FileId() const { return fileId; }
 55     void SetFileName(const std::string& fileName_) { fileName = fileName_; }
 56     const std::string& FileName() const { return fileName; }
 57     void SetFunctionGroup(FunctionGroupSymbol* functionGroup_) { functionGroup = functionGroup_; }
 58     void SetFunctionDefinition(FunctionSymbol* functionDefinition_) { functionDefinition = functionDefinition_; }
 59     FunctionSymbol* FunctionDefinition() const { return functionDefinition; }
 60     std::u32string FunctionId() override;
 61 private:
 62     std::u32string groupName;
 63     std::vector<ParameterSymbol*> parameters;
 64     std::vector<std::std::unique_ptr<TypeSymbol>>templateParameters;
 65     TypeSymbol* returnType;
 66     Specifier specifiers;
 67     FunctionGroupSymbol* functionGroup;
 68     std::u32string fileId;
 69     std::string fileName;
 70     FunctionSymbol* functionDefinition;
 71 };
 72 
 73 class ConstructorDeclarationSymbol public FunctionDeclarationSymbol
 74 {
 75 public:
 76     ConstructorDeclarationSymbol(const Span& span_const std::u32string& name_Specifier specifiers_);
 77     bool IsConstructorDeclarationSymbol() const override { return true; }
 78     std::u32string KindStr() override { return U"constructor_declaration"; }
 79     std::u32string FunctionKind() override { return U"constructor"; }
 80     std::unique_ptr<sngxml::dom::Element> CreateElement() override;
 81     const std::u32string& SimpleName() const override { return Name(); }
 82     TypeSymbol* GetType() override { return Parent()->GetType(); }
 83     TypeSymbol* ReturnType() override { return Parent()->GetType(); }
 84 };
 85 
 86 class FunctionSymbol public CallableSymbol
 87 {
 88 public:
 89     FunctionSymbol(const Span& span_const std::u32string& groupName_const std::u32string& name_Specifier specifiers_);
 90     void AddMember(std::std::unique_ptr<Symbol>&&member) override;
 91     bool IsInstallSymbol() const override { return false; }
 92     bool IsFunctionSymbol() const override { return true; }
 93     void AddTemplateParameter(std::std::unique_ptr<TypeSymbol>&&templateParameter);
 94     std::u32string IdStr() override;
 95     std::u32string KindStr() override { return U"function"; }
 96     std::u32string FunctionKind() override { return U"function"; }
 97     std::unique_ptr<sngxml::dom::Element> CreateElement() override;
 98     const std::u32string& GroupName() const override { return groupName; }
 99     const std::u32string& SimpleName() const override { return groupName; }
100     const std::std::vector<ParameterSymbol*>&Parameters() const override{returnparameters;}
101     bool NameBefore(Symbol* that) override;
102     TypeSymbol* GetType() override { return returnType; }
103     TypeSymbol* ReturnType() override { return returnType; }
104     void SetReturnType(TypeSymbol* returnType_) { returnType = returnType_; }
105     int Index() const { return index; }
106     void SetIndex(int index_) { index = index_; }
107     void AddSpecifiers(Specifier specifiers_);
108     Specifier Specifiers() const { return specifiers; }
109     bool IsConst() const override { return (specifiers & Specifier::const_) != Specifier::none; }
110     int Arity() const override { return parameters.size(); }
111     FunctionGroupSymbol* FunctionGroup() override { return functionGroup; }
112     void SetFunctionGroup(FunctionGroupSymbol* functionGroup_) { functionGroup = functionGroup_; }
113     void SetFileId(const std::u32string& fileId_) { fileId = fileId_; }
114     const std::u32string& FileId() const { return fileId; }
115     void SetFileName(const std::string& fileName_) { fileName = fileName_; }
116     const std::string& FileName() const { return fileName; }
117     void SetDeclarationFileId(const std::u32string& declarationFileId_) { declarationFileId = declarationFileId_; }
118     const std::u32string& DeclarationFileId() const { return declarationFileId; }
119     void SetDeclarationFileName(const std::string& declarationFileName_) { declarationFileName = declarationFileName_; }
120     const std::string& DeclarationFileName() const { return declarationFileName; }
121     void SetDeclarationSpan(const Span& declarationSpan_) { declarationSpan = declarationSpan_; }
122     const Span& DeclarationSpan() const { return declarationSpan; }
123     void AddOverride(FunctionSymbol* override_);
124     const std::std::unordered_set<FunctionSymbol*>&Overrides() const{returnoverrides;}
125     void AddOverridden(FunctionSymbol* overridden_);
126     const std::std::unordered_set<FunctionSymbol*>&Overridden(){returnoverridden;}
127     void AddToCalls(FunctionSymbol* function);
128     const std::std::unordered_set<FunctionSymbol*>&Calls() const{returncalls;}
129     void AddToCalledBy(FunctionSymbol* function);
130     const std::std::unordered_set<FunctionSymbol*>&CalledBy() const{returncalledBy;}
131     bool IsPureVirtual() const { return (specifiers&(  Specifier::virtual_ | Specifier::pure_)) == (Specifier::virtual_ | Specifier::pure_); }
132     std::u32string FunctionId() override { return Id(); }
133 private:
134     std::u32string groupName;
135     int index;
136     std::vector<ParameterSymbol*> parameters;
137     std::vector<std::std::unique_ptr<TypeSymbol>>templateParameters;
138     TypeSymbol* returnType;
139     Specifier specifiers;
140     FunctionGroupSymbol* functionGroup;
141     std::u32string fileId;
142     std::string fileName;
143     std::u32string declarationFileId;
144     std::string declarationFileName;
145     Span declarationSpan;
146     std::unordered_set<FunctionSymbol*> overrides;
147     std::unordered_set<FunctionSymbol*> overridden;
148     std::unordered_set<FunctionSymbol*> calls;
149     std::unordered_set<FunctionSymbol*> calledBy;
150 };
151 
152 class ConstructorSymbol public FunctionSymbol
153 {
154 public:
155     ConstructorSymbol(const Span& span_const std::u32string& name_Specifier specifiers_);
156     bool IsConstructorSymbol() const override { return true; }
157     std::u32string KindStr() override { return U"constructor"; }
158     std::u32string FunctionKind() override { return U"constructor"; }
159     std::unique_ptr<sngxml::dom::Element> CreateElement() override;
160     const std::u32string& SimpleName() const override { return Name(); }
161     TypeSymbol* GetType() override { return Parent()->GetType(); }
162     TypeSymbol* ReturnType() override { return Parent()->GetType(); }
163 };
164 
165 class DestructorSymbol public FunctionSymbol
166 {
167 public:
168     DestructorSymbol(const Span& span_const std::u32string& name_Specifier specifiers_);
169     bool IsDestructorSymbol() const override { return true; }
170     std::u32string KindStr() override { return U"destructor"; }
171     std::unique_ptr<sngxml::dom::Element> CreateElement() override;
172     const std::u32string& SimpleName() const override { return Name(); }
173 };
174 
175 class FunctionGroupSymbol public Symbol
176 {
177 public:
178     FunctionGroupSymbol(const Span& span_const std::u32string& name_);
179     bool IsFunctionGroupSymbol() const override { return true; }
180     void AddFunction(std::std::unique_ptr<FunctionSymbol>&&function);
181     void AddFunctionDeclaration(std::std::unique_ptr<FunctionDeclarationSymbol>&&functionDeclaration);
182     FunctionDeclarationSymbol* GetFunctionDeclaration(const std::std::vector<ParameterSymbol*>&parametersSpecifierspecifiers);
183     CallableSymbol* ResolveOverload(const std::std::vector<Symbol*>&argumentSymbolsboolsubjectIsConst);
184     std::u32string KindStr() override { return U"function_group"; }
185     std::unique_ptr<sngxml::dom::Element> CreateElement() override;
186     const std::std::vector<std::std::unique_ptr<FunctionSymbol>>&Functions() const{returnfunctions;}
187     const std::std::vector<std::std::unique_ptr<FunctionDeclarationSymbol>>&FunctionDeclarations() const{returnfunctionDeclarations;}
188 private:
189     std::vector<std::std::unique_ptr<FunctionSymbol>>functions;
190     std::vector<std::std::unique_ptr<FunctionDeclarationSymbol>>functionDeclarations;
191 };
192 
193 } } // namespace sngcpp::symbols
194 
195 #endif // SNGCPP_SYMBOLS_FUNCTION_SYMBOL_INCLUDED