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/Basic/Module.h"
16#include "clang/Index/USRGeneration.h"
17
18using namespace clang;
19using namespace extractapi;
20
21const NamedDecl *
22TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const {
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
47SymbolReference
48TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type,
49 APISet &API) const {
50 std::string TypeName = Type.getAsString();
51 SmallString<128> TypeUSR;
52 const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
53 const TypedefType *TypedefTy = Type->getAs<TypedefType>();
54 StringRef OwningModuleName;
55
56 if (TypeDecl) {
57 if (!TypedefTy)
58 TypeName = TypeDecl->getName().str();
59
60 clang::index::generateUSRForDecl(D: TypeDecl, Buf&: TypeUSR);
61 if (auto *OwningModule = TypeDecl->getImportedOwningModule())
62 OwningModuleName = OwningModule->Name;
63 } else {
64 clang::index::generateUSRForType(T: Type, Ctx&: Context, Buf&: TypeUSR);
65 }
66
67 return API.createSymbolReference(Name: TypeName, USR: TypeUSR, Source: OwningModuleName);
68}
69
70std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const {
71 SmallString<128> TypeUSR;
72 const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
73
74 if (TypeDecl)
75 clang::index::generateUSRForDecl(D: TypeDecl, Buf&: TypeUSR);
76 else
77 clang::index::generateUSRForType(T: Type, Ctx&: Context, Buf&: TypeUSR);
78
79 return std::string(TypeUSR);
80}
81