From 835c1e3cbf2ed46e2194981ff04d2088d05d4583 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Wed, 6 Aug 2014 00:07:20 +0200 Subject: [PATCH] Simplify code. --- include/cling/Interpreter/AutoloadCallback.h | 27 +--- lib/Interpreter/AutoloadCallback.cpp | 145 ++++++++++--------- 2 files changed, 78 insertions(+), 94 deletions(-) diff --git a/include/cling/Interpreter/AutoloadCallback.h b/include/cling/Interpreter/AutoloadCallback.h index fd78dac4..fc2a5abc 100644 --- a/include/cling/Interpreter/AutoloadCallback.h +++ b/include/cling/Interpreter/AutoloadCallback.h @@ -2,19 +2,8 @@ #define CLING_AUTOLOAD_CALLBACK_H #include "cling/Interpreter/InterpreterCallbacks.h" -#include -#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 > FwdDeclsMap; private: - struct FileInfo { - FileInfo():Included(false){} - bool Included; - std::vector Decls; - }; - // The key is the Unique File ID obtained from the source manager. - std::map 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 Decls); - void HandleNamespace(clang::NamespaceDecl* NS); - void HandleClassTemplate(clang::ClassTemplateDecl* CT); - void HandleFunction(clang::FunctionDecl* F); }; } // end namespace cling diff --git a/lib/Interpreter/AutoloadCallback.cpp b/lib/Interpreter/AutoloadCallback.cpp index 2755eec9..0457066f 100644 --- a/lib/Interpreter/AutoloadCallback.cpp +++ b/lib/Interpreter/AutoloadCallback.cpp @@ -37,25 +37,82 @@ namespace cling { return false; } - class DefaultArgRemover: public RecursiveASTVisitor { + class DefaultArgVisitor: public RecursiveASTVisitor { + 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(); + + (*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(D->getDeclContext()); + if (AnnotateAttr* attr = parent->getAttr()) + InsertIntoAutoloadingState(D, attr->getAnnotation()); + } + else if (D->hasDefaultArgument()) D->removeDefaultArgument(); return true; } bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl* D) { + if (m_IsStoringState) { + Decl* parent = cast(D->getDeclContext()); + if (AnnotateAttr* attr = parent->getAttr()) + InsertIntoAutoloadingState(D, attr->getAnnotation()); + } if (D->hasDefaultArgument()) D->removeDefaultArgument(); return true; } bool VisitParmVarDecl(ParmVarDecl* D) { + if (m_IsStoringState) { + Decl* parent = cast(D->getDeclContext()); + if (AnnotateAttr* attr = parent->getAttr()) + 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 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()->getAnnotation()); - } - void AutoloadCallback::HandleFunction(FunctionDecl *F) { - InsertIntoAutoloadingState(F,F->getAttr()->getAnnotation()); - } - - void AutoloadCallback::HandleDeclVector(std::vector Decls) { - for(auto decl : Decls ) { - if(auto ct = llvm::dyn_cast(decl)) - HandleClassTemplate(ct); - if(auto ns = llvm::dyn_cast(decl)) - HandleNamespace(ns); - if(auto f = llvm::dyn_cast(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()) continue; - std::vector 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); } }