void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text) { QCString incName = text; incName = incName.mid(1,incName.length()-2); // strip ".." or <..> FileDef *ifd=0; if (!incName.isEmpty()) { FileName *fn = Doxygen::inputNameDict->find(incName); if (fn) { bool found=false; FileNameIterator fni(*fn); // for each include name for (fni.toFirst();!found && (ifd=fni.current());++fni) { // see if this source file actually includes the file found = fd->isIncluded(ifd->absFilePath()); //printf(" include file %s found=%d\n",ifd->absFilePath().data(),found); } } } if (ifd) { ol.writeCodeLink(ifd->getReference(),ifd->getOutputFileBase(),0,text,ifd->briefDescriptionAsTooltip()); } else { codifyLines(ol,ifd,text,line,column,"preprocessor"); } }
void ClangParser::linkInclude(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint &line, uint &column, const QString &text) { QString incName = text; incName = incName.mid(1, incName.length() - 2); // strip ".." or <..> QSharedPointer<FileDef> ifd; if (! incName.isEmpty()) { QSharedPointer<FileNameList> fn = Doxy_Globals::inputNameDict->find(incName); if (fn) { bool found = false; // for each include name, see if this source file actually includes the file for (auto fd : *fn) { if (found) { break; } ifd = fd; found = fd->isIncluded(ifd->getFilePath()); } } } if (ifd) { ol.writeCodeLink(ifd->getReference(), ifd->getOutputFileBase(), 0, text, ifd->briefDescriptionAsTooltip()); } else { codifyLines(ol, ifd, text, line, column, "preprocessor"); } }
void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text,int tokenIndex) { CXCursor c = p->cursors[tokenIndex]; CXCursor r = clang_getCursorReferenced(c); if (!clang_equalCursors(r, c)) { c=r; // link to referenced location } CXCursor t = clang_getSpecializedCursorTemplate(c); if (!clang_Cursor_isNull(t) && !clang_equalCursors(t,c)) { c=t; // link to template } CXString usr = clang_getCursorUSR(c); const char *usrStr = clang_getCString(usr); Definition *d = usrStr ? Doxygen::clangUsrMap->find(usrStr) : 0; //CXCursorKind kind = clang_getCursorKind(c); //if (d==0) //{ // printf("didn't find definition for '%s' usr='******' kind=%d\n", // text,usrStr,kind); //} //else //{ // printf("found definition for '%s' usr='******' name='%s'\n", // text,usrStr,d->name().data()); //} if (d && d->isLinkable()) { if (g_insideBody && g_currentMemberDef && d->definitionType()==Definition::TypeMember && (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference { addDocCrossReference(g_currentMemberDef,(MemberDef*)d); } writeMultiLineCodeLink(ol,fd,line,column,d,text); } else { codifyLines(ol,fd,text,line,column); } clang_disposeString(usr); }
void ClangParser::linkMacro(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint &line, uint &column, const QString &text) { QSharedPointer<MemberName> mn = Doxy_Globals::functionNameSDict->find(text); if (mn) { // for (auto iter = mn->begin(); iter != mn->end(); ++iter) { for (auto md : *mn) { if (md->isDefine()) { writeMultiLineCodeLink(ol, fd, line, column, md, text); return; } } } codifyLines(ol, fd, text, line, column, ""); }
void ClangParser::linkMacro(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text) { MemberName *mn=Doxygen::functionNameSDict->find(text); if (mn) { MemberNameIterator mni(*mn); MemberDef *md; for (mni.toFirst();(md=mni.current());++mni) { if (md->isDefine()) { writeMultiLineCodeLink(ol,fd,line,column,md,text); return; } } } codifyLines(ol,fd,text,line,column); }
void ClangParser::linkIdentifier(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint &line, uint &column, const QString &text, int tokenIndex) { CXCursor c = p->cursors[tokenIndex]; CXCursor r = clang_getCursorReferenced(c); if (! clang_equalCursors(r, c)) { // link to referenced location c = r; } CXCursor t = clang_getSpecializedCursorTemplate(c); if (! clang_Cursor_isNull(t) && !clang_equalCursors(t, c)) { // link to template c = t; } CXString usr = clang_getCursorUSR(c); const char *usrStr = clang_getCString(usr); QSharedPointer<Definition> d; if (usrStr) { d = Doxy_Globals::clangUsrMap.value(usrStr); } if (d && d->isLinkable()) { if (g_insideBody && g_currentMemberDef && d->definitionType() == Definition::TypeMember && (g_currentMemberDef != d || g_currentLine < line)) { // avoid self-reference addDocCrossReference(g_currentMemberDef, d.dynamicCast<MemberDef>()); } writeMultiLineCodeLink(ol, fd, line, column, d, text); } else { codifyLines(ol, fd, text, line, column, ""); } clang_disposeString(usr); }
void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) { TooltipManager::instance()->clearTooltips(); // (re)set global parser state g_currentDefinition=0; g_currentMemberDef=0; g_currentLine=0; g_searchForBody=FALSE; g_insideBody=FALSE; g_bracketCount=0; unsigned int line=1,column=1; QCString lineNumber,lineAnchor; ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); for (unsigned int i=0;i<p->numTokens;i++) { CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]); unsigned int l, c; clang_getSpellingLocation(start, 0, &l, &c, 0); if (l > line) column = 1; while (line<l) { line++; ol.endCodeLine(); ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); } while (column<c) { ol.codify(" "); column++; } CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]); char const *s = clang_getCString(tokenString); CXCursorKind cursorKind = clang_getCursorKind(p->cursors[i]); CXTokenKind tokenKind = clang_getTokenKind(p->tokens[i]); //printf("%d:%d %s cursorKind=%d tokenKind=%d\n",line,column,s,cursorKind,tokenKind); switch (tokenKind) { case CXToken_Keyword: if (strcmp(s,"operator")==0) { linkIdentifier(ol,fd,line,column,s,i); } else { codifyLines(ol,fd,s,line,column, cursorKind==CXCursor_PreprocessingDirective ? "preprocessor" : keywordToType(s)); } break; case CXToken_Literal: if (cursorKind==CXCursor_InclusionDirective) { linkInclude(ol,fd,line,column,s); } else if (s[0]=='"' || s[0]=='\'') { codifyLines(ol,fd,s,line,column,"stringliteral"); } else { codifyLines(ol,fd,s,line,column); } break; case CXToken_Comment: codifyLines(ol,fd,s,line,column,"comment"); break; default: // CXToken_Punctuation or CXToken_Identifier if (tokenKind==CXToken_Punctuation) { detectFunctionBody(s); //printf("punct %s: %d\n",s,cursorKind); } switch (cursorKind) { case CXCursor_PreprocessingDirective: codifyLines(ol,fd,s,line,column,"preprocessor"); break; case CXCursor_MacroDefinition: codifyLines(ol,fd,s,line,column,"preprocessor"); break; case CXCursor_InclusionDirective: linkInclude(ol,fd,line,column,s); break; case CXCursor_MacroExpansion: linkMacro(ol,fd,line,column,s); break; default: if (tokenKind==CXToken_Identifier || (tokenKind==CXToken_Punctuation && // for operators (cursorKind==CXCursor_DeclRefExpr || cursorKind==CXCursor_MemberRefExpr || cursorKind==CXCursor_CallExpr || cursorKind==CXCursor_ObjCMessageExpr) ) ) { linkIdentifier(ol,fd,line,column,s,i); if (Doxygen::searchIndex) { ol.addWord(s,FALSE); } } else { codifyLines(ol,fd,s,line,column); } break; } } clang_disposeString(tokenString); } ol.endCodeLine(); TooltipManager::instance()->writeTooltips(ol); }
void ClangParser::writeSources(CodeOutputInterface &ol, QSharedPointer<FileDef> fd) { TooltipManager::instance()->clearTooltips(); // set global parser state g_currentDefinition = QSharedPointer<Definition>(); g_currentMemberDef = QSharedPointer<MemberDef>(); g_currentLine = 0; g_searchForBody = false; g_insideBody = false; g_bracketCount = 0; unsigned int line = 1; unsigned int column = 1; QString lineNumber; QString lineAnchor; ol.startCodeLine(true); writeLineNumber(ol, fd, line); for (unsigned int i = 0; i < p->numTokens; i++) { CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]); unsigned int t_line; unsigned int t_col; clang_getSpellingLocation(start, 0, &t_line, &t_col, 0); if (t_line > line) { column = 1; } while (line < t_line) { line++; ol.endCodeLine(); ol.startCodeLine(true); writeLineNumber(ol, fd, line); } while (column < t_col) { ol.codify(" "); column++; } CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]); char const *s = clang_getCString(tokenString); CXCursorKind cursorKind = clang_getCursorKind(p->cursors[i]); CXTokenKind tokenKind = clang_getTokenKind(p->tokens[i]); switch (tokenKind) { case CXToken_Keyword: if (strcmp(s, "operator") == 0) { linkIdentifier(ol, fd, line, column, s, i); } else { QString temp; if (cursorKind == CXCursor_PreprocessingDirective) { temp = "preprocessor"; } else { temp = keywordToType(s); } codifyLines(ol, fd, s, line, column, temp); } break; case CXToken_Literal: if (cursorKind == CXCursor_InclusionDirective) { linkInclude(ol, fd, line, column, s); } else if (s[0] == '"' || s[0] == '\'') { codifyLines(ol, fd, s, line, column, "stringliteral"); } else { codifyLines(ol, fd, s, line, column, ""); } break; case CXToken_Comment: codifyLines(ol, fd, s, line, column, "comment"); break; default: // CXToken_Punctuation or CXToken_Identifier if (tokenKind == CXToken_Punctuation) { detectFunctionBody(s); } switch (cursorKind) { case CXCursor_PreprocessingDirective: codifyLines(ol, fd, s, line, column, "preprocessor"); break; case CXCursor_MacroDefinition: codifyLines(ol, fd, s, line, column, "preprocessor"); break; case CXCursor_InclusionDirective: linkInclude(ol, fd, line, column, s); break; case CXCursor_MacroExpansion: linkMacro(ol, fd, line, column, s); break; default: if (tokenKind == CXToken_Identifier || (tokenKind == CXToken_Punctuation && (cursorKind == CXCursor_DeclRefExpr || cursorKind == CXCursor_MemberRefExpr || cursorKind == CXCursor_CallExpr || cursorKind == CXCursor_ObjCMessageExpr)) ) { linkIdentifier(ol, fd, line, column, s, i); if (Doxy_Globals::searchIndex) { ol.addWord(s, false); } } else { codifyLines(ol, fd, s, line, column, ""); } break; } } clang_disposeString(tokenString); } ol.endCodeLine(); TooltipManager::instance()->writeTooltips(ol); }