81 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// 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 the37 // USR - this will actually be in the output, unlike a typedef to an38 // anonymous decl39 const TypedefNameDecl *TypedefDecl = TypedefTy->getDecl();40 if (TypedefDecl->getUnderlyingType()->isTypedefNameType())41 TypeDecl = TypedefDecl;42 }43 44 return TypeDecl;45}46 47SymbolReference48TypedefUnderlyingTypeResolver::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 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(TypeDecl, TypeUSR);76 else77 clang::index::generateUSRForType(Type, Context, TypeUSR);78 79 return std::string(TypeUSR);80}81