xref: /freebsd/contrib/llvm-project/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
18 using namespace clang;
19 using namespace extractapi;
20 
21 const NamedDecl *
getUnderlyingTypeDecl(QualType Type) const22 TypedefUnderlyingTypeResolver::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 
47 SymbolReference
getSymbolReferenceForType(QualType Type,APISet & API) const48 TypedefUnderlyingTypeResolver::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(TypeDecl, TypeUSR);
61     if (auto *OwningModule = TypeDecl->getImportedOwningModule())
62       OwningModuleName = OwningModule->Name;
63   } else {
64     clang::index::generateUSRForType(Type, Context, TypeUSR);
65   }
66 
67   return API.createSymbolReference(TypeName, TypeUSR, OwningModuleName);
68 }
69 
getUSRForType(QualType Type) const70 std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const {
71   SmallString<128> TypeUSR;
72   const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
73 
74   if (TypeDecl)
75     clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
76   else
77     clang::index::generateUSRForType(Type, Context, TypeUSR);
78 
79   return std::string(TypeUSR);
80 }
81