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 const NamedDecl * 21 TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const { 22 const NamedDecl *TypeDecl = nullptr; 23 24 const TypedefType *TypedefTy = Type->getAs<TypedefType>(); 25 if (TypedefTy) 26 TypeDecl = TypedefTy->getDecl(); 27 if (const TagType *TagTy = Type->getAs<TagType>()) { 28 TypeDecl = TagTy->getDecl(); 29 } else if (const ObjCInterfaceType *ObjCITy = 30 Type->getAs<ObjCInterfaceType>()) { 31 TypeDecl = ObjCITy->getDecl(); 32 } 33 34 if (TypeDecl && TypedefTy) { 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 const TypedefNameDecl *TypedefDecl = TypedefTy->getDecl(); 39 if (TypedefDecl->getUnderlyingType()->isTypedefNameType()) 40 TypeDecl = TypedefDecl; 41 } 42 43 return TypeDecl; 44 } 45 46 SymbolReference 47 TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type, 48 APISet &API) const { 49 std::string TypeName = Type.getAsString(); 50 SmallString<128> TypeUSR; 51 const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type); 52 const TypedefType *TypedefTy = Type->getAs<TypedefType>(); 53 54 if (TypeDecl) { 55 if (!TypedefTy) 56 TypeName = TypeDecl->getName().str(); 57 58 clang::index::generateUSRForDecl(TypeDecl, TypeUSR); 59 } else { 60 clang::index::generateUSRForType(Type, Context, TypeUSR); 61 } 62 63 return {API.copyString(TypeName), API.copyString(TypeUSR)}; 64 } 65 66 std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const { 67 SmallString<128> TypeUSR; 68 const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type); 69 70 if (TypeDecl) 71 clang::index::generateUSRForDecl(TypeDecl, TypeUSR); 72 else 73 clang::index::generateUSRForType(Type, Context, TypeUSR); 74 75 return std::string(TypeUSR); 76 } 77