-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathASTImportSource.cpp
More file actions
154 lines (128 loc) · 6.86 KB
/
ASTImportSource.cpp
File metadata and controls
154 lines (128 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "ASTImportSource.h"
using namespace clang;
namespace cling {
namespace utils {
void ASTImportSource::ImportDecl(Decl *declToImport,
ASTImporter &importer,
DeclarationName &childDeclName,
DeclarationName &parentDeclName,
const DeclContext *childCurrentDeclContext) {
// Don't do the import if we have a Function Template.
// Not supported by clang.
// FIXME: This is also a temporary check. Will be de-activated
// once clang supports the import of function templates.
if (!(declToImport->isFunctionOrFunctionTemplate() && declToImport->isTemplateDecl())) {
if (Decl *importedDecl = importer.Import(declToImport)) {
if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDecl)) {
std::vector < NamedDecl * > declVector{importedNamedDecl};
llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
//SetExternalVisibleDeclsForName(childCurrentDeclContext,
// importedNamedDecl->getDeclName(),
// FoundDecls);
}
// Put the name of the Decl imported with the
// DeclarationName coming from the parent, in my map.
m_DeclName_map[childDeclName.getAsString()] = parentDeclName;
}
}
}
void ASTImportSource::ImportDeclContext(DeclContext *declContextToImport,
ASTImporter &importer,
DeclarationName &childDeclName,
DeclarationName &parentDeclName,
const DeclContext *childCurrentDeclContext) {
if (DeclContext *importedDeclContext = importer.ImportContext(declContextToImport)) {
importedDeclContext->setHasExternalVisibleStorage(true);
if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDeclContext)) {
std::vector < NamedDecl * > declVector{importedNamedDecl};
llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
// SetExternalVisibleDeclsForName(childCurrentDeclContext,
// importedNamedDecl->getDeclName(),
// FoundDecls);
}
// Put the name of the DeclContext imported with the
// DeclarationName coming from the parent, in my map.
m_DeclName_map[childDeclName.getAsString()] = parentDeclName;
// And also put the declaration context I found from the parent Interpreter
// in the map of the child Interpreter to have it for the future.
m_DeclContexts_map[importedDeclContext] = declContextToImport;
}
}
bool ASTImportSource::Import(DeclContext::lookup_result lookup_result,
ASTContext &from_ASTContext,
ASTContext &to_ASTContext,
const DeclContext *childCurrentDeclContext,
DeclarationName &childDeclName,
DeclarationName &parentDeclName) {
// Prepare to import the Decl(Context) we found in the
// child interpreter by getting the file managers from
// each interpreter.
FileManager &child_FM = m_child_Interp->getCI()->getFileManager();
FileManager &parent_FM = m_parent_Interp->getCI()->getFileManager();
// Clang's ASTImporter
ASTImporter importer(to_ASTContext, child_FM,
from_ASTContext, parent_FM,
/*MinimalImport : ON*/ true);
for (DeclContext::lookup_iterator I = lookup_result.begin(),
E = lookup_result.end();
I != E; ++I) {
// Check if this Name we are looking for is
// a DeclContext (for example a Namespace, function etc.).
if (DeclContext *declContextToImport = llvm::dyn_cast<DeclContext>(*I)) {
ImportDeclContext(declContextToImport, importer, childDeclName,
parentDeclName, childCurrentDeclContext);
} else if (Decl *declToImport = llvm::dyn_cast<Decl>(*I)) {
// else it is a Decl
ImportDecl(declToImport, importer, childDeclName,
parentDeclName, childCurrentDeclContext);
}
}
return true;
}
///\brief This is the most important function of the class ASTImportSource
/// since from here initiates the lookup and import part of the missing
/// Decl(s) (Contexts).
///
bool ASTImportSource::FindExternalVisibleDeclsByName(
const DeclContext *childCurrentDeclContext, DeclarationName childDeclName) {
assert(childCurrentDeclContext->hasExternalVisibleStorage() &&
"DeclContext has no visible decls in storage");
// Check if we have already imported this Decl (Context).
//if (m_DeclName_map.find(childDeclName.getAsString()) != m_DeclName_map.end())
//return true;
// Clang will call FindExternalVisibleDeclsByName with an
// IdentifierInfo valid for the child interpreter. Get the
// IdentifierInfo's StringRef representation.
// Get the identifier info from the parent interpreter
// for this Name.
llvm::StringRef name(childDeclName.getAsString());
IdentifierTable &parentIdentifierTable =
m_parent_Interp->getCI()->getASTContext().Idents;
IdentifierInfo &parentIdentifierInfo = parentIdentifierTable.get(name);
DeclarationName parentDeclName(&parentIdentifierInfo);
// Search in the map of the stored Decl Contexts for this
// Decl Context.
std::map<const clang::DeclContext *, clang::DeclContext *>::iterator I;
if ((I = m_DeclContexts_map.find(childCurrentDeclContext))
!= m_DeclContexts_map.end()) {
// If childCurrentDeclContext was found before and is already in the map,
// then do the lookup using the stored pointer.
DeclContext *parentDeclContext = I->second;
Decl *fromDeclContext = Decl::castFromDeclContext(parentDeclContext);
ASTContext &from_ASTContext = fromDeclContext->getASTContext();
Decl *toDeclContext = Decl::castFromDeclContext(childCurrentDeclContext);
ASTContext &to_ASTContext = toDeclContext->getASTContext();
DeclContext::lookup_result lookup_result =
parentDeclContext->lookup(parentDeclName);
// Check if we found this Name in the parent interpreter
if (!lookup_result.empty()) {
// Do the import
if (Import(lookup_result, from_ASTContext, to_ASTContext,
childCurrentDeclContext, childDeclName, parentDeclName))
return true;
}
}
return false;
}
} // end namespace utils
} // end namespace cling