Coverage Report

Created: 2020-03-31 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/tools/libclang/CIndexCXX.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===//
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
// This file implements the libclang support for C++ cursors.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CIndexer.h"
14
#include "CXCursor.h"
15
#include "CXType.h"
16
#include "clang/AST/DeclCXX.h"
17
#include "clang/AST/DeclTemplate.h"
18
19
using namespace clang;
20
using namespace clang::cxcursor;
21
22
116
unsigned clang_isVirtualBase(CXCursor C) {
23
116
  if (C.kind != CXCursor_CXXBaseSpecifier)
24
0
    return 0;
25
116
  
26
116
  const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
27
116
  return B->isVirtual();
28
116
}
29
30
3.32k
enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
31
3.32k
  AccessSpecifier spec = AS_none;
32
3.32k
33
3.32k
  if (C.kind == CXCursor_CXXAccessSpecifier || 
clang_isDeclaration(C.kind)3.29k
)
34
3.20k
    spec = getCursorDecl(C)->getAccess();
35
116
  else if (C.kind == CXCursor_CXXBaseSpecifier)
36
116
    spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
37
0
  else
38
0
    return CX_CXXInvalidAccessSpecifier;
39
3.32k
  
40
3.32k
  switch (spec) {
41
649
    case AS_public: return CX_CXXPublic;
42
13
    case AS_protected: return CX_CXXProtected;
43
187
    case AS_private: return CX_CXXPrivate;
44
2.47k
    case AS_none: return CX_CXXInvalidAccessSpecifier;
45
0
  }
46
0
47
0
  llvm_unreachable("Invalid AccessSpecifier!");
48
0
}
49
50
0
enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
51
0
  using namespace clang::cxcursor;
52
0
  
53
0
  switch (C.kind) {
54
0
  case CXCursor_ClassTemplate: 
55
0
  case CXCursor_FunctionTemplate:
56
0
    if (const TemplateDecl *Template
57
0
                           = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
58
0
      return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind;
59
0
    break;
60
0
      
61
0
  case CXCursor_ClassTemplatePartialSpecialization:
62
0
    if (const ClassTemplateSpecializationDecl *PartialSpec
63
0
          = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
64
0
                                                            getCursorDecl(C))) {
65
0
      switch (PartialSpec->getTagKind()) {
66
0
      case TTK_Interface:
67
0
      case TTK_Struct: return CXCursor_StructDecl;
68
0
      case TTK_Class: return CXCursor_ClassDecl;
69
0
      case TTK_Union: return CXCursor_UnionDecl;
70
0
      case TTK_Enum: return CXCursor_NoDeclFound;
71
0
      }
72
0
    }
73
0
    break;
74
0
      
75
0
  default:
76
0
    break;
77
0
  }
78
0
  
79
0
  return CXCursor_NoDeclFound;
80
0
}
81
82
78.6k
CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
83
78.6k
  if (!clang_isDeclaration(C.kind))
84
71.9k
    return clang_getNullCursor();
85
6.67k
    
86
6.67k
  const Decl *D = getCursorDecl(C);
87
6.67k
  if (!D)
88
0
    return clang_getNullCursor();
89
6.67k
90
6.67k
  Decl *Template = nullptr;
91
6.67k
  if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
92
541
    if (const ClassTemplatePartialSpecializationDecl *PartialSpec
93
8
          = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
94
8
      Template = PartialSpec->getSpecializedTemplate();
95
533
    else if (const ClassTemplateSpecializationDecl *ClassSpec 
96
28
               = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
97
28
      llvm::PointerUnion<ClassTemplateDecl *,
98
28
                         ClassTemplatePartialSpecializationDecl *> Result
99
28
        = ClassSpec->getSpecializedTemplateOrPartial();
100
28
      if (Result.is<ClassTemplateDecl *>())
101
27
        Template = Result.get<ClassTemplateDecl *>();
102
1
      else
103
1
        Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
104
28
      
105
28
    } else 
106
505
      Template = CXXRecord->getInstantiatedFromMemberClass();
107
6.13k
  } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
108
1.50k
    Template = Function->getPrimaryTemplate();
109
1.50k
    if (!Template)
110
1.49k
      Template = Function->getInstantiatedFromMemberFunction();
111
4.62k
  } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
112
1.36k
    if (Var->isStaticDataMember())
113
24
      Template = Var->getInstantiatedFromStaticDataMember();
114
3.26k
  } else if (const RedeclarableTemplateDecl *Tmpl
115
305
                                        = dyn_cast<RedeclarableTemplateDecl>(D))
116
305
    Template = Tmpl->getInstantiatedFromMemberTemplate();
117
6.67k
  
118
6.67k
  if (!Template)
119
6.62k
    return clang_getNullCursor();
120
55
  
121
55
  return MakeCXCursor(Template, getCursorTU(C));
122
55
}