From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/tools/libclang/CIndexCXX.cpp | 127 +++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 clang/tools/libclang/CIndexCXX.cpp (limited to 'clang/tools/libclang/CIndexCXX.cpp') diff --git a/clang/tools/libclang/CIndexCXX.cpp b/clang/tools/libclang/CIndexCXX.cpp new file mode 100644 index 0000000..240b0f6 --- /dev/null +++ b/clang/tools/libclang/CIndexCXX.cpp @@ -0,0 +1,127 @@ +//===- 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; + + CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); + return B->isVirtual(); +} + +enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { + AccessSpecifier spec = AS_none; + + if (C.kind == CXCursor_CXXAccessSpecifier) + 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 (TemplateDecl *Template + = dyn_cast_or_null(getCursorDecl(C))) + return MakeCXCursor(Template->getTemplatedDecl(), + static_cast(C.data[2])).kind; + break; + + case CXCursor_ClassTemplatePartialSpecialization: + if (ClassTemplateSpecializationDecl *PartialSpec + = dyn_cast_or_null( + 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(D)) { + if (ClassTemplatePartialSpecializationDecl *PartialSpec + = dyn_cast(CXXRecord)) + Template = PartialSpec->getSpecializedTemplate(); + else if (ClassTemplateSpecializationDecl *ClassSpec + = dyn_cast(CXXRecord)) { + llvm::PointerUnion Result + = ClassSpec->getSpecializedTemplateOrPartial(); + if (Result.is()) + Template = Result.get(); + else + Template = Result.get(); + + } else + Template = CXXRecord->getInstantiatedFromMemberClass(); + } else if (FunctionDecl *Function = dyn_cast(D)) { + Template = Function->getPrimaryTemplate(); + if (!Template) + Template = Function->getInstantiatedFromMemberFunction(); + } else if (VarDecl *Var = dyn_cast(D)) { + if (Var->isStaticDataMember()) + Template = Var->getInstantiatedFromStaticDataMember(); + } else if (RedeclarableTemplateDecl *Tmpl + = dyn_cast(D)) + Template = Tmpl->getInstantiatedFromMemberTemplate(); + + if (!Template) + return clang_getNullCursor(); + + return MakeCXCursor(Template, static_cast(C.data[2])); +} + +} // end extern "C" -- cgit v1.2.3