1+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2+ #pragma once
3+
4+ #include " soll/AST/AST.h"
5+ #include " soll/AST/Decl.h"
6+ #include " soll/Basic/DiagnosticSema.h"
7+ #include " soll/Sema/Sema.h"
8+
9+ #include < iostream>
10+ #include < map>
11+ #include < memory>
12+ #include < string>
13+ #include < vector>
14+ using std::cerr;
15+ using std::endl;
16+
17+ namespace soll {
18+
19+ class DeclarationContainer {
20+ public:
21+ DeclarationContainer () = default ;
22+ explicit DeclarationContainer (const ASTNode *EnclosingNode,
23+ DeclarationContainer *EnclosingContainer)
24+ : EnclosingNode(EnclosingNode), EnclosingContainer(EnclosingContainer) {
25+ if (EnclosingContainer)
26+ EnclosingContainer->InnerContainers .emplace_back (this );
27+ }
28+
29+ ASTNode const *enclosingNode () const { return EnclosingNode; }
30+
31+ void activateVariable (llvm::StringRef Name) {
32+ assert (InvisibleDeclarations.count (Name) && InvisibleDeclarations.at (Name).size () == 1 );
33+ assert (Declarations.count (Name) == 0 || Declarations.at (Name).empty ());
34+
35+ Declarations[Name].emplace_back (InvisibleDeclarations.at (Name).front ());
36+ InvisibleDeclarations.erase (Name);
37+ }
38+
39+ bool isInvisible (llvm::StringRef Name) const {
40+ return InvisibleDeclarations.count (Name);
41+ }
42+
43+ bool registerDeclaration (const Decl *D, bool Invisible, bool Update) {
44+ return registerDeclaration (D, llvm::StringRef (), nullptr , Invisible,
45+ Update);
46+ }
47+
48+ bool registerDeclaration (const Decl *D, llvm::StringRef Name,
49+ const SourceRange *Loc, bool Invisible, bool Update) {
50+ if (Name.empty ()) {
51+ Name = D->getName ();
52+ }
53+
54+ if (Name.empty ())
55+ return true ;
56+
57+ if (Update) {
58+ assert (!dynamic_cast <const FunctionDecl *>(D) &&
59+ " Attempt to update function definition." );
60+ Declarations.erase (Name);
61+ InvisibleDeclarations.erase (Name);
62+ return true ;
63+ } else {
64+ if (conflictingDeclaration (D, Name))
65+ return false ;
66+ if (EnclosingContainer && D->isVisibleAsUnqualifiedName ()) {
67+ // assert(false && "TODO: isVisibleAsUnqualifiedName for struct");
68+ cerr << " TODO: isVisibleAsUnqualifiedName for struct" << endl;
69+ // deal with homonymCandidates
70+ }
71+ }
72+
73+ std::vector<const Decl *> Decls =
74+ Invisible ? InvisibleDeclarations[Name] : Declarations[Name];
75+ if (find (Decls.begin (), Decls.end (), D) != Decls.end ())
76+ Decls.emplace_back (D);
77+
78+ return true ;
79+ }
80+
81+ const Decl *conflictingDeclaration (const Decl *D,
82+ llvm::StringRef Name) const {
83+ if (Name.empty ())
84+ Name = D->getName ();
85+ assert (!Name.empty ());
86+
87+ std::vector<Decl const *> Decls;
88+ if (Declarations.count (Name))
89+ Decls += Declarations.at (Name);
90+
91+ if (InvisibleDeclarations.count (Name))
92+ Decls += InvisibleDeclarations.at (Name);
93+
94+ if (dynamic_cast <const FunctionDecl *>(D) ||
95+ dynamic_cast <const EventDecl *>(D) ||
96+ dynamic_cast <const MagicVariableDecl *>(D)) {
97+ for (const Decl *RegDecl : Decls) {
98+ if (dynamic_cast <const FunctionDecl *>(D) &&
99+ !dynamic_cast <const FunctionDecl *>(RegDecl))
100+ return RegDecl;
101+ if (dynamic_cast <const EventDecl *>(D) &&
102+ !dynamic_cast <const EventDecl *>(RegDecl))
103+ return RegDecl;
104+ if (dynamic_cast <const MagicVariableDecl *>(D) &&
105+ !dynamic_cast <const MagicVariableDecl *>(RegDecl))
106+ return RegDecl;
107+ }
108+ } else if (Decls.size () == 1 && Decls.front () == D) {
109+ return nullptr ;
110+ } else if (!Decls.empty ()) {
111+ return Decls.front ();
112+ }
113+
114+ return nullptr ;
115+ }
116+
117+ private:
118+ const ASTNode *EnclosingNode = nullptr ;
119+ const DeclarationContainer *EnclosingContainer = nullptr ;
120+ std::vector<const DeclarationContainer *> InnerContainers;
121+ std::map<llvm::StringRef, std::vector<const Decl *>> Declarations;
122+ std::map<llvm::StringRef, std::vector<const Decl *>> InvisibleDeclarations;
123+ // std::vector<std::tuple<std::string, langutil::SourceLocation const*>>
124+ // m_homonymCandidates;
125+ };
126+
127+ } // namespace soll
0 commit comments