File: TypedefUnderlyingTypeResolver.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (80 lines) | stat: -rw-r--r-- 2,707 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//===- ExtractAPI/TypedefUnderlyingTypeResolver.cpp -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements UnderlyingTypeResolver.
///
//===----------------------------------------------------------------------===//

#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
#include "clang/Basic/Module.h"
#include "clang/Index/USRGeneration.h"

using namespace clang;
using namespace extractapi;

const NamedDecl *
TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const {
  const NamedDecl *TypeDecl = nullptr;

  const TypedefType *TypedefTy = Type->getAs<TypedefType>();
  if (TypedefTy)
    TypeDecl = TypedefTy->getDecl();
  if (const TagType *TagTy = Type->getAs<TagType>()) {
    TypeDecl = TagTy->getDecl();
  } else if (const ObjCInterfaceType *ObjCITy =
                 Type->getAs<ObjCInterfaceType>()) {
    TypeDecl = ObjCITy->getDecl();
  }

  if (TypeDecl && TypedefTy) {
    // if this is a typedef to another typedef, use the typedef's decl for the
    // USR - this will actually be in the output, unlike a typedef to an
    // anonymous decl
    const TypedefNameDecl *TypedefDecl = TypedefTy->getDecl();
    if (TypedefDecl->getUnderlyingType()->isTypedefNameType())
      TypeDecl = TypedefDecl;
  }

  return TypeDecl;
}

SymbolReference
TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type,
                                                         APISet &API) const {
  std::string TypeName = Type.getAsString();
  SmallString<128> TypeUSR;
  const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
  const TypedefType *TypedefTy = Type->getAs<TypedefType>();
  StringRef OwningModuleName;

  if (TypeDecl) {
    if (!TypedefTy)
      TypeName = TypeDecl->getName().str();

    clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
    if (auto *OwningModule = TypeDecl->getImportedOwningModule())
      OwningModuleName = OwningModule->Name;
  } else {
    clang::index::generateUSRForType(Type, Context, TypeUSR);
  }

  return API.createSymbolReference(TypeName, TypeUSR, OwningModuleName);
}

std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const {
  SmallString<128> TypeUSR;
  const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);

  if (TypeDecl)
    clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
  else
    clang::index::generateUSRForType(Type, Context, TypeUSR);

  return std::string(TypeUSR);
}