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 * 22 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 48 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 70 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