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 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 50 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 69 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