2014-07-12 22:23:55 +04:00
# include "llvm/ADT/SmallVector.h"
# include "llvm/Support/Path.h"
# include "clang/Sema/Sema.h"
# include "clang/Basic/Diagnostic.h"
# include "clang/AST/AST.h"
# include "clang/Lex/Preprocessor.h"
2014-07-13 20:43:20 +04:00
# include "clang/Frontend/CompilerInstance.h"
2014-07-12 22:23:55 +04:00
2014-06-08 20:42:58 +04:00
# include "cling/Interpreter/Interpreter.h"
# include "cling/Interpreter/InterpreterCallbacks.h"
2014-06-08 01:52:32 +04:00
# include "cling/Interpreter/AutoloadCallback.h"
2014-07-13 20:43:20 +04:00
# include "cling/Interpreter/DynamicLibraryManager.h"
# include "cling/Interpreter/Transaction.h"
2014-07-12 22:23:55 +04:00
2014-06-08 01:52:32 +04:00
using namespace clang ;
namespace cling {
2014-07-12 22:23:55 +04:00
2014-06-08 01:52:32 +04:00
void AutoloadCallback : : report ( clang : : SourceLocation l , std : : string name , std : : string header ) {
Sema & sema = m_Interpreter - > getSema ( ) ;
unsigned id
= sema . getDiagnostics ( ) . getCustomDiagID ( DiagnosticsEngine : : Level : : Warning ,
" Note: '%0' can be found in %1 " ) ;
/* unsigned idn //TODO: To be enabled after we have a way to get the full path
= sema . getDiagnostics ( ) . getCustomDiagID ( DiagnosticsEngine : : Level : : Note ,
" Type : %0 , Full Path: %1 " ) */ ;
sema . Diags . Report ( l , id ) < < name < < header ;
}
2014-07-12 22:23:55 +04:00
// bool AutoloadCallback::LookupObject (TagDecl *t) {
// if (t->hasAttr<AnnotateAttr>())
// report(t->getLocation(),t->getNameAsString(),t->getAttr<AnnotateAttr>()->getAnnotation());
// return false;
// }
void removeDefaultArg ( TemplateParameterList * Params ) {
for ( unsigned i = 0 , e = Params - > size ( ) ; i ! = e ; + + i ) {
Decl * Param = Params - > getParam ( i ) ;
if ( TemplateTypeParmDecl * TTP = dyn_cast < TemplateTypeParmDecl > ( Param ) ) {
if ( TTP - > hasDefaultArgument ( ) )
TTP - > setDefaultArgument ( nullptr , false ) ;
}
else if ( NonTypeTemplateParmDecl * NTTP =
dyn_cast < NonTypeTemplateParmDecl > ( Param ) ) {
if ( NTTP - > hasDefaultArgument ( ) )
NTTP - > setDefaultArgument ( nullptr , false ) ;
}
}
2014-06-08 01:52:32 +04:00
}
2014-07-12 22:23:55 +04:00
void AutoloadCallback : : InclusionDirective ( clang : : SourceLocation HashLoc ,
const clang : : Token & IncludeTok ,
llvm : : StringRef FileName ,
bool IsAngled ,
clang : : CharSourceRange FilenameRange ,
const clang : : FileEntry * File ,
llvm : : StringRef SearchPath ,
llvm : : StringRef RelativePath ,
const clang : : Module * Imported ) {
2014-07-13 20:43:20 +04:00
auto iterator = m_Map . find ( File - > getUID ( ) ) ;
if ( iterator = = m_Map . end ( ) )
2014-07-12 22:23:55 +04:00
return ; // nothing to do, file not referred in any annotation
if ( iterator - > second . Included )
return ; // nothing to do, file already included once
iterator - > second . Included = true ;
for ( clang : : Decl * decl : iterator - > second . Decls ) {
// llvm::outs() <<"CB:"<<llvm::cast<NamedDecl>(decl)->getName() <<"\n";
decl - > dropAttrs ( ) ;
if ( llvm : : isa < clang : : EnumDecl > ( decl ) ) {
//do something (remove fixed type..how?)
}
if ( llvm : : isa < clang : : ClassTemplateDecl > ( decl ) ) {
clang : : ClassTemplateDecl * ct = llvm : : cast < clang : : ClassTemplateDecl > ( decl ) ;
// llvm::outs() << ct->getName() <<"\n";
removeDefaultArg ( ct - > getTemplateParameters ( ) ) ;
}
}
}
2014-06-08 01:52:32 +04:00
AutoloadCallback : : AutoloadCallback ( Interpreter * interp ) :
2014-07-12 22:23:55 +04:00
InterpreterCallbacks ( interp , true , false , true ) , m_Interpreter ( interp ) {
2014-06-08 01:52:32 +04:00
}
2014-07-13 20:43:20 +04:00
AutoloadCallback : : ~ AutoloadCallback ( ) {
m_Map . clear ( ) ;
}
void AutoloadCallback : : InsertIntoAutoloadingState
( clang : : Decl * decl , std : : string annotation ) {
std : : string canonicalFile = DynamicLibraryManager : : normalizePath ( annotation ) ;
if ( canonicalFile . empty ( ) )
canonicalFile = 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 , canonicalFile , isAngled , LookupFrom , CurDir ,
/*SearchPath*/ 0 , /*RelativePath*/ 0 ,
/*suggestedModule*/ 0 , /*SkipCache*/ false ,
/*OpenFile*/ false , /*CacheFail*/ false ) ;
if ( ! FE )
return ;
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 ( ) ;
if ( cxxr - > hasAttr < AnnotateAttr > ( ) )
InsertIntoAutoloadingState ( CT , cxxr - > 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 ) ;
}
}
void AutoloadCallback : : TransactionCommitted ( const Transaction & T ) {
for ( Transaction : : const_iterator I = T . decls_begin ( ) , E = T . decls_end ( ) ;
I ! = E ; + + I ) {
Transaction : : DelayCallInfo DCI = * I ;
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 ) ;
}
HandleDeclVector ( decls ) ;
}
}
2014-06-08 01:52:32 +04:00
} //end namespace cling