128 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- 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::cxcursor;
 | |
| 
 | |
| extern "C" {
 | |
| 
 | |
| unsigned clang_isVirtualBase(CXCursor C) {
 | |
|   if (C.kind != CXCursor_CXXBaseSpecifier)
 | |
|     return 0;
 | |
|   
 | |
|   const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
 | |
|   return B->isVirtual();
 | |
| }
 | |
| 
 | |
| enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
 | |
|   AccessSpecifier spec = AS_none;
 | |
| 
 | |
|   if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind))
 | |
|     spec = getCursorDecl(C)->getAccess();
 | |
|   else if (C.kind == CXCursor_CXXBaseSpecifier)
 | |
|     spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
 | |
|   else
 | |
|     return CX_CXXInvalidAccessSpecifier;
 | |
|   
 | |
|   switch (spec) {
 | |
|     case AS_public: return CX_CXXPublic;
 | |
|     case AS_protected: return CX_CXXProtected;
 | |
|     case AS_private: return CX_CXXPrivate;
 | |
|     case AS_none: return CX_CXXInvalidAccessSpecifier;
 | |
|   }
 | |
| 
 | |
|   llvm_unreachable("Invalid AccessSpecifier!");
 | |
| }
 | |
| 
 | |
| enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
 | |
|   using namespace clang::cxcursor;
 | |
|   
 | |
|   switch (C.kind) {
 | |
|   case CXCursor_ClassTemplate: 
 | |
|   case CXCursor_FunctionTemplate:
 | |
|     if (const TemplateDecl *Template
 | |
|                            = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
 | |
|       return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind;
 | |
|     break;
 | |
|       
 | |
|   case CXCursor_ClassTemplatePartialSpecialization:
 | |
|     if (const ClassTemplateSpecializationDecl *PartialSpec
 | |
|           = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
 | |
|                                                             getCursorDecl(C))) {
 | |
|       switch (PartialSpec->getTagKind()) {
 | |
|       case TTK_Interface:
 | |
|       case TTK_Struct: return CXCursor_StructDecl;
 | |
|       case TTK_Class: return CXCursor_ClassDecl;
 | |
|       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();
 | |
|     
 | |
|   const Decl *D = getCursorDecl(C);
 | |
|   if (!D)
 | |
|     return clang_getNullCursor();
 | |
|   
 | |
|   Decl *Template = 0;
 | |
|   if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
 | |
|     if (const ClassTemplatePartialSpecializationDecl *PartialSpec
 | |
|           = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
 | |
|       Template = PartialSpec->getSpecializedTemplate();
 | |
|     else if (const 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 (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
 | |
|     Template = Function->getPrimaryTemplate();
 | |
|     if (!Template)
 | |
|       Template = Function->getInstantiatedFromMemberFunction();
 | |
|   } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
 | |
|     if (Var->isStaticDataMember())
 | |
|       Template = Var->getInstantiatedFromStaticDataMember();
 | |
|   } else if (const RedeclarableTemplateDecl *Tmpl
 | |
|                                         = dyn_cast<RedeclarableTemplateDecl>(D))
 | |
|     Template = Tmpl->getInstantiatedFromMemberTemplate();
 | |
|   
 | |
|   if (!Template)
 | |
|     return clang_getNullCursor();
 | |
|   
 | |
|   return MakeCXCursor(Template, getCursorTU(C));
 | |
| }
 | |
|   
 | |
| } // end extern "C"
 |