diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2010-09-17 15:54:40 +0000 | 
| commit | 3d1dcd9bfdb15c49ee34d576a065079ac5c4d29f (patch) | |
| tree | 0bbe07708f7571f8b5291f6d7b96c102b7c99dee /tools/libclang/CIndexCXX.cpp | |
| parent | a0482fa4e7fa27b01184f938097f0666b78016dd (diff) | |
Notes
Diffstat (limited to 'tools/libclang/CIndexCXX.cpp')
| -rw-r--r-- | tools/libclang/CIndexCXX.cpp | 124 | 
1 files changed, 124 insertions, 0 deletions
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp new file mode 100644 index 000000000000..3ade5195d8f8 --- /dev/null +++ b/tools/libclang/CIndexCXX.cpp @@ -0,0 +1,124 @@ +//===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the libclang support for C++ cursors. +// +//===----------------------------------------------------------------------===// + +#include "CIndexer.h" +#include "CXCursor.h" +#include "CXType.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" + +using namespace clang; +using namespace clang::cxstring; +using namespace clang::cxcursor; + +extern "C" { + +unsigned clang_isVirtualBase(CXCursor C) { +  if (C.kind != CXCursor_CXXBaseSpecifier) +    return 0; +   +  CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); +  return B->isVirtual(); +} + +enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { +  if (C.kind != CXCursor_CXXBaseSpecifier) +    return CX_CXXInvalidAccessSpecifier; +   +  CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); +  switch (B->getAccessSpecifier()) { +    case AS_public: return CX_CXXPublic; +    case AS_protected: return CX_CXXProtected; +    case AS_private: return CX_CXXPrivate; +    case AS_none: return CX_CXXInvalidAccessSpecifier; +  } +   +  // FIXME: Clang currently thinks this is reachable. +  return CX_CXXInvalidAccessSpecifier; +} + +enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { +  using namespace clang::cxcursor; +   +  switch (C.kind) { +  case CXCursor_ClassTemplate:  +  case CXCursor_FunctionTemplate: +    if (TemplateDecl *Template +                           = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C))) +      return MakeCXCursor(Template->getTemplatedDecl(),  +                          getCursorASTUnit(C)).kind; +    break; +       +  case CXCursor_ClassTemplatePartialSpecialization: +    if (ClassTemplateSpecializationDecl *PartialSpec +          = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>( +                                                            getCursorDecl(C))) { +      switch (PartialSpec->getTagKind()) { +      case TTK_Class: return CXCursor_ClassDecl; +      case TTK_Struct: return CXCursor_StructDecl; +      case TTK_Union: return CXCursor_UnionDecl; +      case TTK_Enum: return CXCursor_NoDeclFound; +      } +    } +    break; +       +  default: +    break; +  } +   +  return CXCursor_NoDeclFound; +} + +CXCursor clang_getSpecializedCursorTemplate(CXCursor C) { +  if (!clang_isDeclaration(C.kind)) +    return clang_getNullCursor(); +     +  Decl *D = getCursorDecl(C); +  if (!D) +    return clang_getNullCursor(); +   +  Decl *Template = 0; +  if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { +    if (ClassTemplatePartialSpecializationDecl *PartialSpec +          = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) +      Template = PartialSpec->getSpecializedTemplate(); +    else if (ClassTemplateSpecializationDecl *ClassSpec  +               = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { +      llvm::PointerUnion<ClassTemplateDecl *, +                         ClassTemplatePartialSpecializationDecl *> Result +        = ClassSpec->getSpecializedTemplateOrPartial(); +      if (Result.is<ClassTemplateDecl *>()) +        Template = Result.get<ClassTemplateDecl *>(); +      else +        Template = Result.get<ClassTemplatePartialSpecializationDecl *>(); +       +    } else  +      Template = CXXRecord->getInstantiatedFromMemberClass(); +  } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { +    Template = Function->getPrimaryTemplate(); +    if (!Template) +      Template = Function->getInstantiatedFromMemberFunction(); +  } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) { +    if (Var->isStaticDataMember()) +      Template = Var->getInstantiatedFromStaticDataMember(); +  } else if (RedeclarableTemplateDecl *Tmpl +                                        = dyn_cast<RedeclarableTemplateDecl>(D)) +    Template = Tmpl->getInstantiatedFromMemberTemplate(); +   +  if (!Template) +    return clang_getNullCursor(); +   +  return MakeCXCursor(Template, getCursorASTUnit(C)); +} +   +} // end extern "C"  | 
