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) &&
33+ InvisibleDeclarations.at (Name).size () == 1 );
34+ assert (Declarations.count (Name) == 0 || Declarations.at (Name).empty ());
35+
36+ Declarations[Name].emplace_back (InvisibleDeclarations.at (Name).front ());
37+ InvisibleDeclarations.erase (Name);
38+ }
39+
40+ bool isInvisible (llvm::StringRef Name) const {
41+ return InvisibleDeclarations.count (Name);
42+ }
43+
44+ bool registerDeclaration (const Decl *D, bool Invisible, bool Update) {
45+ return registerDeclaration (D, llvm::StringRef (), nullptr , Invisible,
46+ Update);
47+ }
48+
49+ bool registerDeclaration (const Decl *D, llvm::StringRef Name,
50+ const SourceRange *Loc, bool Invisible,
51+ bool Update) {
52+ if (Name.empty ()) {
53+ Name = D->getName ();
54+ }
55+
56+ if (Name.empty ())
57+ return true ;
58+
59+ if (Update) {
60+ assert (!dynamic_cast <const FunctionDecl *>(D) &&
61+ " Attempt to update function definition." );
62+ Declarations.erase (Name);
63+ InvisibleDeclarations.erase (Name);
64+ return true ;
65+ } else {
66+ if (conflictingDeclaration (D, Name))
67+ return false ;
68+ if (EnclosingContainer && D->isVisibleAsUnqualifiedName ()) {
69+ // assert(false && "TODO: isVisibleAsUnqualifiedName for struct");
70+ cerr << " TODO: isVisibleAsUnqualifiedName for struct" << endl;
71+ // deal with homonymCandidates
72+ }
73+ }
74+
75+ std::vector<const Decl *> Decls =
76+ Invisible ? InvisibleDeclarations[Name] : Declarations[Name];
77+ if (find (Decls.begin (), Decls.end (), D) != Decls.end ())
78+ Decls.emplace_back (D);
79+
80+ return true ;
81+ }
82+
83+ const Decl *conflictingDeclaration (const Decl *D,
84+ llvm::StringRef Name) const {
85+ if (Name.empty ())
86+ Name = D->getName ();
87+ assert (!Name.empty ());
88+
89+ std::vector<Decl const *> Decls;
90+ if (Declarations.count (Name))
91+ Decls += Declarations.at (Name);
92+
93+ if (InvisibleDeclarations.count (Name))
94+ Decls += InvisibleDeclarations.at (Name);
95+
96+ if (dynamic_cast <const FunctionDecl *>(D) ||
97+ dynamic_cast <const EventDecl *>(D) ||
98+ dynamic_cast <const MagicVariableDecl *>(D)) {
99+ for (const Decl *RegDecl : Decls) {
100+ if (dynamic_cast <const FunctionDecl *>(D) &&
101+ !dynamic_cast <const FunctionDecl *>(RegDecl))
102+ return RegDecl;
103+ if (dynamic_cast <const EventDecl *>(D) &&
104+ !dynamic_cast <const EventDecl *>(RegDecl))
105+ return RegDecl;
106+ if (dynamic_cast <const MagicVariableDecl *>(D) &&
107+ !dynamic_cast <const MagicVariableDecl *>(RegDecl))
108+ return RegDecl;
109+ }
110+ } else if (Decls.size () == 1 && Decls.front () == D) {
111+ return nullptr ;
112+ } else if (!Decls.empty ()) {
113+ return Decls.front ();
114+ }
115+
116+ return nullptr ;
117+ }
118+
119+ private:
120+ const ASTNode *EnclosingNode = nullptr ;
121+ const DeclarationContainer *EnclosingContainer = nullptr ;
122+ std::vector<const DeclarationContainer *> InnerContainers;
123+ std::map<llvm::StringRef, std::vector<const Decl *>> Declarations;
124+ std::map<llvm::StringRef, std::vector<const Decl *>> InvisibleDeclarations;
125+ // std::vector<std::tuple<std::string, langutil::SourceLocation const*>>
126+ // m_homonymCandidates;
127+ };
128+
129+ } // namespace soll
0 commit comments