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 "TypedefUnderlyingTypeResolver.h"
15 #include "clang/Index/USRGeneration.h"
16
17 using namespace clang;
18 using namespace extractapi;
19
20 namespace {
21
getUnderlyingTypeDecl(QualType Type)22 const NamedDecl *getUnderlyingTypeDecl(QualType Type) {
23 const NamedDecl *TypeDecl = nullptr;
24
25 const TypedefType *TypedefTy = Type->getAs<TypedefType>();
26 if (TypedefTy)
27 TypeDecl = TypedefTy->getDecl();
28 if (const TagType *TagTy = Type->getAs<TagType>()) {
29 TypeDecl = TagTy->getDecl();
30 } else if (const ObjCInterfaceType *ObjCITy =
31 Type->getAs<ObjCInterfaceType>()) {
32 TypeDecl = ObjCITy->getDecl();
33 }
34
35 if (TypeDecl && TypedefTy) {
36 // if this is a typedef to another typedef, use the typedef's decl for the
37 // USR - this will actually be in the output, unlike a typedef to an
38 // anonymous decl
39 const TypedefNameDecl *TypedefDecl = TypedefTy->getDecl();
40 if (TypedefDecl->getUnderlyingType()->isTypedefNameType())
41 TypeDecl = TypedefDecl;
42 }
43
44 return TypeDecl;
45 }
46
47 } // namespace
48
49 SymbolReference
getSymbolReferenceForType(QualType Type,APISet & API) const50 TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type,
51 APISet &API) const {
52 std::string TypeName = Type.getAsString();
53 SmallString<128> TypeUSR;
54 const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
55 const TypedefType *TypedefTy = Type->getAs<TypedefType>();
56
57 if (TypeDecl) {
58 if (!TypedefTy)
59 TypeName = TypeDecl->getName().str();
60
61 clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
62 } else {
63 clang::index::generateUSRForType(Type, Context, TypeUSR);
64 }
65
66 return {API.copyString(TypeName), API.copyString(TypeUSR)};
67 }
68
getUSRForType(QualType Type) const69 std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const {
70 SmallString<128> TypeUSR;
71 const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
72
73 if (TypeDecl)
74 clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
75 else
76 clang::index::generateUSRForType(Type, Context, TypeUSR);
77
78 return std::string(TypeUSR);
79 }
80