Line | Count | Source (jump to first uncovered line) |
1 | //===- ExtractAPI/TypedefUnderlyingTypeResolver.cpp -------------*- C++ -*-===// | |
2 | // | |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
4 | // See https://llvm.org/LICENSE.txt for license information. | |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
6 | // | |
7 | //===----------------------------------------------------------------------===// | |
8 | /// | |
9 | /// \file | |
10 | /// This file implements UnderlyingTypeResolver. | |
11 | /// | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
14 | #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" | |
15 | #include "clang/Index/USRGeneration.h" | |
16 | ||
17 | using namespace clang; | |
18 | using namespace extractapi; | |
19 | ||
20 | const NamedDecl * | |
21 | 41 | TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const { |
22 | 41 | const NamedDecl *TypeDecl = nullptr; |
23 | ||
24 | 41 | const TypedefType *TypedefTy = Type->getAs<TypedefType>(); |
25 | 41 | if (TypedefTy) |
26 | 27 | TypeDecl = TypedefTy->getDecl(); |
27 | 41 | if (const TagType *TagTy = Type->getAs<TagType>()) { |
28 | 21 | TypeDecl = TagTy->getDecl(); |
29 | 21 | } else |
30 | 20 | Type->getAs<ObjCInterfaceType>()) { |
31 | 0 | TypeDecl = ObjCITy->getDecl(); |
32 | 0 | } |
33 | ||
34 | 41 | if (TypeDecl && |
35 | // if this is a typedef to another typedef, use the typedef's decl for the | |
36 | // USR - this will actually be in the output, unlike a typedef to an | |
37 | // anonymous decl | |
38 | 27 | const TypedefNameDecl *TypedefDecl = TypedefTy->getDecl(); |
39 | 27 | if (TypedefDecl->getUnderlyingType()->isTypedefNameType()) |
40 | 11 | TypeDecl = TypedefDecl; |
41 | 27 | } |
42 | ||
43 | 41 | return TypeDecl; |
44 | 41 | } |
45 | ||
46 | SymbolReference | |
47 | TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type, | |
48 | 21 | APISet &API) const { |
49 | 21 | std::string TypeName = Type.getAsString(); |
50 | 21 | SmallString<128> TypeUSR; |
51 | 21 | const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type); |
52 | 21 | const TypedefType *TypedefTy = Type->getAs<TypedefType>(); |
53 | ||
54 | 21 | if (TypeDecl) { |
55 | 13 | if (!TypedefTy) |
56 | 6 | TypeName = TypeDecl->getName().str(); |
57 | ||
58 | 13 | clang::index::generateUSRForDecl(TypeDecl, TypeUSR); |
59 | 13 | } else { |
60 | 8 | clang::index::generateUSRForType(Type, Context, TypeUSR); |
61 | 8 | } |
62 | ||
63 | 21 | return {API.copyString(TypeName), API.copyString(TypeUSR)}; |
64 | 21 | } |
65 | ||
66 | 13 | std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const { |
67 | 13 | SmallString<128> TypeUSR; |
68 | 13 | const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type); |
69 | ||
70 | 13 | if (TypeDecl) |
71 | 13 | clang::index::generateUSRForDecl(TypeDecl, TypeUSR); |
72 | 0 | else |
73 | 0 | clang::index::generateUSRForType(Type, Context, TypeUSR); |
74 | ||
75 | 13 | return std::string(TypeUSR); |
76 | 13 | } |