Simplify code.
This commit is contained in:
parent
737a2c7f39
commit
835c1e3cbf
@ -2,19 +2,8 @@
|
||||
#define CLING_AUTOLOAD_CALLBACK_H
|
||||
|
||||
#include "cling/Interpreter/InterpreterCallbacks.h"
|
||||
#include <map>
|
||||
|
||||
#if 0
|
||||
This feature is disabled by default until stable.
|
||||
To enable, execute the following code as runtime input.
|
||||
Note that, for now, the T meta command will cause the interpreter to segfault,
|
||||
unless these objects are loaded.
|
||||
|
||||
.rawInput 0
|
||||
#include "cling/Interpreter/AutoloadCallback.h"
|
||||
gCling->setCallbacks(new cling::AutoloadCallback(gCling));
|
||||
|
||||
#endif
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
class Decl;
|
||||
@ -51,25 +40,15 @@ namespace cling {
|
||||
const clang::Module *Imported);
|
||||
void TransactionCommitted(const Transaction& T);
|
||||
|
||||
typedef llvm::DenseMap<const clang::FileEntry*, std::vector<clang::Decl*> > FwdDeclsMap;
|
||||
private:
|
||||
struct FileInfo {
|
||||
FileInfo():Included(false){}
|
||||
bool Included;
|
||||
std::vector<clang::Decl*> Decls;
|
||||
};
|
||||
|
||||
// The key is the Unique File ID obtained from the source manager.
|
||||
std::map<unsigned,FileInfo> m_Map;
|
||||
FwdDeclsMap m_Map;
|
||||
|
||||
Interpreter* m_Interpreter;
|
||||
// AutoloadingStateInfo m_State;
|
||||
|
||||
void report(clang::SourceLocation l, std::string name,std::string header);
|
||||
void InsertIntoAutoloadingState(clang::Decl* decl,std::string annotation);
|
||||
void HandleDeclVector(std::vector<clang::Decl*> Decls);
|
||||
void HandleNamespace(clang::NamespaceDecl* NS);
|
||||
void HandleClassTemplate(clang::ClassTemplateDecl* CT);
|
||||
void HandleFunction(clang::FunctionDecl* F);
|
||||
};
|
||||
} // end namespace cling
|
||||
|
||||
|
@ -37,25 +37,82 @@ namespace cling {
|
||||
return false;
|
||||
}
|
||||
|
||||
class DefaultArgRemover: public RecursiveASTVisitor<DefaultArgRemover> {
|
||||
class DefaultArgVisitor: public RecursiveASTVisitor<DefaultArgVisitor> {
|
||||
private:
|
||||
bool m_IsStoringState;
|
||||
AutoloadCallback::FwdDeclsMap* m_Map;
|
||||
clang::Preprocessor* m_PP;
|
||||
private:
|
||||
void InsertIntoAutoloadingState (Decl* decl, std::string annotation) {
|
||||
|
||||
assert(annotation != "" && "Empty annotation!");
|
||||
assert(m_PP);
|
||||
|
||||
const FileEntry* FE = 0;
|
||||
SourceLocation fileNameLoc;
|
||||
bool isAngled = false;
|
||||
const DirectoryLookup* LookupFrom = 0;
|
||||
const DirectoryLookup* CurDir = 0;
|
||||
|
||||
FE = m_PP->LookupFile(fileNameLoc, annotation, isAngled, LookupFrom,
|
||||
CurDir, /*SearchPath*/0, /*RelativePath*/ 0,
|
||||
/*suggestedModule*/0, /*SkipCache*/false,
|
||||
/*OpenFile*/ false, /*CacheFail*/ false);
|
||||
|
||||
assert(FE && "Must have a valid FileEntry");
|
||||
|
||||
if(m_Map->find(FE) == m_Map->end())
|
||||
(*m_Map)[FE] = std::vector<Decl*>();
|
||||
|
||||
(*m_Map)[FE].push_back(decl);
|
||||
}
|
||||
|
||||
public:
|
||||
void Remove(Decl* D) {
|
||||
DefaultArgVisitor() : m_IsStoringState(false), m_Map(0) {}
|
||||
|
||||
void RemoveDefaultArgsOf(Decl* D) {
|
||||
TraverseDecl(D);
|
||||
}
|
||||
|
||||
void TrackDefaultArgStateOf(Decl* D, AutoloadCallback::FwdDeclsMap& map,
|
||||
Preprocessor& PP) {
|
||||
m_IsStoringState = true;
|
||||
m_Map = ↦
|
||||
m_PP = &PP;
|
||||
TraverseDecl(D);
|
||||
m_PP = 0;
|
||||
m_Map = 0;
|
||||
m_IsStoringState = false;
|
||||
}
|
||||
|
||||
bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl* D) {
|
||||
if (D->hasDefaultArgument())
|
||||
if (m_IsStoringState) {
|
||||
Decl* parent = cast<Decl>(D->getDeclContext());
|
||||
if (AnnotateAttr* attr = parent->getAttr<AnnotateAttr>())
|
||||
InsertIntoAutoloadingState(D, attr->getAnnotation());
|
||||
}
|
||||
else if (D->hasDefaultArgument())
|
||||
D->removeDefaultArgument();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl* D) {
|
||||
if (m_IsStoringState) {
|
||||
Decl* parent = cast<Decl>(D->getDeclContext());
|
||||
if (AnnotateAttr* attr = parent->getAttr<AnnotateAttr>())
|
||||
InsertIntoAutoloadingState(D, attr->getAnnotation());
|
||||
}
|
||||
if (D->hasDefaultArgument())
|
||||
D->removeDefaultArgument();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitParmVarDecl(ParmVarDecl* D) {
|
||||
if (m_IsStoringState) {
|
||||
Decl* parent = cast<Decl>(D->getDeclContext());
|
||||
if (AnnotateAttr* attr = parent->getAttr<AnnotateAttr>())
|
||||
InsertIntoAutoloadingState(D, attr->getAnnotation());
|
||||
}
|
||||
if (D->hasDefaultArg())
|
||||
D->setDefaultArg(nullptr);
|
||||
return true;
|
||||
@ -73,21 +130,20 @@ namespace cling {
|
||||
const clang::Module *Imported) {
|
||||
assert(File && "Must have a valid File");
|
||||
|
||||
auto iterator = m_Map.find(File->getUID());
|
||||
if (iterator == m_Map.end())
|
||||
auto found = m_Map.find(File);
|
||||
if (found == m_Map.end())
|
||||
return; // nothing to do, file not referred in any annotation
|
||||
if(iterator->second.Included)
|
||||
return; // nothing to do, file already included once
|
||||
// if(iterator->second.Included)
|
||||
// return; // nothing to do, file already included once
|
||||
|
||||
iterator->second.Included = true;
|
||||
DefaultArgVisitor defaultArgsCleaner;
|
||||
|
||||
DefaultArgRemover defaultArgsCleaner;
|
||||
|
||||
for(clang::Decl* decl : iterator->second.Decls) {
|
||||
decl->dropAttrs();
|
||||
defaultArgsCleaner.Remove(decl);
|
||||
for (auto D : found->second) {
|
||||
D->dropAttrs();
|
||||
defaultArgsCleaner.RemoveDefaultArgsOf(D);
|
||||
}
|
||||
|
||||
// Don't need to keep track of cleaned up decls from file.
|
||||
m_Map.erase(found);
|
||||
}
|
||||
|
||||
AutoloadCallback::AutoloadCallback(Interpreter* interp) :
|
||||
@ -98,60 +154,10 @@ namespace cling {
|
||||
AutoloadCallback::~AutoloadCallback() {
|
||||
}
|
||||
|
||||
void AutoloadCallback::InsertIntoAutoloadingState (clang::Decl* decl,
|
||||
std::string annotation) {
|
||||
|
||||
assert(annotation != "" && "Empty annotation!");
|
||||
|
||||
clang::Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
|
||||
const FileEntry* FE = 0;
|
||||
SourceLocation fileNameLoc;
|
||||
bool isAngled = false;
|
||||
const DirectoryLookup* LookupFrom = 0;
|
||||
const DirectoryLookup* CurDir = 0;
|
||||
|
||||
FE = PP.LookupFile(fileNameLoc, annotation, isAngled, LookupFrom, CurDir,
|
||||
/*SearchPath*/0, /*RelativePath*/ 0,
|
||||
/*suggestedModule*/0, /*SkipCache*/false,
|
||||
/*OpenFile*/ false, /*CacheFail*/ false);
|
||||
|
||||
assert(FE && "Must have a valid FileEntry");
|
||||
|
||||
auto& stateMap = m_Map;
|
||||
auto iterator = stateMap.find(FE->getUID());
|
||||
|
||||
if(iterator == stateMap.end())
|
||||
stateMap[FE->getUID()] = FileInfo();
|
||||
|
||||
stateMap[FE->getUID()].Decls.push_back(decl);
|
||||
}
|
||||
|
||||
void AutoloadCallback::HandleNamespace(NamespaceDecl* NS) {
|
||||
std::vector<clang::Decl*> decls;
|
||||
for(auto dit = NS->decls_begin(); dit != NS->decls_end(); ++dit)
|
||||
decls.push_back(*dit);
|
||||
HandleDeclVector(decls);
|
||||
}
|
||||
|
||||
void AutoloadCallback::HandleClassTemplate(ClassTemplateDecl* CT) {
|
||||
CXXRecordDecl* cxxr = CT->getTemplatedDecl();
|
||||
InsertIntoAutoloadingState(CT,cxxr->getAttr<AnnotateAttr>()->getAnnotation());
|
||||
}
|
||||
void AutoloadCallback::HandleFunction(FunctionDecl *F) {
|
||||
InsertIntoAutoloadingState(F,F->getAttr<AnnotateAttr>()->getAnnotation());
|
||||
}
|
||||
|
||||
void AutoloadCallback::HandleDeclVector(std::vector<clang::Decl*> Decls) {
|
||||
for(auto decl : Decls ) {
|
||||
if(auto ct = llvm::dyn_cast<ClassTemplateDecl>(decl))
|
||||
HandleClassTemplate(ct);
|
||||
if(auto ns = llvm::dyn_cast<NamespaceDecl>(decl))
|
||||
HandleNamespace(ns);
|
||||
if(auto f = llvm::dyn_cast<FunctionDecl>(decl))
|
||||
HandleFunction(f);
|
||||
}
|
||||
}
|
||||
void AutoloadCallback::TransactionCommitted(const Transaction &T) {
|
||||
|
||||
DefaultArgVisitor defaultArgsStateCollector;
|
||||
|
||||
for (Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
|
||||
I != E; ++I) {
|
||||
Transaction::DelayCallInfo DCI = *I;
|
||||
@ -161,12 +167,11 @@ namespace cling {
|
||||
if (DCI.m_DGR.isNull() || (*DCI.m_DGR.begin())->hasAttr<AnnotateAttr>())
|
||||
continue;
|
||||
|
||||
std::vector<clang::Decl*> decls;
|
||||
for (DeclGroupRef::iterator J = DCI.m_DGR.begin(),
|
||||
JE = DCI.m_DGR.end(); J != JE; ++J) {
|
||||
decls.push_back(*J);
|
||||
defaultArgsStateCollector.TrackDefaultArgStateOf(*J, m_Map,
|
||||
m_Interpreter->getCI()->getPreprocessor());
|
||||
}
|
||||
HandleDeclVector(decls);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user