File indexing completed on 2024-05-12 04:39:11

0001 /*
0002     SPDX-FileCopyrightText: 2013 Olivier de Gaalon <olivier.jg@gmail.com>
0003     SPDX-FileCopyrightText: 2015 Milian Wolff <mail@milianw.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "builder.h"
0009 
0010 #include "util/clangdebug.h"
0011 
0012 #include "templatehelpers.h"
0013 #include "cursorkindtraits.h"
0014 #include "clangducontext.h"
0015 #include "macrodefinition.h"
0016 #include "types/classspecializationtype.h"
0017 #include "util/clangutils.h"
0018 #include "util/clangtypes.h"
0019 
0020 #include <util/pushvalue.h>
0021 
0022 #include <language/duchain/duchainlock.h>
0023 #include <language/duchain/classdeclaration.h>
0024 #include <language/duchain/stringhelpers.h>
0025 #include <language/duchain/duchainutils.h>
0026 #include <language/duchain/problem.h>
0027 
0028 #include <language/duchain/types/pointertype.h>
0029 #include <language/duchain/types/arraytype.h>
0030 #include <language/duchain/types/referencetype.h>
0031 #include <language/duchain/types/functiontype.h>
0032 #include <language/duchain/types/structuretype.h>
0033 #include <language/duchain/types/enumerationtype.h>
0034 #include <language/duchain/types/enumeratortype.h>
0035 #include <language/duchain/types/typealiastype.h>
0036 #include <language/duchain/types/indexedtype.h>
0037 
0038 #include <clang-c/Documentation.h>
0039 
0040 #include <QVarLengthArray>
0041 
0042 #include <algorithm>
0043 #include <unordered_map>
0044 #include <typeinfo>
0045 
0046 
0047 /// Turn on for debugging the declaration building
0048 #define IF_DEBUG(x)
0049 
0050 using namespace KDevelop;
0051 
0052 namespace {
0053 
0054 #if CINDEX_VERSION_MINOR >= 100
0055 // TODO: this is ugly, can we find a better alternative?
0056 bool jsonTestRun()
0057 {
0058     static bool runningTest = qEnvironmentVariableIsSet("KDEV_CLANG_JSON_TEST_RUN");
0059     return runningTest;
0060 }
0061 #endif
0062 
0063 //BEGIN helpers
0064 // HACK: current alias type template machinery is badly broken wrt spelling
0065 // location, work around this by adjusting all references to point to child
0066 // type alias node with proper location
0067 // TODO: investigate upstream implementation of CXCursor_TypeAliasTemplateDecl
0068 CXCursor findEmbeddedTypeAlias(CXCursor aliasTemplate)
0069 {
0070     auto result = clang_getNullCursor();
0071     clang_visitChildren(aliasTemplate, [] (CXCursor cursor, CXCursor, CXClientData data) {
0072         if (clang_getCursorKind(cursor) == CXCursor_TypeAliasDecl) {
0073             auto res = reinterpret_cast<CXCursor*>(data);
0074             *res = cursor;
0075             return CXChildVisit_Break;
0076         }
0077         return CXChildVisit_Continue;
0078     }, &result);
0079     return result;
0080 }
0081 
0082 /**
0083  * Find the cursor that cursor @p cursor references
0084  *
0085  * First tries to get the referenced cursor via clang_getCursorReferenced,
0086  * and if that fails, tries to get them via clang_getOverloadedDecl
0087  * (which returns the referenced cursor for CXCursor_OverloadedDeclRef, for example)
0088  *
0089  * @return Valid cursor on success, else null cursor
0090  */
0091 CXCursor referencedCursor(CXCursor cursor)
0092 {
0093     auto referenced = clang_getCursorReferenced(cursor);
0094     // HACK: see notes at getEmbeddedTypeAlias()
0095     if (clang_getCursorKind(referenced) == CXCursor_TypeAliasTemplateDecl) {
0096         return findEmbeddedTypeAlias(referenced);
0097     }
0098 
0099     if (!clang_equalCursors(cursor, referenced)) {
0100         return referenced;
0101     }
0102 
0103     // get the first result for now
0104     referenced = clang_getOverloadedDecl(cursor, 0);
0105     if (!clang_Cursor_isNull(referenced)) {
0106         return referenced;
0107     }
0108     return clang_getNullCursor();
0109 }
0110 
0111 Identifier makeId(CXCursor cursor)
0112 {
0113     if (CursorKindTraits::isClassTemplate(cursor.kind)) {
0114         // TODO: how to handle functions here? We don't want to add the "real" function arguments here
0115         //       and there does not seem to be an API to get the template arguments for non-specializations easily
0116         // NOTE: using the QString overload of the Identifier ctor here, so that the template name gets parsed
0117         return Identifier(ClangString(clang_getCursorDisplayName(cursor)).toString());
0118     }
0119 
0120     const ClangString spelling(clang_getCursorSpelling(cursor));
0121     if (!spelling.isEmpty() && spelling.c_str()[0] == '[') {
0122         // skip unexposed DecompositionDecl, we want to get hold of the BindingsDecl inside instead
0123         return Identifier();
0124     }
0125 
0126     auto name = spelling.toIndexed();
0127     if (name.isEmpty() && CursorKindTraits::isClass(cursor.kind)) {
0128         // try to use the type name for typedef'ed anon structs etc. as a fallback
0129         auto type = ClangString(clang_getTypeSpelling(clang_getCursorType(cursor))).toString();
0130         // but don't associate a super long name for anon structs without a typedef
0131         if (!type.startsWith(QLatin1String("(anonymous "))) {
0132             name = IndexedString(type);
0133         }
0134     }
0135 
0136     return Identifier(name);
0137 }
0138 
0139 #if CINDEX_VERSION_MINOR >= 100 // FIXME https://bugs.llvm.org/show_bug.cgi?id=35333
0140 QByteArray makeComment(CXComment comment)
0141 {
0142     if (Q_UNLIKELY(jsonTestRun())) {
0143         auto kind = clang_Comment_getKind(comment);
0144         if (kind == CXComment_Text)
0145             return ClangString(clang_TextComment_getText(comment)).toByteArray();
0146 
0147         QByteArray text;
0148         int numChildren = clang_Comment_getNumChildren(comment);
0149         for (int i = 0; i < numChildren; ++i)
0150             text += makeComment(clang_Comment_getChild(comment, i));
0151         return text;
0152     }
0153 
0154     return ClangString(clang_FullComment_getAsHTML(comment)).toByteArray();
0155 }
0156 #endif
0157 
0158 AbstractType* createDelayedType(CXType type)
0159 {
0160     auto t = new DelayedType;
0161 
0162     QString typeName = ClangString(clang_getTypeSpelling(type)).toString();
0163     typeName.remove(QStringLiteral("const "));
0164     typeName.remove(QStringLiteral("volatile "));
0165 
0166     t->setIdentifier(IndexedTypeIdentifier(typeName));
0167     return t;
0168 }
0169 
0170 void contextImportDecl(DUContext* context, const DeclarationPointer& decl)
0171 {
0172     auto top = context->topContext();
0173     if (auto import = decl->logicalInternalContext(top)) {
0174         context->addImportedParentContext(import);
0175         context->topContext()->updateImportsCache();
0176     }
0177 }
0178 
0179 //END helpers
0180 
0181 CXChildVisitResult visitCursor(CXCursor cursor, CXCursor parent, CXClientData data);
0182 
0183 //BEGIN IdType
0184 template<CXCursorKind CK, class Enable = void>
0185 struct IdType;
0186 
0187 template<CXCursorKind CK>
0188 struct IdType<CK, typename std::enable_if<CursorKindTraits::isClass(CK)>::type>
0189 {
0190     using Type = StructureType;
0191 };
0192 
0193 template<CXCursorKind CK>
0194 struct IdType<CK, typename std::enable_if<CK == CXCursor_TypedefDecl>::type>
0195 {
0196     using Type = TypeAliasType;
0197 };
0198 
0199 template<CXCursorKind CK>
0200 struct IdType<CK, typename std::enable_if<CK == CXCursor_TypeAliasDecl>::type>
0201 {
0202     using Type = TypeAliasType;
0203 };
0204 
0205 template<CXCursorKind CK>
0206 struct IdType<CK, typename std::enable_if<CK == CXCursor_EnumDecl>::type>
0207 {
0208     using Type = EnumerationType;
0209 };
0210 
0211 template<CXCursorKind CK>
0212 struct IdType<CK, typename std::enable_if<CK == CXCursor_EnumConstantDecl>::type>
0213 {
0214     using Type = EnumeratorType;
0215 };
0216 //END IdType
0217 
0218 //BEGIN DeclType
0219 template<CXCursorKind CK, bool isDefinition, bool isClassMember, class Enable = void>
0220 struct DeclType;
0221 
0222 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0223 struct DeclType<CK, isDefinition, isInClass,
0224     typename std::enable_if<CursorKindTraits::isKDevDeclaration(CK, isInClass)>::type>
0225 {
0226     using Type = Declaration;
0227 };
0228 
0229 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0230 struct DeclType<CK, isDefinition, isInClass,
0231     typename std::enable_if<CK == CXCursor_MacroDefinition>::type>
0232 {
0233     using Type = MacroDefinition;
0234 };
0235 
0236 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0237 struct DeclType<CK, isDefinition, isInClass,
0238     typename std::enable_if<CursorKindTraits::isKDevForwardDeclaration(CK, isDefinition)>::type>
0239 {
0240     using Type = ForwardDeclaration;
0241 };
0242 
0243 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0244 struct DeclType<CK, isDefinition, isInClass,
0245     typename std::enable_if<CursorKindTraits::isKDevClassDeclaration(CK, isDefinition)>::type>
0246 {
0247     using Type = ClassDeclaration;
0248 };
0249 
0250 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0251 struct DeclType<CK, isDefinition, isInClass,
0252     typename std::enable_if<CursorKindTraits::isKDevClassFunctionDeclaration(CK, isInClass)>::type>
0253 {
0254     using Type = ClassFunctionDeclaration;
0255 };
0256 
0257 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0258 struct DeclType<CK, isDefinition, isInClass,
0259     typename std::enable_if<CursorKindTraits::isKDevFunctionDeclaration(CK, isDefinition, isInClass)>::type>
0260 {
0261     using Type = FunctionDeclaration;
0262 };
0263 
0264 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0265 struct DeclType<CK, isDefinition, isInClass,
0266     typename std::enable_if<CursorKindTraits::isKDevFunctionDefinition(CK, isDefinition, isInClass)>::type>
0267 {
0268     using Type = FunctionDefinition;
0269 };
0270 
0271 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0272 struct DeclType<CK, isDefinition, isInClass,
0273     typename std::enable_if<CursorKindTraits::isKDevNamespaceAliasDeclaration(CK, isDefinition)>::type>
0274 {
0275     using Type = NamespaceAliasDeclaration;
0276 };
0277 
0278 template<CXCursorKind CK, bool isDefinition, bool isInClass>
0279 struct DeclType<CK, isDefinition, isInClass,
0280     typename std::enable_if<CursorKindTraits::isKDevClassMemberDeclaration(CK, isInClass)>::type>
0281 {
0282     using Type = ClassMemberDeclaration;
0283 };
0284 //END DeclType
0285 
0286 //BEGIN CurrentContext
0287 struct CurrentContext
0288 {
0289     CurrentContext(DUContext* context, const QSet<DUContext*>& keepAliveContexts)
0290         : context(context)
0291         , keepAliveContexts(keepAliveContexts)
0292     {
0293         DUChainReadLocker lock;
0294         previousChildContexts = context->childContexts();
0295         previousChildDeclarations = context->localDeclarations();
0296     }
0297 
0298     ~CurrentContext()
0299     {
0300         DUChainWriteLocker lock;
0301         for (auto* childContext : qAsConst(previousChildContexts)) {
0302             if (!keepAliveContexts.contains(childContext)) {
0303                 delete childContext;
0304             }
0305         }
0306         qDeleteAll(previousChildDeclarations);
0307         if (resortChildContexts) {
0308             context->resortChildContexts();
0309         }
0310         if (resortLocalDeclarations) {
0311             context->resortLocalDeclarations();
0312         }
0313     }
0314 
0315     DUContext* context;
0316     // when updating, this contains child contexts of the current parent context
0317     QVector<DUContext*> previousChildContexts;
0318     // when updating, this contains contexts that must not be deleted
0319     QSet<DUContext*> keepAliveContexts;
0320     // when updating, this contains child declarations of the current parent context
0321     QVector<Declaration*> previousChildDeclarations;
0322 
0323     bool resortChildContexts = false;
0324     bool resortLocalDeclarations = false;
0325 };
0326 //END CurrentContext
0327 
0328 //BEGIN Visitor
0329 struct Visitor
0330 {
0331     explicit Visitor(CXTranslationUnit tu, CXFile file,
0332                      const IncludeFileContexts& includes, const bool update);
0333 
0334     AbstractType *makeType(CXType type, CXCursor parent);
0335     AbstractType::Ptr makeAbsType(CXType type, CXCursor parent)
0336     {
0337         return AbstractType::Ptr(makeType(type, parent));
0338     }
0339 
0340 //BEGIN dispatch*
0341     template<CXCursorKind CK,
0342       Decision IsInClass = CursorKindTraits::isInClass(CK),
0343       EnableIf<IsInClass == Decision::Maybe> = dummy>
0344     CXChildVisitResult dispatchCursor(CXCursor cursor, CXCursor parent);
0345 
0346     template<CXCursorKind CK,
0347         Decision IsInClass = CursorKindTraits::isInClass(CK),
0348         Decision IsDefinition = CursorKindTraits::isDefinition(CK),
0349         EnableIf<IsDefinition == Decision::Maybe && IsInClass != Decision::Maybe> = dummy>
0350     CXChildVisitResult dispatchCursor(CXCursor cursor, CXCursor parent);
0351 
0352     template<CXCursorKind CK,
0353         Decision IsInClass = CursorKindTraits::isInClass(CK),
0354         Decision IsDefinition = CursorKindTraits::isDefinition(CK),
0355         EnableIf<IsInClass != Decision::Maybe && IsDefinition != Decision::Maybe> = dummy>
0356     CXChildVisitResult dispatchCursor(CXCursor cursor, CXCursor parent);
0357 
0358     CXChildVisitResult dispatchTypeAliasTemplate(CXCursor cursor, CXCursor parent)
0359     {
0360         return CursorKindTraits::isClass(clang_getCursorKind(parent)) ? buildTypeAliasTemplateDecl<true>(cursor)
0361             : buildTypeAliasTemplateDecl<false>(cursor);
0362     }
0363 
0364     template<CXTypeKind TK>
0365     AbstractType *dispatchType(CXType type, CXCursor cursor)
0366     {
0367         IF_DEBUG(clangDebug() << "TK:" << type.kind;)
0368 
0369         auto kdevType = createType<TK>(type, cursor);
0370         if (kdevType) {
0371             setTypeModifiers<TK>(type, kdevType);
0372             setTypeSize(type, kdevType);
0373         }
0374         return kdevType;
0375     }
0376 //BEGIN dispatch*
0377 
0378 //BEGIN build*
0379     template<CXCursorKind CK, class DeclType, bool hasContext>
0380     CXChildVisitResult buildDeclaration(CXCursor cursor);
0381 
0382     template<bool IsInClass>
0383     CXChildVisitResult buildTypeAliasTemplateDecl(CXCursor cursor);
0384 
0385     CXChildVisitResult buildUse(CXCursor cursor);
0386     CXChildVisitResult buildMacroExpansion(CXCursor cursor);
0387 
0388     template<CXCursorKind CK>
0389     CXChildVisitResult buildCompoundStatement(CXCursor cursor);
0390     CXChildVisitResult buildCXXBaseSpecifier(CXCursor cursor);
0391     CXChildVisitResult buildParmDecl(CXCursor cursor);
0392 
0393 //END build*
0394 
0395 //BEGIN create*
0396     template<CXCursorKind CK, class DeclType>
0397     DeclType* createDeclarationCommon(CXCursor cursor, const Identifier& id)
0398     {
0399         auto range = ClangHelpers::cursorSpellingNameRange(cursor, id);
0400 
0401         if (id.isEmpty()) {
0402             // This is either an anonymous function parameter e.g.: void f(int);
0403             // Or anonymous struct/class/union e.g.: struct {} anonymous;
0404             // Set empty range for it
0405             range.end = range.start;
0406         }
0407 
0408         // check if cursor is inside a macro expansion
0409         auto clangRange = clang_Cursor_getSpellingNameRange(cursor, 0, 0);
0410         unsigned int expansionLocOffset;
0411         const auto spellingLocation = clang_getRangeStart(clangRange);
0412         clang_getExpansionLocation(spellingLocation, nullptr, nullptr, nullptr, &expansionLocOffset);
0413         if (m_macroExpansionLocations.contains(expansionLocOffset)) {
0414             unsigned int spellingLocOffset;
0415             clang_getSpellingLocation(spellingLocation, nullptr, nullptr, nullptr, &spellingLocOffset);
0416             // Set empty ranges for declarations inside macro expansion
0417             if (spellingLocOffset == expansionLocOffset) {
0418                 range.end = range.start;
0419             }
0420         }
0421 
0422         if (m_update) {
0423             const IndexedIdentifier indexedId(id);
0424             DUChainWriteLocker lock;
0425             auto it = m_parentContext->previousChildDeclarations.begin();
0426             while (it != m_parentContext->previousChildDeclarations.end()) {
0427                 auto decl = dynamic_cast<DeclType*>(*it);
0428                 if (decl && decl->indexedIdentifier() == indexedId) {
0429                     decl->setRange(range);
0430                     m_parentContext->resortLocalDeclarations = true;
0431                     setDeclData<CK>(cursor, decl);
0432                     m_cursorToDeclarationCache[cursor] = decl;
0433                     m_parentContext->previousChildDeclarations.erase(it);
0434                     return decl;
0435                 }
0436                 ++it;
0437             }
0438         }
0439         auto decl = new DeclType(range, nullptr);
0440         decl->setIdentifier(id);
0441 #if CINDEX_VERSION_MINOR >= 32
0442         decl->setExplicitlyTyped(clang_getCursorType(cursor).kind != CXType_Auto);
0443 #endif
0444         m_cursorToDeclarationCache[cursor] = decl;
0445         setDeclData<CK>(cursor, decl);
0446         {
0447             DUChainWriteLocker lock;
0448             decl->setContext(m_parentContext->context);
0449         }
0450         return decl;
0451     }
0452 
0453     template<CXCursorKind CK, class DeclType>
0454     Declaration* createDeclaration(CXCursor cursor, const Identifier& id, DUContext *context)
0455     {
0456         auto decl = createDeclarationCommon<CK, DeclType>(cursor, id);
0457         auto type = createType<CK>(cursor);
0458         if (type) {
0459             setTypeSize(clang_getCursorType(cursor), type);
0460         }
0461 
0462         DUChainWriteLocker lock;
0463         if (context)
0464             decl->setInternalContext(context);
0465         setDeclType<CK>(decl, type);
0466         setDeclInCtxtData<CK>(cursor, decl);
0467         return decl;
0468     }
0469 
0470     template<CXCursorKind CK, DUContext::ContextType Type>
0471     DUContext* createContext(CXCursor cursor, const QualifiedIdentifier& scopeId = {})
0472     {
0473         // wtf: why is the DUContext API requesting a QID when it needs a plain Id?!
0474         // see: testNamespace
0475         auto range = ClangRange(clang_getCursorExtent(cursor)).toRangeInRevision();
0476         DUChainWriteLocker lock;
0477         if (m_update) {
0478             const IndexedQualifiedIdentifier indexedScopeId(scopeId);
0479             auto it = m_parentContext->previousChildContexts.begin();
0480             while (it != m_parentContext->previousChildContexts.end()) {
0481                 auto ctx = *it;
0482                 if (ctx->type() == Type && ctx->indexedLocalScopeIdentifier() == indexedScopeId) {
0483                     ctx->setRange(range);
0484                     m_parentContext->resortChildContexts = true;
0485                     m_parentContext->previousChildContexts.erase(it);
0486                     return ctx;
0487                 }
0488                 ++it;
0489             }
0490         }
0491         //TODO: (..type, id..) constructor for DUContext?
0492         auto context = new ClangNormalDUContext(range, m_parentContext->context);
0493         context->setType(Type);
0494         context->setLocalScopeIdentifier(scopeId);
0495         if (Type == DUContext::Other || Type == DUContext::Function)
0496             context->setInSymbolTable(false);
0497 
0498         if (CK == CXCursor_CXXMethod) {
0499             CXCursor semParent = clang_getCursorSemanticParent(cursor);
0500             // only import the semantic parent if it differs from the lexical parent
0501             if (!clang_Cursor_isNull(semParent) && !clang_equalCursors(semParent, clang_getCursorLexicalParent(cursor))) {
0502                 auto semParentDecl = findDeclaration(semParent);
0503                 if (semParentDecl) {
0504                     contextImportDecl(context, semParentDecl);
0505                 }
0506             }
0507         }
0508         return context;
0509     }
0510 
0511     template<CXTypeKind TK, EnableIf<CursorKindTraits::integralType(TK) != IntegralType::TypeNotIntegralType> = dummy>
0512     AbstractType *createType(CXType, CXCursor)
0513     {
0514         // TODO: would be nice to instantiate a ConstantIntegralType here and set a value if possible
0515         // but unfortunately libclang doesn't offer API to that
0516         // also see https://marc.info/?l=cfe-commits&m=131609142917881&w=2
0517         return new IntegralType(CursorKindTraits::integralType(TK));
0518     }
0519 
0520     template <CXTypeKind TK, EnableIf<CursorKindTraits::isOpenCLType(TK)> = dummy>
0521     AbstractType* createType(CXType, CXCursor)
0522     {
0523         return new StructureType();
0524     }
0525 
0526 #if CINDEX_VERSION_MINOR >= 60
0527     template <CXTypeKind TK, EnableIf<TK == CXType_Atomic> = dummy>
0528     AbstractType* createType(CXType type, CXCursor parent)
0529     {
0530         // Decompose the atomic type.
0531         return makeType(clang_Type_getValueType(type), parent);
0532     }
0533 #endif
0534 
0535     template<CXTypeKind TK, EnableIf<CursorKindTraits::isPointerType(TK)> = dummy>
0536     AbstractType *createType(CXType type, CXCursor parent)
0537     {
0538         auto ptr = new PointerType;
0539         ptr->setBaseType(makeAbsType(clang_getPointeeType(type), parent));
0540         return ptr;
0541     }
0542 
0543     template<CXTypeKind TK, EnableIf<CursorKindTraits::isArrayType(TK)> = dummy>
0544     AbstractType *createType(CXType type, CXCursor parent)
0545     {
0546         auto arr = new ArrayType;
0547         arr->setDimension((TK == CXType_IncompleteArray || TK == CXType_VariableArray || TK == CXType_DependentSizedArray) ? 0 : clang_getArraySize(type));
0548         arr->setElementType(makeAbsType(clang_getArrayElementType(type), parent));
0549         return arr;
0550     }
0551 
0552     template<CXTypeKind TK, EnableIf<TK == CXType_RValueReference || TK == CXType_LValueReference> = dummy>
0553     AbstractType *createType(CXType type, CXCursor parent)
0554     {
0555         auto ref = new ReferenceType;
0556         ref->setIsRValue(type.kind == CXType_RValueReference);
0557         ref->setBaseType(makeAbsType(clang_getPointeeType(type), parent));
0558         return ref;
0559     }
0560 
0561     template<CXTypeKind TK, EnableIf<TK == CXType_FunctionProto || TK == CXType_FunctionNoProto> = dummy>
0562     AbstractType *createType(CXType type, CXCursor parent)
0563     {
0564         auto func = new FunctionType;
0565         func->setReturnType(makeAbsType(clang_getResultType(type), parent));
0566         const int numArgs = clang_getNumArgTypes(type);
0567         for (int i = 0; i < numArgs; ++i) {
0568             func->addArgument(makeAbsType(clang_getArgType(type, i), parent));
0569         }
0570 
0571         if (clang_isFunctionTypeVariadic(type)) {
0572             auto type = new DelayedType;
0573             static const auto id = IndexedTypeIdentifier(QStringLiteral("..."));
0574             type->setIdentifier(id);
0575             type->setKind(DelayedType::Unresolved);
0576             func->addArgument(AbstractType::Ptr(type));
0577         }
0578 
0579         return func;
0580     }
0581 
0582     template<CXTypeKind TK, EnableIf<TK == CXType_Record || TK == CXType_ObjCInterface || TK == CXType_ObjCClass> = dummy>
0583     AbstractType *createType(CXType type, CXCursor parent)
0584     {
0585         DeclarationPointer decl = findDeclaration(clang_getTypeDeclaration(type));
0586         DUChainReadLocker lock;
0587 
0588         if (!decl) {
0589             // probably a forward-declared type
0590             decl = ClangHelpers::findForwardDeclaration(type, m_parentContext->context, parent);
0591         }
0592 
0593         if (clang_Type_getNumTemplateArguments(type) != -1) {
0594             return createClassTemplateSpecializationType(type, decl);
0595         }
0596 
0597         auto t = new StructureType;
0598         if (decl) {
0599             t->setDeclaration(decl.data());
0600         } else {    // fallback, at least give the spelling to the user
0601             t->setDeclarationId(DeclarationId(IndexedQualifiedIdentifier(QualifiedIdentifier(ClangString(clang_getTypeSpelling(type)).toString()))));
0602         }
0603         return t;
0604     }
0605 
0606     template<CXTypeKind TK, EnableIf<TK == CXType_Enum> = dummy>
0607     AbstractType *createType(CXType type, CXCursor)
0608     {
0609         auto t = new EnumerationType;
0610         setIdTypeDecl(clang_getTypeDeclaration(type), t);
0611         return t;
0612     }
0613 
0614     template<CXTypeKind TK, EnableIf<TK == CXType_Typedef> = dummy>
0615     AbstractType *createType(CXType type, CXCursor parent)
0616     {
0617         auto t = new TypeAliasType;
0618         CXCursor location = clang_getTypeDeclaration(type);
0619         t->setType(makeAbsType(clang_getTypedefDeclUnderlyingType(location), parent));
0620         setIdTypeDecl(location, t);
0621         return t;
0622     }
0623 
0624     template<CXTypeKind TK, EnableIf<CursorKindTraits::delayedTypeName(TK) != nullptr> = dummy>
0625     AbstractType *createType(CXType, CXCursor /*parent*/)
0626     {
0627         auto t = new DelayedType;
0628         static const IndexedTypeIdentifier id(CursorKindTraits::delayedTypeName(TK));
0629         t->setIdentifier(id);
0630         return t;
0631     }
0632 
0633     template <CXTypeKind TK, EnableIf<TK == CXType_Vector || TK == CXType_ExtVector || TK == CXType_Complex> = dummy>
0634     AbstractType* createType(CXType type, CXCursor /*parent*/)
0635     {
0636         return createDelayedType(type);
0637     }
0638 
0639     template<CXTypeKind TK, EnableIf<TK == CXType_Unexposed> = dummy>
0640     AbstractType *createType(CXType type, CXCursor parent)
0641     {
0642         auto numTA = clang_Type_getNumTemplateArguments(type);
0643         // TODO: We should really expose more types to libclang!
0644         if (numTA != -1 && ClangString(clang_getTypeSpelling(type)).toString().contains(QLatin1Char('<'))) {
0645             return createClassTemplateSpecializationType(type);
0646         }
0647 
0648         // Maybe it's the ElaboratedType. E.g.: "struct Type foo();" or "NS::Type foo();" or "void foo(enum Enum e);" e.t.c.
0649         auto oldType = type;
0650 
0651         type = clang_getCanonicalType(type);
0652         bool isElaboratedType = type.kind != CXType_FunctionProto && type.kind != CXType_FunctionNoProto && type.kind != CXType_Unexposed && type.kind != CXType_Invalid && type.kind != CXType_Record;
0653 
0654         return !isElaboratedType ? createDelayedType(oldType) : makeType(type, parent);
0655     }
0656 
0657     template<CXCursorKind CK, EnableIf<CursorKindTraits::isIdentifiedType(CK) && !CursorKindTraits::isAliasType(CK) && CK != CXCursor_EnumConstantDecl> = dummy>
0658     typename IdType<CK>::Type *createType(CXCursor)
0659     {
0660         return new typename IdType<CK>::Type;
0661     }
0662 
0663     template<CXCursorKind CK, EnableIf<CK == CXCursor_EnumConstantDecl> = dummy>
0664     EnumeratorType *createType(CXCursor cursor)
0665     {
0666         auto type = new EnumeratorType;
0667         type->setValue<quint64>(clang_getEnumConstantDeclUnsignedValue(cursor));
0668         return type;
0669     }
0670 
0671     template<CXCursorKind CK, EnableIf<CursorKindTraits::isAliasType(CK)> = dummy>
0672     TypeAliasType *createType(CXCursor cursor)
0673     {
0674         auto type = new TypeAliasType;
0675         type->setType(makeAbsType(clang_getTypedefDeclUnderlyingType(cursor), cursor));
0676         return type;
0677     }
0678 
0679     template <CXCursorKind CK, EnableIf<CK == CXCursor_FunctionDecl> = dummy>
0680     AbstractType* createType(CXCursor cursor)
0681     {
0682         auto clangType = clang_getCursorType(cursor);
0683 
0684 #if CINDEX_VERSION_MINOR < 31
0685         if (clangType.kind == CXType_Unexposed) {
0686             // Clang sometimes can return CXType_Unexposed for CXType_FunctionProto kind. E.g. if it's AttributedType.
0687             return dispatchType<CXType_FunctionProto>(clangType, cursor);
0688         }
0689 #endif
0690 
0691         return makeType(clangType, cursor);
0692     }
0693 
0694     template<CXCursorKind CK, EnableIf<CK == CXCursor_LabelStmt> = dummy>
0695     AbstractType *createType(CXCursor)
0696     {
0697         auto t = new DelayedType;
0698         static const IndexedTypeIdentifier id(QStringLiteral("Label"));
0699         t->setIdentifier(id);
0700         return t;
0701     }
0702 
0703     template<CXCursorKind CK, EnableIf<!CursorKindTraits::isIdentifiedType(CK) && CK != CXCursor_FunctionDecl && CK != CXCursor_LabelStmt> = dummy>
0704     AbstractType *createType(CXCursor cursor)
0705     {
0706         auto clangType = clang_getCursorType(cursor);
0707         return makeType(clangType, cursor);
0708     }
0709 
0710 #if CINDEX_VERSION_MINOR >= 32
0711     template<CXTypeKind TK, EnableIf<TK == CXType_Auto> = dummy>
0712     AbstractType *createType(CXType type, CXCursor parent)
0713     {
0714         auto deducedType = clang_getCanonicalType(type);
0715         bool isDeduced = deducedType.kind != CXType_Invalid && deducedType.kind != CXType_Auto;
0716 
0717         return !isDeduced ? createDelayedType(type) : makeType(deducedType, parent);
0718     }
0719 #endif
0720 
0721 #if CINDEX_VERSION_MINOR >= 34
0722     template<CXTypeKind TK, EnableIf<TK == CXType_Elaborated> = dummy>
0723     AbstractType *createType(CXType type, CXCursor parent)
0724     {
0725         auto underyingType = clang_Type_getNamedType(type);
0726         return makeType(underyingType, parent);
0727     }
0728 #endif
0729 
0730     /// @param declaration an optional declaration that will be associated with created type
0731     AbstractType* createClassTemplateSpecializationType(CXType type, const DeclarationPointer& declaration = {})
0732     {
0733         auto numTA = clang_Type_getNumTemplateArguments(type);
0734         Q_ASSERT(numTA != -1);
0735 
0736         auto typeDecl = clang_getTypeDeclaration(type);
0737 
0738         if (!declaration && typeDecl.kind == CXCursor_NoDeclFound) {
0739             // clang_getTypeDeclaration doesn't handle all types, fall back to delayed type...
0740             return createDelayedType(type);
0741         }
0742 
0743         const QString tStr = ClangString(clang_getTypeSpelling(type)).toString();
0744         QVarLengthArray<QStringView, 8> typesStr;
0745         ParamIterator iter(u"<>", tStr);
0746 
0747         while (iter) {
0748             typesStr.push_back(*iter);
0749             ++iter;
0750         }
0751 
0752         auto cst = new ClassSpecializationType;
0753 
0754         for (int i = 0; i < numTA; i++) {
0755             auto argumentType = clang_Type_getTemplateArgumentAsType(type, i);
0756             AbstractType::Ptr currentType;
0757             if (argumentType.kind == CXType_Invalid) {
0758                 if(i >= typesStr.size()){
0759                     currentType = createDelayedType(argumentType);
0760                 } else {
0761                     auto t = new DelayedType;
0762                     t->setIdentifier(IndexedTypeIdentifier(typesStr[i]));
0763                     currentType = t;
0764                 }
0765             } else {
0766                 currentType = makeType(argumentType, typeDecl);
0767             }
0768 
0769             if (currentType) {
0770                 cst->addParameter(currentType->indexed());
0771             }
0772         }
0773 
0774         auto decl = declaration ? declaration : findDeclaration(typeDecl);
0775 
0776         DUChainReadLocker lock;
0777         if (decl) {
0778             cst->setDeclaration(decl.data());
0779         } else { // fallback, at least give the spelling to the user
0780             Identifier id(tStr);
0781             id.clearTemplateIdentifiers();
0782             cst->setDeclarationId(DeclarationId(IndexedQualifiedIdentifier(QualifiedIdentifier(id))));
0783         }
0784 
0785         return cst;
0786     }
0787 
0788 //END create*
0789 
0790 //BEGIN setDeclData
0791     template<CXCursorKind CK>
0792     void setDeclData(CXCursor cursor, Declaration *decl, bool setComment = true) const;
0793 
0794     template<CXCursorKind CK>
0795     void setDeclData(CXCursor cursor, MacroDefinition* decl) const;
0796 
0797     template<CXCursorKind CK>
0798     void setDeclData(CXCursor cursor, ClassMemberDeclaration *decl) const;
0799 
0800     template<CXCursorKind CK, EnableIf<CursorKindTraits::isClassTemplate(CK)> = dummy>
0801     void setDeclData(CXCursor cursor, ClassDeclaration* decl) const;
0802 
0803     template<CXCursorKind CK, EnableIf<!CursorKindTraits::isClassTemplate(CK)> = dummy>
0804     void setDeclData(CXCursor cursor, ClassDeclaration* decl) const;
0805 
0806     template<CXCursorKind CK>
0807     void setDeclData(CXCursor cursor, AbstractFunctionDeclaration* decl) const;
0808 
0809     template<CXCursorKind CK>
0810     void setDeclData(CXCursor cursor, ClassFunctionDeclaration* decl) const;
0811 
0812     template<CXCursorKind CK>
0813     void setDeclData(CXCursor cursor, FunctionDeclaration *decl, bool setComment = true) const;
0814 
0815     template<CXCursorKind CK>
0816     void setDeclData(CXCursor cursor, FunctionDefinition *decl) const;
0817 
0818     template<CXCursorKind CK>
0819     void setDeclData(CXCursor cursor, NamespaceAliasDeclaration *decl) const;
0820 
0821 //END setDeclData
0822 
0823 //BEGIN setDeclInCtxtData
0824     template<CXCursorKind CK>
0825     void setDeclInCtxtData(CXCursor, Declaration*)
0826     {
0827         //No-op
0828     }
0829 
0830     template<CXCursorKind CK>
0831     void setDeclInCtxtData(CXCursor cursor, ClassFunctionDeclaration *decl)
0832     {
0833         // HACK to retrieve function-constness
0834         // This looks like a bug in Clang -- In theory setTypeModifiers should take care of setting the const modifier
0835         // however, clang_isConstQualifiedType() for TK == CXType_FunctionProto always returns false
0836         // TODO: Debug further
0837         auto type = decl->abstractType();
0838         if (type) {
0839             if (clang_CXXMethod_isConst(cursor)) {
0840                 type->setModifiers(type->modifiers() | AbstractType::ConstModifier);
0841                 decl->setAbstractType(type);
0842             }
0843         }
0844     }
0845 
0846     template<CXCursorKind CK>
0847     void setDeclInCtxtData(CXCursor cursor, FunctionDefinition *def)
0848     {
0849         setDeclInCtxtData<CK>(cursor, static_cast<FunctionDeclaration*>(def));
0850 
0851         const CXCursor canon = clang_getCanonicalCursor(cursor);
0852         if (auto decl = findDeclaration(canon)) {
0853             def->setDeclaration(decl.data());
0854         }
0855     }
0856 //END setDeclInCtxtData
0857 
0858 //BEGIN setDeclType
0859     template<CXCursorKind CK>
0860     void setDeclType(Declaration *decl, typename IdType<CK>::Type *type)
0861     {
0862         setDeclType<CK>(decl, static_cast<IdentifiedType*>(type));
0863         setDeclType<CK>(decl, static_cast<AbstractType*>(type));
0864     }
0865 
0866     template<CXCursorKind CK>
0867     void setDeclType(Declaration *decl, IdentifiedType *type)
0868     {
0869         type->setDeclaration(decl);
0870     }
0871 
0872     template<CXCursorKind CK>
0873     void setDeclType(Declaration *decl, AbstractType *type)
0874     {
0875         decl->setAbstractType(AbstractType::Ptr(type));
0876     }
0877 //END setDeclType
0878 
0879     template<CXTypeKind TK>
0880     void setTypeModifiers(CXType type, AbstractType* kdevType) const;
0881     void setTypeSize(CXType type, AbstractType* kdevType) const;
0882 
0883     const CXFile m_file;
0884     const IncludeFileContexts &m_includes;
0885 
0886     DeclarationPointer findDeclaration(CXCursor cursor) const;
0887     void setIdTypeDecl(CXCursor typeCursor, IdentifiedType* idType) const;
0888 
0889     std::unordered_map<DUContext*, std::vector<CXCursor>> m_uses;
0890     /// At these location offsets (cf. @ref clang_getExpansionLocation) we encountered macro expansions
0891     QSet<unsigned int> m_macroExpansionLocations;
0892     mutable QHash<CXCursor, DeclarationPointer> m_cursorToDeclarationCache;
0893     CurrentContext *m_parentContext;
0894 
0895     const bool m_update;
0896 };
0897 
0898 //BEGIN setTypeModifiers
0899 template<CXTypeKind TK>
0900 void Visitor::setTypeModifiers(CXType type, AbstractType* kdevType) const
0901 {
0902     quint64 modifiers = 0;
0903     if (clang_isConstQualifiedType(type)) {
0904         modifiers |= AbstractType::ConstModifier;
0905     }
0906     if (clang_isVolatileQualifiedType(type)) {
0907         modifiers |= AbstractType::VolatileModifier;
0908     }
0909 #if CINDEX_VERSION_MINOR >= 60
0910     if (TK == CXType_Atomic) {
0911         modifiers |= AbstractType::AtomicModifier;
0912     }
0913 #endif
0914     if (TK == CXType_Short || TK == CXType_UShort) {
0915         modifiers |= AbstractType::ShortModifier;
0916     }
0917     if (TK == CXType_Long || TK == CXType_LongDouble || TK == CXType_ULong) {
0918         modifiers |= AbstractType::LongModifier;
0919     }
0920     if (TK == CXType_LongLong || TK == CXType_ULongLong) {
0921         modifiers |= AbstractType::LongLongModifier;
0922     }
0923     if (TK == CXType_SChar) {
0924         modifiers |= AbstractType::SignedModifier;
0925     }
0926     if (TK == CXType_UChar || TK == CXType_UInt || TK == CXType_UShort
0927         || TK == CXType_UInt128 || TK == CXType_ULong || TK == CXType_ULongLong)
0928     {
0929         modifiers |= AbstractType::UnsignedModifier;
0930     }
0931     kdevType->setModifiers(modifiers);
0932 }
0933 //END setTypeModifiers
0934 
0935 void Visitor::setTypeSize(CXType type, AbstractType* kdevType) const
0936 {
0937     if (CINDEX_VERSION_MINOR < 59) {
0938         // clang_Type_getSizeOf is unstable, see https://bugs.kde.org/show_bug.cgi?id=431391
0939         return;
0940     }
0941 
0942 
0943     if (kdevType->whichType() == AbstractType::TypeFunction)
0944         return;
0945 
0946     type = clang_getCanonicalType(type);
0947     if (type.kind == CXType_Elaborated)
0948         return;
0949 
0950     auto sizeOf = clang_Type_getSizeOf(type);
0951     if (sizeOf >= 0) {
0952         kdevType->setSizeOf(sizeOf);
0953 
0954         // clang_Type_getAlignOf sometimes crashes, so better guard
0955         // it and only call it when we got a size
0956         auto alignOf = clang_Type_getAlignOf(type);
0957         if (alignOf >= 0)
0958             kdevType->setAlignOf(alignOf);
0959     }
0960 }
0961 
0962 //BEGIN dispatchCursor
0963 
0964 template<CXCursorKind CK, Decision IsInClass,
0965          EnableIf<IsInClass == Decision::Maybe>>
0966 CXChildVisitResult Visitor::dispatchCursor(CXCursor cursor, CXCursor parent)
0967 {
0968     const bool decision = CursorKindTraits::isClass(clang_getCursorKind(parent));
0969     return decision ?
0970         dispatchCursor<CK, Decision::True, CursorKindTraits::isDefinition(CK)>(cursor, parent) :
0971         dispatchCursor<CK, Decision::False, CursorKindTraits::isDefinition(CK)>(cursor, parent);
0972 }
0973 
0974 template<CXCursorKind CK, Decision IsInClass, Decision IsDefinition,
0975          EnableIf<IsDefinition == Decision::Maybe && IsInClass != Decision::Maybe>>
0976 CXChildVisitResult Visitor::dispatchCursor(CXCursor cursor, CXCursor parent)
0977 {
0978     IF_DEBUG(clangDebug() << "IsInClass:" << IsInClass << "- isDefinition:" << IsDefinition;)
0979 
0980     const bool isDefinition = clang_isCursorDefinition(cursor);
0981     return isDefinition ?
0982         dispatchCursor<CK, IsInClass, Decision::True>(cursor, parent) :
0983         dispatchCursor<CK, IsInClass, Decision::False>(cursor, parent);
0984 }
0985 
0986 template<CXCursorKind CK, Decision IsInClass, Decision IsDefinition,
0987          EnableIf<IsInClass != Decision::Maybe && IsDefinition != Decision::Maybe>>
0988 CXChildVisitResult Visitor::dispatchCursor(CXCursor cursor, CXCursor parent)
0989 {
0990     IF_DEBUG(clangDebug() << "IsInClass:" << IsInClass << "- isDefinition:" << IsDefinition;)
0991 
0992     // We may end up visiting the same cursor twice in some cases
0993     // see discussion on https://git.reviewboard.kde.org/r/119526/
0994     // TODO: Investigate why this is happening in libclang
0995     if ((CursorKindTraits::isClass(CK) || CK == CXCursor_EnumDecl) &&
0996             clang_getCursorKind(parent) == CXCursor_VarDecl) {
0997         return CXChildVisit_Continue;
0998     }
0999 
1000     constexpr bool isClassMember = IsInClass == Decision::True;
1001     constexpr bool isDefinition = IsDefinition == Decision::True;
1002     // always build a context for class templates and functions, otherwise we "leak"
1003     // the function/template parameter declarations into the surrounding context,
1004     // which can lead to interesting bugs, like https://bugs.kde.org/show_bug.cgi?id=368067
1005     constexpr bool hasContext = isDefinition || CursorKindTraits::isFunction(CK) || CursorKindTraits::isClassTemplate(CK);
1006 
1007     return buildDeclaration<CK, typename DeclType<CK, isDefinition, isClassMember>::Type, hasContext>(cursor);
1008 }
1009 
1010 //END dispatchCursor
1011 
1012 //BEGIN setDeclData
1013 template<CXCursorKind CK>
1014 void Visitor::setDeclData(CXCursor cursor, Declaration *decl, bool setComment) const
1015 {
1016     if (setComment)
1017 #if CINDEX_VERSION_MINOR < 100 // FIXME https://bugs.llvm.org/show_bug.cgi?id=35333
1018         decl->setComment(KDevelop::formatComment(ClangString(clang_Cursor_getRawCommentText(cursor)).toByteArray()));
1019 #else
1020         decl->setComment(makeComment(clang_Cursor_getParsedComment(cursor)));
1021 #endif
1022     if (CursorKindTraits::isAliasType(CK)) {
1023         decl->setIsTypeAlias(true);
1024     }
1025     if (CK == CXCursor_Namespace)
1026         decl->setKind(Declaration::Namespace);
1027     if (CK == CXCursor_EnumDecl || CK == CXCursor_EnumConstantDecl || CursorKindTraits::isClass(CK) || CursorKindTraits::isAliasType(CK))
1028         decl->setKind(Declaration::Type);
1029 
1030     int isAlwaysDeprecated;
1031     clang_getCursorPlatformAvailability(cursor, &isAlwaysDeprecated, nullptr, nullptr, nullptr, nullptr, 0);
1032     decl->setDeprecated(isAlwaysDeprecated);
1033 }
1034 
1035 /// @return the position in @p contents where the macro identifier ends.
1036 static int skipMacroIdentifier(QStringView contents)
1037 {
1038     const auto isPartOfIdentifier = [](QChar c) {
1039         return c.isLetterOrNumber() || c == QLatin1Char('_');
1040     };
1041 
1042     int posAfterMacroId = 0;
1043     while (posAfterMacroId < contents.size()) {
1044         posAfterMacroId = std::find_if_not(contents.cbegin() + posAfterMacroId, contents.cend(), isPartOfIdentifier)
1045             - contents.cbegin();
1046 
1047         // Escaped newline characters can separate parts of a macro identifier or a macro identifier and '(' in a
1048         // function-like macro. And the escape character can be separated from the '\n' it escapes by any number of
1049         // whitespace characters other than '\n'. Furthermore, the same escaped-newline pattern can precede the macro
1050         // identifier. Simply skip such escape and whitespace characters as displaying them in a tooltip is not useful.
1051         if (posAfterMacroId == contents.size() || contents[posAfterMacroId] != QLatin1Char{'\\'}) {
1052             break; // no escape character => the macro identifier ends here
1053         }
1054         ++posAfterMacroId;
1055 
1056         bool foundNewLineCharacter = false;
1057         while (posAfterMacroId < contents.size() && contents[posAfterMacroId].isSpace()) {
1058             if (contents[posAfterMacroId++] == QLatin1Char{'\n'}) {
1059                 foundNewLineCharacter = true;
1060                 break;
1061             }
1062         }
1063         if (!foundNewLineCharacter) {
1064             // The escape character does not escape a newline character. The code probably does not compile. Go back to
1065             // the previous character to prevent the calling code from wrongly considering this macro function-like.
1066             --posAfterMacroId;
1067             break;
1068         }
1069     }
1070 
1071     return posAfterMacroId;
1072 }
1073 
1074 template<CXCursorKind CK>
1075 void Visitor::setDeclData(CXCursor cursor, MacroDefinition* decl) const
1076 {
1077     setDeclData<CK>(cursor, static_cast<Declaration*>(decl));
1078 
1079     if (m_update) {
1080         decl->clearParameters();
1081     }
1082 
1083     auto unit = clang_Cursor_getTranslationUnit(cursor);
1084     auto range = clang_getCursorExtent(cursor);
1085 
1086     // TODO: Quite lacking API in libclang here.
1087     // No way to find out if this macro is function-like or not
1088     // cf. https://clang.llvm.org/doxygen/classclang_1_1MacroInfo.html
1089     // And no way to get the actual definition text range
1090     // Should be quite easy to expose that in libclang, though
1091     // Let' still get some basic support for this and parse on our own, it's not that difficult
1092 
1093     // Macro definition strings get '\n' replaced with "<br/>", then are rendered as HTML, which ignores whitespace.
1094     // Newline characters are escaped in macro definiton C++ code. ClangUtils::getRawContents() preserves the escape
1095     // characters: its return value contains "\\\n". ClangUtils::getRawContents() removes whitespace, including the
1096     // escaped newline characters, at the end of the definition string.
1097     // Trim definition string views before passing them to MacroDefinition::setDefinition() to facilitate testing.
1098     // This trimming never strips newline characters in practice (shouldn't have been a problem even if it did).
1099     const auto setDefinition = [decl](QStringView definition) {
1100         decl->setDefinition(IndexedString{definition.trimmed()});
1101     };
1102 
1103     const QString rawContentsString = ClangUtils::getRawContents(unit, range);
1104     // Use a QStringView contents, because it works as fast as or faster than a QString in the code below.
1105     const QStringView contents(rawContentsString);
1106 
1107     const int posAfterMacroId = skipMacroIdentifier(contents);
1108 
1109     if (posAfterMacroId == contents.size() || contents[posAfterMacroId] != QLatin1Char{'('}) {
1110         // '(', a space, a tab or '/' (a comment) usually follows a macro identifier.
1111         // Compilers consider a macro function-like only if '(' immediately follows its identifier.
1112         decl->setFunctionLike(false);
1113         setDefinition(contents.mid(posAfterMacroId));
1114         return;
1115     }
1116 
1117     decl->setFunctionLike(true);
1118 
1119     // extract macro function parameters
1120     ParamIterator paramIt(u"()", contents, posAfterMacroId);
1121     while (paramIt) {
1122         decl->addParameter(IndexedString(*paramIt));
1123         ++paramIt;
1124     }
1125 
1126     const auto paramEndPosition = paramIt.position();
1127     if (paramEndPosition > 0 && contents[paramEndPosition - 1] == QLatin1Char{')'}) {
1128         setDefinition(contents.mid(paramEndPosition));
1129     } else {
1130         // unlikely: invalid macro definition, insert the complete #define statement
1131         const QString definition = QLatin1String("#define ") + contents;
1132         setDefinition(definition);
1133     }
1134 }
1135 
1136 template<CXCursorKind CK>
1137 void Visitor::setDeclData(CXCursor cursor, ClassMemberDeclaration *decl) const
1138 {
1139     setDeclData<CK>(cursor, static_cast<Declaration*>(decl));
1140     //A CXCursor_VarDecl in a class is static (otherwise it'd be a CXCursor_FieldDecl)
1141     if (CK == CXCursor_VarDecl)
1142         decl->setStatic(true);
1143     decl->setAccessPolicy(CursorKindTraits::kdevAccessPolicy(clang_getCXXAccessSpecifier(cursor)));
1144 
1145 #if CINDEX_VERSION_MINOR >= 32
1146     decl->setMutable(clang_CXXField_isMutable(cursor));
1147 #endif
1148 
1149 #if CINDEX_VERSION_MINOR >= 30
1150     auto offset = clang_Cursor_getOffsetOfField(cursor);
1151     if (offset >= 0) {
1152         decl->setBitOffsetOf(offset);
1153     }
1154 #endif
1155 
1156 #if CINDEX_VERSION_MINOR >= 16
1157     if (clang_Cursor_isBitField(cursor)) {
1158         const auto bitWidth = clang_getFieldDeclBitWidth(cursor);
1159         decl->setBitWidth(bitWidth == -1 ? ClassMemberDeclaration::ValueDependentBitWidth : bitWidth);
1160     } else {
1161         decl->setBitWidth(ClassMemberDeclaration::NotABitField);
1162     }
1163 #endif
1164 
1165     if (clang_isCursorDefinition(cursor)) {
1166         decl->setDeclarationIsDefinition(true);
1167     }
1168 }
1169 
1170 template<CXCursorKind CK, EnableIf<CursorKindTraits::isClassTemplate(CK)>>
1171 void Visitor::setDeclData(CXCursor cursor, ClassDeclaration* decl) const
1172 {
1173     CXCursorKind kind = clang_getTemplateCursorKind(cursor);
1174     switch (kind) {
1175         case CXCursor_UnionDecl: setDeclData<CXCursor_UnionDecl>(cursor, decl); break;
1176         case CXCursor_StructDecl: setDeclData<CXCursor_StructDecl>(cursor, decl); break;
1177         case CXCursor_ClassDecl: setDeclData<CXCursor_ClassDecl>(cursor, decl); break;
1178         default: Q_ASSERT(false); break;
1179     }
1180 }
1181 
1182 template<CXCursorKind CK, EnableIf<!CursorKindTraits::isClassTemplate(CK)>>
1183 void Visitor::setDeclData(CXCursor cursor, ClassDeclaration* decl) const
1184 {
1185     if (m_update) {
1186         decl->clearBaseClasses();
1187     }
1188     setDeclData<CK>(cursor, static_cast<ClassMemberDeclaration*>(decl));
1189     if (CK == CXCursor_UnionDecl)
1190         decl->setClassType(ClassDeclarationData::Union);
1191     if (CK == CXCursor_StructDecl)
1192         decl->setClassType(ClassDeclarationData::Struct);
1193     if (clang_isCursorDefinition(cursor)) {
1194         decl->setDeclarationIsDefinition(true);
1195     }
1196 }
1197 
1198 template<CXCursorKind CK>
1199 void Visitor::setDeclData(CXCursor cursor, AbstractFunctionDeclaration* decl) const
1200 {
1201     if (m_update) {
1202         decl->clearDefaultParameters();
1203     }
1204     // No setDeclData<CK>(...) here: AbstractFunctionDeclaration is an interface
1205     // TODO: Can we get the default arguments directly from Clang?
1206     // also see http://clang-developers.42468.n3.nabble.com/Finding-default-value-for-function-argument-with-clang-c-API-td4036919.html
1207     const QVector<QString> defaultArgs = ClangUtils::getDefaultArguments(cursor, ClangUtils::MinimumSize);
1208     for (const QString& defaultArg : defaultArgs) {
1209         decl->addDefaultParameter(IndexedString(defaultArg));
1210     }
1211 }
1212 
1213 template<CXCursorKind CK>
1214 void Visitor::setDeclData(CXCursor cursor, ClassFunctionDeclaration* decl) const
1215 {
1216     setDeclData<CK>(cursor, static_cast<AbstractFunctionDeclaration*>(decl));
1217     setDeclData<CK>(cursor, static_cast<ClassMemberDeclaration*>(decl));
1218     decl->setIsAbstract(clang_CXXMethod_isPureVirtual(cursor));
1219     decl->setStatic(clang_CXXMethod_isStatic(cursor));
1220     decl->setVirtual(clang_CXXMethod_isVirtual(cursor));
1221 
1222     // TODO: Set flags in one go? (needs new API in kdevplatform)
1223     const auto attributes = ClangUtils::specialAttributes(cursor);
1224     decl->setIsSignal(attributes & FunctionSignalFlag);
1225     decl->setIsSlot(attributes & FunctionSlotFlag);
1226     decl->setIsFinal(attributes & FinalFunctionFlag);
1227 }
1228 
1229 template<CXCursorKind CK>
1230 void Visitor::setDeclData(CXCursor cursor, FunctionDeclaration *decl, bool setComment) const
1231 {
1232     setDeclData<CK>(cursor, static_cast<AbstractFunctionDeclaration*>(decl));
1233     setDeclData<CK>(cursor, static_cast<Declaration*>(decl), setComment);
1234 }
1235 
1236 template<CXCursorKind CK>
1237 void Visitor::setDeclData(CXCursor cursor, FunctionDefinition *decl) const
1238 {
1239     bool setComment = clang_equalCursors(clang_getCanonicalCursor(cursor), cursor);
1240     setDeclData<CK>(cursor, static_cast<FunctionDeclaration*>(decl), setComment);
1241 }
1242 
1243 template<CXCursorKind CK>
1244 void Visitor::setDeclData(CXCursor cursor, NamespaceAliasDeclaration *decl) const
1245 {
1246     setDeclData<CK>(cursor, static_cast<Declaration*>(decl));
1247     clang_visitChildren(cursor, [] (CXCursor cursor, CXCursor parent, CXClientData data) -> CXChildVisitResult {
1248         if (clang_getCursorKind(cursor) == CXCursor_NamespaceRef) {
1249             const auto id = QualifiedIdentifier(ClangString(clang_getCursorSpelling(cursor)).toString());
1250             reinterpret_cast<NamespaceAliasDeclaration*>(data)->setImportIdentifier(id);
1251             return CXChildVisit_Break;
1252         } else {
1253             return visitCursor(cursor, parent, data);
1254         }
1255     }, decl);
1256 }
1257 //END setDeclData
1258 
1259 //BEGIN build*
1260 template<CXCursorKind CK, class DeclType, bool hasContext>
1261 CXChildVisitResult Visitor::buildDeclaration(CXCursor cursor)
1262 {
1263     auto id = makeId(cursor);
1264     if (CK == CXCursor_UnexposedDecl && id.isEmpty()) {
1265         // skip unexposed declarations that have no identifier set
1266         // this is useful to skip e.g. friend declarations
1267         return CXChildVisit_Recurse;
1268     }
1269     IF_DEBUG(clangDebug() << "id:" << id << "- CK:" << CK << "- DeclType:" << typeid(DeclType).name() << "- hasContext:" << hasContext;)
1270 
1271     // Code path for class declarations that may be defined "out-of-line", e.g.
1272     // "SomeNameSpace::SomeClass {};"
1273     QScopedPointer<CurrentContext> helperContext;
1274     if (CursorKindTraits::isClass(CK) || CursorKindTraits::isFunction(CK)) {
1275         const auto lexicalParent = clang_getCursorLexicalParent(cursor);
1276         const auto semanticParent = clang_getCursorSemanticParent(cursor);
1277         const bool isOutOfLine = !clang_equalCursors(lexicalParent, semanticParent);
1278         if (isOutOfLine) {
1279             const QString scope = ClangUtils::getScope(cursor);
1280             auto context = createContext<CK, DUContext::Helper>(cursor, QualifiedIdentifier(scope));
1281             helperContext.reset(new CurrentContext(context, m_parentContext->keepAliveContexts));
1282         }
1283     }
1284 
1285     // if helperContext is null, this is a no-op
1286     PushValue<CurrentContext*> pushCurrent(m_parentContext, helperContext.isNull() ? m_parentContext : helperContext.data());
1287 
1288     if (hasContext) {
1289         auto context = createContext<CK, CursorKindTraits::contextType(CK)>(cursor, QualifiedIdentifier(id));
1290         createDeclaration<CK, DeclType>(cursor, id, context);
1291         CurrentContext newParent(context, m_parentContext->keepAliveContexts);
1292         PushValue<CurrentContext*> pushCurrent(m_parentContext, &newParent);
1293         clang_visitChildren(cursor, &visitCursor, this);
1294         return CXChildVisit_Continue;
1295     }
1296     createDeclaration<CK, DeclType>(cursor, id, nullptr);
1297     return CXChildVisit_Recurse;
1298 }
1299 
1300 CXChildVisitResult Visitor::buildParmDecl(CXCursor cursor)
1301 {
1302     return buildDeclaration<CXCursor_ParmDecl, typename DeclType<CXCursor_ParmDecl, false, false>::Type, false>(cursor);
1303 }
1304 
1305 CXChildVisitResult Visitor::buildUse(CXCursor cursor)
1306 {
1307     m_uses[m_parentContext->context].push_back(cursor);
1308     return cursor.kind == CXCursor_DeclRefExpr || cursor.kind == CXCursor_MemberRefExpr ?
1309         CXChildVisit_Recurse : CXChildVisit_Continue;
1310 }
1311 
1312 CXChildVisitResult Visitor::buildMacroExpansion(CXCursor cursor)
1313 {
1314     buildUse(cursor);
1315 
1316     // cache that we encountered a macro expansion at this location
1317     unsigned int offset;
1318     clang_getSpellingLocation(clang_getCursorLocation(cursor), nullptr, nullptr, nullptr, &offset);
1319     m_macroExpansionLocations << offset;
1320 
1321     return CXChildVisit_Recurse;
1322 }
1323 
1324 template<CXCursorKind CK>
1325 CXChildVisitResult Visitor::buildCompoundStatement(CXCursor cursor)
1326 {
1327     if (CK == CXCursor_LambdaExpr || m_parentContext->context->type() == DUContext::Function)
1328     {
1329         auto context = createContext<CK, CK == CXCursor_LambdaExpr ? DUContext::Function : DUContext::Other>(cursor);
1330         CurrentContext newParent(context, m_parentContext->keepAliveContexts);
1331         PushValue<CurrentContext*> pushCurrent(m_parentContext, &newParent);
1332         clang_visitChildren(cursor, &visitCursor, this);
1333         return CXChildVisit_Continue;
1334     }
1335     return CXChildVisit_Recurse;
1336 }
1337 
1338 CXChildVisitResult Visitor::buildCXXBaseSpecifier(CXCursor cursor)
1339 {
1340     auto currentContext = m_parentContext->context;
1341 
1342     bool virtualInherited = clang_isVirtualBase(cursor);
1343     Declaration::AccessPolicy access = CursorKindTraits::kdevAccessPolicy(clang_getCXXAccessSpecifier(cursor));
1344 
1345     auto classDeclCursor = clang_getCursorReferenced(cursor);
1346     auto decl = findDeclaration(classDeclCursor);
1347     if (!decl) {
1348         // this happens for templates with template-dependent base classes e.g. - dunno whether we can/should do more here
1349         clangDebug() << "failed to find declaration for base specifier:" << clang_getCursorDisplayName(cursor);
1350         return CXChildVisit_Recurse;
1351     }
1352 
1353     DUChainWriteLocker lock;
1354     contextImportDecl(currentContext, decl);
1355     auto classDecl = dynamic_cast<ClassDeclaration*>(currentContext->owner());
1356     Q_ASSERT(classDecl);
1357 
1358     classDecl->addBaseClass({decl->indexedType(), access, virtualInherited});
1359     return CXChildVisit_Recurse;
1360 }
1361 
1362 template<bool IsInClass>
1363 CXChildVisitResult Visitor::buildTypeAliasTemplateDecl(CXCursor cursor)
1364 {
1365     auto aliasDecl = findEmbeddedTypeAlias(cursor);
1366     // NOTE: using aliasDecl here averts having to add a workaround to makeId()
1367     auto id = makeId(aliasDecl);
1368     // create template context to prevent leaking child template params
1369     auto context = createContext<CXCursor_TypeAliasTemplateDecl, DUContext::Template>(cursor, QualifiedIdentifier(id));
1370     using DeclType = typename DeclType<CXCursor_TypeAliasDecl, false, IsInClass>::Type;
1371     createDeclaration<CXCursor_TypeAliasDecl, DeclType>(aliasDecl, id, context);
1372     CurrentContext newParent(context, m_parentContext->keepAliveContexts);
1373     PushValue<CurrentContext*> pushCurrent(m_parentContext, &newParent);
1374     clang_visitChildren(cursor, [] (CXCursor cursor, CXCursor parent, CXClientData data) {
1375         // NOTE: immediately recurse into embedded alias decl
1376         return clang_getCursorKind(cursor) == CXCursor_TypeAliasDecl ?
1377             CXChildVisit_Recurse : visitCursor(cursor, parent, data);
1378     }, this);
1379     return CXChildVisit_Continue;
1380 }
1381 //END build*
1382 
1383 DeclarationPointer Visitor::findDeclaration(CXCursor cursor) const
1384 {
1385     const auto it = m_cursorToDeclarationCache.constFind(cursor);
1386     if (it != m_cursorToDeclarationCache.constEnd()) {
1387         return *it;
1388     }
1389 
1390     // fallback, and cache result
1391     auto decl = ClangHelpers::findDeclaration(cursor, m_includes);
1392 
1393     m_cursorToDeclarationCache.insert(cursor, decl);
1394     return decl;
1395 }
1396 
1397 void Visitor::setIdTypeDecl(CXCursor typeCursor, IdentifiedType* idType) const
1398 {
1399     DeclarationPointer decl = findDeclaration(typeCursor);
1400     DUChainReadLocker lock;
1401     if (decl) {
1402         idType->setDeclaration(decl.data());
1403     }
1404 }
1405 
1406 AbstractType *Visitor::makeType(CXType type, CXCursor parent)
1407 {
1408 #define UseKind(TypeKind) case TypeKind: return dispatchType<TypeKind>(type, parent)
1409     switch (type.kind) {
1410     UseKind(CXType_Void);
1411     UseKind(CXType_Bool);
1412     UseKind(CXType_Short);
1413     UseKind(CXType_UShort);
1414     UseKind(CXType_Int);
1415     UseKind(CXType_UInt);
1416     UseKind(CXType_Long);
1417     UseKind(CXType_ULong);
1418     UseKind(CXType_LongLong);
1419     UseKind(CXType_ULongLong);
1420     UseKind(CXType_Half);
1421     UseKind(CXType_Float);
1422     UseKind(CXType_LongDouble);
1423     UseKind(CXType_Double);
1424     UseKind(CXType_Char_U);
1425     UseKind(CXType_Char_S);
1426     UseKind(CXType_UChar);
1427     UseKind(CXType_SChar);
1428     UseKind(CXType_Char16);
1429     UseKind(CXType_Char32);
1430     UseKind(CXType_Pointer);
1431     UseKind(CXType_BlockPointer);
1432     UseKind(CXType_MemberPointer);
1433     UseKind(CXType_ObjCObjectPointer);
1434     UseKind(CXType_ConstantArray);
1435     UseKind(CXType_VariableArray);
1436     UseKind(CXType_IncompleteArray);
1437     UseKind(CXType_DependentSizedArray);
1438     UseKind(CXType_LValueReference);
1439     UseKind(CXType_RValueReference);
1440     UseKind(CXType_FunctionNoProto);
1441     UseKind(CXType_FunctionProto);
1442     UseKind(CXType_Record);
1443     UseKind(CXType_Enum);
1444     UseKind(CXType_Typedef);
1445     UseKind(CXType_Int128);
1446     UseKind(CXType_UInt128);
1447     UseKind(CXType_Vector);
1448     UseKind(CXType_ExtVector);
1449     UseKind(CXType_Unexposed);
1450     UseKind(CXType_WChar);
1451     UseKind(CXType_ObjCInterface);
1452     UseKind(CXType_ObjCId);
1453     UseKind(CXType_ObjCClass);
1454     UseKind(CXType_ObjCSel);
1455     UseKind(CXType_NullPtr);
1456 #if CINDEX_VERSION_MINOR >= 32
1457     UseKind(CXType_Auto);
1458 #endif
1459 #if CINDEX_VERSION_MINOR >= 34
1460     UseKind(CXType_Elaborated);
1461 #endif
1462 #if CINDEX_VERSION_MINOR >= 38
1463     UseKind(CXType_Float128);
1464 #endif
1465 #if CINDEX_VERSION_MINOR >= 60
1466     UseKind(CXType_Atomic);
1467 #endif
1468     UseKind(CXType_Complex);
1469     UseKind(CXType_OCLImage1dRO);
1470     UseKind(CXType_OCLImage1dArrayRO);
1471     UseKind(CXType_OCLImage1dBufferRO);
1472     UseKind(CXType_OCLImage2dRO);
1473     UseKind(CXType_OCLImage2dArrayRO);
1474     UseKind(CXType_OCLImage2dDepthRO);
1475     UseKind(CXType_OCLImage2dArrayDepthRO);
1476     UseKind(CXType_OCLImage2dMSAARO);
1477     UseKind(CXType_OCLImage2dArrayMSAARO);
1478     UseKind(CXType_OCLImage2dMSAADepthRO);
1479     UseKind(CXType_OCLImage2dArrayMSAADepthRO);
1480     UseKind(CXType_OCLImage3dRO);
1481     UseKind(CXType_OCLImage1dWO);
1482     UseKind(CXType_OCLImage1dArrayWO);
1483     UseKind(CXType_OCLImage1dBufferWO);
1484     UseKind(CXType_OCLImage2dWO);
1485     UseKind(CXType_OCLImage2dArrayWO);
1486     UseKind(CXType_OCLImage2dDepthWO);
1487     UseKind(CXType_OCLImage2dArrayDepthWO);
1488     UseKind(CXType_OCLImage2dMSAAWO);
1489     UseKind(CXType_OCLImage2dArrayMSAAWO);
1490     UseKind(CXType_OCLImage2dMSAADepthWO);
1491     UseKind(CXType_OCLImage2dArrayMSAADepthWO);
1492     UseKind(CXType_OCLImage3dWO);
1493     UseKind(CXType_OCLImage1dRW);
1494     UseKind(CXType_OCLImage1dArrayRW);
1495     UseKind(CXType_OCLImage1dBufferRW);
1496     UseKind(CXType_OCLImage2dRW);
1497     UseKind(CXType_OCLImage2dArrayRW);
1498     UseKind(CXType_OCLImage2dDepthRW);
1499     UseKind(CXType_OCLImage2dArrayDepthRW);
1500     UseKind(CXType_OCLImage2dMSAARW);
1501     UseKind(CXType_OCLImage2dArrayMSAARW);
1502     UseKind(CXType_OCLImage2dMSAADepthRW);
1503     UseKind(CXType_OCLImage2dArrayMSAADepthRW);
1504     UseKind(CXType_OCLImage3dRW);
1505     UseKind(CXType_OCLSampler);
1506     UseKind(CXType_OCLEvent);
1507     UseKind(CXType_OCLQueue);
1508     UseKind(CXType_OCLReserveID);
1509     case CXType_Invalid:
1510         return nullptr;
1511     default:
1512         qCWarning(KDEV_CLANG) << "Unhandled type:" << type.kind << clang_getTypeSpelling(type);
1513         return nullptr;
1514     }
1515 #undef UseKind
1516 }
1517 
1518 RangeInRevision rangeInRevisionForUse(CXCursor cursor, CXCursorKind referencedCursorKind, CXSourceRange useRange, const QSet<unsigned int>& macroExpansionLocations)
1519 {
1520     auto range = ClangRange(useRange).toRangeInRevision();
1521 
1522     //TODO: Fix in clang, happens for operator<<, operator<, probably more
1523     if (clang_Range_isNull(useRange)) {
1524         useRange = clang_getCursorExtent(cursor);
1525         range = ClangRange(useRange).toRangeInRevision();
1526     }
1527 
1528     if (referencedCursorKind == CXCursor_ConversionFunction) {
1529         range.end = range.start;
1530         range.start.column--;
1531     }
1532 
1533     // For uses inside macro expansions, create an empty use range at the spelling location
1534     // the empty range is required in order to not "overlap" the macro expansion range
1535     // and to allow proper navigation for the macro expansion
1536     // also see JSON test 'macros.cpp'
1537     if (clang_getCursorKind(cursor) != CXCursor_MacroExpansion) {
1538         unsigned int expansionLocOffset;
1539         const auto spellingLocation = clang_getRangeStart(useRange);
1540         clang_getExpansionLocation(spellingLocation, nullptr, nullptr, nullptr, &expansionLocOffset);
1541         if (macroExpansionLocations.contains(expansionLocOffset)) {
1542             unsigned int spellingLocOffset;
1543             clang_getSpellingLocation(spellingLocation, nullptr, nullptr, nullptr, &spellingLocOffset);
1544             if (spellingLocOffset == expansionLocOffset) {
1545                 range.end = range.start;
1546             }
1547         }
1548     } else {
1549         // Workaround for wrong use range returned by clang for macro expansions
1550         const auto contents = ClangUtils::getRawContents(clang_Cursor_getTranslationUnit(cursor), useRange);
1551         const int firstOpeningParen = contents.indexOf(QLatin1Char('('));
1552         if (firstOpeningParen != -1) {
1553             range.end.column = range.start.column + firstOpeningParen;
1554             range.end.line = range.start.line;
1555         }
1556     }
1557 
1558     return range;
1559 }
1560 
1561 Visitor::Visitor(CXTranslationUnit tu, CXFile file,
1562                  const IncludeFileContexts& includes, const bool update)
1563     : m_file(file)
1564     , m_includes(includes)
1565     , m_parentContext(nullptr)
1566     , m_update(update)
1567 {
1568     CXCursor tuCursor = clang_getTranslationUnitCursor(tu);
1569     auto top = includes[file];
1570 
1571     // when updating, this contains child contexts that should be kept alive
1572     // even when they are not part of the AST anymore
1573     // this is required for some assistants, such as the signature assistant
1574     QSet<DUContext*> keepAliveContexts;
1575     {
1576         DUChainReadLocker lock;
1577         const auto problems = top->problems();
1578         for (const auto& problem : problems) {
1579             const auto& desc = problem->description();
1580             if (desc.startsWith(QLatin1String("Return type of out-of-line definition of '"))
1581                 && desc.endsWith(QLatin1String("' differs from that in the declaration"))) {
1582                 auto ctx = top->findContextAt(problem->range().start);
1583                 // keep the context and its parents alive
1584                 // this also keeps declarations in this context alive
1585                 while (ctx) {
1586                     keepAliveContexts << ctx;
1587                     ctx = ctx->parentContext();
1588                 }
1589             }
1590         }
1591     }
1592 
1593     CurrentContext parent(top, keepAliveContexts);
1594     m_parentContext = &parent;
1595     clang_visitChildren(tuCursor, &visitCursor, this);
1596 
1597     if (m_update) {
1598         DUChainWriteLocker lock;
1599         top->deleteUsesRecursively();
1600     }
1601     for (const auto &contextUses : m_uses) {
1602         for (const auto &cursor : contextUses.second) {
1603             auto referenced = referencedCursor(cursor);
1604             if (clang_Cursor_isNull(referenced)) {
1605                 continue;
1606             }
1607             // first, try the canonical referenced cursor
1608             // this is important to get the correct function declaration e.g.
1609             auto canonicalReferenced = clang_getCanonicalCursor(referenced);
1610             auto used = findDeclaration(canonicalReferenced);
1611 
1612             if (!used) {
1613                 // if the above failed, try the non-canonicalized version as a fallback
1614                 // this is required for friend declarations that occur before
1615                 // the real declaration. there, the canonical cursor points to
1616                 // the friend declaration which is not what we are looking for
1617                 used = findDeclaration(referenced);
1618             }
1619 
1620             if (!used) { // as a last resort, try to resolve the forward declaration
1621                 DUChainReadLocker lock;
1622                 DeclarationPointer decl = ClangHelpers::findForwardDeclaration(clang_getCursorType(referenced), contextUses.first, referenced);
1623                 used = decl;
1624                 if (!used) {
1625                     continue;
1626                 }
1627             }
1628 
1629 #if CINDEX_VERSION_MINOR >= 29
1630             if (clang_Cursor_getNumTemplateArguments(referenced) >= 0) {
1631                 // Ideally, we don't need this, but for function templates clang_getCanonicalCursor returns a function definition
1632                 // See also the testUsesCreatedForDeclarations test
1633                 DUChainReadLocker lock;
1634                 used = DUChainUtils::declarationForDefinition(used.data());
1635             }
1636 #endif
1637 
1638             const auto useRange = clang_getCursorReferenceNameRange(cursor, 0, 0);
1639             const auto range = rangeInRevisionForUse(cursor, referenced.kind, useRange, m_macroExpansionLocations);
1640 
1641             DUChainWriteLocker lock;
1642             auto usedIndex = top->indexForUsedDeclaration(used.data());
1643             contextUses.first->createUse(usedIndex, range);
1644         }
1645     }
1646 }
1647 
1648 //END Visitor
1649 
1650 CXChildVisitResult visitCursor(CXCursor cursor, CXCursor parent, CXClientData data)
1651 {
1652     auto *visitor = static_cast<Visitor*>(data);
1653 
1654     const auto kind = clang_getCursorKind(cursor);
1655 
1656     auto location = clang_getCursorLocation(cursor);
1657     CXFile file;
1658     clang_getFileLocation(location, &file, nullptr, nullptr, nullptr);
1659     if (!ClangUtils::isFileEqual(file, visitor->m_file)) {
1660         // don't skip MemberRefExpr with invalid location, see also:
1661         // http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-May/043114.html
1662         const auto invalidMemberRefExpr = !file && kind == CXCursor_MemberRefExpr;
1663         // also don't skip unexposed declarations, which may e.g. be an `extern "C"` directive
1664         const auto unexposedDecl = file && kind == CXCursor_UnexposedDecl;
1665         if (!invalidMemberRefExpr && !unexposedDecl) {
1666             return CXChildVisit_Continue;
1667         }
1668     }
1669 
1670 #define UseCursorKind(CursorKind, ...) case CursorKind: return visitor->dispatchCursor<CursorKind>(__VA_ARGS__);
1671     switch (kind)
1672     {
1673     UseCursorKind(CXCursor_UnexposedDecl, cursor, parent);
1674     UseCursorKind(CXCursor_StructDecl, cursor, parent);
1675     UseCursorKind(CXCursor_UnionDecl, cursor, parent);
1676     UseCursorKind(CXCursor_ClassDecl, cursor, parent);
1677     UseCursorKind(CXCursor_EnumDecl, cursor, parent);
1678     UseCursorKind(CXCursor_FieldDecl, cursor, parent);
1679     UseCursorKind(CXCursor_EnumConstantDecl, cursor, parent);
1680     UseCursorKind(CXCursor_FunctionDecl, cursor, parent);
1681     UseCursorKind(CXCursor_VarDecl, cursor, parent);
1682     UseCursorKind(CXCursor_TypeAliasDecl, cursor, parent);
1683     UseCursorKind(CXCursor_TypedefDecl, cursor, parent);
1684     UseCursorKind(CXCursor_CXXMethod, cursor, parent);
1685     UseCursorKind(CXCursor_Namespace, cursor, parent);
1686     UseCursorKind(CXCursor_NamespaceAlias, cursor, parent);
1687     UseCursorKind(CXCursor_Constructor, cursor, parent);
1688     UseCursorKind(CXCursor_Destructor, cursor, parent);
1689     UseCursorKind(CXCursor_ConversionFunction, cursor, parent);
1690     UseCursorKind(CXCursor_TemplateTypeParameter, cursor, parent);
1691     UseCursorKind(CXCursor_NonTypeTemplateParameter, cursor, parent);
1692     UseCursorKind(CXCursor_TemplateTemplateParameter, cursor, parent);
1693     UseCursorKind(CXCursor_FunctionTemplate, cursor, parent);
1694     UseCursorKind(CXCursor_ClassTemplate, cursor, parent);
1695     UseCursorKind(CXCursor_ClassTemplatePartialSpecialization, cursor, parent);
1696     UseCursorKind(CXCursor_ObjCInterfaceDecl, cursor, parent);
1697     UseCursorKind(CXCursor_ObjCCategoryDecl, cursor, parent);
1698     UseCursorKind(CXCursor_ObjCProtocolDecl, cursor, parent);
1699     UseCursorKind(CXCursor_ObjCPropertyDecl, cursor, parent);
1700     UseCursorKind(CXCursor_ObjCIvarDecl, cursor, parent);
1701     UseCursorKind(CXCursor_ObjCInstanceMethodDecl, cursor, parent);
1702     UseCursorKind(CXCursor_ObjCClassMethodDecl, cursor, parent);
1703     UseCursorKind(CXCursor_ObjCImplementationDecl, cursor, parent);
1704     UseCursorKind(CXCursor_ObjCCategoryImplDecl, cursor, parent);
1705     UseCursorKind(CXCursor_MacroDefinition, cursor, parent);
1706     UseCursorKind(CXCursor_LabelStmt, cursor, parent);
1707     case CXCursor_TypeRef:
1708     case CXCursor_TemplateRef:
1709     case CXCursor_NamespaceRef:
1710     case CXCursor_MemberRef:
1711     case CXCursor_LabelRef:
1712     case CXCursor_OverloadedDeclRef:
1713     case CXCursor_VariableRef:
1714     case CXCursor_DeclRefExpr:
1715     case CXCursor_MemberRefExpr:
1716     case CXCursor_ObjCClassRef:
1717         return visitor->buildUse(cursor);
1718     case CXCursor_MacroExpansion:
1719         return visitor->buildMacroExpansion(cursor);
1720     case CXCursor_CompoundStmt:
1721         return visitor->buildCompoundStatement<CXCursor_CompoundStmt>(cursor);
1722     case CXCursor_LambdaExpr:
1723         return visitor->buildCompoundStatement<CXCursor_LambdaExpr>(cursor);
1724     case CXCursor_CXXBaseSpecifier:
1725         return visitor->buildCXXBaseSpecifier(cursor);
1726     case CXCursor_ParmDecl:
1727         return visitor->buildParmDecl(cursor);
1728     // TODO: fix upstream and then just adapt this to UseCursorKind()
1729     case CXCursor_TypeAliasTemplateDecl:
1730         return visitor->dispatchTypeAliasTemplate(cursor, parent);
1731     default:
1732         return CXChildVisit_Recurse;
1733     }
1734 }
1735 
1736 }
1737 
1738 namespace Builder {
1739 
1740 void visit(CXTranslationUnit tu, CXFile file, const IncludeFileContexts& includes, const bool update)
1741 {
1742     Visitor visitor(tu, file, includes, update);
1743 }
1744 
1745 }